TAPESTRY-2421: Allow Tapestry4/Tapestry5 to be deployed in the same WAR

git-svn-id: https://svn.apache.org/repos/asf/tapestry/tapestry5/tags/hlship-20070503@658288 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/hlship-20080520/.classpath b/hlship-20080520/.classpath
new file mode 100644
index 0000000..f18e8bb
--- /dev/null
+++ b/hlship-20080520/.classpath
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="bin" path="tapestry-annotations/src/main/java"/>
+	<classpathentry kind="src" output="bin" path="tapestry-component-report/src/main/java"/>
+	<classpathentry kind="src" output="bin" path="tapestry-core/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-core/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-core/src/main/resources"/>
+	<classpathentry kind="lib" path="tapestry-core/src/test/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-hibernate/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-hibernate/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-hibernate/src/main/resources"/>
+	<classpathentry kind="lib" path="tapestry-hibernate/src/test/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-ioc/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-ioc/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-ioc/src/main/resources"/>
+	<classpathentry kind="lib" path="tapestry-ioc/src/test/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-spring/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-spring/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-spring/src/main/resources"/>
+	<classpathentry kind="lib" path="tapestry-spring/src/test/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-test/src/main/java"/>
+	<classpathentry kind="lib" path="tapestry-test/src/main/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-tutorial1/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-tutorial1/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-tutorial1/src/main/resources"/>
+	<classpathentry kind="lib" path="tapestry-tutorial1/src/test/resources"/>
+	<classpathentry kind="src" output="bin" path="tapestry-upload/src/main/java"/>
+	<classpathentry kind="src" output="bin-test" path="tapestry-upload/src/test/java"/>
+	<classpathentry kind="lib" path="tapestry-upload/src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/modules/noworkspace"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/.project b/hlship-20080520/.project
new file mode 100644
index 0000000..f58498f
--- /dev/null
+++ b/hlship-20080520/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>tapestry5</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/hlship-20080520/.settings/org.eclipse.jdt.core.prefs b/hlship-20080520/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b3e2286
--- /dev/null
+++ b/hlship-20080520/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,58 @@
+#Sat Sep 15 07:54:57 PDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/hlship-20080520/LICENSE.txt b/hlship-20080520/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/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/hlship-20080520/NOTICE.txt b/hlship-20080520/NOTICE.txt
new file mode 100644
index 0000000..4e5d2f5
--- /dev/null
+++ b/hlship-20080520/NOTICE.txt
@@ -0,0 +1,5 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+Please refer to the NOTICE.txt for each sub-module to
+identify further dependencies.
diff --git a/hlship-20080520/build.xml b/hlship-20080520/build.xml
new file mode 100644
index 0000000..27e7b07
--- /dev/null
+++ b/hlship-20080520/build.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0"?>
+<!-- 
+   Copyright 2007, 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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 default="generate" xmlns:mvn="urn:maven-artifact-ant">
+
+    <!-- Requires Ant 1.7.0 to execute! -->
+
+    <property name="target.dir" value="target"/>
+    <!-- Binary and source distributions, in .zip and .tar.gz formats, go here. -->
+    <property name="dists.dir" value="${target.dir}/dist"/>
+    <!-- Directory that contains the image for the binary distro. -->
+    <property name="binimage.dir" value="${target.dir}/bin-image"/>
+
+    <property name="group" value="org.apache.tapestry"/>
+
+
+    <!-- Read the Maven POM ... -->
+    <xmlproperty file="pom.xml" prefix="pom" keeproot="false"/>
+
+    <!-- ... to obtain the version number. -->
+    <property name="version" value="${pom.version}"/>
+
+    <property name="licenses" value="LICENSE*,*.txt"/>
+    <property name="sources" value="${licenses},pom.xml,src/**"/>
+
+    <property name="bin.zip" value="${dists.dir}/tapestry-bin-${version}.zip"/>
+    <property name="src.zip" value="${dists.dir}/tapestry-src-${version}.zip"/>
+
+    <macrodef name="copyto">
+        <attribute name="dir"/>
+        <attribute name="filesetid"/>
+
+        <sequential>
+            <mkdir dir="@{dir}"/>
+            <copy todir="@{dir}" flatten="true">
+                <fileset refid="@{filesetid}"/>
+            </copy>
+        </sequential>
+    </macrodef>
+
+    <macrodef name="copy-licenses">
+        <attribute name="module"/>
+
+        <sequential>
+            <copy todir="${binimage.dir}" flatten="true">
+                <fileset dir="@{module}" includes="${licenses}"/>
+                <globmapper from="*" to="@{module}-*"/>
+            </copy>
+        </sequential>
+
+
+    </macrodef>
+
+
+    <target name="-maven-setup" unless="maven-ant-tasks.classpath">
+        <path id="maven-ant-tasks.classpath" path="support/maven-ant-tasks-2.0.8.jar"/>
+
+        <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant"
+                 classpathref="maven-ant-tasks.classpath"/>
+
+        <echo>Maven Ant Tasks loaded.</echo>
+    </target>
+
+
+    <target name="assemble-bin" depends="-maven-setup">
+        <echo>Building binary distribution</echo>
+
+        <mvn:dependencies filesetid="bin.dependency.fileset" sourcesfilesetid="bin.dependency.sources.fileset">
+            <dependency groupid="${group}" artifactid="tapestry-upload" version="${pom.version}"/>
+            <dependency groupid="${group}" artifactid="tapestry-hibernate" version="${pom.version}"/>
+            <dependency groupid="${group}" artifactid="tapestry-spring" version="${pom.version}"/>
+
+            <!-- All else will be dragged in. -->
+        </mvn:dependencies>
+
+        <copyto dir="${binimage.dir}/lib" filesetid="bin.dependency.fileset"/>
+        <copyto dir="${binimage.dir}/lib-src" filesetid="bin.dependency.sources.fileset"/>
+
+        <!-- We don't package tapestry-test because of its huge number of large dependencies. -->
+
+        <copy-licenses module="tapestry-ioc"/>
+        <copy-licenses module="tapestry-core"/>
+        <copy-licenses module="tapestry-hibernate"/>
+        <copy-licenses module="tapestry-spring"/>
+        <copy-licenses module="tapestry-upload"/>
+
+        <mkdir dir="${dists.dir}"/>
+
+        <parallel>
+            <zip destfile="${bin.zip}">
+                <fileset dir="${binimage.dir}"/>
+            </zip>
+            <tar destfile="${dists.dir}/tapestry-bin-${version}.tar.gz" compression="gzip">
+                <fileset dir="${binimage.dir}"/>
+            </tar>
+
+            <tar destfile="${dists.dir}/tapestry-bin-${version}.tar.bz2" compression="bzip2">
+                <fileset dir="${binimage.dir}"/>
+            </tar>
+
+        </parallel>
+
+    </target>
+
+    <target name="-announce">
+        <echo>*** Building distribution for project version ${version} ***</echo>
+    </target>
+
+    <target name="assemble-src">
+
+        <zip destfile="${src.zip}">
+            <fileset dir="." includes="${licenses}"/>
+
+            <zipfileset prefix="tapestry-annotations" dir="tapestry-annotations" includes="${sources}"/>
+            <zipfileset prefix="tapestry-core" dir="tapestry-core" includes="${sources}"/>
+            <zipfileset prefix="tapestry-hibernate" dir="tapestry-hibernate" includes="${sources}"/>
+            <zipfileset prefix="tapestry-ioc" dir="tapestry-ioc" includes="${sources}"/>
+            <zipfileset prefix="tapestry-spring" dir="tapestry-spring" includes="${sources}"/>
+            <zipfileset prefix="tapestry-test" dir="tapestry-spring" includes="${sources}"/>
+            <zipfileset prefix="tapestry-upload" dir="tapestry-upload" includes="${sources}"/>
+
+            <zipfileset prefix="tapestry-project" dir="." includes="${sources}"/>
+            <zipfileset prefix="quickstart" dir="quickstart" includes="${sources}"/>
+            <zipfileset prefix="tapestry-component-report" dir="tapestry-component-report" includes="${sources}"/>
+            <zipfileset prefix="tapestry-tutorial1" dir="tapestry-tutorial1" includes="${sources}"/>
+
+        </zip>
+
+        <tar destfile="${dists.dir}/tapestry-src-${version}.tar.gz" compression="gzip" longfile="gnu">
+            <zipfileset src="${src.zip}"/>
+        </tar>
+
+        <tar destfile="${dists.dir}/tapestry-src-${version}.tar.bz2" compression="bzip2" longfile="gnu">
+            <zipfileset src="${src.zip}"/>
+        </tar>
+
+        <echo>Generating MD5 Checksums</echo>
+
+        <checksum fileext=".md5">
+            <fileset dir="${dists.dir}" includes="*.bz2,*.gz,*.zip"/>
+        </checksum>
+    </target>
+
+    <!-- This has to be kept synchronized with the modules, as they change. We include just the "runtime" modules,
+  no the ones used only within a Maven build; if the user is using Maven, they know how to (let Maven) get
+  the code. -->
+
+    <target name="assemble" description="Build distribution files." depends="-announce,assemble-bin,assemble-src">
+
+        <echo>Building source distribution</echo>
+
+        <!-- Now on to the source files. -->
+
+
+        <echo>*** Please sign the distributions using GPG before uploading the files. ***
+
+
+            Signing Mojo: for i in target/dist/*.zip target/dist/*.gz target/dist/*.bz2; do echo $i; gpg --armor
+            --detach-sig $i; done
+
+            Upload Mojo: scp target/dist/* hlship@people.apache.org:public_html/tapestry-releases
+
+        </echo>
+
+
+    </target>
+
+    <target name="clean" description="Remove distribution directory.">
+        <delete dir="${dists.dir}" quiet="true"/>
+        <delete dir="${binimage.dir}" quiet="true"/>
+    </target>
+
+    <target name="generate" description="Generate and deploy the build.">
+        <macrodef name="maven">
+            <attribute name="args"/>
+
+            <sequential>
+                <echo><![CDATA[
+
+*** Executing mvn @{args} ***
+
+]]></echo>
+                <exec searchpath="true" executable="mvn">
+                    <arg line="@{args}"/>
+                </exec>
+            </sequential>
+        </macrodef>
+
+        <maven args="clean"/>
+        <maven args="install"/>
+        <maven args="site site:deploy -Pjavadoc"/>
+        <maven args="deploy -Pdeploy"/>
+        <antcall target="assemble"/>
+    </target>
+
+</project>
\ No newline at end of file
diff --git a/hlship-20080520/pom.xml b/hlship-20080520/pom.xml
new file mode 100644
index 0000000..3c60efd
--- /dev/null
+++ b/hlship-20080520/pom.xml
@@ -0,0 +1,439 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-project</artifactId>
+    <packaging>pom</packaging>
+    <version>5.0.12-SNAPSHOT</version>
+    <name>Tapestry 5 Project</name>
+    <description>Master project for the modules of Tapestry 5.</description>
+    <inceptionYear>2006</inceptionYear>
+    <url>http://tapestry.apache.org/tapestry5/</url>
+    <issueManagement>
+        <system>Jira</system>
+        <url>https://issues.apache.org/jira/browse/TAPESTRY</url>
+    </issueManagement>
+    <licenses>
+        <license>
+            <name>Apache Software License 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+    <organization>
+        <name>Apache Software Foundation</name>
+        <url>http://www.apache.org</url>
+    </organization>
+    <scm>
+        <connection>scm:svn:https://svn.apache.org/repos/asf/tapestry/tapestry5/trunk/</connection>
+        <url>http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/</url>
+    </scm>
+    <developers>
+        <developer>
+            <id>hls</id>
+            <name>Howard M. Lewis Ship</name>
+            <email>hlship@apache.org</email>
+            <url>http://howardlewisship.com</url>
+            <roles>
+                <role>Menace</role>
+            </roles>
+            <timezone>PDT</timezone>
+        </developer>
+        <developer>
+            <id>gredler</id>
+            <name>Daniel Gredler</name>
+            <email>gredler@apache.org</email>
+            <url>http://daniel.gredler.net/</url>
+            <roles>
+                <role>Newbie</role>
+            </roles>
+            <timezone>EDT</timezone>
+        </developer>
+        <developer>
+            <id>dadams</id>
+            <name>Dan Adams</name>
+            <email>dadams@apache.org</email>
+            <roles>
+                <role>Engineer</role>
+            </roles>
+            <timezone>EST</timezone>
+            <organization>Interactive Factory</organization>
+            <organizationUrl>http://ifactory.com</organizationUrl>
+        </developer>
+        <developer>
+            <id>kmenard</id>
+            <name>Kevin Menard</name>
+            <email>kmenard@servprise.com</email>
+            <organization>Servprise International, Inc.</organization>
+            <roles>
+                <role>Developer</role>
+            </roles>
+            <timezone>-5</timezone>
+        </developer>
+        <developer>
+            <id>tedst</id>
+            <name>Ted Steen</name>
+            <email>ted.steen@gmail.com</email>
+            <roles>
+                <role>Developer</role>
+            </roles>
+            <timezone>+1</timezone>
+        </developer>
+    </developers>
+
+    <ciManagement>
+        <system>bamboo</system>
+        <url>http://tapestry.formos.com/bamboo/</url>
+    </ciManagement>
+
+    <mailingLists>
+        <mailingList>
+            <name>Tapestry User List</name>
+            <subscribe>users-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>users-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://markmail.org/search/list:org.apache.tapestry.users</archive>
+        </mailingList>
+        <mailingList>
+            <name>Tapestry Developer List</name>
+            <subscribe>dev-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://markmail.org/search/list:org.apache.tapestry.dev</archive>
+        </mailingList>
+        <mailingList>
+            <name>Tapestry Commits List</name>
+            <subscribe>commits-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>commits-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://markmail.org/search/list:org.apache.tapestry.commits</archive>
+        </mailingList>
+    </mailingLists>
+
+    <modules>
+        <module>tapestry-test</module>
+        <module>tapestry-ioc</module>
+        <module>tapestry-annotations</module>
+        <module>tapestry-core</module>
+
+        <!-- Integrations -->
+
+        <module>tapestry-spring</module>
+        <module>tapestry-hibernate</module>
+        <module>tapestry-upload</module>
+
+
+        <!-- Now we're getting into the archetypes. -->
+
+        <module>quickstart</module>
+
+        <!-- And the Maven plugin. -->
+        <module>tapestry-component-report</module>
+
+        <!-- Tutorials -->
+
+        <module>tapestry-tutorial1</module>
+
+    </modules>
+
+
+    <dependencyManagement>
+        <dependencies>
+
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>servlet-api</artifactId>
+                <version>2.4</version>
+                <scope>provided</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>jboss</groupId>
+                <artifactId>javassist</artifactId>
+                <version>3.7.ga</version>
+            </dependency>
+
+
+            <dependency>
+                <groupId>org.easymock</groupId>
+                <artifactId>easymock</artifactId>
+                <version>2.3</version>
+                <scope>test</scope>
+            </dependency>
+
+            <!-- Now, artifacts created by Tapestry sub-projects. -->
+
+            <dependency>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-ioc</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-test</artifactId>
+                <version>${project.version}</version>
+                <scope>test</scope>
+            </dependency>
+        </dependencies>
+
+    </dependencyManagement>
+
+
+    <build>
+        <pluginManagement>
+
+
+            <plugins>
+
+                <plugin>
+                    <artifactId>maven-plugin-plugin</artifactId>
+                    <version>2.3</version>
+                </plugin>
+
+                <plugin>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <!-- Snapshots after this are broken. %#%#%$#@% Maven. TAPESTRY-1943 -->
+                    <version>2.0-beta-5</version>
+                </plugin>
+
+                <!-- We configure this either way, but it's only active when the "deploy" profile is active. -->
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-gpg-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>sign-artifacts</id>
+                            <phase>verify</phase>
+                            <goals>
+                                <goal>sign</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-assembly-plugin</artifactId>
+                    <configuration>
+                        <descriptorRefs>
+                            <descriptorRef>bin</descriptorRef>
+                            <descriptorRef>src</descriptorRef>
+                        </descriptorRefs>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <configuration>
+                        <source>1.5</source>
+                        <target>1.5</target>
+                        <optimize>true</optimize>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.4</version>
+                    <configuration>
+                        <suiteXmlFiles>
+                            <suiteXmlFile>src/test/conf/testng.xml</suiteXmlFile>
+                        </suiteXmlFiles>
+                        <argLine>-Xmx500m</argLine>
+                        <redirectTestOutputToFile>false</redirectTestOutputToFile>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <configuration>
+                        <archive>
+                            <compress>true</compress>
+                            <index>true</index>
+                        </archive>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <configuration>
+                        <!-- Will be true for profile "deploy" -->
+                        <updateReleaseInfo>${update-release-info}</updateReleaseInfo>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    <profiles>
+        <profile>
+            <!-- Used only when cuttting a full release.  Configures the deploy plugin to mark
+          each artifact as a release (especially important for the archetype). Signs each
+          file deployed (it actually signs way too many files and we have to clean up a bit
+          once deployed). -->
+            <id>deploy</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                    </plugin>
+                </plugins>
+            </build>
+            <properties>
+                <update-release-info>true</update-release-info>
+                <!--  Don't re-run tests as part of the deploy build. -->
+                <maven.test.skip>true</maven.test.skip>
+            </properties>
+        </profile>
+        <!--  Only enable Javadoc as part of the output site when the javadoc profile is active. -->
+        <profile>
+            <id>javadoc</id>
+            <reporting>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <!--  Version 2.3 is broken: See http://jira.codehaus.org/browse/MJAVADOC-145 -->
+                        <version>2.2</version>
+                        <configuration>
+                            <linksource>true</linksource>
+                            <links>
+                                <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
+                                <link>http://java.sun.com/j2ee/1.4/docs/api/</link>
+                                <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+                            </links>
+                            <stylesheetfile>${basedir}/src/site/resources/css/jdstyle.css</stylesheetfile>
+                            <aggregate>true</aggregate>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </reporting>
+        </profile>
+
+        <profile>
+            <!-- bamboo: running inside the Bamboo CI server and deploying to the snapshot repository and nightly web site. -->
+            <id>bamboo</id>
+            <distributionManagement>
+                <repository>
+                    <id>tapestry</id>
+                    <url>file:/var/www/html/maven-repository</url>
+                </repository>
+                <snapshotRepository>
+                    <id>tapestry-snapshot</id>
+                    <url>file:/var/www/html/maven-snapshot-repository</url>
+                </snapshotRepository>
+                <site>
+                    <url>file:/var/www/html/nightly/tapestry5</url>
+                </site>
+            </distributionManagement>
+        </profile>
+
+    </profiles>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>license</report>
+                            <report>scm</report>
+                            <report>project-team</report>
+                            <report>mailing-list</report>
+                            <report>cim</report>
+                            <report>issue-tracking</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+    <repositories>
+        <repository>
+            <id>tapestry</id>
+            <url>http://tapestry.formos.com/maven-repository</url>
+        </repository>
+        <repository>
+            <id>tapestry-snapshot</id>
+            <url>http://tapestry.formos.com/maven-snapshot-repository</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>codehaus.snapshots</id>
+            <url>http://snapshots.repository.codehaus.org</url>
+        </repository>
+        <!-- Pick up the selenium JARs. -->
+        <repository>
+            <id>OpenQA_Release</id>
+            <name>OpenQA Release Repository</name>
+            <url>http://archiva.openqa.org/repository/releases/</url>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>tapestry</id>
+            <url>http://tapestry.formos.com/maven-repository</url>
+        </pluginRepository>
+        <!-- I believe the Cobertura plugin lives here. -->
+        <pluginRepository>
+            <id>codehaus.snapshots</id>
+            <url>http://snapshots.repository.codehaus.org</url>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <!-- Be sure to have the following in your ~/.m2/settings.xml
+
+      <servers>
+      <server> <id>tapestry</id> <username>hlship</username>  </server>
+      </servers>
+
+      Adjust for your personal apache.org user name. Otherwise (especially on Windows),
+      Maven and ssh trip over the user name when remote logging in.
+
+      The <id> element below is used to rendevous with server data from settings.xml
+      in order to determine meta-information such as remote username.
+
+      Don't put your password in settings.xml; just upload to apache.org your
+      public key and make sure to ssh-add before invoking Maven.
+
+    -->
+
+    <distributionManagement>
+        <site>
+            <id>tapestry</id>
+            <url>scpexe://people.apache.org/www/tapestry.apache.org/tapestry5/</url>
+        </site>
+        <repository>
+            <id>tapestry</id>
+            <url>scpexe://people.apache.org/home/hlship/public_html/tapestry-ibiblio-rsynch-repository
+            </url>
+        </repository>
+        <snapshotRepository>
+            <id>tapestry-snapshot</id>
+            <url>scpexe://people.apache.org/home/hlship/public_html/tapestry-snapshot-repository</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+
+    <properties>
+        <!-- Version 2.1 lists everything as 100% covered, weird. -->
+        <cobertura-plugin-version>2.2-SNAPSHOT</cobertura-plugin-version>
+        <update-release-info>false</update-release-info>
+    </properties>
+
+</project>
diff --git a/hlship-20080520/quickstart/.project b/hlship-20080520/quickstart/.project
new file mode 100644
index 0000000..cac59c8
--- /dev/null
+++ b/hlship-20080520/quickstart/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>quickstart</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/hlship-20080520/quickstart/LICENSE-2.0.txt b/hlship-20080520/quickstart/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/quickstart/LICENSE-2.0.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/hlship-20080520/quickstart/NOTICE.txt b/hlship-20080520/quickstart/NOTICE.txt
new file mode 100644
index 0000000..7196130
--- /dev/null
+++ b/hlship-20080520/quickstart/NOTICE.txt
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/pom.xml b/hlship-20080520/quickstart/pom.xml
new file mode 100644
index 0000000..25b428f
--- /dev/null
+++ b/hlship-20080520/quickstart/pom.xml
@@ -0,0 +1,17 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>quickstart</artifactId>
+    <packaging>maven-plugin</packaging>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <name>Tapestry 5 Quickstart Archetype</name>
+    <inceptionYear>2007</inceptionYear>
+    <url>http://tapestry.apache.org/tapestry5/${pom.artifactId}/</url>
+    <description>Archetype for creating a basic Tapestry 5 application, including Eclipse control
+        files.
+    </description>
+</project>
diff --git a/hlship-20080520/quickstart/src/main/resources/META-INF/archetype.xml b/hlship-20080520/quickstart/src/main/resources/META-INF/archetype.xml
new file mode 100644
index 0000000..99a1b19
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/META-INF/archetype.xml
@@ -0,0 +1,33 @@
+<archetype>
+    <!--
+       Copyright 2007, 2008 The Apache Software Foundation
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+    -->
+
+    <id>tapestry-simple</id>
+    <resources>
+        <resource>.classpath</resource>
+        <resource>.project</resource>
+        <resource>src/main/webapp/WEB-INF/web.xml</resource>
+        <resource>src/main/webapp/Index.tml</resource>
+        <resource>src/main/webapp/favicon.ico</resource>
+        <resource>src/main/resources/log4j.properties</resource>
+        <resource>src/test/java/PLACEHOLDER</resource>
+        <resource>src/test/resources/PLACEHOLDER</resource>
+    </resources>
+    <sources>
+        <source>src/main/java/pages/Index.java</source>
+        <source>src/main/java/services/AppModule.java</source>
+    </sources>
+</archetype>
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/.classpath b/hlship-20080520/quickstart/src/main/resources/archetype-resources/.classpath
new file mode 100644
index 0000000..0e644ba
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src/main/java"/>

+	<classpathentry kind="lib" path="src/main/resources"/>

+	<classpathentry kind="src" path="src/test/java"/>

+	<classpathentry kind="lib" path="src/test/resources"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/.project b/hlship-20080520/quickstart/src/main/resources/archetype-resources/.project
new file mode 100644
index 0000000..898a6df
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>${artifactId}</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.maven.ide.eclipse.maven2Builder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+		<nature>org.maven.ide.eclipse.maven2Nature</nature>

+	</natures>

+</projectDescription>

diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/pom.xml b/hlship-20080520/quickstart/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 0000000..198d81c
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,124 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>${groupId}</groupId>
+    <artifactId>${artifactId}</artifactId>
+    <version>${version}</version>
+    <packaging>war</packaging>
+    <name>${artifactId} Tapestry 5 Application</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-core</artifactId>
+            <version>${tapestry-release-version}</version>
+        </dependency>
+
+        <!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the tests)
+will fail, preventing Maven from packaging the WAR. Tapestry includes a large number
+of testing facilities designed for use with TestNG (http://testng.org/), so it's recommended. -->
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.1</version>
+            <classifier>jdk15</classifier>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <finalName>${artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                    <optimize>true</optimize>
+                </configuration>
+            </plugin>
+
+            <!-- Run the application using "mvn jetty:run" -->
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>maven-jetty-plugin</artifactId>
+                <version>6.1.9</version>
+                <configuration>
+                    <!-- Log to the console. -->
+                    <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
+                        <!-- This doesn't do anything for Jetty, but is a workaround for a Maven bug
+                             that prevents the requestLog from being set. -->
+                        <append>true</append>
+                    </requestLog>
+                </configuration>
+            </plugin>
+
+
+            <!-- This changes the WAR file packaging so that what would normally go into WEB-INF/classes
+             is instead packaged as WEB-INF/lib/${artifactId}.jar.  This is necessary for Tapestry
+             to be able to search for page and component classes at startup. Only
+             certain application servers require this configuration, please see the documentation
+             at the Tapestry 5 project page (http://tapestry.apache.org/tapestry5/). -->
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <configuration>
+                    <archiveClasses>true</archiveClasses>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <reporting>
+
+        <!-- Adds a report detailing the components, mixins and base classes defined by this module. -->
+        <plugins>
+            <plugin>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-component-report</artifactId>
+                <version>${tapestry-release-version}</version>
+                <configuration>
+                    <rootPackage>${packageName}</rootPackage>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <repositories>
+        <!-- This can be commented out when the tapestry-release-version is a not a snapshot.
+ The non-snapshot Tapestry artifacts are distributed through the central
+ repository at ibiblio.     -->
+
+        <repository>
+            <id>tapestry-snapshots</id>
+            <url>http://tapestry.formos.com/maven-snapshot-repository/</url>
+        </repository>
+
+        <repository>
+            <id>codehaus.snapshots</id>
+            <url>http://snapshots.repository.codehaus.org</url>
+        </repository>
+       <repository>
+            <id>OpenQA_Release</id>
+            <name>OpenQA Release Repository</name>
+            <url>http://archiva.openqa.org/repository/releases/</url>
+        </repository>        
+    </repositories>
+
+    <pluginRepositories>
+
+        <!-- As above, this can be commented out when access to the snapshot version
+of a Tapestry Maven plugin is not required.   -->
+        <pluginRepository>
+            <id>tapestry-snapshots</id>
+            <url>http://tapestry.formos.com/maven-snapshot-repository/</url>
+        </pluginRepository>
+
+
+    </pluginRepositories>
+
+    <properties>
+        <tapestry-release-version>5.0.12-SNAPSHOT</tapestry-release-version>
+    </properties>
+</project>
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/pages/Index.java b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/pages/Index.java
new file mode 100644
index 0000000..0d4cb3b
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/pages/Index.java
@@ -0,0 +1,14 @@
+package ${packageName}.pages;
+
+import java.util.Date;
+
+/**
+ * Start page of application ${artifactId}.
+ */
+public class Index
+{
+	public Date getCurrentTime() 
+	{ 
+		return new Date(); 
+	}
+}
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/services/AppModule.java b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/services/AppModule.java
new file mode 100644
index 0000000..90761de
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/java/services/AppModule.java
@@ -0,0 +1,111 @@
+package ${packageName}.services;
+
+import java.io.IOException;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.RequestFilter;
+import org.apache.tapestry.services.RequestHandler;
+import org.apache.tapestry.services.Response;
+import org.slf4j.Logger;
+
+/**
+ * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
+ * configure and extend Tapestry, or to place your own service definitions.
+ */
+public class AppModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);
+        
+        // Make bind() calls on the binder object to define most IoC services.
+        // Use service builder methods (example below) when the implementation
+        // is provided inline, or requires more initialization than simply
+        // invoking the constructor.
+    }
+    
+    
+    public static void contributeApplicationDefaults(
+            MappedConfiguration<String, String> configuration)
+    {
+        // Contributions to ApplicationDefaults will override any contributions to
+        // FactoryDefaults (with the same key). Here we're restricting the supported
+        // locales to just "en" (English). As you add localised message catalogs and other assets,
+        // you can extend this list of locales (it's a comma seperated series of locale names;
+        // the first locale name is the default when there's no reasonable match).
+        
+        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
+
+        // The factory default is true but during the early stages of an application
+        // overriding to false is a good idea. In addition, this is often overridden
+        // on the command line as -Dtapestry.production-mode=false
+        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
+    }
+    
+
+    /**
+     * This is a service definition, the service will be named "TimingFilter". The interface,
+     * RequestFilter, is used within the RequestHandler service pipeline, which is built from the
+     * RequestHandler service configuration. Tapestry IoC is responsible for passing in an
+     * appropriate Log instance. Requests for static resources are handled at a higher level, so
+     * this filter will only be invoked for Tapestry related requests.
+     * 
+     * <p>
+     * Service builder methods are useful when the implementation is inline as an inner class
+     * (as here) or require some other kind of special initialization. In most cases,
+     * use the static bind() method instead. 
+     * 
+     * <p>
+     * If this method was named "build", then the service id would be taken from the 
+     * service interface and would be "RequestFilter".  Since Tapestry already defines
+     * a service named "RequestFilter" we use an explicit service id that we can reference
+     * inside the contribution method.
+     */    
+    public RequestFilter buildTimingFilter(final Logger log)
+    {
+        return new RequestFilter()
+        {
+            public boolean service(Request request, Response response, RequestHandler handler)
+                    throws IOException
+            {
+                long startTime = System.currentTimeMillis();
+
+                try
+                {
+                    // The reponsibility of a filter is to invoke the corresponding method
+                    // in the handler. When you chain multiple filters together, each filter
+                    // received a handler that is a bridge to the next filter.
+                    
+                    return handler.service(request, response);
+                }
+                finally
+                {
+                    long elapsed = System.currentTimeMillis() - startTime;
+
+                    log.info(String.format("Request time: %d ms", elapsed));
+                }
+            }
+        };
+    }
+
+    /**
+     * This is a contribution to the RequestHandler service configuration. This is how we extend
+     * Tapestry using the timing filter. A common use for this kind of filter is transaction
+     * management or security.
+     */
+    public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
+            @InjectService("TimingFilter")
+            RequestFilter filter)
+    {
+        // Each contribution to an ordered configuration has a name, When necessary, you may
+        // set constraints to precisely control the invocation order of the contributed filter
+        // within the pipeline.
+        
+        configuration.add("Timing", filter);
+    }
+}
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties
new file mode 100644
index 0000000..5e85d7d
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/resources/log4j.properties
@@ -0,0 +1,28 @@
+# Default to info level output; this is very handy if you eventually use Hibernate as well.
+log4j.rootCategory=info, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=[%p] %c{2} %m%n
+
+# Service category names are the name of the defining module class
+# and then the service id.
+log4j.category.${packageName}.services.AppModule.TimingFilter=info
+
+# Outputs a list of pages, components and mixins at startup.
+log4j.category.org.apache.tapestry.services.TapestryModule.ComponentClassResolver=info
+
+# Outputs startup statistics; time to setup and initialize the registry, and a list of
+# available services.
+log4j.category.org.apache.tapestry.TapestryFilter=info
+
+
+# Turning on debug mode for a page or component will show all of the code changes that occur when the
+# class is loaded.  Turning on debug mode for a page will enable detailed output about
+# the contruction of the page, including the runtime code modifications that occur. Verbose
+# mode is rarely used, as it outputs voluminous details about the rendering of the page.
+
+# log4j.category.${packageName}.pages.Index=debug
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/Index.tml b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/Index.tml
new file mode 100644
index 0000000..51558f6
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/Index.tml
@@ -0,0 +1,18 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>${artifactId} Start Page</title>
+    </head>
+    <body>
+        <h1>${artifactId} Start Page</h1>
+
+        <p> This is the start page for this application, a good place to start your modifications.
+            Just to prove this is live: </p>
+
+        <p> The current time is: ${currentTime}. </p>
+
+
+        <p>
+            [<t:pagelink t:page="Index">refresh</t:pagelink>]
+        </p>
+    </body>
+</html>
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..3fa06f3
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>${artifactId} Tapestry 5 Application</display-name>
+    <context-param>
+        <!-- The only significant configuration for Tapestry 5, this informs Tapestry
+of where to look for pages, components and mixins. -->
+        <param-name>tapestry.app-package</param-name>
+        <param-value>${packageName}</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
+      
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/favicon.ico b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/favicon.ico
new file mode 100644
index 0000000..ffd53d6
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/main/webapp/favicon.ico
Binary files differ
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/java/PLACEHOLDER b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/java/PLACEHOLDER
new file mode 100644
index 0000000..62c163c
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/java/PLACEHOLDER
@@ -0,0 +1 @@
+This placeholder exists to ensure the directory is created. It may be deleted when real files are placed under src/test/java.
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/resources/PLACEHOLDER b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/resources/PLACEHOLDER
new file mode 100644
index 0000000..05ace36
--- /dev/null
+++ b/hlship-20080520/quickstart/src/main/resources/archetype-resources/src/test/resources/PLACEHOLDER
@@ -0,0 +1 @@
+This placeholder exists to ensure the directory is created. It may be deleted when real files are placed under src/test/resources.
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/site/apt/index.apt b/hlship-20080520/quickstart/src/site/apt/index.apt
new file mode 100644
index 0000000..b041223
--- /dev/null
+++ b/hlship-20080520/quickstart/src/site/apt/index.apt
@@ -0,0 +1,141 @@
+ ----
+ Quickstart Archetype
+ ----
+ 
+Quickstart Archetype
+
+  An
+  {{{http://maven.apache.org/plugins/maven-archetype-plugin/index.html}archetype}} is the Maven term for a project template.  Using a Maven archetype, you
+  can create an empty shell of your project in just seconds.
+  
+  What you end up with is a basic Maven project, ready to build and deploy.
+  
+  First, you must decide on your group id, artifact id, and version number. For example, let's choose <<org.example>> for our group id,
+  <<myapp>> for the artifactId, and <<1.0.0-SNAPSHOT>> for the version number.  We also need a root package name, which we'll create by combining the group id
+  and the artifact id.
+  
+  From the command line, you execute the following command (it's a bit of a doozy):
+  
+  mvn archetype:create -DarchetypeGroupId=org.apache.tapestry -DarchetypeArtifactId=quickstart -DgroupId=<<org.example>> -DartifactId=<<myapp>> -DpackageName=<<org.example.myapp>> -Dversion=<<1.0.0-SNAPSHOT>>
+  
+  Maven will use the information from that massive command line to locate and configure the archetype, and produce the project:
+  
++---+
+$ mvn archetype:create -DarchetypeGroupId=org.apache.tapestry -DarchetypeArtifactId=quickstart -DgroupId=org.example -DartifactId=myapp -DpackageName=org.example.myapp -Dversion=1.0.0-SNAPSHOT
+[INFO] Scanning for projects...
+[INFO] Searching repository for plugin with prefix: 'archetype'.
+[INFO] ----------------------------------------------------------------------------
+[INFO] Building Maven Default Project
+[INFO]    task-segment: [archetype:create] (aggregator-style)
+[INFO] ----------------------------------------------------------------------------
+[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
+[INFO] Setting property: velocimacro.messages.on => 'false'.
+[INFO] Setting property: resource.loader => 'classpath'.
+[INFO] Setting property: resource.manager.logwhenfound => 'false'.
+[INFO] ************************************************************** 
+[INFO] Starting Jakarta Velocity v1.4
+[INFO] RuntimeInstance initializing.
+[INFO] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties
+[INFO] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl)
+[INFO] Resource Loader Instantiated: org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader
+[INFO] ClasspathResourceLoader : initialization starting.
+[INFO] ClasspathResourceLoader : initialization complete.
+[INFO] ResourceCache : initialized. (class org.apache.velocity.runtime.resource.ResourceCacheImpl)
+[INFO] Default ResourceManager initialization complete.
+[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
+[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
+[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
+[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Include
+[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
+[INFO] Created: 20 parsers.
+[INFO] Velocimacro : initialization starting.
+[INFO] Velocimacro : adding VMs from VM library template : VM_global_library.vm
+[ERROR] ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
+[INFO] Velocimacro : error using  VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'VM_global_library.vm'
+[INFO] Velocimacro :  VM library template macro registration complete.
+[INFO] Velocimacro : allowInline = true : VMs can be defined inline in templates
+[INFO] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
+[INFO] Velocimacro : allowInlineLocal = false : VMs defined inline will be  global in scope if allowed.
+[INFO] Velocimacro : initialization complete.
+[INFO] Velocity successfully started.
+[INFO] [archetype:create]
+[INFO] artifact org.apache.tapestry:quickstart: checking for updates from central
+[INFO] ----------------------------------------------------------------------------
+[INFO] Using following parameters for creating Archetype: quickstart:RELEASE
+[INFO] ----------------------------------------------------------------------------
+[INFO] Parameter: groupId, Value: org.example
+[INFO] Parameter: packageName, Value: org.example.myapp
+[INFO] Parameter: basedir, Value: /Users/Howard/Documents/workspace/tapestry5/target
+[INFO] Parameter: package, Value: org.example.myapp
+[INFO] Parameter: version, Value: 1.0.0-SNAPSHOT
+[INFO] Parameter: artifactId, Value: myapp
+[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 14,column 22] : ${tapestry-release-version} is not a valid reference.
+[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/pom.xml [line 80,column 26] : ${tapestry-release-version} is not a valid reference.
+[INFO] ********************* End of debug info from resources from generated POM ***********************
+[WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/src/main/webapp/Start.tml [line 11,column 34] : ${currentTime} is not a valid reference.
+[INFO] Archetype created in dir: /Users/Howard/Documents/workspace/tapestry5/target/myapp
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 2 seconds
+[INFO] Finished at: Fri Oct 26 18:12:49 PDT 2007
+[INFO] Final Memory: 5M/9M
+[INFO] ------------------------------------------------------------------------
+$
++---+
+
+  <This first time you try this, you'll probably see a huge amount of messages about Maven downloading stuff, in addition to what's above.>
+
+  Maven has combined your information to form a new directory containing your application.  It has created a Maven pom.xml, a web.xml, a log4j.properties file,
+  and a starting page (Start.html and Start.java) with each file in its correct location. It also creates a starter Tapestry IoC module for the application (AppModule.java).
+  
+  You can run the application directly, using the Jetty servlet container:
+  
++---+
+$ cd myapp
+~/work/myapp
+$ mvn jetty:run
+[INFO] Scanning for projects...
+[INFO] Searching repository for plugin with prefix: 'jetty'.
+[INFO] ----------------------------------------------------------------------------
+[INFO] Building myapp Tapestry 5 Application
+[INFO]    task-segment: [jetty:run]
+[INFO] ----------------------------------------------------------------------------
+[INFO] Preparing jetty:run
+[INFO] [resources:resources]
+[INFO] Using default encoding to copy filtered resources.
+[INFO] [compiler:compile]
+Compiling 1 source file to /Users/Howard/work/myapp/target/classes
+[INFO] [jetty:run]
+[INFO] Configuring Jetty for project: myapp Tapestry 5 Application
+[INFO] Webapp source directory = /Users/Howard/work/myapp/src/main/webapp
+[INFO] web.xml file = /Users/Howard/work/myapp/src/main/webapp/WEB-INF/web.xml
+[INFO] Classes = /Users/Howard/work/myapp/target/classes
+2007-01-23 12:00:56.656::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
+[INFO] Context path = /myapp
+[INFO] Tmp directory = /Users/Howard/work/myapp/target/work
+[INFO] Web defaults =  jetty default
+[INFO] Webapp directory = /Users/Howard/work/myapp/src/main/webapp
+[INFO] Starting jetty 6.1.0pre0 ...
+2007-01-23 12:00:56.739::INFO:  jetty-6.1.0pre0
+[INFO] Classpath = [file:/Users/Howard/work/myapp/target/classes/, file:/Users/Howard/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar, . . .
+[INFO] TapestryFilter Startup time: 306 ms to build IoC Registry, 761 ms overall.
+2007-01-23 12:00:57.962::INFO:  Started SelectChannelConnector @ 0.0.0.0:8080
+[INFO] Started Jetty Server
++---+
+
+  <Again, the first time you do this, you'll see a large number of download messages.>
+  
+  You can now see your running application as {{{http://localhost:8080/myapp}http://localhost:8080/myapp}}.
+  
+  You can hit Control-C to stop Jetty.
+  
+About Snapshots
+
+  Tapestry 5 is currently in a pre-release stage. The Tapestry libraries, including this archetype, are being distributed as snaphots and are rebuilt nightly. Being snapshots, these artifacts are not in the central Maven repository.
+  To make use of the Tapestry snapshots, append  <<<-DremoteRepositories=http://tapestry.formos.com/maven-snapshot-repository/>>> and <<<-DarchetypeVersion=5.0.x-SNAPSHOT>>>  (you'll have to figure out what
+  the lastest snapshot version is) to the command line when invoking Maven. 
+  
+  The generated POM includes entries to automatically search the snapshot repository, so you won't need to use <<<-DremoteRepositories>>> after creating your initial project.
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/quickstart/src/site/resources/images/asf_logo_wide.gif b/hlship-20080520/quickstart/src/site/resources/images/asf_logo_wide.gif
new file mode 100644
index 0000000..b240328
--- /dev/null
+++ b/hlship-20080520/quickstart/src/site/resources/images/asf_logo_wide.gif
Binary files differ
diff --git a/hlship-20080520/quickstart/src/site/site.xml b/hlship-20080520/quickstart/src/site/site.xml
new file mode 100644
index 0000000..cdf324b
--- /dev/null
+++ b/hlship-20080520/quickstart/src/site/site.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Quickstart Archetype">

+    <bannerLeft>

+        <name>Tapestry 5</name>

+        <href>http://tapestry.apache.org/tapestry5/</href>

+        <src>images/tapestry_banner.gif</src>

+    </bannerLeft>

+    <bannerRight>

+        <name>Apache</name>

+        <href>http://www.apache.org</href>

+        <src>images/asf_logo_wide.gif</src>

+    </bannerRight>

+    <skin>

+        <groupId>org.apache.tapestry</groupId>

+        <artifactId>maven-skin</artifactId>

+        <version>1.1</version>

+    </skin>

+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+
+        <menu name="Usage">
+            <item name="Introduction" href="index.html"/>
+        </menu>
+        <menu ref="reports"/>
+
+    </body>
+</project>

diff --git a/hlship-20080520/src/architecture.graffle b/hlship-20080520/src/architecture.graffle
new file mode 100644
index 0000000..4a63bf2
--- /dev/null
+++ b/hlship-20080520/src/architecture.graffle
@@ -0,0 +1,690 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2007-03-03 18:28:45 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{278, 231.4}, {252, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>20</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Templates}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 231.4}, {258, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>19</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Parameter Bindings}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 161.8}, {514, 65}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>18</integer>
+			<key>Shape</key>
+			<string>SemiCircle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0.501961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf2 User Application}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{278, 290}, {252, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>12</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Asset Distribution}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{278, 348.6}, {252, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>11</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 State Management}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 290}, {258, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>10</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Request Dispatch}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{278, 407.2}, {252, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>8</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Localization}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 348.6}, {258, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>7</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Page Caching}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 407.2}, {258, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>6</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Class Transformation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 465.8}, {514, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>5</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>0.8</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Tapestry Inversion of Control Container}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 583}, {514, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>4</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Java 1.5 Runtime}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{16, 524.4}, {514, 54}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>3</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs48 \cf0 Servlet Container}</string>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2007-03-03 18:46:34 -0800</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<string>0</string>
+		<key>DrawerOpen</key>
+		<false/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>209</real>
+		<key>FitInWindow</key>
+		<false/>
+		<key>Frame</key>
+		<string>{{482, 183}, {970, 957}}</string>
+		<key>ShowRuler</key>
+		<true/>
+		<key>ShowStatusBar</key>
+		<true/>
+		<key>VisibleRegion</key>
+		<string>{{-180, -21}, {939, 797}}</string>
+		<key>Zoom</key>
+		<string>1</string>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/src/pagestructure.graffle b/hlship-20080520/src/pagestructure.graffle
new file mode 100644
index 0000000..65d3c48
--- /dev/null
+++ b/hlship-20080520/src/pagestructure.graffle
@@ -0,0 +1,1696 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2007-03-03 18:50:58 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{373.618, 141}, {109.657, 20}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>8</real>
+			</dict>
+			<key>ID</key>
+			<integer>59</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs16 \cf0 org.example.myapp.\
+pages.Start}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{188.327, 301.652}, {83.9941, 22}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>58</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>57</integer>
+				<key>Position</key>
+				<real>0.4177631139755249</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 container resources}</string>
+			</dict>
+			<key>Wrap</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>7</integer>
+			</dict>
+			<key>ID</key>
+			<integer>57</integer>
+			<key>Points</key>
+			<array>
+				<string>{230.324, 337.874}</string>
+				<string>{230.324, 277.5}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{188.327, 408.47}, {83.9941, 22}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>56</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>55</integer>
+				<key>Position</key>
+				<real>0.36486351490020752</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 container resources}</string>
+			</dict>
+			<key>Wrap</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+			<key>ID</key>
+			<integer>55</integer>
+			<key>Points</key>
+			<array>
+				<string>{230.324, 445.088}</string>
+				<string>{230.324, 374.874}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{142.268, 307.582}, {49, 13}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>54</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>53</integer>
+				<key>Position</key>
+				<real>0.37852653861045837</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 container}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+			<key>ID</key>
+			<integer>53</integer>
+			<key>Points</key>
+			<array>
+				<string>{202.857, 338.097}</string>
+				<string>{107.517, 274.655}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{142.191, 410.466}, {49, 13}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>52</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>51</integer>
+				<key>Position</key>
+				<real>0.39187759160995483</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 container}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+			</dict>
+			<key>ID</key>
+			<integer>51</integer>
+			<key>Points</key>
+			<array>
+				<string>{205.353, 445.293}</string>
+				<string>{106.695, 373.009}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{63.9902, 386.147}, {40, 13}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>49</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>48</integer>
+				<key>Position</key>
+				<real>0.2531268298625946</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs18 \cf0 _pager}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>40</integer>
+			</dict>
+			<key>ID</key>
+			<integer>48</integer>
+			<key>Points</key>
+			<array>
+				<string>{83.9902, 374.874}</string>
+				<string>{83.9902, 445.088}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{380.721, 404.623}, {58.985, 24}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>45</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>44</integer>
+				<key>Position</key>
+				<real>0.42455002665519714</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs20 \cf0 containing element}</string>
+			</dict>
+			<key>Wrap</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{183.824, 445.588}, {93, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>42</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Component Resources}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{319.118, 445.588}, {109.657, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>11</real>
+			</dict>
+			<key>ID</key>
+			<integer>41</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.701961</string>
+						<key>g</key>
+						<string>0.701961</string>
+						<key>r</key>
+						<string>0.701961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs22 \cf1 CPE: grid.pager}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35.2157, 445.588}, {97.549, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>40</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.25098</string>
+						<key>r</key>
+						<string>0.501961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs28 \cf1 GridPager}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{407.721, 236.765}, {89.4608, 20}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>8</real>
+			</dict>
+			<key>ID</key>
+			<integer>39</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs16 \cf0 Component Page Element}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{380.721, 302.271}, {58.985, 24}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>37</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>36</integer>
+				<key>Position</key>
+				<real>0.42455002665519714</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs20 \cf0 containing element}</string>
+			</dict>
+			<key>Wrap</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{183.824, 338.374}, {93, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>34</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Component Resources}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{349, 338.374}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Font</key>
+				<string>Futura-Medium</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>33</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.701961</string>
+						<key>g</key>
+						<string>0.701961</string>
+						<key>r</key>
+						<string>0.701961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 CPE: grid}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{56.9902, 338.374}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>32</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.25098</string>
+						<key>r</key>
+						<string>0.501961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs28 \cf1 Grid}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{361.003, 182.654}, {83.9941, 12}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>10</real>
+			</dict>
+			<key>ID</key>
+			<integer>30</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>28</integer>
+				<key>Position</key>
+				<real>0.5</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs20 \cf0 containing page}</string>
+			</dict>
+			<key>Wrap</key>
+			<string>YES</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{301.304, 200.16}, {67, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>27</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>26</integer>
+				<key>Position</key>
+				<real>0.41252449154853821</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs20 \cf0 root element}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{56.9902, 241}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>8</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.25098</string>
+						<key>r</key>
+						<string>0.501961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs28 \cf1 Start}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{183.824, 241}, {93, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>7</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Component Resources}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{349, 241}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>6</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.701961</string>
+						<key>g</key>
+						<string>0.701961</string>
+						<key>r</key>
+						<string>0.701961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs28 \cf1 CPE}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{308, 141}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>5</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.701961</string>
+						<key>g</key>
+						<string>0.701961</string>
+						<key>r</key>
+						<string>0.701961</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Futura-Medium;}
+{\colortbl;\red255\green255\blue255;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs28 \cf2 Page}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>47</integer>
+			<key>Points</key>
+			<array>
+				<string>{133.265, 463.588}</string>
+				<string>{183.324, 463.588}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>40</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>33</integer>
+			</dict>
+			<key>ID</key>
+			<integer>44</integer>
+			<key>Points</key>
+			<array>
+				<string>{393.179, 445.243}</string>
+				<string>{407.721, 431.373}</string>
+				<string>{407.721, 383.824}</string>
+				<string>{396.808, 374.38}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>41</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>41</integer>
+			</dict>
+			<key>ID</key>
+			<integer>43</integer>
+			<key>Points</key>
+			<array>
+				<string>{277.324, 463.588}</string>
+				<string>{318.618, 463.588}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+			<key>ID</key>
+			<integer>38</integer>
+			<key>Points</key>
+			<array>
+				<string>{111.49, 356.374}</string>
+				<string>{183.324, 356.374}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+			<key>ID</key>
+			<integer>36</integer>
+			<key>Points</key>
+			<array>
+				<string>{399.887, 341.238}</string>
+				<string>{407.721, 336.275}</string>
+				<string>{407.721, 290.196}</string>
+				<string>{394.659, 277.351}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>33</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>33</integer>
+			</dict>
+			<key>ID</key>
+			<integer>35</integer>
+			<key>Points</key>
+			<array>
+				<string>{277.324, 356.374}</string>
+				<string>{348.5, 356.374}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Points</key>
+			<array>
+				<string>{392.23, 240.625}</string>
+				<string>{403, 228.431}</string>
+				<string>{403, 178.922}</string>
+				<string>{361.274, 158.823}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+			<key>ID</key>
+			<integer>26</integer>
+			<key>Points</key>
+			<array>
+				<string>{334.804, 177}</string>
+				<string>{334.804, 217.647}</string>
+				<string>{357.715, 240.646}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>7</integer>
+			</dict>
+			<key>ID</key>
+			<integer>25</integer>
+			<key>Points</key>
+			<array>
+				<string>{111.49, 259}</string>
+				<string>{183.324, 259}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+			<key>ID</key>
+			<integer>24</integer>
+			<key>Points</key>
+			<array>
+				<string>{277.324, 259}</string>
+				<string>{348.5, 259}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>7</integer>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2007-03-04 18:47:00 -0800</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<string>0</string>
+		<key>DrawerOpen</key>
+		<false/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>209</real>
+		<key>FitInWindow</key>
+		<false/>
+		<key>Frame</key>
+		<string>{{368, 84}, {1197, 1494}}</string>
+		<key>ShowRuler</key>
+		<false/>
+		<key>ShowStatusBar</key>
+		<true/>
+		<key>VisibleRegion</key>
+		<string>{{0, 0}, {579.412, 676.471}}</string>
+		<key>Zoom</key>
+		<string>2.04</string>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/src/site/apt/dev/bible.apt b/hlship-20080520/src/site/apt/dev/bible.apt
new file mode 100644
index 0000000..bc5b9ab
--- /dev/null
+++ b/hlship-20080520/src/site/apt/dev/bible.apt
@@ -0,0 +1,231 @@
+ ----
+ Tapestry Developer's Bible
+ ----
+
+Tapestry Developer's Bible
+
+ This is a semi-random outpouring of thoughts related to being a Tapestry committer.
+
+IDE
+
+ <<IntelliJ>>.  It's a free license for all committers and it's just better. You'll love it after the
+ first couple of days fumbling because you're so used to Eclipse bending you over and doing unspeakable things.
+
+ There are shared code formatting settings in <<<support/idea-settings.jar>>>.  This will prevent
+ unexpected conflicts due to formatting.
+
+Copyrights
+
+  All source files should have a copyright comment on top, except where such a comment
+  would interfere with its behavior.  For example, component template files omit the comment.
+
+  The year on the copyright should be updated as a file changes.  As you are reviewing your changes
+  before checking them in, try to check the coyright date, and add the current year to the list if not
+  present.
+
+Commit Messages
+
+  Always provide a commit message.  I generally try to work off the JIRA, so my commit message is often:
+
+----
+TAPESTRY-1234: Make the Foo Widget more Ajax-tastic!
+----
+
+  It is <<very important>> to include the JIRA issue id in the commit.  This is used in many places:
+  JIRA links issues to the SVN commits for that issue (very handy for seeing what changed
+  as part of a bug fix).  Bamboo (the continuous integration server) does something similar.
+
+JIRA Procedures
+
+  All Tapestry committers should be registerred with JIRA and part of the tapestry-developers JIRA group.
+
+  I work the following JIRA list:
+  {{{https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&requestId=12311597}JIRA Work Queue}}.
+
+
+  Ideally, we would always work top priortity to low priority.  I (Howard) sometimes jump out of order,
+  if there's something cool to work on that fits in an available time slot.  Alternately, you are always
+  allowed to change the priority of a bug before or as you work it.
+
+* Starting work  
+
+  When you start to work on an issue, make sure it is <<assigned to you>> and use the <<start progress>>
+  option.
+
+  I often add comments about the state of the fix, or the challenges.  This often spurs the Issue's adder to
+  provide more details.
+
+  I often update the issue description to make it more legible and more precise, i.e., "NPE in CheckUpdates"
+  might become "NullPointerException when checking for updates to file that have been deleted".  Verbose is good.
+
+* Closing bugs  
+
+  Is it a bug fix without tests?  <<No.>>  In some cases, I write new tests to prove that an issue is not valid and
+  then leave
+  the tests in place -- the close the bug as invalid.
+
+  A good plan is to write a test that fails then work the code until the test passes.
+  I'm also surprised by how often code works in a unit test but fails unexpectedly in an integration test.
+  As the G-Man says, <"Expect unforseen consequences">.
+
+  When you check in a fix, you should <<close>> the issue and make sure the <<fix release>> is correct.
+
+  We're playing fast and loose -- a better procedure would be to mark the bug resolved and verify
+  the fix before closing it.  That's ok, we have a community to double check our work :-).
+
+  For anything non-trivial, wait for the Bamboo server to build.  It catches a lot of things ... such as
+  files that were not added to SVN.  And even IntelliJ has a bit of trouble with wildly refactored code.
+  Bamboo will catch all that.
+
+* Invalid issues and duplicates
+
+  Always provide comments about <why> an issue is invalid (<"A Ruby implementation of Tapestry is out of scope for the project.">),
+  or at least, a link to the duplicate issues.
+
+  Close the issue but <<make sure the fix release is blank>>.  Otherwise, the issue <<will be listed
+  in the release notes>>, which we don't want.
+
+Copyrights
+
+  The ASF copyright must appear on all Java source files.  Technically it should appear on all non-binary
+  files in the repository.
+
+  As you make changes to files, update the copyright to add the current year to the list.  The goal is that the copyright
+  notice includes the year in which files change.  When creating a new file, don't back date the copyright year ... start
+  with the current year.  Try not to change the copyright year on files that haven't actually changed.
+
+  IntelliJ has a great comparison view: Cmd-9 to see the local changes, the Cmd-D to see the differences.
+  I whip through the changes (using Cmd-forward arrow) and make sure copyrights are up to date as I review the changes
+  prior to a commit.
+
+Public vs. Private/Internal
+
+  This is a real big deal.  As long as code is in the internal package, we have a high degree of carte-blanche
+  to change it.  As soon as code is public, we become handcuffed to backwards compatibility.
+
+  <<Interfaces are public, implementations are private>>.  You can see this is the bulk of the code, where
+  org.apache.tapestry.services is almost all interfaces and the implementations are
+  in org.apache.tapestry.internal.services.
+
+  Many more services have both the interface and the implementation in org.apache.tapestry.internal.services.
+
+  We absolutely <<do not>> want to make Page or ComponentPageElement public.  You will often see
+  public service facades that take a page name as a method parameter,
+  and convert it to a page instance before invoking methods
+  on internal services.
+
+Evolving Components
+
+  We do not have a specific plan for this yet. Future Tapestry 5 will add features to allow clean renames
+  of parameters, and a way to deprecated and eventually remove components.
+
+Code Style
+
+  Yes, I (Howard) use leading underscores for field names.  I just prefer that to prefixing with <<<this.>>>, you don't
+  have to do so, but try to make your code blend in when modifying existing source.
+
+  Long ago, Tapestry code use the regrettable "leading-I-on-interfaces" style.  Don't do that.  Everythings an interface.
+
+  I prefer braces on a new line (and thus, open braces lined up with close braces), so that's what the default
+  code formatting is set up for. I sometimes omit braces for trivial if statements, such as <<<return;>>>.  I use a lot
+  of vertical whitespace to break methods into logical sections.
+
+  We're coding Java, not Pascal; I'd much rather see a few checks early on with quick returns or exceptions than
+  have ten-levels deep block nesting just so a method can have a single return statement. In other words, <else
+   considered harmful>. Low code complexity is
+  better, more readable, more maintainable code.
+
+  I don't bother alphabetizing things, because I have an IDE that lets me jump around easily.
+
+  <<Final is the new private.>>  Final fields are great for multi-threaded code.  Especially when creating
+  service implementations with dependencies, store that dependencies into final fields. Once we're all running
+  on 100 core workstations, you'll thank me.  Seriously, Java's memory model is seriously twisted stuff, and
+  assigning to a non-final field from a constructor opens up a tiny window of non-thread safety.
+
+Comments
+
+  Comments are overwhelmingly important.  Try to capture the <why> of a class or method.   Add lots
+  of links, to code that will be invoked by the method, to related methods or classes, and so forth.
+
+  Comment the <interfaces> and don't get worked up on the <implementations>.  Javadoc does a perfectly
+  good job of copying interface comments to implementations, so this falls under the <Dont Repeat Yourself>
+  guideline.
+
+  Be very careful about documenting what methods can accept null, and what methods may return null.
+
+Class and Method Naming Conventions
+
+ Naming things is hard.  Names that make sense to one person won't to another.
+
+ That being said, I've tried to be somewhat consistent with naming.  Not perfectly.
+
+ [Factory, Creator]
+ A factory class creates new objects. Methods will often be prefixed with "create"
+ or "new".  Don't expect a Factory to cache anything, it just creates new things.
+
+ [Source]
+ A source is a level up from a Factory.  It <may> combine multiple factories together.
+ It <usually> will cache the result.  Method are often prefixed with "get".
+
+ [Find vs. Get]
+ For methods:  A "find" prefix indicates that a non-match is valid and null may be returned.
+ A "get" prefix indicates that a non-match is invalid and an exception will be thrown
+ in that case (and null will never be returned).
+
+ [Contribution]
+ A data object usually associated with a Tapestry IoC service's configuration.
+
+ [Filter]
+ Part of a pipeline, where there's an associated main interface,
+ and the Filter wraps around that main interface.  Each main interface
+ method is duplicated in the Filter, with an extra parameter used
+ to chain the interface.
+
+ [Manager]
+ Often a wrapper around a service configuration, it provides access
+ to the contributed values (possibly after some transformation).
+
+ [To]
+ A method prefix that indicates a conversion or coersion from one type to another.
+
+ [Worker]
+ An object that peforms a specific job.  Workers will be stateless, but will be passed
+ a stateful object to perform some operation upon.
+
+ [Builder]
+ An object whose job is to create other objects, typically in the context of
+ creating a core service implementation for a Tapestry IoC service (such as PipelineBuilder
+ or ChainBuilder).
+
+ [Support]
+ An object that provides supporting operations to other objects; this is a kind of "loose aggregation".
+
+ [Parameters]
+ An data object that holds a number of related values that would otherwise be seperate
+ parameter values to a method. This tends to streamline code (especially when using
+ a Filter interface) and allows the parameters to be changed without changing the method signature.
+
+ [Strategy]
+ An object that "plugs into" some other code, allowing certain decisions to be deferred
+ to the Strategy. Often a Strategy is selected based on the type of some object
+ being operated upon.
+
+ [Context]
+ Captures some stateful information that may be passed around between stateless services.
+
+ [Constants]
+ A non-instantiable class that contains public static fields that are referenced in multiple places.
+
+ [Hub]
+ An object that allows listeners to be registered. Often includes a method prefixed with "trigger"
+ that will send notifications to listeners.
+ 
+toString()
+
+ Objects that are exposed to user code should generally implement a meaningful toString() method.
+ And that method should be tested.
+
+ 
+
+
+
diff --git a/hlship-20080520/src/site/apt/dev/checklist.apt b/hlship-20080520/src/site/apt/dev/checklist.apt
new file mode 100644
index 0000000..41d4c7c
--- /dev/null
+++ b/hlship-20080520/src/site/apt/dev/checklist.apt
@@ -0,0 +1,209 @@
+ ----
+ Release Checklist
+ ----
+ 
+Release Checklist
+
+  Quick notes on how to prepare a new release of Tapestry.
+  
+Preparation
+
+  Send an announcement to the list, asking them to hold off on trunk checkins.
+  
+  Make <<sure>> (<<sure!>>) you have the latest copies of the Tapestry 5 project and all its modules.
+  
+Bumping the Version Number
+
+  At this point, the version number of the project POM is 5.0.x-SNAPSHOT. 
+  Modules inherit their version number from the project POM version number.
+  
+  We need to update the version number across all modules, from 5.0.x-SNAPSHOT to just 5.0.x.
+  
+  The Ruby script,  support/update-versions, can change the version numbers everywhere they need changing.  A single parameter on the command line is the new version number.
+    	 
+  From the root folder, execute <<<mvn clean install>>>; this should take a couple of minutes.
+  
+Add The Next Release to JIRA
+
+  Use:
+  
+  {{{https://issues.apache.org/jira/secure/project/ManageVersions.jspa?pid=10573}https://issues.apache.org/jira/secure/project/ManageVersions.jspa?pid=10573}}
+  
+  to add the next release.  Any bugs that are fixed will be tagged with this new version number (5.0.x + 1).  Example: after building out 5.0.3, create 5.0.4.    
+  Schedule it above the existing version.
+  
+  While you're there, use the <<Release>> option for the previous release; this ensures that any existing bugs are not marked as pending for the old release,
+  and sets the date of release in JIRA.  
+  
+Generate the Release Notes
+
+  JIRA has the ability to generate release notes automatically (this is why it is so important to keep the fix version number accurate).
+  
+  {{{https://issues.apache.org/jira/secure/ConfigureReleaseNote.jspa?projectId=10573}https://issues.apache.org/jira/secure/ConfigureReleaseNote.jspa?projectId=10573}}
+  
+  Select the correct version, in HTML format.
+  
+  Paste the notes to the <<top>> of tapestry-project/src/site/xdoc/release-notes.xdoc
+  
+  Wrap the title ("Release Notes - Tapestry - Version 5.0.x") inside an \<h1\> element.
+  
+Build and Deploy Site
+
+  Execute <<<mvn site site:deploy -Pjavadoc>>>
+  
+  This will build the project site and each of the module sites.  The sites go to a server that is periodically copied over to the live server; it can take up to an hour
+  for changes to show up.
+  
+  The -Pjavadoc activates a profile that ensure that Javadoc is generated (normally, Javadoc is not generated as it is so time consuming).
+  
+Build and Deploy Artifacts
+
+  Execute <<<mvn deploy -Pdeploy>>>
+  
+  This will sign the artifacts using GPG and deploy them.  Alas, due to bugs in Maven, it has a tendency to sign the signature files (".asc") and upload those as well; we'll clean that up in a bit.
+  
+  Since the version number is not longer -SNAPSHOT, each file
+  will be published to the Tapestry Snapshot Repository ({{{http://people.apache.org/~hlship/tapestry-snapshot-repository/}http://people.apache.org/~hlship/tapestry-snapshot-repository/}}).
+  Once the vote on the release is approved, the files will be moved from there to the Apache Ibiblio Sync directory, and from there to the world.   
+  
+Binary / Source Distributions
+
+  An Ant script is used to build traditional binary and source distributions.  It requires Ant <<1.7.0>>.
+  
+  Execute <<<ant>>>.
+  
+----
+$ ant
+Buildfile: build.xml
+
+assemble:
+     [echo] *** Building distribution for project version 5.0.5 ***
+     [echo] Building binary distribution
+      [zip] Building zip: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-bin-5.0.5.zip
+      [tar] Building tar: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-bin-5.0.5.tar.gz
+      [tar] Building tar: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-bin-5.0.5.tar.bz2
+     [echo] Building source distribution
+      [zip] Building zip: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-src-5.0.5.zip
+      [tar] Building tar: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-src-5.0.5.tar.gz
+      [tar] Building tar: /Users/Howard/Documents/workspace/tapestry-project/target/dist/tapestry-src-5.0.5.tar.bz2
+     [echo] Generating MD5 Checksums
+     [echo] *** Please sign the distributions using GPG before uploading the files. ***
+
+BUILD SUCCESSFUL
+Total time: 6 minutes 0 seconds
+----
+
+  Now, sign the distribution, using <<<for i in target/dist/*.zip target/dist/*.gz target/dist/*.bz2; do echo $i; gpg --armor --detach-sig $i; done>>>
+  
+  (I set this up as an alias).  You'll be prompted for your GPG password six times (sorry!).
+  
+  Finally, copy the distros up to the tapestry-releases directory, with <<<scp target/dist/* hlship@people.apache.org:public_html/tapestry-releases>>>
+  
+  (I set this up as an alias, too).
+  
+  
+Cleaning up
+
+  Alas, Maven leaves a bit of junk behind to be cleaned up.
+  
+  You must login to people.apache.org and perform a couple of cleanups.  Starting in <<<~hlship/public_html>>>, you must execute:
+  
+  <<<find tapestry-ibiblio-rsynch-repository -name \\*.asc.\\* | xargs rm>>>
+  
+  This deletes lots of excess GnuPG signature files that were inadvertently created and uploaded.
+  
+  And, of course, permissions are never quite right:
+  
+  <<<chmod -R ug+w tapestry-ibiblio-rsynch-repository/ tapestry-releases/>>>
+       
+Commit Changes
+
+  Commit changes to the project.
+  
+Tag In Subversion
+
+  You must the source in SVN, copying the trunk folder to tags/releases/5.0.x.  The SVN tags/releases folder must
+  already exist, the specific folder must not.
+
+  I do this from Eclipse, but the command line (for example) is pretty straight forward (and I may create a script to help with this):
+    
+  <<<copy -rHEAD https://svn.apache.org/repos/asf/tapestry/tapestry5/trunk https://svn.apache.org/repos/asf/tapestry/tapestry5/tags/releases/5.0.x>>>
+    
+
+
+Run the vote
+
+	Send a "[VOTE] Tapestry Release 5.0.x" message onto the dev@tapestry.apache.org mailing list.
+	
+----
+I've created and uploaded a release of Tapestry 5.0.x, ready to be voted upon.
+
+The files are uploaded to:
+
+http://people.apache.org/~hlship/tapestry-releases/
+
+and a Maven repository:
+
+http://people.apache.org/~hlship/tapestry-ibiblio-rsynch-repository/
+
+Please examine these files to determine if a new preview release, 5.0.x, is ready.
+
+I've also created a 5.0.x tag in Subversion:
+
+http://svn.apache.org/viewvc/tapestry/tapestry5/tags/releases/5.0.x/
+
+On a successful vote, I'll move the files from these directories to the proper distribution directories.
+
+Vote will run for three days; on success I'll move the voted artifacts into place and send out appropriate notifications. 
+----
+
+On success: roll it out!
+  
+	You need to ssh to people.apache.org.
+	
+----
+> cd ~hlship/public_html/tapestry-releases/
+> chmod 664 *
+> mv * /www/www.apache.org/dist/tapestry/
+> rm /www/www.apache.org/dist/tapestry/*-5.0.4*
+----
+
+  Adjust the last line to remove the previous release.  Only the current release should be in the dist folder.
+  
+  The Maven artifacts are a little trickier, since there's the whole Maven folder hiearchy to deal with.
+  
+----
+> cd ~hlship/public_html/tapestry-ibiblio-rsynch-repository/
+> rsync -av * /www/people.apache.org/repo/m2-ibiblio-rsync-repository
+----
+
+  The aritfacts copied to m2-ibiblio-rsync-repository will (eventually) by copied to the central Maven ibiblio repository, where they will be
+  visible to every Maven user.
+  
+  
+Wait 24 Hours
+
+	It takes up to 24 hours for all the mirrors to sync, to don't go announcing the new release just yet.
+	
+Update the Downloads Page
+
+ 	The downloads page is inside the tapestry-site project as,  src/site/apt/download.apt.
+ 	
+ 	If you should edit the large block concerning Tapestry 5, updating the version number. There is no need (at least until we have a final release of Tapestry 5) to keep the links
+ 	to the old version number.
+ 	
+ 	After making the changes, and checking it in to Subversion, you can build and deploy the site.
+ 	
+ 	After deployment, it takes up to an hour for the changes to be visible.
+  
+Advance the Version Numbers
+
+	This is optional but is useful, go find all those version numbers again and set them to 5.0.(n+1)-SNAPSHOT.  So, if you just released 5.0.3, set all the version numbers to 5.0.4-SNAPSHOT.    Again,
+	use the support/update-versions Ruby script.  
+    
+    
+    
+    
+    
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/dev/env.apt b/hlship-20080520/src/site/apt/dev/env.apt
new file mode 100644
index 0000000..dcf7ae4
--- /dev/null
+++ b/hlship-20080520/src/site/apt/dev/env.apt
@@ -0,0 +1,26 @@
+ ---

+ Developer Info

+ ---

+ 

+Development Environment

+

+  Developing Tapestry requires the use of JDK 1.5.

+  

+  Effectively, you should have the following tools:

+  

+  * Maven 2.0.8

+  

+  * Ant 1.7.0

+  

+  * IDEA IntelliJ

+

+  []

+

+  IntelliJ is available to all Tapestry committers under their generous open-source policy.  This is one of the

+  perks of being invited as a committer.

+  

+Builds

+

+  Tapestry 5 is built by Maven 2.

+  

+  You can build individual modules, or (from the root folder) build everything.
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/index.apt b/hlship-20080520/src/site/apt/index.apt
new file mode 100644
index 0000000..7e9e492
--- /dev/null
+++ b/hlship-20080520/src/site/apt/index.apt
@@ -0,0 +1,282 @@
+ ----

+ Apache Tapestry 5

+ ----

+ 

+What is Tapestry?

+

+ Tapestry is an open-source framework for creating dynamic, robust, highly scalable web applications in Java. 

+ Tapestry complements and builds upon the standard Java Servlet API, and so it works in any servlet container or application server.

+

+ Tapestry divides a web application into a set of pages, each constructed from components. This provides a consistent structure, 

+ allowing the Tapestry framework to assume responsibility for key concerns such as URL construction and dispatch, persistent state 

+ storage on the client or on the server, user input validation, localization/internationalization, and exception reporting. 

+ Developing Tapestry applications involves creating HTML templates using plain HTML, and combining the templates with small amounts of 

+ Java code. In Tapestry, you create your application in terms of objects, and the methods and properties of those 

+ objects -- and specifically not in terms of URLs and query parameters. 

+ Tapestry brings true object oriented development to Java web applications.

+

+ Tapestry is specifically designed to make creating new components very easy, 

+ as this is a routine approach when building applications. 

+ 

+ Tapestry is architected to scale from tiny, single-page applications all the way up to

+ massive applications consisting of hundreds of individual pages, developed by

+ large, diverse teams. Tapestry easily integrates with any kind of backend, including JEE, 

+ HiveMind, Spring and Hibernate.

+ 

+ It's more than what you <can> do with Tapestry ... it's also <how> you do it!  Tapestry is a vastly productive environment.

+ Java developers love it because they can make <Java code> changes and see them immediately ... no redeploy, no restart! And it's blazingly fast to boot

+ (even when files change). Designers

+ love it because Tapestry templates are so close to ordinary HTML, without all the cruft and confusion seen in JavaServer Pages. Managers love it because

+ it makes it easy for large teams to work together, and because they know important features (including localization) are baked right in. Once you work

+ in Tapestry there's no going back!

+

+ Tapestry is released under the Apache Software Licence 2.0.

+

+Where To Go

+

+ You are currently reading the Tapestry 5 project site.  Tapestry itself is broken into several modules:

+ 

+*---+---+

+| {{{tapestry-annotations/index.html}tapestry-annotations}} | A few Tapestry annotations that may be used with non-component classes. |

+*---+---+

+| {{{tapestry-core/index.html}tapestry-core}} | The core implementation of the Tapestry framework, including all the primary built-in components. |

+*---+---+

+| {{{tapestry-hibernate/index.html}tapestry-hibernate}} |  Integration with the {{{http://hibernate.org}Hibernate}} Object/Relational Mapping framework. |

+*---+---+

+| {{{tapestry-ioc/index.html}tapestry-ioc}} |  The Tapestry Inversion of Control Container. |

+*---+---+

+| {{{tapestry-spring/index.html}tapestry-spring}} |  Integration with {{{http://springframework.org}Spring}}. |

+*---+---+

+| {{{tapestry-test/index.html}tapestry-test}} |  Tapestry test utilities. |

+*---+---+

+| {{{tapestry-upload/index.html}tapestry-upload}} |  Tapestry file upload component. |

+*---+---+

+ 

+  Or, you can start with the {{{screencast.html}screencasts}}, which give you a better idea about how Tapestry fits together.

+

+Roadmap

+

+  Tapestry is, of course, an open-source project, with all the work coming from unpaid volunteers.  That being said, our rough timeline is as follows:

+  

+  * 5.0 Release Candidate in Q1 2008

+

+  * 5.0 Final Release shortly thereafter

+

+  * 5.1 development to follow, on a much shorter release schedule

+

+  * ... but we are all open source developers working on our own time and schedules are hard to pin down.  Please be patient.  Tapestry 5

+    is increasingly stable.  Further "stable" with Tapestry usually refers to names of interfaces and methods, not to code quality,

+    which is always very, very high.

+

+  * We are now edging towards a release candidate, with most work being documentation, minor bug fixes and modest

+    enhancements.

+     

+  []

+

+Third Party Libraries, Tutorials and Resources

+

+  Tapestry 5 has inspired a number of people to create third party libraries, providing a mix of new components

+  and new and improved integrations.

+

+*--+--+--+

+| <<Name>> | <<Author>> | <<Description>>

+*--+--+--+

+| {{{http://equanda.org/equanda-tapestry5/}equanda-tapestry5}} |   Joachim Van der Auwera |      Components useful for building enterprise applications. Includes Accordion, Tabs, Formtraversal. Amongst other things, these focus on easy input of data without the need for a mouse.

+*--+--+--+

+| {{{http://code.google.com/p/gc-tapestry-components/}Godcode Components}} |   Chris Lewis |         A mixed collection of components providing simple but time-saving functionality, as well as more exotic ones; built on top of the prototype and script.aculo.us javascript libraries. |

+*--+--+--+

+| {{{http://files.doublenegative.com.au/jumpstart/}JumpStart}} |   Geoff Callender | A "living tutorial" in the form of a base Tapestry application ready to be expanded and customized. |

+*--+--+--+

+| {{{http://interldap.org}InterLDAP}} | Linagora / Francois Armand | LDAP content management system for non tech users. |

+*--+--+--+

+| {{{http://code.google.com/p/shams/}Shams Examples, Components}} |  Mohammad H. Shamsi |   A set of Tapestry 5 Examples, Tutorials, Components, and Documents for beginners. |

+*--+--+--+

+| {{{http://code.google.com/p/tapestry5-components/}T5Components}} | Sven Homburg | Ajax-enabled components based on Prototype and Scriptaculous. |

+*--+--+--+

+| {{{http://tacos.sourceforge.net/tacos5/tacos-seam/}tacos-seam}} | Igor Drobiazko | Intregrates with {{{http://www.jboss.com/products/seam}JBoss Seam}}. |

+*--+--+--+

+| {{{http://www.localhost.nu/java/tapestry5-acegi/}tapestry5-acegi}} | Robin Helgelin  | Integration with the Acegi path-based security framework. |

+*--+--+--+

+| {{{http://code.google.com/p/tapestry5-treegrid/}tapestry5-treegrid}} | Gabriel Landais |  Combination tree navigation and data grid, based on sstree. |

+*--+--+--+

+

+

+What's changed since Tapestry 4?

+

+  Tapestry 5 is an all new code base, written from the ground up to take Java web

+  component development to new levels of productivity.

+  

+  This new release removes many limitations of Tapestry 4:

+  

+  * Components no longer extend from base classes.

+  

+  * {{{tapestry-core/guide/component-classes.html}Components classes are no longer <abstract>}}.  

+     Components are pure, simple POJOs (<plain old Java

+    objects>).

+  

+  * Tapestry no longer uses XML page and component specification files. Information that used to

+    be supplied in such files is now supplied directly in the Java class, using Java annotations and naming conventions.

+    

+  * {{{tapestry-core/guide/reload.html}Changes to Tapestry component templates <and classes> are now picked up <immediately>}}, 

+    without any kind

+    of restart. This will even work properly in <production>, not just during development.

+    

+  * <<Blazing Speed>>. The new code base operates considerably faster than Tapestry 4. Critical

+  code paths have been simplified, and the use of reflection has been virtually eliminated.

+  Tapestry 4 was as fast as an equivalent Servlet/JSP application, Tapestry 5 is much faster.

+    

+  []

+  

+New and Noteworthy

+

+  * In order to support Tapestry 4 applications co-existing with Tapestry 5 applications within the same WAR,

+    a small number of Tapestry 5 classes and packages have been renamed or refactored.  For more information,

+    see the upgrade notes for

+    {{{tapestry-ioc/upgrade.html}tapestry-ioc}} and

+    {{{tapestry-core/upgrade.html}tapestry-core}}.

+

+  * A {{{faq/general.html}FAQ (Frequently Asked Questions) page}} has been added.

+

+  * An {{{tapestry-ioc/overview.html}overview}} and {{{tapestry-ioc/cookbook/}cookbook}} for Tapestry IoC has been written.

+

+  * The nightly build on the {{{http://tapestry.formos.com/bamboo}Bamboo CI server}} now creates 

+    {{{http://tapestry.formos.com/nightly/tapestry5/}full documentation}}.

+

+  * There is now a RegistryStartup service, allowing you to provide logic that executes when the Registry is first created.

+

+  * Logging in Tapestry is now implemented on top of {{{http://www.slf4j.org/docs.html}Simple Logging Facade for Java}}.

+ 

+  * A file upload form component has been added, in a new library: {{{tapestry-upload/}tapestry-upload}}. 

+ 

+  * The {{{tapestry-spring/}tapestry-spring}} module has also been simplified, to make

+  Spring beans look like Tapestry IoC services. It's all now quite seamless.

+

+  * The {{{tapestry-ioc/}tapestry-ioc}} module has been simplified, removing the concept

+  of module ids and namespaces, as well as private services, and borrowing a lot of cool

+  ideas from {{{http://code.google.com/p/google-guice/}Guice}}. The goal is to make the container

+  all but invisible.

+

+  * Work has been started on {{{http://hibernate.org}Hibernate}} integration in the

+  new {{{tapestry-hibernate/}tapestry-hibernate}} module.

+

+  * A few simple utility classes for building integration tests (on top of 

+  {{{http://www.openqa.org/selenium/}Selenium}}) have been split out as a new module: 

+  {{{tapestry-test/}tapestry-test}}.

+    

+  * A  module for integrating Tapestry 5 with {{{http://springframework.org/}Spring}} has been

+  added: {{{tapestry-spring/}tapestry-spring}}.

+

+  * A Maven plugin to generate documentation about components and parameters has been added:

+  {{{tapestry-component-report/}tapestry-component-report}}.

+ 

+  * {{{http://www.formos.com}Formos}} has donated hardware and bandwidth to support the Tapestry project, starting

+  with a {{{http://tapestry.formos.com/bamboo}continuous integration site}} running on

+  {{{http://www.atlassian.com/software/bamboo/}Bamboo}}.  And thanks to Atlassian for donating

+  the Bamboo license.

+

+  * Howard Lewis Ship has begun work on a {{{tutorial1/}Tapestry 5 Tutorial}}. 

+  

+  [] 

+    

+About Snapshots and Releases

+

+  Tapestry is built using {{{http://maven.apache.org/}Maven}}, which makes it really easy to download the source and build it yourself, either the whole

+  project, or just one single module.

+  

+  Better yet, you can pull down Tapestry modules from the central Maven repository.

+  

+  The use of Maven has let us move with great speed, providing preview releases and <snapshots>.

+  

+  Snapshots are <intermediate versions> of releases. As I'm writing this, the most recent preview release is 5.0.2 and the current snapshots are

+  for 5.0.3-SNAPSHOT.  Maven keys off the -SNAPSHOT suffix and handles the dependency specially. It knows that snapshot releases can change frequently,

+  so it will keep checking (at least once a day, maybe more often) to see if there's an updated version of the snapshot.

+  

+  A nightly build process on Tapestry's continuous integration server creates new snapshots <em>every night</em>.

+  

+  Snapshots don't go in the central Maven repository (that's reserved for full releases). Instead, they  go into the Tapestry snapshots repository

+  at {{{http://tapestry.formos.com/maven-snapshot-repository}http://tapestry.formos.com/maven-snapshot-repository}}.

+  

+  To access this repository, you may add <<<-DremoteRepositories=http://tapestry.formos.com/maven-snapshot-repository>>> to the command line when

+  running Maven.

+  

+  Your best bet is to use the {{{quickstart/}quickstart Maven archetype}} to create your initial Tapestry project; it generates a full project

+  directory, including a POM that links to the Apache snapshots repository.

+  

+  <<Documentation on this site usually refers to the latest snapshot ... that is, it is usually ahead of the last official release. In some cases,

+  it is written as if the snapshot release is stable; if documentation refers to version 5.0.x and that doesn't work, try 5.0.x-SNAPSHOT.>>

+    

+Principle 1 -- Static Structure, Dynamic Behavior

+

+  Tapestry is designed to be extremely scalable in several dimensions:

+  

+  * Tapestry applications may contain many pages and many custom components.

+  

+  * Tapestry applications may contain very complex functionality.

+  

+  * Tapestry applications may be created by large, diverse teams.

+  

+  * Tapestry applications can service large numbers of concurrent users.

+  

+ One core architecture decision in Tapestry exists to service many of the above goals

+ (and others that are harder to describe).  <<Static Structure, Dynamic Behavior>>

+

+ In Tapestry, the structure of any particular page is <static>. This is necessary for

+ several reasons, most importantly because Tapestry pages are <pooled>.  Creating a Tapestry page

+ is an involved process, because the page object is simply the root of a large tree of other

+ objects including user provided components, many kinds of structural objects, template objects,

+ and others. Creating a new page instance for each request is simply not <scalable>.

+ 

+ Instead, Tapestry <pools> pages.  Once created, a page instance will be stored in a pool for

+ that particular type of page, and reused

+ in later requests. An incoming request, the result of a user clicking a link or submitting a form,

+ will be processed by <some> server within a cluster, and will use <some> page instance within the

+ page pool. Because page instances are static and uniform across instances and servers, 

+ Tapestry can use any available page instance, or create a new one as needed.

+ 

+ Tapestry does not need to store page instances inside the HttpSession. At most, it stores a smattering

+ of <persistent field values> from the page, but not the entire page instance. This lean

+ use of the HttpSession is key to Tapestry's very high scalability, especially in a clustered

+ configuration.

+ 

+ In some Tapestry-like frameworks, such as Faces and Wicket, the page structure is more dynamic, at 

+ the cost of storing much, much more data in the HttpSession.

+ 

+ This static structure is not so limiting as you might think. With different kinds of conditional

+ and looping components, and the ability to "jump out of the flow" and render components in an arbitrary order, 

+ you will not find Tapestry to be rigid ... anything but!

+  

+Public vs. Internal

+

+  An issue plaguing previous versions of Tapestry 4 (and earlier) was the lack of a clear delineator

+  between private, internal APIs and public, external APIs.  The fact that your code would extend

+  from base objects but that many of the methods on those base objects were "off limits"

+  further confused the issue. This has been identified as a key factor in the

+  "steep learning curve of Tapestry" meme.

+  

+  With the clean slate of Tapestry 5, we are being much more ruthless about internal vs. external.

+  

+  First of all, anything inside the org.apache.tapestry.internal package

+  is <<internal>>.  It is part of the implementation of Tapestry.  It is the man behind the curtain.

+  You should not ever need to directly use this code.  It is a <<bad idea>> to do so, because

+  internal code may <<change from one release to the next>> without concern for backwards

+  compatibility.

+  

+Backwards Compatibility

+

+  Tapestry has been plagued by backwards compatibility problems with every major release. Tapestry 5

+  does not even attempt to be backwards compatible to Tapestry 4. Instead, it lays the ground work for

+  true backwards compatibility going forwards.

+  

+  Tapestry 5's API is based almost entirely on naming conventions and <annotations>.  You components are just

+  ordinary Java classes; you will annotate fields to allow Tapestry to maintain their state or to allow Tapestry 

+  to inject resources, and you will name (or annotate) methods to tell Tapestry under what circumstances

+  a method should be invoked.

+  

+  Tapestry will adapt to your classes. It will call your methods, passing in values via method parameters. 

+  Instead of the rigidness of a fixed interface to implement, Tapestry will simply adapt to your classes, using

+  the hints provided by annotations and simple naming conventions.

+  

+  Because of this, Tapestry will be able to change internally to a great degree without it affecting any

+  of the application code <you> write. This should finally crack the backwards compatibility nut, allowing you to have

+  great assurance that you can upgrade to future releases of Tapestry without breaking your existing applications.

+    
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/jboss.apt b/hlship-20080520/src/site/apt/jboss.apt
new file mode 100644
index 0000000..8eed2a2
--- /dev/null
+++ b/hlship-20080520/src/site/apt/jboss.apt
@@ -0,0 +1,11 @@
+ ----
+ Deployment Notes: JBoss
+ ----
+ 
+Deployment Notes: JBoss
+
+  JBoss's default servlet container is {{{tomcat.html}Tomcat}}, so deployment notes for Tomcat apply to JBoss as well.
+      
+* Logging
+
+  TODO: Discuss logging configuration for JBoss.     
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/jetty.apt b/hlship-20080520/src/site/apt/jetty.apt
new file mode 100644
index 0000000..698a2f7
--- /dev/null
+++ b/hlship-20080520/src/site/apt/jetty.apt
@@ -0,0 +1,25 @@
+ ----
+ Deployment Notes: Jetty
+ ----
+ 
+Deployment Notes: Jetty
+
+  {{{http://jetty.mortbay.com}Jetty}} is the easiest servlet container to deploy Tapestry into, it just plain works.
+  
+  The easiest way to develop Tapestry applications is to run Jetty <embedded> inside your IDE. If you use Eclipse,
+  then {{{http://jettylauncher.sourceforge.net/}the Jetty Launcher plugin}} is invaluable.  The
+  {{{tutorial1/}Tapestry 5 Tutorial}}  discusses installing and using Jetty Launcher.
+  
+  Jetty Launcher  only works  with Jetty <<4 or 5>> and <<not>> Jetty 6.
+  
+* Logging
+
+  Tapestry, in its default configuration, requires Log4J version 1.2.12 or better
+  (it makes use of the 
+  {{{http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Logger.html#isTraceEnabled()}isTraceEnabled()}} and
+  {{http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Logger.html#trace(java.lang.Object)}trace()}} methods,
+  introduced in version 1.2.12.
+  
+  You may have to replace the version of Log4J in your Jetty's ext directory with a newer version.
+
+  
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/screencast.apt b/hlship-20080520/src/site/apt/screencast.apt
new file mode 100644
index 0000000..09bf6dd
--- /dev/null
+++ b/hlship-20080520/src/site/apt/screencast.apt
@@ -0,0 +1,47 @@
+ ----

+ Tapestry Screencasts

+ ----

+ 

+  Screencasts are a great way to learn about a new tool or framework without having to download

+  a single thing to your computer.

+ 

+  Howard Lewis Ship has started creating a series of screencasts about Tapestry 5.

+  

+  <<These screencasts reflect the rapid evolution of the framework. Many things have changed and simplfied over the last few weeks and months. Watch these

+  in the manner intended ... as a preview of the flavor of Tapestry 5, not a reference for how to do things.>> 

+  

+Screencast #1

+

+  Howard demonstrates how to set up a new Tapestry 5 project inside Eclipse (using the 

+  Maven plugin). He also demonstrates 

+  {{{guide/reload.html}live class reloading}}.

+  

+  {{{http://howardlewisship.com/screencasts/tap5-classreload-oct2006/tap5-classreload-oct2006.html}Tapestry 5 Technology Preview -- 17 Oct 2006}} 5:04

+  

+  

+Screencast #2

+

+  Howard demonstrates the Loop, If and ActionLink components, touches on the

+  exception page, as well as transient and persistent page data.

+  

+  {{{http://howardlewisship.com/screencasts/actionlink-oct2006/actionlink-oct2006.html}Tapestry 5 Technology Preview #2 -- 20 Oct 2006}} 9:08

+  

+Screencast #3

+

+  Howard shows how to use Maven and the {{{tapestry-simple/index.html}tapestry-simple}} archetype to create a new Tapestry 5 project.

+  

+  {{{screencast_3.html}Tapestry 5 Screencast #3 -- 29 Jan 2007}} 4:52

+  

+Screencast #4

+

+  Howard demonstrates the BeanEditForm component to build a simple UI for collecting some registration data from the user.

+  

+  {{{screencast_4.html}Tapestry 5 Screencast #4 -- 15 Feb 2007}} 12:22  

+  

+Screencast #5

+

+  Howard shows off the powerful Grid component, used to view and navigate large data sets.

+  

+  {{{screencast_5.html}Tapestry 5 Screencast #5 -- 28 Feb 2007}} 10:46

+  

+  

diff --git a/hlship-20080520/src/site/apt/struts.apt b/hlship-20080520/src/site/apt/struts.apt
new file mode 100644
index 0000000..835693b
--- /dev/null
+++ b/hlship-20080520/src/site/apt/struts.apt
@@ -0,0 +1,190 @@
+ ----

+ Tapestry for Struts Programmers

+ ----

+ 

+Introduction

+	

+  There's no getting around it ... Struts is the 800lb gorilla of Java web application frameworks.

+  It was on the scene early, it got wide coverage and wide adoptions, and vast numbers of

+  applications have been written in it.

+  

+  Struts is an <action based> framework, and exists as a kind of thin wrapper on top of the

+  base Servlet API.  This is good as far as it goes, but Tapestry has always existed

+  as an example of why that view of the world is limited.

+    

+  Tapestry, especially Tapestry 5, represents a somewhat radical approach compared to

+  Struts. You will find it to be quite compelling ... but it also requires adjusting your

+  mindset to a completely different way of looking at building web applications.

+  

+Struts: Actions and Views

+

+  Tapestry and Struts approach the division of concerns represented by the Model-View-Controller

+  design pattern from very different angles.

+  

+  Struts maps incoming URLs to <actions>; these actions are objects that extends from the 

+  Action base class.

+  

+  What does an action do?  It reads query parameters in the request either directly,

+  or via an associated ActionForm object. It probably talks to your backend to read information

+  from a database, or write information out to it. It probably stores some information

+  in the request, information that will be needed by the <view> when it renders.

+  Finally, it returns the name of the view.

+  

+  The framework picks it up from there; it uses that view name to select

+  a template, usually a JavaServer page, 

+  and gets the template to render a response to the user.

+  

+  How does Struts find all this?  Lots of XML configuration; endless details for each

+  and every "page" to define the controller class, the map view names to JSPs, to link

+  views and actions to ActionForm classes.

+

+The Problem of Statelessness

+

+  Where does Struts (and similar frameworks) get things wrong?  The first issue is with

+  the management of <state>.

+  

+  Remember "<Beginning Object Oriented Programming 101>"?  Objects are generally defined

+  as a software construct that encapsulates behavior <and state>.

+  

+  Struts actions do not have internal state.  They can't -- they're singletons, one instance

+  shared by however many threads are operating within the servlet container.  Any internal state,

+  which is to say, any <instance variables>, would be immediately overwritten by some

+  other thread servicing a request for some other user.

+  

+  Struts approaches this problem by externalizing state: into the HttpServletRequest (for

+  state needed just by the view), or into

+  the HttpSession (for state that must persist from one request to the next). 

+  

+  Basically, what we have here is a crippled form of object oriented programming:

+  objects that have a single behavior, and have no internal state.

+  

+  As we'll see, Tapestry addresses both of these issues: in Tapestry, components

+  can have internal state, and they may have not just one, but many different behaviors.

+  

+Views: An Artifical Barrier

+

+  Action frameworks create a separation between the behavior logic, the code inside 

+  a Struts Action, and the view logic, which it typically a JavaServer Page.

+  

+  The <artificial barrier> is the lack of linkage between the template and the controller

+  (the Struts Action).  The only line of communication is the data in the HttpServletRequest

+  and HttpSession.

+  

+  There's a purpose to this design: it's all about the choice for the view. Because the

+  action may select one of several views, it's necessary to loosely couple the action

+  and the view.  The HttpServletRequest, and the named attributes stored in the request,

+  is the form of this loose coupling.

+  

+  This puts an onus on the action to stuff into the HttpServletRequest any and all data

+  that might be needed by the view as it renders a response. After all, there's no other

+  alternative, is there?

+  

+  Additionally, there's the issue of getting the action and the view, or views, to agree

+  on the name and type of every bit of state stored inside the HttpServletRequest or

+  HttpSession. Small changes to the controller, such as storing a different piece of data,

+  or using a different name, can have a ripple effect inside the view.

+  

+  This makes sense, doesn't it? After all, the result of an action (such as clicking a link

+  or submitting a form) may be some kind of success, or some kind of error. Or perhaps

+  you decide on the flavor of output based on the kind of client: HTML for the desktop or WML

+  for a phone.

+  

+  Perhaps in theory, but certainly not <in practice>. Errors are rarely presented as a whole

+  new view; they are usually presented as additional content within the same view. As to the

+  myth of a single application that vends out different markups for different clients ... 

+  that is just a myth. It's not just about output, but about every aspect of application development.

+  It's more than just what content shows up where ... it's about the very functionality offered

+  and the use cases supported, which are very different from one device to another. Pull back the covers

+  on any single application that supports such diverse clients and you'll find multiple applications, one

+  per device type, squeezed together as a not-so-coherent package.

+  

+Components: Its Not Just About Output

+

+  What happens when you have common <fixtures> to your application?  By fixtures,

+  we mean, bits of the view that are used in many places throughout the application.

+  This includes large chunks of functionality, such as a menu system used on every page,

+  down to tiny bits of functionality, like some kind of "widget" to format a date for output.

+  

+  JSPs provide two approaches for this kind of behavior: you can use JSP includes, to reuse

+  JSPs snippets across many larger JSPs.  Alternately, you can define and use JSP tags, which provide

+  a way to generate output using code, and provides mechanism for passing information from the 

+  HttpServletRequest into the JSP tag implementation.

+  Alas, in the real world, the vast majority of actions do have just a <single> view, named

+  "success" by convention. After all, even when an error occurs, you don't want to lose

+  all context ... if a user enters incorrect information into a form, then you want

+  to redisplay the form with the error messages. The view has to <adapt> to the state

+  determined by the request.

+  

+  But what happens when the "fixture" has its own behavior? It's own state?

+  

+  For example, maybe a fixture is a login form

+  that's displayed on every page until the user logs in.  The form may have a URL that

+  points to a login Action ... but how do you return to the same view after logging in?

+  A similar case may be a component that displays tabular data and supports paging. Such

+  a component will have links for navigation and sorting. How do the actions for those links

+  return the user to the same view after changing the set of displayed items?  

+  What if there's more than one such component in a single view?

+  

+  You end up writing more and more configuration and boilerplate code. 

+  You must define more and more JSP attributes

+  or other tricks in order to tell the appropriate action how to get the correct view after

+  performing the actions.

+  

+  You've run into the limitation of not having true web components on your side.

+  

+  With Tapestry, individual components can have their own interactions, blended seamlessly into the page, even

+  when the same component is used across multiple pages. Tapestry is able to keep everything organized

+  because it has its own view of the application, the component object model.

+  

+Tapestry: The Full Cycle Solution

+

+  What Tapestry offers is <structure>.  A well defined, fixed structure of pages and components within

+  pages. This structure is used in every aspect of Tapestry, including state management, output rendering,

+  and request dispatching.

+  

+  You don't have to worry about URLs. Incoming requests for Tapestry encode the

+  name of the page and the id of the component within the page, along with other information,

+  into the URL for you. Your code never has to pick apart a URL, you create

+  {{{tapestry-core/guide/event.html}event listening methods}} to know when the user has clicked a link

+  or submitted a form, or done something more interesting using Ajax.  Tapestry has the structure it needs

+  to build all necessary information into the URL, and unpack that information in a later request.

+  

+  Tapestry is truly object oriented: you don't have to be concerned with singletons and multithreading; your 

+  pages and components have instance variables like any other plain Java object. Tapestry lets your write

+  your application using true object oriented techniques.

+

+  In terms of state management: Tapestry takes care of 

+  {{{tapestry-core/guide/persist.html}persisting field values into the session}}. You don't have to figure out mneumonic,

+  unique names for session attributes, or write code to pull data out of the session or push it back in.

+  Tapestry is able to do this for you.

+

+  Further, in Tapestry pages and components are identical. They are <consistent>. Pages have templates, so

+  do components. Pages have transient and persistent fields. So do components. Pages have event handler methods,

+  so do components.  

+  

+  Tapestry doesn't have the idea of multiple views for a single page. However, processing within one page can easily "hand off" to

+  another <page>, in Java code, to provide the response to an action by the user.

+  

+Making the Transition

+

+  Don't expect there to be a magic tool to convert an existing application to Tapestry 5. The worlds

+  between Struts and other action oriented frameworks, and Tapestry, are just too far.  

+  

+  With Tapestry, you can start to think of your application in the same terms as your users ... as a collection

+  of pages that are connected together.  

+  

+  You don't create URLs and map them to singleton classes; you put a <component> in your page, and

+  add an {{{tapestry-core/guide/event.html}event handling method}} to your class to be invoked when that component is triggered. Many components?

+  No problem, just add more event handler methods.

+  

+Leave Behind the Pain

+

+  Tired of constantly rebuilding and redeploying your application every time you make a change? Tapestry features

+  {{{tapestry-core/guide/reload.html}live class reloading}}. Every time you make a change to your code or your templates, Tapestry picks up the

+  changes immediately ... no waiting!  Just think about how fast and easy building an application is without the expected

+  constraints; scripting language speed with all the power of Java.

+  

+  

+  

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/tomcat.apt b/hlship-20080520/src/site/apt/tomcat.apt
new file mode 100644
index 0000000..75938ce
--- /dev/null
+++ b/hlship-20080520/src/site/apt/tomcat.apt
@@ -0,0 +1,31 @@
+ ----
+ Deployment Notes: Tomcat
+ ----
+ 
+Deployment Notes: Tomcat
+
+  Deploying Tapestry applications into {{{http://tomcat.apache.org/}Tomcat}} is relatively easy, with one big caveat:  you must not store your Tapestry component classes under WEB-INF/classes.
+  
+  At startup, Tapestry needs to locate all your page and component classes, so that it can match page names in request URLs to page classes.  Due to the way
+  Tomcat creates ClassLoaders, this information is not accessible to Tapestry.
+  
+  Fortunately, Maven has an option inside its war plugin,
+  {{{http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#archiveClasses}archiveClasses}}, that changes the packaging; instead of putting compiled
+  classes and resource files in
+  WEB-INF/classes, they are instead placed inside an additional JAR inside WEB-INF/lib.  This keeps Tapestry happy at runtime.
+
+  The {{{http://tapestry.apache.org/tapestry5/tapestry-simple}tapestry-simple archetype}} configures your project's Maven pom.xml file to make use of this
+  option.
+     
+  Tapestry 5 has been tested with Tomcat 5.5.20.
+  
+* index.html
+
+  If your application has an index.html file, Tomcat appears to use that file, rather than triggering the Tapestry filter to render the application Start page
+  for a base URL (just the context path).
+  
+  By contrast, {{{jetty.html}Jetty}} favors the filter over the index.html file. 
+  
+* Logging
+
+  TODO: Discuss logging configuration for Tomcat.   
\ No newline at end of file
diff --git a/hlship-20080520/src/site/apt/websphere.apt b/hlship-20080520/src/site/apt/websphere.apt
new file mode 100644
index 0000000..4a429c3
--- /dev/null
+++ b/hlship-20080520/src/site/apt/websphere.apt
@@ -0,0 +1,24 @@
+ ----
+ Deployment Notes: WebSphere
+ ----
+
+Deployment Notes: WebSphere
+
+  WebSphere <<6.1>> can work with Tapestry ... if configured correctly.  WebSphere doesn't quite
+  conform to the Servlet API specification.
+
+  This can be addressed by installing fixpack 9:
+
+  * {{{http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1PK31377}http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1PK31377}}
+
+  * {{{http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1PK33090}http://www-1.ibm.com/support/docview.wss?rs=180&uid=swg1PK33090}}
+
+  []
+
+  In addition, you must configure the setting <<<com.ibm.ws.webcontainer.invokeFiltersCompatibility>>> to <<<true>>>.  With
+  all of that in place (plus some additional code inside Tapestry that patches around WebSphere's odd behavior), you
+  should be ready to deploy with WebSphere.
+
+* Logging
+
+  TODO: Discuss logging configuration for WebSphere.
\ No newline at end of file
diff --git a/hlship-20080520/src/site/fml/faq/general.fml b/hlship-20080520/src/site/fml/faq/general.fml
new file mode 100644
index 0000000..f7b949a
--- /dev/null
+++ b/hlship-20080520/src/site/fml/faq/general.fml
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faqs title="Frequently Asked Questions">
+
+    <part id="MavenIsAFuckingPieceOfShit">
+
+        <faq id="jetty-is-trace-enabled">
+            <question>Why do I get an error about org.apache.log4j.Logger.isTraceEnabled()Z when launching an
+                application in Jetty?
+            </question>
+            <answer>
+                <p>Tapestry is dependent on a particular version of Log4J, one that adds the isTraceEnabled() method.
+                </p>
+                <p>You need to get a copy of Log4J 1.2.14 and copy it into the Jetty
+                    <code>ext</code>
+                    directory. You should
+                    delete the existing log4j.jar file.
+                </p>
+            </answer>
+        </faq>
+
+
+       <faq id="classcastexception">
+            <question>Why do I get a ClassCastException when I pass a page or component to a service?</question>
+            <answer>
+                <p>
+                    Tapestry uses a special class loader for component classes. This includes pages, components, mixins
+                    and base classes (each in their own sub package).
+                </p>
+
+                <p>
+                    As Tapestry loads the class, it transforms the class. This is to support the Tapestry page
+                    lifecycle, including pooling of pages. It also accounts for other things, such as
+                    persistent fields and parameters. This is also how Tapestry is able to
+                    invoke non-public event handler methods.
+                </p>
+
+                <p>
+                    This means there are
+                    <em>two</em>
+                    versions of each class: the vanilla version and the Tapestry-tranformed version.
+                    Inside a component,
+                    <code>this</code>
+                    refers to the transformed instance and the
+                    transformed class. To the service layer, the type is the vanilla version. Same class name, different
+                    java.lang.Class, and thus a ClassCastException.
+                </p>
+
+                <p>
+                    The established technique is to define an interface that the component can implement.
+                    The parameter to the service layer method is the interface, not the component class.
+                </p>
+            </answer>
+        </faq>
+
+        <faq id="why-not-spring-guice">
+            <question>Why Tapestry IoC?  Why not use Spring or Guice?</question>
+            <answer>
+                <p>
+                    This comes up too frequently. Spring and Guice are very good containers, but are
+                    targetted at defining services for <em>applications</em>, not <em>frameworks</em>.
+    Tapestry has certain specific needs that are pervasive in the IoC layer, chief among them
+                    extensibility.  It must be possible to override internal services on a spot basis.
+                    It must be possible to extend the configuration of an existing service.
+                </p>
+
+                <p>
+                    These simply aren't concepts present in Spring and Guice. Spring can autowire by type
+                    or by explicit name. To support Tapestry's level of extensibility, each new Tapestry
+                    project would require a copy of a large Spring configuration file that would need to
+                    be customized. Adding an additional layer, such as tapestry-hibernate, would
+                    add additional configuration into the configuration file.  This simply isn't the Tapestry way,
+                    where things <em>Just Work</em> (and where we avoid XML).
+                </p>
+
+                <p>
+                    Guice is very similar; there's no XML, but there are marker annotations used to select a specific
+                    implementaton from a pool of objects with the same interface. This means that Java code would have to be
+                    replaced in some cases, to slip overrides into place.
+                </p>
+
+                <p>
+                    Tapestry's service configuration concept is simply not present in other containers.
+                    The ability to extend existing service behavior by providing additional configuration
+                    is part of the light touch of Tapestry. Examples are elsewhere in this documentation.
+                </p>
+            </answer>
+        </faq>
+
+        <faq id="page-lifecycle-and-new">
+
+            <question>
+                Why do I have to inject a page?  Why can't I just create one using <code>new</code>?
+            </question>
+
+            <answer>
+                <p>
+                    As explained elsewhere, Tapestry tranforms your class at runtime.  It tends to build
+                    a large constructor for the class instance.  Further, an instance of the
+                    class is useless by itself, it must be wired together with its template
+                    and its sub-components.
+                </p>
+            </answer>
+
+        </faq>
+
+        <faq id="why-pool-pages">
+            <question>
+                Why is it necessary to pool pages?  Couldn't they just be created fresh?  Or stored in the HttpSession?
+            </question>
+
+            <answer>
+                <p>
+                    Tapestry pages tend to be quite large collections of objects. In the largely invisible structure
+                    around a page will be template objects, binding objects (the active parts of a component parameter),
+                    many injected services, and a lot of other structure besides.
+                </p>
+
+                <p>
+                    Many of those objects are not serializable, and therefore, should not go into
+                    the HttpSession.  In addition, many of the objects are shared between page instances, but
+                    serialization is like a deep copy and would create duplicates of such objects.
+                </p>
+
+                <p>
+                    Finally, a relatively small number of page instances can support a much larger number
+                    of concurrent clients, as each page is only needed for a few milliseconds of work time. Even with
+                    users clicking buttons as fast as humanly possible, the majority of thier time is
+                    "think time" and there's no need to keep entire page instances waiting in the wings while
+                    they think.
+                </p>
+
+                <p>
+                    It takes an appreciable amount of time to construct a working page instance, as all
+                    those objects need to be instantiated, looked up, organized and wired together. It's barely
+                    noticable to a single developer, but a real site with real traffic, would find it unnacceptible
+                    to create a new page instance for each request.
+                </p>
+
+                <p>
+                    Further, Tapestry's structure allows for a lot of optimizations and caching. This means that the
+                    <em>second</em> use of a page tends to be more efficient than the first, as most
+                    cacheable values have been cached.
+                </p>
+            </answer>
+        </faq>
+
+        <faq id="event-method-duplication">
+
+            <question>
+                Why are my methods getting invoked multiple times?
+            </question>
+
+            <answer>
+                <p>
+                   There are some odd edge cases involving inheritance and
+                    render phase methods.  Here's an example:
+                </p>
+
+<source><![CDATA[
+
+public class BasePage
+{
+    void beginRender()
+    {
+        System.out.println("BasePage -- beginRender()");
+    }
+}
+
+public class ChildPage
+{
+    void beginRender()
+    {
+        System.out.println("ChildPage -- beginRender()");
+    }
+}
+
+]]>  (sorry about the CDATA, it's a typical Maven bug, please ignore)</source>
+
+                <p>
+                 Because there is a beginRender() method in the BasePage class, it will be invoked as part
+                    of the BeginRender phase. However, it is overridden by an identical ChildPage method.
+                    So the ChildPage method gets invoked once.
+                </p>
+
+                <p>
+                    However, ChildPage also provides a beginRender() (an override of the parent class), so
+                    this method also gets invoked ... for a second time.
+                </p>
+
+                <p>
+                    You can't turn off base class method invocations; what you can and should do is
+                    make your event handler methods in a base class <code>final</code>.
+                </p>
+
+
+
+            </answer>
+
+        </faq>
+
+    </part>
+
+
+    <!--
+<part id="General">
+ <faq id="dead-doo-dad">
+   <question>My doo-dad is dead. How can I regenerate it?</question>
+   <answer>
+     <p>
+       Doo-dad generation happens at system boot. Therefore, the simplest
+       answer is to restart the hello-world-doodad service.
+     </p>
+     <p>
+       If your doodad service is widget-enabled, you can also regenerate
+       dead doo-dads using the /widgets/reincarnate.doodad address and the
+       following message data:
+     </p>
+     <source>
+       <reincarnation>
+         <id>1</id>
+         <password>ThisShouldBeEncrypted</password>
+       </reincarnation>
+     </source>
+   </answer>
+ </faq>
+ <faq id="what-is-a-doo-dad">
+   <question>What the h@!! is a doo-dad anyway?</question>
+   <answer>
+     <p>
+       Doo-dads are components of the hello-world system used to obfuscate
+       the misdirection server. It is critical to system health that the
+       doo-dad pool have an appropriate threshold and that it be culled
+       regularly.
+     </p>
+   </answer>
+ </faq>
+</part>     -->
+</faqs>
\ No newline at end of file
diff --git a/hlship-20080520/src/site/resources/css/jdstyle.css b/hlship-20080520/src/site/resources/css/jdstyle.css
new file mode 100644
index 0000000..819d52f
--- /dev/null
+++ b/hlship-20080520/src/site/resources/css/jdstyle.css
@@ -0,0 +1,117 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults  */
+
+/* Page background color */
+body { 	font-family: Arial;
+	background-color: white;
+	font-size: 10pt;
+ }
+td { 	font-family: Arial;
+	font-size: 10pt;
+ }
+/* Table colors */
+.TableHeadingColor     { background: #F4F4F4 }
+.TableSubHeadingColor  { background: #F4F4F4 }
+.TableRowColor         { background: #FFFFFF }
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: normal; font-family: Arial }
+.FrameHeadingFont { font-size: normal; font-family: Arial }
+.FrameItemFont    { font-size: normal; font-family: Arial }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color:#F4F4F4;}
+.NavBarCell1Rev { background-color:silver;}
+
+.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+
+.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+
+A {
+    color: #003399;
+}
+
+A:active {
+    color: #003399;
+}
+
+A:visited {
+    color: #888888;
+}
+
+P, OL, UL, LI, DL, DT, DD, BLOCKQUOTE {
+    color: #000000;
+}
+
+TD, TH, SPAN {
+    color: #000000;
+}
+
+BLOCKQUOTE {
+    margin-right: 0px;
+}
+
+
+/*H1, H2, H3, H4, H5, H6    {
+    color: #000000;
+    font-weight:500;
+    margin-top:10px;
+    padding-top:15px;
+}
+
+H1 { font-size: 150%; }
+H2 { font-size: 140%; }
+H3 { font-size: 110%; font-weight: bold; }
+H4 { font-size: 110%; font-weight: bold;}
+H5 { font-size: 100%; font-style: italic; }
+H6 { font-size: 100%; font-style: italic; }*/
+
+TT {
+font-size: 90%;
+    font-family: "Courier New", Courier, monospace;
+    color: #000000;
+}
+
+PRE {
+font-size: 90%;
+    padding: 5px;
+    border-style: solid;
+    border-width: 1px;
+    border-color: #CCCCCC;
+    background-color: #F4F4F4;
+}
+
+UL, OL, LI {
+    list-style: disc;
+}
+
+HR  {
+    width: 100%;
+    height: 1px;
+    background-color: #CCCCCC;
+    border-width: 0px;
+    padding: 0px;
+    color: #CCCCCC;
+}
+
+.variablelist { 
+    padding-top: 10; 
+    padding-bottom:10; 
+    margin:0;
+}
+
+.itemizedlist, UL { 
+    padding-top: 0; 
+    padding-bottom:0; 
+    margin:0; 
+}
+
+.term { 
+    font-weight:bold;
+}
diff --git a/hlship-20080520/src/site/resources/screencast_3.html b/hlship-20080520/src/site/resources/screencast_3.html
new file mode 100644
index 0000000..f6aed03
--- /dev/null
+++ b/hlship-20080520/src/site/resources/screencast_3.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+
+
+
+
+
+
+
+
+<html>
+    <head>
+        <title>Apache Tapestry - Tapestry Screencasts</title>
+        <style type="text/css" media="all">
+            @import url("./css/maven-base.css");
+            @import url("./css/maven-theme.css");
+            @import url("./css/site.css");
+        </style>
+        <link rel="stylesheet" href="./css/print.css" type="text/css" media="print"/>
+        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+    </head>
+    <body class="composite">
+        <div id="banner">
+            <a href="../" id="bannerLeft">
+
+                <img src="images/tapestry_banner.gif" alt=""/>
+
+            </a>
+            <a href="http://www.apache.org" id="bannerRight">
+
+                <img src="images/asf_logo_wide.gif" alt=""/>
+
+            </a>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+        <div id="breadcrumbs">
+
+
+
+
+
+
+
+            <div class="xleft"> Last Published: 29 Jan 2007 </div>
+            <div class="xright">
+                <a href="../">Tapestry</a> | <a href="http://www.apache.org/">Apache</a>
+            </div>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+        <div id="leftColumn">
+            <div id="navcolumn">
+
+
+
+
+
+
+
+                <h5>Tapestry 5 Project</h5>
+                <ul>
+
+                    <li class="none">
+                        <strong>Screencasts</strong>
+                    </li>
+
+                    <li class="none">
+                        <a href="struts.html">Tapestry for Struts Developers</a>
+                    </li>
+                </ul>
+                <h5>Tapestry 5 Modules</h5>
+                <ul>
+
+                    <li class="none">
+                        <a href="tapestry-core/">tapestry-core</a>
+                    </li>
+
+                    <li class="none">
+                        <a href="tapestry-ioc">tapestry-ioc</a>
+                    </li>
+                </ul>
+                <h5>Tapestry 5 Archetypes</h5>
+                <ul>
+
+                    <li class="none">
+                        <a href="tapestry-simple/">tapestry-simple</a>
+                    </li>
+                </ul>
+                <h5>Developer Info</h5>
+                <ul>
+
+                    <li class="none">
+                        <a href="tap5devwiki.html">DevWiki</a>
+                    </li>
+
+                    <li class="none">
+                        <a href="dev/env.html">Environment</a>
+                    </li>
+                </ul>
+                <h5>Project Documentation</h5>
+                <ul>
+
+
+
+
+
+
+
+
+
+
+
+                    <li class="collapsed">
+                        <a href="project-info.html">Project Information</a>
+                    </li>
+                </ul>
+                <a href="http://maven.apache.org/" title="Built by Maven" id="poweredBy">
+                    <img alt="Built by Maven" src="./images/logos/maven-feather.png"/>
+                </a>
+
+
+
+
+
+
+
+            </div>
+        </div>
+        <div id="bodyColumn">
+            <div id="contentBox">
+
+                <h2> Screencast #3 </h2>
+
+
+                <OBJECT CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
+                    CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab" HEIGHT="616" WIDTH="816">
+
+
+
+                    <PARAM NAME="src"
+                        VALUE="http://howardlewisship.com/screencasts/tapestry5_screencast3.mov"/>
+
+                    <PARAM NAME="AutoPlay" VALUE="true"/>
+
+                    <PARAM NAME="Controller" VALUE="true"/>
+
+
+
+                    <EMBED SRC="http://howardlewisship.com/screencasts/tapestry5_screencast3.mov"
+                        HEIGHT="616" WIDTH="816" TYPE="video/quicktime"
+                        PLUGINSPAGE="http://www.apple.com/quicktime/download/" AUTOPLAY="true"
+                        CONTROLLER="true"/>
+
+
+
+                </OBJECT>
+
+            </div>
+        </div>
+        <div class="clear">
+            <hr/>
+        </div>
+        <div id="footer">
+            <div class="xright">&#169; 2006-2007 Apache Software Foundation </div>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+    </body>
+</html>
diff --git a/hlship-20080520/src/site/resources/screencast_4.html b/hlship-20080520/src/site/resources/screencast_4.html
new file mode 100644
index 0000000..5b936ae
--- /dev/null
+++ b/hlship-20080520/src/site/resources/screencast_4.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+
+
+
+
+
+
+
+
+<html>
+    <head>
+        <title>Apache Tapestry - Tapestry Screencasts</title>
+        <style type="text/css" media="all">
+            @import url("./css/maven-base.css");
+            @import url("./css/maven-theme.css");
+            @import url("./css/site.css");
+        </style>
+        <link rel="stylesheet" href="./css/print.css" type="text/css" media="print"/>
+        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+    </head>
+    <body class="composite">
+        <div id="banner">
+            <a href="../" id="bannerLeft">
+                
+                <img src="images/tapestry_banner.gif" alt=""/>
+                
+            </a>
+            <a href="http://www.apache.org" id="bannerRight">
+                
+                <img src="images/asf_logo_wide.gif" alt=""/>
+                
+            </a>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+        <div id="breadcrumbs">
+            
+            
+            
+            
+            
+            
+            
+            <div class="xleft"> Last Published: 15 Feb 2007 </div>
+            <div class="xright">
+                <a href="../">Tapestry</a> | <a href="http://www.apache.org/">Apache</a>
+            </div>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+        <div id="leftColumn">
+            <div id="navcolumn">
+                
+                
+                
+                
+                
+                
+                
+                <h5>Tapestry 5 Project</h5>
+                <ul>
+                    
+                    <li class="none">
+                        <strong>Screencasts</strong>
+                    </li>
+                    
+                    <li class="none">
+                        <a href="struts.html">Tapestry for Struts Developers</a>
+                    </li>
+                </ul>
+                <h5>Tapestry 5 Modules</h5>
+                <ul>
+                    
+                    <li class="none">
+                        <a href="tapestry-core/">tapestry-core</a>
+                    </li>
+                    
+                    <li class="none">
+                        <a href="tapestry-ioc">tapestry-ioc</a>
+                    </li>
+                </ul>
+                <h5>Tapestry 5 Archetypes</h5>
+                <ul>
+                    
+                    <li class="none">
+                        <a href="tapestry-simple/">tapestry-simple</a>
+                    </li>
+                </ul>
+                <h5>Developer Info</h5>
+                <ul>
+                    
+                    <li class="none">
+                        <a href="tap5devwiki.html">DevWiki</a>
+                    </li>
+                    
+                    <li class="none">
+                        <a href="dev/env.html">Environment</a>
+                    </li>
+                </ul>
+                <h5>Project Documentation</h5>
+                <ul>
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    <li class="collapsed">
+                        <a href="project-info.html">Project Information</a>
+                    </li>
+                </ul>
+                <a href="http://maven.apache.org/" title="Built by Maven" id="poweredBy">
+                    <img alt="Built by Maven" src="./images/logos/maven-feather.png"/>
+                </a>
+                
+                
+                
+                
+                
+                
+                
+            </div>
+        </div>
+        <div id="bodyColumn">
+            <div id="contentBox">
+                
+                <h2> Screencast #4 </h2>
+                
+                
+                <OBJECT CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
+                    CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab" HEIGHT="616" WIDTH="816">
+                    
+                    
+                    
+                    <PARAM NAME="src"
+                        VALUE="http://howardlewisship.com/screencasts/tapestry5_screencast4.mov"/>
+                    
+                    <PARAM NAME="AutoPlay" VALUE="true"/>
+                    
+                    <PARAM NAME="Controller" VALUE="true"/>
+                    
+                    
+                    
+                    <EMBED SRC="http://howardlewisship.com/screencasts/tapestry5_screencast4.mov"
+                        HEIGHT="616" WIDTH="816" TYPE="video/quicktime"
+                        PLUGINSPAGE="http://www.apple.com/quicktime/download/" AUTOPLAY="true"
+                        CONTROLLER="true"/>
+                    
+                    
+                    
+                </OBJECT>
+                
+            </div>
+        </div>
+        <div class="clear">
+            <hr/>
+        </div>
+        <div id="footer">
+            <div class="xright">&#169; 2006-2007 Apache Software Foundation </div>
+            <div class="clear">
+                <hr/>
+            </div>
+        </div>
+    </body>
+</html>
diff --git a/hlship-20080520/src/site/resources/screencast_5.html b/hlship-20080520/src/site/resources/screencast_5.html
new file mode 100644
index 0000000..86c8ca9
--- /dev/null
+++ b/hlship-20080520/src/site/resources/screencast_5.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+
+
+
+
+
+
+
+
+<html>
+  <head>
+    <title>Apache Tapestry - Tapestry Screencasts</title>
+    <style type="text/css" media="all">
+      @import url("./css/maven-base.css");
+      @import url("./css/maven-theme.css");
+      @import url("./css/site.css");
+    </style>
+    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+  </head>
+  <body class="composite">
+    <div id="banner">
+      <a href="../" id="bannerLeft">
+        
+        <img src="images/tapestry_banner.gif" alt=""/>
+        
+      </a>
+      <a href="http://www.apache.org" id="bannerRight">
+        
+        <img src="images/asf_logo_wide.gif" alt=""/>
+        
+      </a>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      
+      
+      
+      
+      
+      
+      
+      <div class="xleft"> Last Published: 28 Feb 2007 </div>
+      <div class="xright">
+        <a href="../">Tapestry</a> | <a href="http://www.apache.org/">Apache</a>
+      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+        
+        
+        
+        
+        
+        
+        
+        <h5>Tapestry 5 Project</h5>
+        <ul>
+          
+          <li class="none">
+            <strong>Screencasts</strong>
+          </li>
+          
+          <li class="none">
+            <a href="struts.html">Tapestry for Struts Developers</a>
+          </li>
+        </ul>
+        <h5>Tapestry 5 Modules</h5>
+        <ul>
+          
+          <li class="none">
+            <a href="tapestry-core/">tapestry-core</a>
+          </li>
+          
+          <li class="none">
+            <a href="tapestry-ioc">tapestry-ioc</a>
+          </li>
+        </ul>
+        <h5>Tapestry 5 Archetypes</h5>
+        <ul>
+          
+          <li class="none">
+            <a href="tapestry-simple/">tapestry-simple</a>
+          </li>
+        </ul>
+        <h5>Developer Info</h5>
+        <ul>
+          
+          <li class="none">
+            <a href="tap5devwiki.html">DevWiki</a>
+          </li>
+          
+          <li class="none">
+            <a href="dev/env.html">Environment</a>
+          </li>
+        </ul>
+        <h5>Project Documentation</h5>
+        <ul>
+          
+          
+          
+          
+          
+          
+          
+          
+          
+          
+          
+          <li class="collapsed">
+            <a href="project-info.html">Project Information</a>
+          </li>
+        </ul>
+        <a href="http://maven.apache.org/" title="Built by Maven" id="poweredBy">
+          <img alt="Built by Maven" src="./images/logos/maven-feather.png"/>
+        </a>
+        
+        
+        
+        
+        
+        
+        
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+        
+        <h2> Screencast #5 </h2>
+        
+        
+        <OBJECT CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
+          CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab" HEIGHT="616" WIDTH="816">
+          
+          
+          
+          <PARAM NAME="src"
+            VALUE="http://howardlewisship.com/screencasts/tapestry5_screencast5.mov"/>
+          
+          <PARAM NAME="AutoPlay" VALUE="true"/>
+          
+          <PARAM NAME="Controller" VALUE="true"/>
+          
+          
+          
+          <EMBED SRC="http://howardlewisship.com/screencasts/tapestry5_screencast5.mov"
+            HEIGHT="616" WIDTH="816" TYPE="video/quicktime"
+            PLUGINSPAGE="http://www.apple.com/quicktime/download/" AUTOPLAY="true"
+            CONTROLLER="true"/>
+          
+          
+          
+        </OBJECT>
+        
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">&#169; 2006-2007 Apache Software Foundation </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/hlship-20080520/src/site/site.xml b/hlship-20080520/src/site/site.xml
new file mode 100644
index 0000000..33aa5dd
--- /dev/null
+++ b/hlship-20080520/src/site/site.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 

+   Copyright 2007 The Apache Software Foundation

+

+   Licensed under the Apache License, Version 2.0 (the "License");

+   you may not use this file except in compliance with the License.

+   You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT 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 Tapestry">

+    <bannerLeft>

+        <name>Tapestry 5</name>

+        <href>http://tapestry.apache.org/tapestry5/</href>

+        <src>images/tapestry_banner.gif</src>

+    </bannerLeft>

+    <bannerRight>

+        <name>Apache</name>

+        <href>http://www.apache.org</href>

+        <src>images/asf_logo_wide.gif</src>

+    </bannerRight>

+    <skin>

+        <groupId>org.apache.tapestry</groupId>

+        <artifactId>maven-skin</artifactId>

+        <version>1.1</version>

+    </skin>

+

+    <publishDate format="dd MMM yyyy"/>

+

+    <body>

+

+        <menu name="Tapestry 5 Project">

+            <item name="Screencasts" href="screencast.html"/>

+            <item name="Tapestry for Struts Developers" href="struts.html"/>

+            <item name="Download" href="http://tapestry.apache.org/download.html"/>

+            <item name="Release Notes" href="release-notes.html"/>

+            <item name="Nightly Docs" href="http://tapestry.formos.com/nightly/tapestry5/"/>

+            <item name="Issues" href="https://issues.apache.org/jira/browse/TAPESTRY"/>

+            <item name="FAQ" href="faq/general.html"/>

+        </menu>

+

+        <menu name="Tapestry 5 Modules">

+            <item name="tapestry-annotations" href="tapestry-annotations/"/>

+            <item name="tapestry-core" href="tapestry-core/"/>

+            <item name="tapestry-hibernate" href="tapestry-hibernate/"/>

+            <item name="tapestry-ioc" href="tapestry-ioc/"/>

+            <item name="tapestry-spring" href="tapestry-spring/"/>

+            <item name="tapestry-test" href="tapestry-test/"/>

+            <item name="tapestry-upload" href="tapestry-upload/"/>

+        </menu>

+

+        <menu name="Tapestry Tutorials">

+            <item name="Tutorial #1" href="tutorial1/"/>

+        </menu>

+

+        <menu name="Tapestry 5 Maven Support">

+            <item name="quickstart" href="quickstart/"/>

+            <item name="tapestry-component-report" href="tapestry-component-report/"/>

+        </menu>

+

+

+        <menu name="Deployment Notes">

+            <item name="Jetty" href="jetty.html"/>

+            <item name="Tomcat" href="tomcat.html"/>

+            <item name="JBoss" href="jboss.html"/>

+            <item name="WebSphere" href="websphere.html"/>

+        </menu>

+

+        <menu name="Resources">

+            <item name="Wiki" href="http://wiki.apache.org/tapestry"/>

+            <item name="Wiki HowTos" href="http://wiki.apache.org/tapestry/Tapestry5HowTos"/>

+        </menu>

+

+        <menu name="Developer Info">

+            <item name="Environment" href="dev/env.html"/>

+            <item name="Release Checklist" href="dev/checklist.html"/>

+            <item name="Bible" href="dev/bible.html"/>

+        </menu>

+

+

+        <menu ref="reports"/>

+

+    </body>

+</project>

diff --git a/hlship-20080520/src/site/xdoc/release-notes.xml b/hlship-20080520/src/site/xdoc/release-notes.xml
new file mode 100644
index 0000000..d6b56b7
--- /dev/null
+++ b/hlship-20080520/src/site/xdoc/release-notes.xml
@@ -0,0 +1,1620 @@
+<document>
+    <!--
+       Copyright 2007, 2008 The Apache Software Foundation
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+    -->
+
+    <properties>
+        <title>Tapestry Project Release Notes</title>
+    </properties>
+    <body>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.11</h1>
+
+
+        <h2>Bug
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1475'>TAPESTRY-1475</a>] - Tapestry is missing
+                an API for clearing out persistent properties of a particular page
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1605'>TAPESTRY-1605</a>] - The request encoding
+                (for component action requests) occurs too late; after query parameters of the request have been
+                accessed, which prevents the proper request encoding from being used
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1780'>TAPESTRY-1780</a>] - T5 Form component
+                NPE if no FORM_DATA found
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2103'>TAPESTRY-2103</a>] - When referencing a
+                method as part of a property expression, the method name must be case exact whereas the rest of the
+                property expression is case insensitive
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2108'>TAPESTRY-2108</a>] - Tapestry.onDOMLoaded
+                not working in konqueror
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2117'>TAPESTRY-2117</a>] - Circular @SubModule
+                will crash the IOC container with OutOfMemoryException
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2141'>TAPESTRY-2141</a>] -
+                NullPointerExceptions under JDK 1.5 due to underlying ThreadLocal bug
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2145'>TAPESTRY-2145</a>] - Documentation
+                (including javadoc), refers to &quot;ZoneEffects&quot; instead of &quot;ZoneEffect&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2147'>TAPESTRY-2147</a>] - Typo in Tapestry
+                developer &quot;bible&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2149'>TAPESTRY-2149</a>] - Tapestry should
+                allow the pages and components to be referenced by their &quot;unstripped&quot; names as well
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2150'>TAPESTRY-2150</a>] - Tapestry should
+                recognize pages that are &quot;nested&quot; beneath other pages
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2151'>TAPESTRY-2151</a>] - Date format used by
+                DateField shows the year as two digits, not four
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2172'>TAPESTRY-2172</a>] - DateField component
+                shows up misplaced in major browsers
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2177'>TAPESTRY-2177</a>] - Conversion of
+                context parameters to server-side objects uses the TypeCoercer rather than the correct ValueEncoder
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2184'>TAPESTRY-2184</a>] - Null pointer
+                exception when creating an action link during a component event request
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2188'>TAPESTRY-2188</a>] - GridModel and
+                GridDataSource should be changed to support multiple sort columns
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2190'>TAPESTRY-2190</a>] -
+                JSONObjectEventResultProcessor sends the wrong content type value
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2192'>TAPESTRY-2192</a>] -
+                DateField.xdoc:65:11: The element type &quot;p&quot; must be terminated by the matching end-tag &quot;&lt;/p&gt;&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2206'>TAPESTRY-2206</a>] - Tapestry should have
+                a different data type for numbers than for strings
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2208'>TAPESTRY-2208</a>] - The data type &quot;checkbox&quot;
+                should be renamed to &quot;boolean&quot; to reflect what it is, rather than how it is rendered
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2209'>TAPESTRY-2209</a>] - JSONObject response
+                contains additional {}
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2212'>TAPESTRY-2212</a>] - Index.tml generated
+                by Quickstart Archetype is broken due to recent Index page change.
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2219'>TAPESTRY-2219</a>] - Enum label
+                overrides, as outlined in the Tapestry Tutorial, no longer work
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2220'>TAPESTRY-2220</a>] - In some cases,
+                component event requests are incorrectly interpretted as render requests (with a page activation
+                context)
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2221'>TAPESTRY-2221</a>] - Exception message
+                when a context value is null or blank is confusing
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2226'>TAPESTRY-2226</a>] - Requests for the
+                root index page that include a page activation context fail with a 404 error
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2229'>TAPESTRY-2229</a>] - BeanEditForm is
+                including properties that are read only, causing errors when the form is submitted
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2238'>TAPESTRY-2238</a>] - Returning a Block
+                from an Ajax form submission fails with IllegalStateException
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2240'>TAPESTRY-2240</a>] - Groovy classes can
+                no longer be used as component classes because of the public metaClass field
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2245'>TAPESTRY-2245</a>] - GridDataSource
+                getAvailableRows() method called inefficiently
+            </li>
+        </ul>
+
+        <h2>Improvement
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1336'>TAPESTRY-1336</a>] - Refactor
+                ApplicationGlobals's store methods
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1612'>TAPESTRY-1612</a>] - Allow access to the
+                PageTester registry
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1835'>TAPESTRY-1835</a>] - Need an API to see
+                if a field is required or optional
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1890'>TAPESTRY-1890</a>] - Allow Tapestry
+                applications to NOT autoload modules from library
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1930'>TAPESTRY-1930</a>] - Render missing
+                parameter names in different font and/or text style.
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1932'>TAPESTRY-1932</a>] - Extend PropertyModel
+                to allow access to annotations associated with the property
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1954'>TAPESTRY-1954</a>] - Move the
+                ClassNameLocator service to the tapestry-ioc module
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1955'>TAPESTRY-1955</a>] - Hibernate
+                SessionFactory close on webapp destroy
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1978'>TAPESTRY-1978</a>] - When supplying an
+                empty parameter binding, indicate problem parameter in error message.
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1983'>TAPESTRY-1983</a>] - Add parameter to
+                Grid component that will add additional columns to the BeanModel
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1999'>TAPESTRY-1999</a>] - Allow the context
+                for an event to be specified as a List as well as an Object array
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2078'>TAPESTRY-2078</a>] - More understandable
+                error messages needed when incorrect classes found in component/page packages
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2087'>TAPESTRY-2087</a>] - Add &quot;else&quot;
+                parameter to Unless component.
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2164'>TAPESTRY-2164</a>] - The Tapestry binary
+                distribution should include appropriate third party dependencies
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2173'>TAPESTRY-2173</a>] - When Tapestry must
+                instantiate an Application State Object without an explicit ApplicationStateCreator, it should autobuild
+                the object rather than just use the default constructor
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2180'>TAPESTRY-2180</a>] - Add release notes
+                about API changes
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2182'>TAPESTRY-2182</a>] -
+                NullPointerExceptions, due to reading nested properties that do not suppress null values, do not
+                indicate problematic expression for AbstractPropertyOutput derivatives
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2200'>TAPESTRY-2200</a>] - Need a mechanism via
+                which display and/or edit BeanBlocks may be overridden
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2204'>TAPESTRY-2204</a>] - Upgrade
+                tapestry-test to use Selenium 0.9.2
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2205'>TAPESTRY-2205</a>] - Upgrade to Javassist
+                3.7
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2218'>TAPESTRY-2218</a>] - Grid component
+                should render informal parameters
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2222'>TAPESTRY-2222</a>] - The exception report
+                should highlight the lines related to the application in the stack trace
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2227'>TAPESTRY-2227</a>] - Typo in User Guide -&gt;
+                Persistent Data -&gt; Persistence Strategy
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2237'>TAPESTRY-2237</a>] - Grid should make its
+                &quot;currentPage&quot; value available to containing components
+            </li>
+        </ul>
+
+        <h2>New Feature
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1653'>TAPESTRY-1653</a>] - Provide automatic
+                ValueEncoders for Hibernate entities
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1778'>TAPESTRY-1778</a>] - Allow extending the
+                PageTester with extra modules for better integration with tapestry-spring
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1919'>TAPESTRY-1919</a>] - Let Tapestry control
+                HTTP/HTTPS in links via page configuration
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2169'>TAPESTRY-2169</a>] - Create an
+                ExceptionAnalysisDisplay component
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2170'>TAPESTRY-2170</a>] - Add annotation to
+                inject a component defined in the template
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2197'>TAPESTRY-2197</a>] - Support for &quot;index&quot;
+                pages in packages
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2202'>TAPESTRY-2202</a>] - When the
+                BeanEditForm or BeanEditor components must create the bean to be editted, it should be autobuilt
+                (supporting injection) rather than just instantiated via the default constructor
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2214'>TAPESTRY-2214</a>] - Select component
+                should provide control over a blank option for optional selects
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2216'>TAPESTRY-2216</a>] - Add a @Property
+                annotation for fields to create a getter and setter method
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2241'>TAPESTRY-2241</a>] - Add new parameter
+                &quot;include&quot; to BeanEditor, Grid, etc. to limit properties to a provided list, and rename
+                existing &quot;remove&quot; parameter to &quot;exclude&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2244'>TAPESTRY-2244</a>] - Add @Cached
+                annotation for caching method values
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2246'>TAPESTRY-2246</a>] - Add @Persist
+                strategy for Hibernate entities
+            </li>
+        </ul>
+
+        <h2>Task
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1933'>TAPESTRY-1933</a>] - Setup infrastructure
+                for integration tests in tapestry-hibernate
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2162'>TAPESTRY-2162</a>] - Update roadmap on
+                site
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.10</h1>
+
+
+        <h2>Bug
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1518'>TAPESTRY-1518</a>] - Add support for JDK
+                1.5 Generics when defining pages and accessing bean properties
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1594'>TAPESTRY-1594</a>] - tapestry-upload
+                processes requests with multipart content even if Tapestry doesn't recognize the page
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1727'>TAPESTRY-1727</a>] - Exception report
+                page doesn't display object arrays very nicely
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1850'>TAPESTRY-1850</a>] - Hibernate Sessions
+                are not being closed at the end of the request
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1853'>TAPESTRY-1853</a>] - Create a guide to
+                using the Grid component
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1901'>TAPESTRY-1901</a>] - Grid component calls
+                prepare() and getRowValue() with incorrect values after items are removed
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1969'>TAPESTRY-1969</a>] - Error messages in
+                Errors component are misaligned in Internet Explorer 7
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2027'>TAPESTRY-2027</a>] -
+                AbstractIntegrationTestSuite does not allow custom selenium browser selection
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2048'>TAPESTRY-2048</a>] - Tapestry default.css
+                includes a bad rule for the autocomplete mixin's styles
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2052'>TAPESTRY-2052</a>] - Disabled fields
+                still perfom client side validation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2054'>TAPESTRY-2054</a>] - page activation
+                context with spaces are incorrectly decoded when using forms
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2061'>TAPESTRY-2061</a>] -
+                tapestry-component-report reports only components with parameters
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2080'>TAPESTRY-2080</a>] -
+                PageRenderRequestFilter's service() method should throw IOException as PageRenderRequestHandler does
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2083'>TAPESTRY-2083</a>] - Using @Inject with a
+                primitive field fails with a &quot;cannot find constructor&quot; transformation error
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2085'>TAPESTRY-2085</a>] - When a user submit a
+                form with a TextField and the value is missing or blank, the value null is passed through the component
+                to the model property
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2088'>TAPESTRY-2088</a>] -
+                ClassNotFoundException when passing an int[] parameter to a component
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2089'>TAPESTRY-2089</a>] - File upload does not
+                ever invoke FileCleaner.exitWhenFinished()
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2094'>TAPESTRY-2094</a>] - Exception when
+                creating service MultipartDecoder prevents the use of the Upload component
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2095'>TAPESTRY-2095</a>] - Incorrect
+                optimization for requests that contain a colon but do not contain a slash
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2099'>TAPESTRY-2099</a>] - Contribution to
+                PartialMarkupRenderer should be named &quot;Heartbeat&quot; not &quot;Heatbeat&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2112'>TAPESTRY-2112</a>] - Tapestry should use
+                ValueEncoders, not simple type coercion, to convert between event context values, URL strings, and event
+                method handler parameters
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2118'>TAPESTRY-2118</a>] -
+                ComponentReport.extractSubpackage throws ArrayOutOfBoundException
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2128'>TAPESTRY-2128</a>] - If-Modified-Since
+                always returns not modified for js and css in jar files
+            </li>
+        </ul>
+
+        <h2>Improvement
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1416'>TAPESTRY-1416</a>] - Add support for
+                programatically adding new columns to a Grid
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1642'>TAPESTRY-1642</a>] - When the Label
+                component has a body, it should render that rather than using the field's label
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1887'>TAPESTRY-1887</a>] - Extend the
+                AbstractLink class to provide access to the clientId and disabled flag, as well as to the URL
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2036'>TAPESTRY-2036</a>] - Add a parameter to
+                the Output component to add control over whether output is filtered or unfiltered
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2040'>TAPESTRY-2040</a>] - Allow subclasses of
+                the Autocomplete mixin greater control over the JSON and markup rendered to the client
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2081'>TAPESTRY-2081</a>] - It should be
+                possible to override a Grid column header as easily as overriding a Grid cell
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2097'>TAPESTRY-2097</a>] - Render exceptions
+                should identify the components that are actively rendering
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2101'>TAPESTRY-2101</a>] - DateField icon
+                should be configurable
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2134'>TAPESTRY-2134</a>] - Add a link to
+                InterLDAP project
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2142'>TAPESTRY-2142</a>] - Document the Layout
+                component pattern
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2144'>TAPESTRY-2144</a>] - Upgrade to Prototype
+                1.6.0.2
+            </li>
+        </ul>
+
+        <h2>New Feature
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1843'>TAPESTRY-1843</a>] - Tapestry should have
+                a &quot;production mode&quot; (vs. development mode)
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2002'>TAPESTRY-2002</a>] - Add annotations to
+                easily set content type and response encoding
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2009'>TAPESTRY-2009</a>] - Add examples to
+                component reference
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2076'>TAPESTRY-2076</a>] - Component report
+                should break out as one class per page and include examples
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2084'>TAPESTRY-2084</a>] - Add control over
+                whether whitespace is stripped from templates by default
+            </li>
+        </ul>
+
+        <h2>Task
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1851'>TAPESTRY-1851</a>] - Extend scripts and
+                Ant build.xml to make rolling out a release easier
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2069'>TAPESTRY-2069</a>] - Replace LGPL
+                JavaScript calendar with a properly licensed one
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.9</h1>
+
+        <h2>Bug
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2074'>TAPESTRY-2074</a>] - Tapestry fails with
+                URISyntaxException when the project folder contains spaces
+            </li>
+        </ul>
+
+        <h2>Improvement
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1647'>TAPESTRY-1647</a>] - Need to be able to
+                render elements before and after form labels
+            </li>
+        </ul>
+
+        <h2>New Feature
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1724'>TAPESTRY-1724</a>] - Add ability for
+                pages to be notified about errors within themselves so that they can override the default error handling
+                behavior
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.8</h1>
+
+        <em>Release not made public due to TAPESTRY-2074</em>
+
+        <h2>Bug
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1315'>TAPESTRY-1315</a>] - Context expression
+                without period results in StringIndexOutOfBoundsException
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1377'>TAPESTRY-1377</a>] - NullPointerException
+                invoking methods on the Request service
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1546'>TAPESTRY-1546</a>] - Add
+                inheritInformalParameters flag to the @Component annotation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1595'>TAPESTRY-1595</a>] - Add support for
+                ignoring paths that belong to other servlets in the web application
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1598'>TAPESTRY-1598</a>] - Tapestry should not
+                require explicit value encoders (via the encoder parameter) where it can automatically coerce the value
+                between string and the appropriate server-side type
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1600'>TAPESTRY-1600</a>] - Cannot render XML
+                from page templates: XML declaration and namespaces are removed
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1636'>TAPESTRY-1636</a>] - Template reloading
+                in Tomcat doesn't work
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1713'>TAPESTRY-1713</a>] - Tapestry doesn't run
+                correctly on Websphere 6.1 due to an incorrect implementation of HttpServletRequest.getServletPath()
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1823'>TAPESTRY-1823</a>] - It is not possible
+                to create a reasonable implementation of RequestExceptionHandler without importing internal interfaces
+                and services
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1840'>TAPESTRY-1840</a>] - Tapestry 5 does not
+                compile with Java 6
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1849'>TAPESTRY-1849</a>] - There are two
+                virtually identical PersistentLocaleImpl classes, one unused (probably an incomplete refactoring)
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1880'>TAPESTRY-1880</a>] - DateField component
+                should support editting of time as well as date
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1926'>TAPESTRY-1926</a>] - DateField disabling
+                does not work
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1941'>TAPESTRY-1941</a>] - ValidationTracker
+                retaining field values inconsistently
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1948'>TAPESTRY-1948</a>] - Null pointer
+                exception when performing a partial page render
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1957'>TAPESTRY-1957</a>] - EnumValueEncoder
+                missing null check when converting to client value
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1984'>TAPESTRY-1984</a>] - Error occurs with a
+                multipart (file upload) request if the request encoding is null
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1988'>TAPESTRY-1988</a>] - Page activation
+                paremeter with escaped ( %2f ) slash ( &quot; / &quot; ) character not passed correctly
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2005'>TAPESTRY-2005</a>] - Using component
+                classes as component parameters fails (Could not find a coercion)
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2007'>TAPESTRY-2007</a>] - PNG images related
+                to validation render poorly in IE
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2013'>TAPESTRY-2013</a>] - BeanEditor does not
+                support informal parameters
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2017'>TAPESTRY-2017</a>] - AssetDispatcher
+                doesn't stream asset when the 'If-Modified-Since' header can't be converted to a date
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2019'>TAPESTRY-2019</a>] - Autocompleter mixin
+                now fails with a NullPointerException
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2028'>TAPESTRY-2028</a>] - Mimimize whitespace
+                in the output markup
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2033'>TAPESTRY-2033</a>] - Optimized requests
+                paths are broken for root paths within contexts
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2044'>TAPESTRY-2044</a>] - Component action
+                requests are not capable of handling the case where the active page and the page containing the
+                component are different
+            </li>
+        </ul>
+
+        <h2>Improvement
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1478'>TAPESTRY-1478</a>] - Validation messages
+                for zh_CN locale
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1502'>TAPESTRY-1502</a>] - Generated URLs
+                should be relative to request base URL
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1599'>TAPESTRY-1599</a>] - Make it possible to
+                differentiate between preparing for a Form render vs. preparing for a Form submission
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1639'>TAPESTRY-1639</a>] - Components that
+                generate hyperlinks (ActionLink, PageLink, EventLink) should have a getLink() method to retrieve the
+                link as generated
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1671'>TAPESTRY-1671</a>] - Need a way to
+                redirect to external URLs
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1739'>TAPESTRY-1739</a>] - Add byte, short and
+                float Translators
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1802'>TAPESTRY-1802</a>] - Add documentation
+                for the intended project layout
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1818'>TAPESTRY-1818</a>] - Template parser
+                should handle CDATA blocks
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1830'>TAPESTRY-1830</a>] - Add ability to store
+                temporary data without having to define new properties
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1940'>TAPESTRY-1940</a>] - Italian translation
+                of messages for Error component, and validation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1991'>TAPESTRY-1991</a>] - It should be easier
+                to access an Application State Object without forcing its creation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2008'>TAPESTRY-2008</a>] - Validation popup
+                bubbles are somewhat distracting, should be simplified
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2012'>TAPESTRY-2012</a>] - Add BeanEditor
+                support for data types &quot;password&quot; and &quot;longtext&quot;
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2014'>TAPESTRY-2014</a>] - ComponentResources
+                should expose the page's lifecycle to interested listeners
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2021'>TAPESTRY-2021</a>] - It should be
+                possible to turn off the generation of CSS classes for table headers and table cells inside a Grid
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2049'>TAPESTRY-2049</a>] - Avoid reflection
+                when instantiating component instances
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2056'>TAPESTRY-2056</a>] - Add configurable
+                null handling for text fields
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2057'>TAPESTRY-2057</a>] - Add EventLink
+                component that can create a link that triggers an arbitrarily named event in its container
+            </li>
+        </ul>
+
+        <h2>New Feature
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1526'>TAPESTRY-1526</a>] - Strip the folder
+                name used to identify libraries from logical page names, just as the subfolder is stripped
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1847'>TAPESTRY-1847</a>] - Grid component
+                should output additional CSS classes into TDs to identify first and last column, first and last row
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2006'>TAPESTRY-2006</a>] - Replace naive page
+                pool mechanism with a more realistic one that can handle larger sites
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-2042'>TAPESTRY-2042</a>] - Make it possible to
+                merge action requests with rendering, as with Tapestry 4
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.7</h1>
+
+        <h2>Bug
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1541'>TAPESTRY-1541</a>] - Can't find page with
+                same name as parent folder
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1608'>TAPESTRY-1608</a>] - Some documentation
+                pages link to the out-of-date PDF tutorial, rather than the current HTML tutorial
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1627'>TAPESTRY-1627</a>] - Start page redirect
+                requests can return an empty response.
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1723'>TAPESTRY-1723</a>] - tapestry-upload does
+                not use character encoding
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1745'>TAPESTRY-1745</a>] - Palette javascript
+                errors in Internet Explorer
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1748'>TAPESTRY-1748</a>] - Field validators
+                continue to generate client-side JavaScript even though the Form is configured to not do client-side
+                validation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1816'>TAPESTRY-1816</a>] - Some tapestry-ioc
+                tests fail on IBM JDK due to subtle differences in JDK implementations
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1834'>TAPESTRY-1834</a>] - Fields not rewritten
+                when modifying existing methods
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1838'>TAPESTRY-1838</a>] - Palette javascript
+                Error when an item contains a quote
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1863'>TAPESTRY-1863</a>] - Tapestry should
+                verify that marker annotations have retention type runtime
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1864'>TAPESTRY-1864</a>] - Code sample in
+                documentation on how to add a new property editor incorrect
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1871'>TAPESTRY-1871</a>] - Null date displayed
+                in a Grid raises error
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1879'>TAPESTRY-1879</a>] - PageLink does not
+                have an anchor parameter
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1882'>TAPESTRY-1882</a>] - Formatted messages
+                are not localized properly
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1922'>TAPESTRY-1922</a>] - EJB3 Beans can not
+                be referenced as properties inside JBoss 4.0
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1925'>TAPESTRY-1925</a>] - Obscure exception
+                when a Collection (not a List) is used as a GridDataSource
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1934'>TAPESTRY-1934</a>] - Tapestry should
+                enforce that component classes only extend from other (transformed) component classes, or
+                java.lang.Object
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1936'>TAPESTRY-1936</a>] - Non-null return
+                value from form action event causes exception
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1937'>TAPESTRY-1937</a>] - If a single module
+                contains more than one integration test (subclass of AbstractIntegrationTestSuite), then the second one
+                fails
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1943'>TAPESTRY-1943</a>] - Site menu is the
+                same on all pages
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1947'>TAPESTRY-1947</a>] - Mangled URLs that
+                should result in standard 404 error pages are instead resulting in a Tapestry exception report
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1949'>TAPESTRY-1949</a>] - Component action
+                requests where the action context contains a period are not parsed correctly leading to request failures
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1951'>TAPESTRY-1951</a>] - &quot;No
+                ClassLoaders found for&quot; exception
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1952'>TAPESTRY-1952</a>] - The &quot;match any
+                event&quot; feature for the OnEvent handler is not useful and should be removed
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1966'>TAPESTRY-1966</a>] -
+                Non-private/non-static fields in a page should be an exception, not a warning
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1975'>TAPESTRY-1975</a>] - Template parser is
+                insufficiently picky about component ids
+            </li>
+        </ul>
+
+        <h2>Improvement
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1360'>TAPESTRY-1360</a>] - Add a @Width
+                annotation to set the width of input fields generated by BeanEditForm
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1576'>TAPESTRY-1576</a>] - Getting access to
+                the created configuration
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1862'>TAPESTRY-1862</a>] - Change Tapestry to
+                be compatible with Eclipse/Maven Plugin 0.0.11
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1897'>TAPESTRY-1897</a>] - Upgrade to Javassist
+                3.6 for improved JDK 1.6 support
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1900'>TAPESTRY-1900</a>] - Allow multiple
+                markers annotations per service
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1903'>TAPESTRY-1903</a>] - Upgrade to Prototype
+                1.6 / Scriptaculous 1.8
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1917'>TAPESTRY-1917</a>] - Tapestry should list
+                available pages, components and mixins at startup, and when classes change
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1918'>TAPESTRY-1918</a>] - Tapestry's reload
+                logic should be able to see additions, not just deletions and changes
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1935'>TAPESTRY-1935</a>] - Create an annotation
+                to add a CSS stylesheet to the rendered page
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1942'>TAPESTRY-1942</a>] - Client side
+                validation should be triggered when the user moves out of a field
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1973'>TAPESTRY-1973</a>] - Tapestry 5 Tutorial
+                Improvements
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1990'>TAPESTRY-1990</a>] - More flexibility for
+                specifying timeouts and other time periods in minutes, seconds, etc. rather than milliseconds
+            </li>
+        </ul>
+
+        <h2>New Feature
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1476'>TAPESTRY-1476</a>] - Component events for
+                input translation and validation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1509'>TAPESTRY-1509</a>] - Create an annotation
+                to add a static JavaScript library to the rendered page
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1829'>TAPESTRY-1829</a>] - Allow @Marker
+                annotation on module classes, to automatically mark all services of that module with the annotation
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1860'>TAPESTRY-1860</a>] - Extend ObjectLocator
+                to create a proxied, autobuilt service
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1891'>TAPESTRY-1891</a>] - Tapestry IoC Service
+                Proxies should be serializable
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1931'>TAPESTRY-1931</a>] - Add an annotation to
+                allow explicit setting of property types
+            </li>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1994'>TAPESTRY-1994</a>] - Allow easy override
+                of the default Tapestry stylesheet
+            </li>
+        </ul>
+
+        <h2>Task
+        </h2>
+        <ul>
+            <li>[<a href='https://issues.apache.org/jira/browse/TAPESTRY-1914'>TAPESTRY-1914</a>] - Nightly build broken
+                inside quickstart module
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.6</h1>
+
+
+        <h2>Bug</h2>
+        <ul>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1328'>TAPESTRY-1328</a>] - Support for form
+                elements inside a Grid
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1345'>TAPESTRY-1345</a>] - Exception generated
+                when a page does not have a template is
+                confusing: &quot;No root element has been defined.&quot;
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1389'>TAPESTRY-1389</a>] - Coercion to numeric
+                types does not check for null
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1417'>TAPESTRY-1417</a>] - CSS classes on text
+                input fields are discarded when field is
+                in error
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1471'>TAPESTRY-1471</a>] - Controlling the
+                order of properties within a BeanModel is
+                too complex and needs an improved API
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1506'>TAPESTRY-1506</a>] - Add support for
+                anchors when generating links
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1597'>TAPESTRY-1597</a>] - When a List is
+                converted to a SelectModel, the keys are
+                converted unnecessarily to strings
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1604'>TAPESTRY-1604</a>] - Attributes of
+                elements do not have entity values quoted
+                (including the &amp;quot; character itself) resulting in invalid
+                markup
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1606'>TAPESTRY-1606</a>] - Anchor-Links in
+                &quot;Component Index&quot; web page for T5
+                doesn't work with FireFox
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1625'>TAPESTRY-1625</a>] - T5 Form Component
+                Generates Script Tag With Deprecated
+                Language Attribute
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1626'>TAPESTRY-1626</a>] - T5 Form Component
+                Generates contactForm:errors Div With
+                Invalid Empty List
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1629'>TAPESTRY-1629</a>] - Licenses are not
+                distributed correctly
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1631'>TAPESTRY-1631</a>] - tapestry-spring
+                initializes lazy-init beans too soon
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1648'>TAPESTRY-1648</a>] - Coercing from null
+                to BigDecimal causes an NPE
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1667'>TAPESTRY-1667</a>] - Parameters bound to
+                expansions may be cached when they
+                should not be
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1702'>TAPESTRY-1702</a>] - Missing coercion
+                from primitive arrays to List
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1709'>TAPESTRY-1709</a>] - Radio component
+                throws an exception when used with
+                RadioGroup and Label
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1730'>TAPESTRY-1730</a>] - Order of event
+                handler method invocation should be greatest
+                number of parameters to fewest
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1731'>TAPESTRY-1731</a>] - @Inject @Symbol does
+                not work inside a component
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1735'>TAPESTRY-1735</a>] - PageLink doesn't
+                have a disabled parameter
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1746'>TAPESTRY-1746</a>] - Input validation
+                documentation includes an invalid template
+                that results in a parser error
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1752'>TAPESTRY-1752</a>] - Expansions used in
+                bound parameters are never re-evaluated
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1769'>TAPESTRY-1769</a>] - Bug when component
+                name i same as component package
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1785'>TAPESTRY-1785</a>] - Move non-component
+                classes out of corelib.components
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1789'>TAPESTRY-1789</a>] - Exception messages
+                listing pages, components, etc, should
+                strip out the &quot;core/&quot; prefix
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1790'>TAPESTRY-1790</a>] - Component Report
+                generates bad links to apidocs when the
+                apidocs are generated at the project level
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1809'>TAPESTRY-1809</a>] - archetype.xml
+                doesn't account for change to .tml
+                (/WEB-INF/Start.html should be /Start.tml)
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1815'>TAPESTRY-1815</a>] - The InjectComponent
+                annotation is misnamed, should be
+                InjectContainer
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1824'>TAPESTRY-1824</a>] - Code example on
+                Alias page of tapestry-core guide is wrong,
+                has extra &quot;new&quot;
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1825'>TAPESTRY-1825</a>] - Full Tapestry
+                releases should have the artifacts deployed
+                with the updateReleaseInfo flag set
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1831'>TAPESTRY-1831</a>] - Builtin services
+                (TypeCoercer, ClassFactory, etc.) are not
+                marked with the @Builtin annotation
+            </li>
+        </ul>
+
+        <h2>Improvement</h2>
+        <ul>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1372'>TAPESTRY-1372</a>] - Allow contributions
+                to the Hibernate Configuration
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1469'>TAPESTRY-1469</a>] - Templates should
+                support an outer t:container element for
+                when a template consists of non-tree structured content
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1579'>TAPESTRY-1579</a>] - Allow multiple
+                BeanEditor components within a form
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1603'>TAPESTRY-1603</a>] - BeanEditForm submit
+                button cannot be uniquely identified for
+                CSS purposes
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1607'>TAPESTRY-1607</a>] - Tapestry modules
+                should have a link to Tapestry's JIRA
+                instance
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1615'>TAPESTRY-1615</a>] - ClassTransformation
+                needs ability to rename a method and
+                extend the beginning of a method
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1619'>TAPESTRY-1619</a>] - Add coercion from
+                type [C ( simple char ) to type
+                java.lang.Character
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1633'>TAPESTRY-1633</a>] -
+                PropertyDisplayContext should expose the id/propertyName of
+                the currently rendering property
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1697'>TAPESTRY-1697</a>] - There is no link to
+                the bug database on the Tapestry project
+                site
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1737'>TAPESTRY-1737</a>] - When a property name
+                in a property expression is not valid,
+                the exception message should list the available property names
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1738'>TAPESTRY-1738</a>] - Render debugging
+                output is incredibly verbose, and should
+                only be output at the TRACE (i.e. more vebose than DEBUG)
+                logging level
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1750'>TAPESTRY-1750</a>] - Separate out
+                Tapestry annotations for use in other tiers
+                (without dragging in all of Tapestry)
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1777'>TAPESTRY-1777</a>] - Allow HTML 4
+                doctypes to be used in component templates
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1781'>TAPESTRY-1781</a>] - Tapestry templates
+                should use the extension .tml (Tapestry
+                Markup Language) since they may contain other than (X)HTML
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1800'>TAPESTRY-1800</a>] - Having two different
+                Inject annotations with virtually
+                identical behavior is confusing, they should be consolidated
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1808'>TAPESTRY-1808</a>] - Automatic coercion
+                from String to File would be handy
+            </li>
+        </ul>
+
+        <h2>New Feature</h2>
+        <ul>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1358'>TAPESTRY-1358</a>] - Create BeanDisplay
+                component to display the content of a
+                single bean
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1634'>TAPESTRY-1634</a>] - Create a DateField
+                component that uses client-side
+                JavaScript
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1676'>TAPESTRY-1676</a>] - Add component for
+                editing a single bean property
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1722'>TAPESTRY-1722</a>] - Startup service for
+                Tapestry IoC to perform initialization
+                when the Registry starts up
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1741'>TAPESTRY-1741</a>] - TestBase/MockTester
+                should give each Mock a name based on
+                the type of mock, which assists with debugging
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1742'>TAPESTRY-1742</a>] - Support removal and
+                reordering of BeanModel properties
+                inside Grid and BeanEditForm components
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1786'>TAPESTRY-1786</a>] - Add JVM system
+                property for adding modules to the IoC
+                container
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1798'>TAPESTRY-1798</a>] - Injection via Marker
+                Annotations
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1841'>TAPESTRY-1841</a>] - Extend
+                PageRenderSupport to have equivalent support for CSS
+                stylesheets
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1845'>TAPESTRY-1845</a>] - Need a simple way to
+                access a component's messages for use
+                in testing
+            </li>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1848'>TAPESTRY-1848</a>] - Make status of
+                Tapestry IoC services available
+                programattically and via a simple user interface
+            </li>
+        </ul>
+
+        <h2>Task</h2>
+        <ul>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1367'>TAPESTRY-1367</a>] - Documentation error
+                on Application State page:
+                ApplicationStateConfiguration should be
+                ApplicationStateContribution
+            </li>
+        </ul>
+
+        <h2>Wish</h2>
+        <ul>
+            <li>
+                [<a href='https://issues.apache.org/jira/browse/TAPESTRY-1704'>TAPESTRY-1704</a>] - Convert logging
+                strategy from commons-logging to Simple
+                Logging Facade for Java (SLF4J)
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.5</h1>
+
+
+        <h2>Bug</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1294">TAPESTRY-1294</a>] - Tapestry does not
+                set an output encoding which prevents
+                Unicode content from being output correctly
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1423">TAPESTRY-1423</a>] - Tapestry IoC fails
+                to get the correct class from
+                javassist.CtClass when the instance is already a proxy
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1425">TAPESTRY-1425</a>] - Eager Loaded service
+                (builder) cannot use object injection
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1434">TAPESTRY-1434</a>] - Service builder
+                methods do not allow services to be defined
+                in terms of non-interface class, even though ServiceBinder does
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1443">TAPESTRY-1443</a>] -
+                org.apache.tapestry.annotation.Service annotation is
+                ignored
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1447">TAPESTRY-1447</a>] - Headers are not set
+                appropiately to allow the browser to
+                cache javascript resources.
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1451">TAPESTRY-1451</a>] - T5 website: Broken
+                Link to script.aculo.us
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1464">TAPESTRY-1464</a>] - Cannot Subclass
+                TapestryFilter to add custom init() and
+                destroy() logic
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1465">TAPESTRY-1465</a>] - BeanEditForm and
+                Grid are not extensible in terms of
+                supported property types to be editted or viewed
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1480">TAPESTRY-1480</a>] - Implement Radio
+                component
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1481">TAPESTRY-1481</a>] - ActionLink and
+                PageLink render an id attribute, but don't
+                provide a clientId property, making it impossible to reference
+                them in JavaScript
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1491">TAPESTRY-1491</a>] - No way to get the
+                logical page name for a page instance
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1494">TAPESTRY-1494</a>] - Artifact snapshots
+                are being deployed to the
+                tapestry-repository, not the tapestry-snapshot-repository
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1497">TAPESTRY-1497</a>] - EagerLoad is too
+                early for a normal Tapestry application
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1498">TAPESTRY-1498</a>] - nbsp in template
+                causes exception in SAX Parser.
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1504">TAPESTRY-1504</a>] - When a Map is
+                converted to a SelectModel, the keys are
+                converted unnecessarily to strings
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1511">TAPESTRY-1511</a>] - VerifyError when
+                using inner classes inside components
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1528">TAPESTRY-1528</a>] - No way to cleanup
+                the thread without access to the Registry
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1537">TAPESTRY-1537</a>] - Release notes for
+                5.0.4 claim that TAPESTRY-1294 is fixed,
+                which it isn't
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1559">TAPESTRY-1559</a>] - application package
+                initializer removed while merging svn
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1562">TAPESTRY-1562</a>] - Spurious warnings
+                about missing component ids due to
+                case-sensitive checking of template ids vs. declared components
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1571">TAPESTRY-1571</a>] -
+                CheckForUpdatesFilter can cause deadlock
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1583">TAPESTRY-1583</a>] - The &quot;block:&quot;
+                binding prefix may only reference
+                blocks that appear before the reference in the template, an
+                error occurs if the block is defined later in the template
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1585">TAPESTRY-1585</a>] - tapestry-upload has
+                an incorrect manifest entry for the
+                module class
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1590">TAPESTRY-1590</a>] - Page templates in
+                WEB-INF located based on logical page name
+                (which may not match the class name)
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1593">TAPESTRY-1593</a>] - Various typos in
+                docs/comments
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1596">TAPESTRY-1596</a>] - Contributing a
+                service to the Alias service configuration
+                fails if the service uses a non-standard scope, such as
+                perthread
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1614">TAPESTRY-1614</a>] - No &quot;expires&quot;
+                header should be set in asset
+                download requests, as that can confuse the browser, preventing
+                changes versions of assets from being downloaded
+            </li>
+        </ul>
+
+        <h2>Improvement</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1359">TAPESTRY-1359</a>] - The BeanEditForm
+                component should attempt to create its
+                object parameter if it is null
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1409">TAPESTRY-1409</a>] - Extend
+                StreamResponse to support setting headers in the
+                Response prior to streaming the contents from the InputStream
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1439">TAPESTRY-1439</a>] - Convert Tutorial
+                from Pages/PDF to new module using APT
+                format
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1457">TAPESTRY-1457</a>] - No way for PageLink
+                to distinguish between an explicitly
+                empty page activate context and normal delegation to the target
+                page's passivate event
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1479">TAPESTRY-1479</a>] - It would be nice to
+                have a pipeline between the Dispatchers
+                and the RequestHandlers (for component action requests and for
+                page render requests)
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1493">TAPESTRY-1493</a>] - Grid component
+                should display sort icon next to all sortable
+                fields
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1505">TAPESTRY-1505</a>] - The quickstart
+                archetype should include an empty bind()
+                method
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1523">TAPESTRY-1523</a>] - Split mock-control
+                managing logic in TestBase so that it can
+                be used in a JUnit test suite
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1572">TAPESTRY-1572</a>] -
+                AbstractIntegrationTestSuite should mark setup() and
+                cleanup() as alwaysRun
+            </li>
+        </ul>
+
+        <h2>New Feature</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1354">TAPESTRY-1354</a>] - Implement a file
+                upload component
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1356">TAPESTRY-1356</a>] - Implement
+                client-side field persistence
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1369">TAPESTRY-1369</a>] - There should be a
+                global application-level message catalog
+                for messages common to all pages &amp; components
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1370">TAPESTRY-1370</a>] - Add a component
+                event result processor for Class instances
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1373">TAPESTRY-1373</a>] - Recreate T4's
+                Palette component for T5
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1446">TAPESTRY-1446</a>] - @Symbol annotation
+                for injecting a specific symbol
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1463">TAPESTRY-1463</a>] - Way to inherit
+                binding from containing component
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1466">TAPESTRY-1466</a>] - Support expansions
+                inside ordinary attributes
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1492">TAPESTRY-1492</a>] - The Session
+                interface needs methods for getting and setting
+                the session timeout
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1503">TAPESTRY-1503</a>] - BeanEditForm should
+                default its object parameter to
+                container property that matches its id
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1610">TAPESTRY-1610</a>] - Implement regular
+                expression based input validation (client
+                and server)
+            </li>
+        </ul>
+
+        <h2>Task</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1485">TAPESTRY-1485</a>] - Remove the Any
+                component --- not necessary because of
+                expansions in attributes
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1501">TAPESTRY-1501</a>] - Remove Img
+                component, not needed because expansions are
+                allowed in attributes
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1566">TAPESTRY-1566</a>] - Hibernate
+                configuration documentation is out of date /
+                broken
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1570">TAPESTRY-1570</a>] - wrong link to
+                RequestGlobals in the guide
+            </li>
+        </ul>
+
+        <h2>Wish</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1472">TAPESTRY-1472</a>] - The module and
+                filter are coded against Spring's
+                WebApplicationContext, but doesn't use any APIs not present in
+                ApplicationContext
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.4</h1>
+
+
+        <h2>Bug</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1263">TAPESTRY-1263</a>] - Can't use HTML
+                entities in templates
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1264">TAPESTRY-1264</a>] - Can't specify
+                DOCTYPE in template
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1317">TAPESTRY-1317</a>] - Service contributors
+                are not case insensitive with respect
+                to the service id.
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1333">TAPESTRY-1333</a>] - Cannot bundle
+                component classes &amp; templates in
+                WEB-INF/classes when deploying to Tomcat (&amp; JBoss)
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1337">TAPESTRY-1337</a>] - PageTester can't
+                handle pages with context assets
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1338">TAPESTRY-1338</a>] -
+                ApplicationStateObjects not properly instantiated when using
+                PageTester
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1357">TAPESTRY-1357</a>] - Quickstart archetype
+                still uses out-of-date @Id and
+                @Contribute annotations
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1363">TAPESTRY-1363</a>] - Some of the Java
+                comments in the generated AppModule class
+                are out of date
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1371">TAPESTRY-1371</a>] - The Submit component
+                should have a defer parameter, but just
+                has a _defer private instance variable.
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1387">TAPESTRY-1387</a>] - @Inject should
+                expose annotations on the field to the
+                ObjectProvider
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1411">TAPESTRY-1411</a>] - PageLink component
+                does not render informal parameters
+            </li>
+        </ul>
+
+        <h2>Improvement</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1365">TAPESTRY-1365</a>] - RandomDataSource
+                should allow any type of value for the
+                oneOf() method, not just String
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1424">TAPESTRY-1424</a>] - @OnEvent annotation
+                should be simplified to specify at most
+                one event and at most one component id
+            </li>
+        </ul>
+
+        <h2>New Feature</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1330">TAPESTRY-1330</a>] - The @Scope annotaton
+                should be allowed on service
+                implementation classes (in addition to service builder methods
+                inside a module class)
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1331">TAPESTRY-1331</a>] - Need an @InjectValue
+                annotation for cases where a value to
+                insert contains a colon
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1353">TAPESTRY-1353</a>] - Include copies of
+                common DTDs in the JAR such that the
+                template parser does not need to access the network to parse
+                templates with specific doctypes
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1368">TAPESTRY-1368</a>] - The
+                @ApplicationState annotation should be capable of
+                enhancing a boolean field to indicate whether the state object
+                already exists
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1382">TAPESTRY-1382</a>] - Strip out
+                duplication of names in the class name -> page
+                name / component type conversion
+            </li>
+        </ul>
+
+
+        <h1>Release Notes - Tapestry - Version 5.0.3</h1>
+
+        <h2>Bug</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1270">TAPESTRY-1270</a>] - The StringTranslator
+                should return null when an empty text
+                field is submitted with a form, not the empty string
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1275">TAPESTRY-1275</a>] - Recursive Components
+                cause heap space overflow
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1282">TAPESTRY-1282</a>] - Assets should be
+                streamed with an appropriate content type,
+                even when the container is unable to provide the content type
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1291">TAPESTRY-1291</a>] - Race condition in
+                IoC service creation can create runtime
+                failures
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1297">TAPESTRY-1297</a>] - incorrect context
+                generated for URLs with final slash
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1300">TAPESTRY-1300</a>] - Unit tests require
+                english locale to run succesfully
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1303">TAPESTRY-1303</a>] - Update licences and
+                notice files for external dependencies
+                (javassist, etc.)
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1314">TAPESTRY-1314</a>] - ExceptionAnalyzer
+                throws NPE when an exception message is
+                null
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1316">TAPESTRY-1316</a>] - Address class loader
+                issues inside JBoss
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1321">TAPESTRY-1321</a>] - JBoss deployment
+                error
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1322">TAPESTRY-1322</a>] - Spurious errors in
+                log concerning page "favicon"
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1329">TAPESTRY-1329</a>] - The favicon.ico file
+                is not generated into the project by
+                the quickstart archetype
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1343">TAPESTRY-1343</a>] - Under Tomcat, a root
+                path URL such as http://.../context
+                (without a trailing slash) causes a
+                StringIndexOutOfBoundsException inside PageRenderDispatcher
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1344">TAPESTRY-1344</a>] - Render phase methods
+                should be allowed to return a
+                Renderable object
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1346">TAPESTRY-1346</a>] - tapestry-hibernate
+                module depends on missing
+                ComponentClassLocator service
+            </li>
+        </ul>
+
+        <h2>Improvement</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1025">TAPESTRY-1025</a>] - Add support for
+                eager loading of services
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1295">TAPESTRY-1295</a>] - Event handling
+                methods that have too many parameters for the
+                event context should be silently skipped
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1298">TAPESTRY-1298</a>] - ExceptionReport can
+                be too verbose and repetative
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1308">TAPESTRY-1308</a>] - Exceptions while
+                building services are poorly reported
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1320">TAPESTRY-1320</a>] - Render phase
+                BeginRender should respond to a "false" result
+                by switching to phase AfterRender (rather than phase
+                CleanupRender).
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1323">TAPESTRY-1323</a>] - Support caseless
+                mapped service configurations
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1335">TAPESTRY-1335</a>] - The
+                "infrastructure:" object provider prefix is too long and
+                the name is confusing, rename to "alias:"
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1339">TAPESTRY-1339</a>] - Rework Tapestry IoC
+                to remove the concept of module ids and
+                qualified service ids
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1342">TAPESTRY-1342</a>] - When an exception is
+                reported concerning a particular
+                method, the string identifying the method should include the
+                file name and line number (if available)
+            </li>
+        </ul>
+
+        <h2>New Feature</h2>
+        <ul>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1276">TAPESTRY-1276</a>] - If component should
+                include an optional negate parameter
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1284">TAPESTRY-1284</a>] - Tapestry Spring
+                integration module
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1292">TAPESTRY-1292</a>] - Allow lists to be
+                used as select models
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1302">TAPESTRY-1302</a>] - JavaScript support
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1311">TAPESTRY-1311</a>] - Identify type of
+                component via tag element name in templates
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1319">TAPESTRY-1319</a>] -
+                tapestry.InfrastructureOverrides is not yet implemented
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1325">TAPESTRY-1325</a>] - Add an "asset:"
+                object provider, to simplfy injecting assets
+                into services
+            </li>
+            <li>
+                [<a href="https://issues.apache.org/jira/browse/TAPESTRY-1341">TAPESTRY-1341</a>] - Allow service
+                builders named "build" and determine service
+                id from the result type
+            </li>
+        </ul>
+
+    </body>
+</document>
diff --git a/hlship-20080520/src/tapestry-favicon.graffle b/hlship-20080520/src/tapestry-favicon.graffle
new file mode 100644
index 0000000..c3ac42a
--- /dev/null
+++ b/hlship-20080520/src/tapestry-favicon.graffle
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2007-03-07 10:15:08 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{108.9, 126}, {161.1, 244}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>NSKern</key>
+				<real>0.0</real>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>3</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+					<key>GradientColor</key>
+					<dict>
+						<key>w</key>
+						<string>0.666667</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Beneath</key>
+					<string>YES</string>
+					<key>Fuzziness</key>
+					<real>13.994791030883789</real>
+					<key>ShadowVector</key>
+					<string>{9, 4}</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Align</key>
+				<integer>0</integer>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 Zapfino;}
+{\colortbl;\red255\green255\blue255;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
+
+\f0\fs144 \cf2 \shad\shadx61\shady-62\shadr62\shado220 \shadc0 T}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{108.9, 144}, {146, 146}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>2</integer>
+			<key>Shape</key>
+			<string>Circle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>FillType</key>
+					<integer>3</integer>
+					<key>GradientCenter</key>
+					<string>{-0.133333, -0.190476}</string>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>1</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2007-03-12 15:33:34 -0700</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<string>0</string>
+		<key>DrawerOpen</key>
+		<true/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>209</real>
+		<key>FitInWindow</key>
+		<false/>
+		<key>Frame</key>
+		<string>{{641, 469}, {594, 870}}</string>
+		<key>ShowRuler</key>
+		<false/>
+		<key>ShowStatusBar</key>
+		<true/>
+		<key>VisibleRegion</key>
+		<string>{{0, 0}, {579, 756}}</string>
+		<key>Zoom</key>
+		<string>1</string>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/support/copyright-java.txt b/hlship-20080520/support/copyright-java.txt
new file mode 100644
index 0000000..a755112
--- /dev/null
+++ b/hlship-20080520/support/copyright-java.txt
@@ -0,0 +1,14 @@
+// Copyright {YEAR} {ORG}
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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/hlship-20080520/support/copyright-properties.txt b/hlship-20080520/support/copyright-properties.txt
new file mode 100644
index 0000000..0006f5a
--- /dev/null
+++ b/hlship-20080520/support/copyright-properties.txt
@@ -0,0 +1,14 @@
+# Copyright {YEAR} {ORG}
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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/hlship-20080520/support/copyright-xml.txt b/hlship-20080520/support/copyright-xml.txt
new file mode 100644
index 0000000..61b1009
--- /dev/null
+++ b/hlship-20080520/support/copyright-xml.txt
@@ -0,0 +1,16 @@
+<!-- 
+   Copyright {YEAR} {ORG}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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/hlship-20080520/support/idea-settings.jar b/hlship-20080520/support/idea-settings.jar
new file mode 100644
index 0000000..10c7c28
--- /dev/null
+++ b/hlship-20080520/support/idea-settings.jar
Binary files differ
diff --git a/hlship-20080520/support/maven-ant-tasks-2.0.8.jar b/hlship-20080520/support/maven-ant-tasks-2.0.8.jar
new file mode 100644
index 0000000..8d0abaa
--- /dev/null
+++ b/hlship-20080520/support/maven-ant-tasks-2.0.8.jar
Binary files differ
diff --git a/hlship-20080520/support/new-project b/hlship-20080520/support/new-project
new file mode 100755
index 0000000..2e44fa5
--- /dev/null
+++ b/hlship-20080520/support/new-project
@@ -0,0 +1,84 @@
+#!/usr/bin/ruby
+
+require 'optparse'
+
+$group = nil
+$artifact = nil
+$package = nil
+$archetypeVersion = nil
+$version = "1.0.0-SNAPSHOT"
+$offline = false
+
+$opts = OptionParser.new do |opts|
+  
+  opts.banner = "Usage: new-project.rb [options]"
+  
+  opts.on("-g", "--group GROUP", "The group id for the new project") do |value|
+    $group = value
+  end
+
+  opts.on("-a", "--artifact ARTIFACT", "The artifact for the new project") do |value|
+    $artifact = value
+  end
+  
+  opts.on("-p", "--package PACKAGE", "The root package for source code in the new project") do |value|
+    $package = value
+  end
+  
+  opts.on("-v", "--version VERSION", "The version number of the new project") do |value|
+    $version = value
+  end
+  
+  opts.on("-o", "--offline", "Execute Maven in offline mode") { $offline = true }
+  
+  opts.on("-V", "--archetype-version VERSION", "Version of the Tapestry quickstart archetype") do |value|
+    $archetypeVersion = value
+  end
+  
+  opts.on("-h", "--help", "Help for this command") do
+    puts opts
+    exit
+  end
+end
+
+def fail(message)
+  puts "Error: #{message}"
+  puts $opts
+  exit
+end
+
+
+begin
+  $opts.parse!
+rescue OptionParser::InvalidOption
+  fail $!
+end
+
+fail "Unexpected command line argument" if ARGV.length > 0
+fail "Must specify group" unless $group
+fail "Must specify artifact" unless $artifact
+
+$package = $package || "#$group.#$artifact"
+
+command = ["mvn"]
+
+command << "-o" if $offline
+
+command << [
+  "archetype:create",
+  "-DarchetypeGroupId=org.apache.tapestry",
+  "-DarchetypeArtifactId=quickstart",
+  "-DgroupId=#$group",
+  "-DartifactId=#$artifact",
+  "-DartifactVersion=#$version",
+  "-DpackageName=#$package"]
+
+if $archetypeVersion
+  command << "-DarchetypeVersion=#$archetypeVersion"
+end
+
+command = command.join ' '
+
+exec command
+
+
diff --git a/hlship-20080520/support/prepsvn b/hlship-20080520/support/prepsvn
new file mode 100755
index 0000000..e1858b3
--- /dev/null
+++ b/hlship-20080520/support/prepsvn
@@ -0,0 +1,172 @@
+#!/usr/bin/ruby
+
+# Used to prepare a directory for commit to Subversion. This is necessary for certain file types on Mac OS X because what appear to be files in the Finder
+# are actually directories (Mac uses the term "bundle" for this concept). It is useless to put the .svn folder inside such a directory, because it will
+# tend to be deleted whenever the "file" is saved.  
+#
+# Instead, we want to compress the directory to a single archive file; the bundle will be marked as svn:ignore.
+#
+# We use tar with Bzip2 compression, which is resource intensive to create, but compresses much better than GZip or PKZip.
+#
+# The trick is that we only want to create the archive version when necessary; when the archive does not exist, or when any file
+# in the bundle is newer than the archive.
+
+require 'optparse'
+
+# Set via command line options
+
+$extensions = %w{pages key oo3 graffle}
+$recursive = true
+$dry_run = false
+
+# Queue of folders to search (for bundles)
+
+$queue = []
+
+def matching_extension(name)
+  dotx = name.rindex('.')
+  
+  return false unless dotx
+  
+  ext = name[dotx + 1 .. -1]
+  
+  return $extensions.include?(ext)
+end
+
+
+# Iterate over the directory, identify bundles that may need to be compressed and (if recursive) subdirectories
+# to search.
+#
+# path: string path for a directory
+def search_directory(dirpath)
+  
+  Dir.foreach(dirpath) do |name|
+    
+    # Skip hidden files and directories
+    next if name[0..0] == "."
+    
+    path = File.join(dirpath, name)
+        
+    next unless File.directory?(path)
+                  
+    if matching_extension(name)
+      update_archive path
+      next
+    end
+    
+    if $recursive
+      $queue << path
+    end
+    
+  end
+  
+end
+
+
+def needs_update(bundle_path, archive_path)
+  
+  return true unless File.exists?(archive_path)
+  
+  archive_mtime = File.mtime(archive_path)
+  
+  # The archive exists ... can we find a file inside the bundle thats newer?
+  # This won't catch deletions, but that's ok.  Bundles tend to get completly
+  # overwritten when any tiny thing changes.
+  
+  dirqueue = [bundle_path]
+
+  until dirqueue.empty?
+    
+    dirpath = dirqueue.pop
+    
+    Dir.foreach(dirpath) do |name|
+      
+      path = File.join(dirpath, name)
+      
+      if File.directory?(path)
+        dirqueue << path unless [".", ".."].include?(name)
+        next
+      end
+      
+      # Is this file newer?
+      
+      if File.mtime(path) > archive_mtime
+        return true
+      end
+      
+    end
+    
+  end
+  
+  return false
+end
+
+def update_archive(path)
+  archive = path + ".tar.bz2"
+  
+  return unless needs_update(path, archive)
+
+  if $dry_run
+    puts "Would create #{archive}"
+    return
+  end
+
+  puts "Creating #{archive}"
+    
+  dir = File.dirname(path)
+  bundle = File.basename(path)
+    
+  # Could probably fork and do it in a subshell
+  system "tar --create --file=#{archive} --bzip2 --directory=#{dir} #{bundle}"
+
+end
+
+$opts = OptionParser.new do |opts|
+  
+  opts.banner = "Usage: prepsvn [options]"
+
+  opts.on("-d", "--dir DIR", "Add directory to search (if no directory specify, current directory is searched)") do |value|
+    $queue << value
+  end
+
+  opts.on("-e", "--extension EXTENSION", "Add another extension to match when searching for bundles to archive") do |value|
+    $extensions << value
+  end
+  
+  opts.on("-N", "--non-recursive", "Do not search non-bundle sub directories for files to archive") do
+    $recursive = false
+  end
+  
+  opts.on("-D", "--dry-run", "Identify what archives would be created") do
+    $dry_run = true
+  end
+  
+  opts.on("-h", "--help", "Help for this command") do
+    puts opts
+    exit
+  end
+end
+
+def fail(message)
+    puts "Error: #{message}"
+    puts $opts
+end
+
+begin
+    $opts.parse!
+rescue OptionParser::InvalidOption
+    fail $!
+end
+
+# If no --dir specified, use the current directory.
+
+if $queue.empty?
+  $queue << Dir.getwd
+end
+
+until $queue.empty? 
+  search_directory $queue.pop
+end
+
+
+
diff --git a/hlship-20080520/support/sign-and-upload b/hlship-20080520/support/sign-and-upload
new file mode 100755
index 0000000..7c5cc35
--- /dev/null
+++ b/hlship-20080520/support/sign-and-upload
@@ -0,0 +1,13 @@
+#!/usr/bin/ruby
+
+DIST_DIR="target/dist"
+
+Dir.glob("#{DIST_DIR}/*.{zip,gz,bz2}") do |filename|
+  puts filename
+  # ... and you have to provide your passphrase again and again!
+  system "gpg --armor --output #{filename}.asc --detach-sig #{filename}"
+end
+
+puts "Uploading distributions ..."
+
+system 'scp #{DIST_DIR}/* hlship@people.apache.org:public_html/tapestry-releases'
\ No newline at end of file
diff --git a/hlship-20080520/support/tapestry-core.launch b/hlship-20080520/support/tapestry-core.launch
new file mode 100644
index 0000000..4d923c7
--- /dev/null
+++ b/hlship-20080520/support/tapestry-core.launch
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.testng.eclipse.launchconfig">
+<booleanAttribute key="com.mountainminds.eclemma.core.INPLACE_INSTRUMENTATION" value="false"/>
+<listAttribute key="com.mountainminds.eclemma.core.INSTRUMENTATION_PATHS">
+<listEntry value="/tapestry5/bin"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.testng.remote.RemoteTestNG"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tapestry5"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx600m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:tapestry5/tapestry-core}"/>
+<mapAttribute key="org.testng.eclipse.ALL_CLASS_METHODS"/>
+<listAttribute key="org.testng.eclipse.CLASS_TEST_LIST"/>
+<stringAttribute key="org.testng.eclipse.COMPLIANCE_LEVEL" value="JDK"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST_CLASS"/>
+<stringAttribute key="org.testng.eclipse.LOG_LEVEL" value="10"/>
+<listAttribute key="org.testng.eclipse.SUITE_TEST_LIST">
+<listEntry value="tapestry-core/src/test/conf/testng.xml"/>
+</listAttribute>
+<intAttribute key="org.testng.eclipse.TYPE" value="3"/>
+</launchConfiguration>
diff --git a/hlship-20080520/support/tapestry-ioc.launch b/hlship-20080520/support/tapestry-ioc.launch
new file mode 100644
index 0000000..8579e15
--- /dev/null
+++ b/hlship-20080520/support/tapestry-ioc.launch
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.testng.eclipse.launchconfig">
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.testng.remote.RemoteTestNG"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tapestry5"/>
+<mapAttribute key="org.testng.eclipse.ALL_CLASS_METHODS"/>
+<listAttribute key="org.testng.eclipse.CLASS_TEST_LIST"/>
+<stringAttribute key="org.testng.eclipse.COMPLIANCE_LEVEL" value="JDK"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST_CLASS"/>
+<stringAttribute key="org.testng.eclipse.LOG_LEVEL" value="2"/>
+<listAttribute key="org.testng.eclipse.SUITE_TEST_LIST">
+<listEntry value="tapestry-ioc/src/test/conf/testng.xml"/>
+</listAttribute>
+<intAttribute key="org.testng.eclipse.TYPE" value="3"/>
+</launchConfiguration>
diff --git a/hlship-20080520/support/tapestry-spring.launch b/hlship-20080520/support/tapestry-spring.launch
new file mode 100644
index 0000000..5956176
--- /dev/null
+++ b/hlship-20080520/support/tapestry-spring.launch
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.testng.eclipse.launchconfig">
+<booleanAttribute key="com.mountainminds.eclemma.core.INPLACE_INSTRUMENTATION" value="false"/>
+<listAttribute key="com.mountainminds.eclemma.core.INSTRUMENTATION_PATHS">
+<listEntry value="/tapestry5/bin"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.testng.remote.RemoteTestNG"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tapestry5"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx600m"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:tapestry5/tapestry-spring}"/>
+<mapAttribute key="org.testng.eclipse.ALL_CLASS_METHODS"/>
+<listAttribute key="org.testng.eclipse.CLASS_TEST_LIST"/>
+<stringAttribute key="org.testng.eclipse.COMPLIANCE_LEVEL" value="JDK"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST"/>
+<listAttribute key="org.testng.eclipse.GROUP_LIST_CLASS"/>
+<stringAttribute key="org.testng.eclipse.LOG_LEVEL" value="10"/>
+<listAttribute key="org.testng.eclipse.SUITE_TEST_LIST">
+<listEntry value="tapestry-spring/src/test/conf/testng.xml"/>
+</listAttribute>
+<intAttribute key="org.testng.eclipse.TYPE" value="3"/>
+</launchConfiguration>
diff --git a/hlship-20080520/support/update-copyrights b/hlship-20080520/support/update-copyrights
new file mode 100755
index 0000000..e1181ef
--- /dev/null
+++ b/hlship-20080520/support/update-copyrights
@@ -0,0 +1,298 @@
+#!/usr/bin/ruby -w
+
+# Executable Ruby script to walk one or more directories worth of
+# source files and add or update the copyright comment block on each file.
+#
+# File types are identified by extension, different file types
+# vary in the format of the copyright comment block and its exact position.
+#
+# The template for each block will contain the string {YEAR}.  This is replaced
+# by the current year.  However, if a current comment block exists,
+# then the file is not touched (ASF rules is that the copyright year should
+# only be updated when an actual change occurs to the file).
+#
+# The {ORG} placeholder in the template is replaced with the organization,
+# which defaults to "The Apache Software Foundation", but can be overridden with the
+# -o command line argument.
+
+require 'find'
+
+# Directory containing this script, used to locate templates (which are stored
+# relative to the script itself.
+
+SCRIPT_DIR = File.split(__FILE__)[0]
+YEAR = Time.now.year.to_s
+
+$ORG = "The Apache Software Foundation"
+
+def read_template(file)
+  result = []
+ 
+  File.open(SCRIPT_DIR + "/" + file) do |file|
+    file.each { |line| result << line }
+  end
+ 
+  return result
+end
+
+# Writes out the content (array of strings) to the file.
+# Actually, writes to a temporary file, then deletes the original
+# file and renames the new file to it.
+
+def write_file(path, content)
+  puts "Writing #{path} ..."
+ 
+  temp = path + "~"
+ 
+  File.open(temp, "w") do |file|
+    content.each { |line| file << line }
+  end
+ 
+  File.delete(path)
+  File.rename(temp, path)
+end
+
+# Scans the content (which should be the complete file)
+# for the copyright year.  Returns the year, which
+# may be as single year ("2004") or a sequence of
+# years ("2004, 2005, 2007"). Returns YEAR if
+# no copyright year was found in the content.
+
+def scan_for_year(content, comment_prefix)
+ 
+  content.each do |line|
+    
+    if ! line.strip.empty? then
+      
+      return YEAR if line[0, comment_prefix.length] != comment_prefix
+      
+      if line =~ /copyright ((\d+)(\s*,\s*\d+)*)/i
+        then
+        return $1
+      end
+      
+    end
+    
+  end
+ 
+  # Degenerate case -- a file that contains just comments?  Shouldn't happen
+  # but just in case.
+ 
+  return YEAR
+ 
+end
+
+# Synthesizes a copyright comment block by locating the {YEAR} token
+# and substituting the year paremeter, and the {ORG} token with $ORG
+
+def synthesize_copyright(template, year)
+  template.collect { |line| line.sub(/\{YEAR\}/, year).sub(/\{ORG\}/, $ORG) }
+end
+
+class Filter
+
+  def initialize(comment, template_file)
+    @comment = comment
+    @template = read_template(template_file)
+  end
+
+ def update(path)
+    
+    content = nil
+    dirty = false
+    
+    File.open(path) { |file|  content = file.readlines }
+    
+    year = scan_for_year(content, @comment)
+    
+    copyright_comment = synthesize_copyright(@template, year)
+    
+    0.upto(@template.length() - 1) do |line|
+      dirty ||= content[line] != copyright_comment[line]
+    end
+    
+    # TODO: What if the new comment is *shorter* than the old comment?
+    # Need to find and trim those line.
+    
+    return false if !dirty    
+    
+    # Strip out all leading blank lines and comments
+    
+    while ! content.empty?
+      line = content[0]
+      
+      if line.strip.empty? || line[0, @comment.length] == @comment
+        content.delete_at(0)
+      else
+        break
+      end
+    end
+    
+    # content[0] should now be the package statement (or, if in the default package,
+    # an import, class, interface, etc.
+    
+    content.insert(0, *copyright_comment)
+    
+    # Write the new content to the file
+    
+    write_file(path, content)
+    
+    return true
+  end
+end
+
+# Filter for Java files.  The copyright comment is placed
+# before the first statement or directive (typically, before the package
+# directive)
+
+class JavaFilter < Filter
+ 
+  def initialize
+    super("//", "copyright-java.txt")
+  end
+ 
+end
+
+class PropertiesFilter < Filter
+
+  def initialize
+    super("#", "copyright-properties.txt")
+  end
+end
+
+# Filter used for any XML file.  The copyright is placed after the <?xml ...?> line, and before
+# anything else.
+
+class XMLFilter
+ 
+  def initialize
+    @template = read_template("copyright-xml.txt")
+  end
+ 
+  # Returns true if the line looks like an XML "<!DOCTYPE ..",
+  # or element "<foo ..."  This will not match an XML comment
+  # or the "<?xml ..." declaration.
+ 
+  def document_start?(line)
+    return line == nil || line.match(/^\s*<(!DOCTYPE|\w+)/) != nil
+  end
+ 
+  def scan_for_year(content)
+    
+    content.each do |line|
+      if line =~ /Copyright ((\d+)(\s*,\s*\d+)*)/
+        return $1
+      elsif document_start?(line)
+        return YEAR
+      end
+    end
+    
+    return YEAR
+  end
+ 
+  def update(path)
+    
+    content = nil
+    dirty = false
+    
+    File.open(path) { |file|  content = file.readlines }
+    
+    year = scan_for_year(content)
+    
+    copyright_comment = synthesize_copyright(@template, year)
+    
+    # Ignore the first line, it is expected to be the <?xml
+    # directive.
+    
+    0.upto(@template.length() - 1) do |line|
+      dirty ||= content[line + 1] != copyright_comment[line]
+    end
+    
+    # TODO: What if the new comment is *shorter* than the old comment?
+    # Need to find and trim those line.
+    
+    return false if !dirty    
+    
+    until document_start?(content[1])
+      content.delete_at(1)
+    end
+    
+    content.insert(1, *copyright_comment)
+    
+    write_file(path, content)
+    
+    return true
+  end
+end
+
+# Maps a particular file path pattern to a particular filter.  Tracks the files
+# that have matched the pattern.
+
+class FilterPattern
+ 
+  def initialize(pattern, filter)
+    @pattern = pattern
+    @filter = filter    
+    @files = []
+  end
+ 
+  def match?(path)
+    if path.match(@pattern) != nil
+      @files << path
+      return true      
+    end
+    
+    return false    
+  end
+ 
+  def update
+    count = 0
+    @files.each do |file|
+      count += 1 if @filter.update(file)
+    end
+    
+    return count
+  end
+end
+
+$filter_patterns = []
+
+def register_filter(pattern, filter)
+  $filter_patterns << FilterPattern.new(pattern, filter)
+end
+
+def match?(path)
+  $filter_patterns.each do |fp|
+    return true if fp.match?(path)    
+  end
+ 
+  return false
+end
+
+
+register_filter(/\.(java|aj)$/, JavaFilter.new)
+register_filter(/(\/cli\.xconf|(\.(xml|xsl|jwc|application|library|page|script)))$/, XMLFilter.new)
+register_filter(/\.properties$/, PropertiesFilter.new)
+
+$matches = 0
+$update_count = 0
+
+if (ARGV[0] == "-o")
+  ARGV.shift  
+  $ORG = ARGV.shift
+  puts "Using organization '#$ORG'"
+end
+
+Find.find(*ARGV) do |f|
+ 
+  if f =~ /(CVS|SVN|target)$/
+    Find.prune
+  else
+    $matches += 1 if match?(f)
+  end
+end
+
+$filter_patterns.each { |fp| $update_count += fp.update }
+
+puts "Updated #$update_count files (of #$matches files found)."
+
diff --git a/hlship-20080520/support/update-eclipse b/hlship-20080520/support/update-eclipse
new file mode 100755
index 0000000..e9c2988
--- /dev/null
+++ b/hlship-20080520/support/update-eclipse
@@ -0,0 +1,186 @@
+#!/usr/bin/ruby
+
+# This script is used to update the Eclipse .classpath file for the master project; it is used when
+# a module is added or removed, or when a src folder is added or removed from a module.
+#
+# It assumes the layout of each module conforms to the normal Maven structure.
+#
+# This script must be executed from the root project directory (the directory containing the master pom.xml, and containing
+# the directories for the modules).
+
+# TODO: Generated IDEA control files as well
+
+require 'optparse'
+
+# Rub gems:  Think of it as Maven for Ruby but not brain-damaged. See http://www.rubygems.org/read/book/1
+
+require 'rubygems'
+
+# This script requires the Ruby gem hpricot ("gem install hpricot"). It was built with version 0.6.
+# http://code.whytheluckystiff.net/hpricot
+
+require 'hpricot'
+
+CLASSPATH_HEADER = [
+  %Q{<?xml version="1.0" encoding="UTF-8"?>},
+  %Q{<classpath>}
+].freeze
+
+CLASSPATH_TRAILER = [
+  %Q{  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>},
+  %Q{  <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>},
+  %Q{  <classpathentry kind="output" path="bin"/>},
+  %Q{</classpath>}
+].freeze
+
+# These may be overridden based on command line options
+
+$project_only = false
+$dryrun = false
+
+$opts = OptionParser.new do |opts|
+    opts.banner = "Usage: update-eclipse [options]"
+  
+    opts.on("-d", "--dry-run", "Show the generated POM but don't write anything") do
+        $dryrun = true
+    end
+    
+    opts.on("-p", "--project-only", "Update only the project control files, not the individual modules") do
+      $project_only = true
+    end
+    
+    opts.on("-h", "--help", "Help for this command") do
+        puts opts
+        exit
+    end
+    
+end
+
+def fail(message)
+    puts "Error: #{message}"
+    puts $opts
+end
+
+begin
+    $opts.parse!
+rescue OptionParser::InvalidOption
+    fail $!
+end
+
+def exist(mod_name, folder)
+  path = "#{mod_name}/#{folder}"
+
+  if File.directory?(path) 
+    yield path
+  end
+end
+
+def add_source_folder(mod_name, folder, output_dir)
+  exist(mod_name, folder) do |path|
+    $project_classpath << %Q{  <classpathentry kind="src" output="#{output_dir}" path="#{path}"/>}
+    $module_classpath <<  %Q{  <classpathentry kind="src" output="#{output_dir}"  path="#{folder}"/>}
+  end
+end
+
+def add_class_folder(mod_name, folder)
+  exist(mod_name, folder) do |path|
+    $project_classpath <<    %Q{  <classpathentry kind="lib" path="#{path}"/>}
+    $module_classpath << %Q{  <classpathentry kind="lib" path="#{folder}"/> }
+  end
+end
+
+def process_module(mod_name)
+  
+  # quickstart, being an archetype, is the odd man out
+  
+  return if mod_name == "quickstart"
+  
+  $module_classpath = []
+  
+  add_source_folder(mod_name, "src/main/java", "bin");
+  add_source_folder(mod_name, "src/test/java", "bin-test")
+  
+  add_class_folder(mod_name, "src/main/resources") 
+  add_class_folder(mod_name, "src/test/resources") 
+  
+  write_control_files(mod_name, mod_name, $module_classpath) unless $project_only
+  
+end
+
+def write_control_files(folder,  project_name, classpath)
+  
+  lines = CLASSPATH_HEADER.dup.concat(classpath).concat(CLASSPATH_TRAILER)
+  
+  write_lines("#{folder}/.classpath", lines)
+  
+  lines = [ 
+"<projectDescription>",
+"  <name>#{project_name}</name>",
+"  <comment></comment>",
+"  <projects>",
+"  </projects>",
+"  <buildSpec>",
+"    <buildCommand>",
+"      <name>org.eclipse.jdt.core.javabuilder</name>",
+"      <arguments>",
+"      </arguments>",
+"    </buildCommand>",
+"    <buildCommand>",
+"      <name>org.maven.ide.eclipse.maven2Builder</name>",
+"      <arguments>",
+"      </arguments>",
+"     </buildCommand>",
+"  </buildSpec>",
+"  <natures>",
+"    <nature>org.eclipse.jdt.core.javanature</nature>",
+"    <nature>org.maven.ide.eclipse.maven2Nature</nature>",
+"  </natures>",
+"</projectDescription>"
+]
+  
+  write_lines("#{folder}/.project", lines)
+  
+end
+
+def write_lines(file, lines)
+  if $dryrun
+    puts "Generated #{file}:\n"
+    lines.each { |s| puts s }
+    puts
+    return
+  end
+  
+  puts "Writing #{file} ..."
+  
+  File.open(file, "w") do |file|
+   lines.each do |line| 
+      file.print line 
+      file.print "\n"
+    end
+  end
+  
+end
+
+$master_pom = open("pom.xml") do |f|
+    Hpricot.XML(f)
+end
+
+
+# We're going to build up the project classpath a line at a time.  This part is always the same:
+
+$project_classpath = []
+
+$modules = []
+
+($master_pom/"project/modules/module").each { |elem| $modules << elem.inner_html }
+
+# Add entries for each module
+
+$modules.sort.each { |mod_name| process_module(mod_name) }
+
+# Write out the updated .classpath
+
+write_control_files(".", "datatech",  $project_classpath)
+
+puts "Updated .classpath across project."
+
diff --git a/hlship-20080520/support/update-versions b/hlship-20080520/support/update-versions
new file mode 100755
index 0000000..b7f5b6b
--- /dev/null
+++ b/hlship-20080520/support/update-versions
@@ -0,0 +1,64 @@
+#!/usr/bin/ruby
+
+# This script is used to roll the version numbers of all modules up.
+# The version number is always determined from the master POM's version number.
+# However, when changing version number of the master POM, every module must have
+# it's <parent>/<version> element updated.  That's what this script is for.
+
+# Rub gems:  Think of it as Maven for Ruby but not brain-damaged. See http://www.rubygems.org/read/book/1
+
+require 'rubygems'
+
+# This script requires the Ruby gem hpricot ("gem install hpricot"). It was built with version 0.6.
+# http://code.whytheluckystiff.net/hpricot
+
+require 'hpricot'
+
+# This script doesn't bother with optparse, it's just a single command line option: the new version number.
+# Use with care!
+
+$version = ARGV[0]
+
+def read_pom(file)
+  open(file) do |f|
+    Hpricot.XML(f)
+  end
+end
+
+def write(file, pom)
+  puts "Updating #{file} ..."
+  
+  File.open(file, "w") do |stream|
+    stream << pom
+  end  
+end
+
+def edit_pom(file)
+  pom = read_pom(file)
+  yield pom
+  write(file, pom)
+end
+
+def process_module(mod_name)
+
+  edit_pom("#{mod_name}/pom.xml") do |pom|
+    pom.at("/project/parent/version").inner_html = $version
+  end
+end
+
+puts "Updating to version #{$version} ..."
+
+edit_pom("pom.xml") do |pom|
+  
+  modules = []
+
+  (pom/"project/modules/module").each { |elem| modules << elem.inner_html }
+
+  modules.sort.each { |mod_name| process_module(mod_name) }
+
+  pom.at("/project/version").inner_html = $version
+end
+
+edit_pom("quickstart/src/main/resources/archetype-resources/pom.xml") do |pom|
+  pom.at("/project/properties/tapestry-release-version").inner_html = $version
+end
diff --git a/hlship-20080520/tapestry-annotations/.classpath b/hlship-20080520/tapestry-annotations/.classpath
new file mode 100644
index 0000000..04b0af6
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-annotations/.project b/hlship-20080520/tapestry-annotations/.project
new file mode 100644
index 0000000..c8451e2
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-annotations</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-annotations/LICENSE-2.0.txt b/hlship-20080520/tapestry-annotations/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/LICENSE-2.0.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/hlship-20080520/tapestry-annotations/NOTICE.txt b/hlship-20080520/tapestry-annotations/NOTICE.txt
new file mode 100644
index 0000000..4e5d2f5
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/NOTICE.txt
@@ -0,0 +1,5 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+Please refer to the NOTICE.txt for each sub-module to
+identify further dependencies.
diff --git a/hlship-20080520/tapestry-annotations/pom.xml b/hlship-20080520/tapestry-annotations/pom.xml
new file mode 100644
index 0000000..67fcf87
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/pom.xml
@@ -0,0 +1,58 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <!-- We've been lucky on T4/T5 name mismatches elsewhere, but T4 has a tapestry-annotation artifact. -->
+    <artifactId>tapestry5-annotations</artifactId>
+    <packaging>jar</packaging>
+    <!-- This should change to tapestry-project -->
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <name>Tapestry Annotations</name>
+    <description>
+        Annotations used with Tapestry applications.
+    </description>
+    <inceptionYear>2007</inceptionYear>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.7</version>
+            <classifier>jdk15</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/DataType.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/DataType.java
new file mode 100644
index 0000000..9f84f18
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/DataType.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.*;
+
+/**
+ * Used to explicitly set the data type used to select an editor (or display) block.  Normally, the data type
+ * is determined from the type of the property (for example, property type java.lang.String would map to data
+ * type "text").
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataType
+{
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/NonVisual.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/NonVisual.java
new file mode 100644
index 0000000..d2ac8e3
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/NonVisual.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for properties which are non-visual, and so should not appear (by default)
+ * inside a {@link BeanModel}. The annotation may be placed on either the getter or the setter
+ * method.
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface NonVisual {
+
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java
new file mode 100644
index 0000000..92d2a46
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderAfter.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Placed on either a property getter or a property setter method to control the order in which the
+ * properties are presented to the user.
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface OrderAfter {
+    /**
+     * The name of the other property. This property will be ordered before the other property.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java
new file mode 100644
index 0000000..21ccf45
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/OrderBefore.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Placed on either a property getter or a property setter method to control the order in which the
+ * properties are presented to the user.
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface OrderBefore {
+    /**
+     * The name of the other property. This property will be ordered before the other property.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java
new file mode 100644
index 0000000..98ca2d0
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/RelativePosition.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+/**
+ * Controls the position of newly added {@link PropertyModel}s inside a {@link BeanModel}.
+ */
+public enum RelativePosition {
+    /**
+     * The new {@link PropertyModel} goes before the existing model.
+     */
+    BEFORE,
+
+    /**
+     * The new {@link PropertyModel} goes after the existing model.
+     */
+    AFTER
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Validate.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Validate.java
new file mode 100644
index 0000000..b7fa31a
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Validate.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to attach validation constraints directly to a property (either the getter or the setter
+ * method). The annotation value is a comma separated list of <em>validation constraints</em>,
+ * each one identifying a validator type (such as "required", "minlength") and optionally, a
+ * constraint value. Most validators need a constraint value, which is separated from the type by an
+ * equals size (i.e., "maxlength=30").
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Validate {
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Width.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Width.java
new file mode 100644
index 0000000..f4d22cf
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/beaneditor/Width.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Defines the desired width of the field used to edit the property.  Note that width (generally equivalent to the
+ * size attribute of an HTML &lt;input&gt; element) is only used for presentation; validation must be used to
+ * actually enforce a maximum input length.
+ */
+@Target(METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Width
+{
+    /**
+     * The width used to display the field for the property (values less than one indicate unspecified).
+     */
+    int value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Inject.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Inject.java
new file mode 100644
index 0000000..f45c1df
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Inject.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation serves is something of the Swiss Army knife for operations related to injection of dependencies into
+ * an arbitrary method of Java Bean.
+ * <p/>
+ * <p>It marks parameters that should be injected in the IoC container, and it marks fields that should be injected
+ * inside Tapestry components.
+ * <p/>
+ * In terms of the IoC container; normally, resources take precedence over annotations when injecting. The Inject
+ * annotation overrides this default, forcing the resolution of the parameters value via the master {@link
+ * org.apache.tapestry.ioc.ObjectProvider}, even when the parameter's type matches a type that is normally a resource.
+ * This is most often used in conjunction with {@link org.apache.tapestry.ioc.annotation.Value} annotation when
+ * injecting a string, as normally, the String would be matched as the service id.
+ * <p/>
+ * In terms of the IoC container, the Inject annotation is only used on parameters to service builder methods (and
+ * contributor and decorator methods) and on module class constructors. constructors. However, inside Tapestry
+ * components (<em>and only inside components</em>), it may be applied to fields. On fields that require injection, the
+ * Inject annotation is <em>required</em>.
+ * <p/>
+ * Finally, on a constructor, this is used to indicate <em>which</em> constructor should be used when more than one is
+ * available.
+ *
+ * @see org.apache.tapestry.ioc.ObjectProvider
+ */
+@Target(
+        { PARAMETER, FIELD, ElementType.CONSTRUCTOR })
+@Retention(RUNTIME)
+@Documented
+public @interface Inject
+{
+
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/InjectService.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/InjectService.java
new file mode 100644
index 0000000..fd548bb
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/InjectService.java
@@ -0,0 +1,41 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.PARAMETER;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+@Target(PARAMETER)

+@Retention(RUNTIME)

+@Documented

+/**

+ * Annotation used with parameters of service builder methods to identify the service to be injected

+ * into the service builder method via the parameter. In many cases the

+ * {@link org.apache.tapestry.ioc.annotation.Inject} annotation is more flexible or appropriate.

+ *

+ *

+ */

+public @interface InjectService

+{

+

+    /**

+     * The id of the service to inject; either a fully qualified id, or the unqualified id of a service within the same

+     * module.

+     */

+    String value();

+}

diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/IntermediateType.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/IntermediateType.java
new file mode 100644
index 0000000..7dafd85
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/IntermediateType.java
@@ -0,0 +1,37 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Used to guide Tapestry when coercing from a raw type to a field or parameter type, by forcing Tapestry to coerce to
+ * the intermediate type.  This was introduced to allow coercion from string to a time period (in milliseconds) via
+ * {@link org.apache.tapestry.ioc.util.TimeInterval}.
+ *
+ * @see org.apache.tapestry.ioc.annotation.Value
+ * @see org.apache.tapestry.ioc.annotation.Symbol
+ */
+@Target({ ElementType.PARAMETER, ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IntermediateType
+{
+    /**
+     * The intermediate to coerce through.
+     */
+    Class value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Primary.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Primary.java
new file mode 100644
index 0000000..4f5cc7f
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Primary.java
@@ -0,0 +1,37 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation used to denote a service that is the primary instance of some common interface. This is often used
+ * when a service is a {@linkplain org.apache.tapestry.ioc.services.ChainBuilder chain of command} or {@linkplain
+ * org.apache.tapestry.ioc.services.StrategyBuilder strategy-based} and, therefore, many services will implement the
+ * same interface.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Primary
+{
+
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Symbol.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Symbol.java
new file mode 100644
index 0000000..81500cf
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Symbol.java
@@ -0,0 +1,39 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to inject a symbol value, via a symbol name. This is used much like {@link
+ * org.apache.tapestry.ioc.annotation.Value} annotation, except that symbols are not expanded ... the entire value is a
+ * symbol name. This allows the annotation to reference a public constant variable.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Symbol
+{
+    /**
+     * The name of the symbol to inject.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Value.java b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Value.java
new file mode 100644
index 0000000..3b5fbab
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/main/java/org/apache/tapestry/ioc/annotation/Value.java
@@ -0,0 +1,43 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used in conjunction with {@link org.apache.tapestry.ioc.annotation.Inject} to inject a literal value, rather than a
+ * service. Symbols in the value are expanded and the resulting string is coerced to the desired type. For IoC, this
+ * annotation is only applied to parameters (on service builder methods, and on service constructors); for components,
+ * it may also be applied to field.
+ *
+ * @see org.apache.tapestry.ioc.services.SymbolSource
+ * @see org.apache.tapestry.ioc.services.TypeCoercer
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Value
+{
+    /**
+     * The value to be coerced and injected.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-annotations/src/site/apt/index.apt b/hlship-20080520/tapestry-annotations/src/site/apt/index.apt
new file mode 100644
index 0000000..ee376bf
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/site/apt/index.apt
@@ -0,0 +1,23 @@
+ ----
+ Tapestry Annotations
+ ----
+ 
+Tapestry Annotations
+
+ The majority of Tapestry annotations (defined in the {{{.../tapestry-core}tapestry-core}} and {{{.../tapestry-ioc}tapestry-ioc}} modules)
+ are very specific to Tapestry components or Tapestry IoC services.
+ 
+ A small number of annotations are intended for data holding classes that are not Tapestry components; these annotations
+ allow high-level components such as Grid and BeanEditForm to
+ create powerful user interfaces with out any additional coding.
+ 
+ By separating out those annotations from the rest of Tapestry, it is reasonable to includes such annotations inside your 
+ data tier classes <without> having to bring all of Tapestry into your classpath.  This is very useful in multi-tier applications
+ where data objects may originate in an application tier (such as a JEE application server) and travel to the presentation tier (a Tapestry application).
+
+Upgrade Nodes
+
+* Release 5.0.12
+
+ The artifact id for this module has changed to tapestry<<5>>-annotations.  This is necessary to
+ support Tapestry 4 and Tapestry 5 applications co-existing within a single WAR.
diff --git a/hlship-20080520/tapestry-annotations/src/site/site.xml b/hlship-20080520/tapestry-annotations/src/site/site.xml
new file mode 100644
index 0000000..40d2c65
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/site/site.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Annotations">
+    <bannerLeft>
+        <name>Tapestry 5</name>
+        <href>http://tapestry.apache.org/tapestry5/</href>
+        <src>images/tapestry_banner.gif</src>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache</name>
+        <href>http://www.apache.org</href>
+        <src>images/asf_logo_wide.gif</src>
+    </bannerRight>
+    <skin>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>maven-skin</artifactId>
+        <version>1.1</version>
+    </skin>
+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+
+        <menu ref="reports"/>
+
+    </body>
+</project>
diff --git a/hlship-20080520/tapestry-annotations/src/test/conf/testng.xml b/hlship-20080520/tapestry-annotations/src/test/conf/testng.xml
new file mode 100644
index 0000000..e7dc420
--- /dev/null
+++ b/hlship-20080520/tapestry-annotations/src/test/conf/testng.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!--
+   Copyright 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Annotations" annotations="1.5" verbose="2">
+    <!-- This avoids a build error when performing a non-clean build.  Just another Maven fuckup to be worked around. -->
+    <test name="Placeholder (no tests)"/>
+</suite>
diff --git a/hlship-20080520/tapestry-component-report/.classpath b/hlship-20080520/tapestry-component-report/.classpath
new file mode 100644
index 0000000..04b0af6
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-component-report/.project b/hlship-20080520/tapestry-component-report/.project
new file mode 100644
index 0000000..12cb642
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-component-report</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-component-report/LICENSE.txt b/hlship-20080520/tapestry-component-report/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/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/hlship-20080520/tapestry-component-report/NOTICE.txt b/hlship-20080520/tapestry-component-report/NOTICE.txt
new file mode 100644
index 0000000..7196130
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/NOTICE.txt
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-component-report/pom.xml b/hlship-20080520/tapestry-component-report/pom.xml
new file mode 100644
index 0000000..6e211de
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/pom.xml
@@ -0,0 +1,165 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-component-report</artifactId>
+    <packaging>maven-plugin</packaging>
+    <name>Tapestry Component Parameters Report</name>
+    <description>
+        Generates component parameter documentation for Tapestry components,
+        mixins (and base classes)
+    </description>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+
+    <inceptionYear>2007</inceptionYear>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                    <optimize>true</optimize>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+
+        <!-- Copied from the maven javadoc plugin, for what's its worth. -->
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-project</artifactId>
+            <version>2.0.2</version>
+            <exclusions>
+                <!-- Using org.codehaus.plexus:plexus-utils instead of
+                -->
+                <exclusion>
+                    <groupId>plexus</groupId>
+                    <artifactId>plexus-utils</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>2.0.2</version>
+            <exclusions>
+                <!-- Using org.codehaus.plexus:plexus-utils instead of
+                -->
+                <exclusion>
+                    <groupId>plexus</groupId>
+                    <artifactId>plexus-utils</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>1.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-descriptor</artifactId>
+            <version>2.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.reporting</groupId>
+            <artifactId>maven-reporting-impl</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.doxia</groupId>
+            <artifactId>doxia-site-renderer</artifactId>
+            <version>1.0-alpha-8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-ioc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>xom</groupId>
+            <artifactId>xom</artifactId>
+            <version>1.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.7</version>
+            <classifier>jdk15</classifier>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+    <reporting>
+        <plugins>
+            <plugin>
+                <artifactId>maven-plugin-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <profiles>
+        <profile>
+            <id>default-tools.jar</id>
+            <activation>
+                <property>
+                    <name>java.vendor</name>
+                    <value>Sun Microsystems Inc.</value>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>com.sun</groupId>
+                    <artifactId>tools</artifactId>
+                    <version>1.5.0</version>
+                    <scope>system</scope>
+                    <systemPath>${java.home}/../lib/tools.jar</systemPath>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+    <!-- Temporary: until we figure out what needs org.apache.maven.plugins:maven-plugins:pom:2-SNAPSHOT -->
+    <pluginRepositories>
+        <pluginRepository>
+            <id>apache-snapshots</id>
+            <url>http://people.apache.org/repo/m2-snapshot-repository/</url>
+        </pluginRepository>
+    </pluginRepositories>
+</project>
diff --git a/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ClassDescription.java b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ClassDescription.java
new file mode 100644
index 0000000..b37fe72
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ClassDescription.java
@@ -0,0 +1,58 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.mojo;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+
+import java.util.Map;
+
+public class ClassDescription
+{
+    private final String superClassName;
+
+    private final String className;
+
+    private final String description;
+
+    private final Map<String, ParameterDescription> parameters = newMap();
+
+    public ClassDescription(String className, String superClassName, String description)
+    {
+        this.className = className;
+        this.superClassName = superClassName;
+        this.description = description;
+    }
+
+    public String getClassName()
+    {
+        return className;
+    }
+
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public Map<String, ParameterDescription> getParameters()
+    {
+        return parameters;
+    }
+
+    public String getSuperClassName()
+    {
+        return superClassName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
new file mode 100644
index 0000000..4125a77
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
@@ -0,0 +1,816 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.mojo;
+
+import nu.xom.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Resource;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.reporting.AbstractMavenReport;
+import org.apache.maven.reporting.MavenReportException;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.codehaus.doxia.sink.Sink;
+import org.codehaus.doxia.site.renderer.SiteRenderer;
+import org.codehaus.plexus.util.cli.CommandLineException;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+import org.codehaus.plexus.util.cli.DefaultConsumer;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * The component report generates documentation about components and parameters within the current project.
+ *
+ * @goal component-report
+ * @requiresDependencyResolution compile
+ * @execute phase="generate-sources"
+ */
+public class ComponentReport extends AbstractMavenReport
+{
+    /**
+     * Subdirectory containing the component reference pages and index.
+     */
+    private static final String REFERENCE_DIR = "ref";
+
+    private final static String[] PARAMETER_HEADERS = {"Name", "Type", "Flags", "Default", "Default Prefix",
+            "Description"};
+
+
+    /**
+     * Identifies the application root package.
+     *
+     * @parameter
+     * @required
+     */
+    private String rootPackage;
+
+    /**
+     * The Maven Project Object
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+    /**
+     * Generates the site report
+     *
+     * @component
+     */
+    private SiteRenderer siteRenderer;
+
+    /**
+     * Location of the generated site.
+     *
+     * @parameter default-value="${project.reporting.outputDirectory}"
+     * @required
+     */
+    private String outputDirectory;
+
+    /**
+     * @parameter expression="${project.build.directory}/generated-site/xdoc"
+     * @required
+     */
+    private File generatedDocsDirectory;
+
+    /**
+     * @parameter expression="${project.build.directory}/generated-site/resources"
+     * @required
+     */
+    private File generatedResourcesDirectory;
+
+    /**
+     * Working directory for temporary files.
+     *
+     * @parameter default-value="target"
+     * @required
+     */
+    private String workDirectory;
+
+    /**
+     * Relative path from the generated report to the API documentation (Javadoc). Defaults to "apidocs" but will often
+     * be changed to "../apidocs" when documentation is created at the project level.
+     *
+     * @parameter default-value="apidocs"
+     * @required
+     */
+    private String apidocs;
+
+    @Override
+    protected String getOutputDirectory()
+    {
+        return outputDirectory;
+    }
+
+    @Override
+    protected MavenProject getProject()
+    {
+        return project;
+    }
+
+    @Override
+    protected SiteRenderer getSiteRenderer()
+    {
+        return siteRenderer;
+    }
+
+    public String getDescription(Locale locale)
+    {
+        return "Tapestry component parameter reference documentation";
+    }
+
+    public String getName(Locale locale)
+    {
+        return "Component Reference";
+    }
+
+
+    public String getOutputName()
+    {
+        return REFERENCE_DIR + "/index";
+    }
+
+
+    private final static Set<String> SUPPORTED_SUBPACKAGES = CollectionFactory.newSet("base", "components", "mixins",
+                                                                                      "pages");
+
+    /**
+     * Generates the report; this consist of the index page
+     *
+     * @param locale
+     * @throws MavenReportException
+     */
+    @Override
+    protected void executeReport(Locale locale) throws MavenReportException
+    {
+        Map<String, ClassDescription> descriptions = runJavadoc();
+
+        getLog().info("Generating reference pages ...");
+
+        try
+        {
+            File refDir = new File(generatedDocsDirectory, REFERENCE_DIR);
+
+            refDir.mkdirs();
+
+
+            List<File> docSearchPath = createDocSearchPath();
+
+            Sink sink = getSink();
+
+            sink.head();
+            sink.title();
+            sink.text("Component Reference");
+            sink.title_();
+            sink.head_();
+
+            sink.section1();
+            sink.sectionTitle1();
+            sink.text("Component Reference");
+            sink.sectionTitle1_();
+            sink.list();
+
+            String currentSubpackage = null;
+
+            for (String className : InternalUtils.sortedKeys(descriptions))
+            {
+                String subpackage = extractSubpackage(className);
+
+                if (!SUPPORTED_SUBPACKAGES.contains(subpackage)) continue;
+
+                if (!subpackage.equals(currentSubpackage))
+                {
+                    if (currentSubpackage != null)
+                    {
+                        sink.list_();
+                        sink.section2_();
+                    }
+
+                    sink.section2();
+                    sink.sectionTitle2();
+                    sink.text(StringUtils.capitalize(subpackage));
+                    sink.sectionTitle2_();
+
+
+                    sink.list();
+
+                    currentSubpackage = subpackage;
+                }
+
+
+                sink.listItem();
+
+                sink.link(toPath(className) + ".html");
+
+                sink.text(className);
+                sink.link_();
+
+                writeClassDescription(descriptions, refDir, docSearchPath, className);
+
+
+                sink.listItem_();
+            }
+
+            if (currentSubpackage != null)
+            {
+                sink.list_();
+                sink.section2_();
+            }
+
+        }
+        catch (Exception ex)
+        {
+            throw new MavenReportException(ex.getMessage(), ex);
+        }
+    }
+
+    private String toPath(String className)
+    {
+        return className.replace('.', '/');
+    }
+
+    private String extractSubpackage(String className)
+    {
+        int dotx = className.indexOf(".", rootPackage.length() + 1);
+
+        // For classes directly in the root package.
+
+        if (dotx < 1) return "";
+
+        return className.substring(rootPackage.length() + 1, dotx);
+    }
+
+    private List<File> createDocSearchPath()
+    {
+        List<File> result = CollectionFactory.newList();
+
+        for (String sourceRoot : (List<String>) project.getCompileSourceRoots())
+        {
+            result.add(new File(sourceRoot));
+        }
+
+
+        for (Resource r : (List<Resource>) project.getResources())
+        {
+            String dir = r.getDirectory();
+
+            result.add(new File(dir));
+        }
+
+        return result;
+    }
+
+    private void writeClassDescription(Map<String, ClassDescription> descriptions, File refDir,
+                                       List<File> docSearchPath, String className) throws Exception
+    {
+
+        int dotx = className.lastIndexOf('.');
+        String packageName = className.substring(0, dotx);
+        File outputDir = new File(refDir, toPath(packageName));
+        outputDir.mkdirs();
+
+        File outputFile = new File(refDir, toPath(className) + ".xml");
+
+
+        Element root = new Element("document");
+
+        ClassDescription cd = descriptions.get(className);
+
+        Map<String, ParameterDescription> parameters = newMap(cd.getParameters());
+        List<String> parents = newList();
+
+        String current = cd.getSuperClassName();
+
+        while (true)
+        {
+            ClassDescription superDescription = descriptions.get(current);
+
+            if (superDescription == null) break;
+
+            parents.add(current);
+            parameters.putAll(superDescription.getParameters());
+
+            current = superDescription.getSuperClassName();
+        }
+
+        Collections.reverse(parents);
+
+        // XOM is pretty verbose; it really needs a builder/fluent interface.
+
+        Element properties = addChild(root, "properties");
+        addChild(properties, "title", String.format("Component Reference: %s", className));
+
+        Element body = new Element("body");
+        root.appendChild(body);
+
+        Element section = addSection(body, className);
+
+        addChild(section, "p", cd.getDescription());
+
+
+        StringBuilder javadocURL = new StringBuilder(200);
+
+        int depth = packageName.split("\\.").length;
+
+
+        for (int i = 0; i < depth; i++)
+        {
+            javadocURL.append("../");
+        }
+
+        String pathToRefRoot = javadocURL.toString();
+
+        javadocURL.append("../").append(apidocs).append("/").append(toPath(className)).append(".html");
+
+        addLink(addChild(section, "p"), javadocURL.toString(), "[JavaDoc]");
+
+        if (!parents.isEmpty())
+        {
+            section = addSection(body, "Component Inheritance");
+            Element container = section;
+
+            for (String name : parents)
+            {
+
+                Element ul = addChild(container, "ul");
+
+                Element li = addChild(ul, "li");
+
+                addLink(li, name + ".html", name);
+
+                container = li;
+            }
+
+            addChild(addChild(container, "ul"), "li", className);
+        }
+
+
+        if (!parameters.isEmpty())
+        {
+            section = addSection(body, "Component Parameters");
+
+            Element table = new Element("table");
+
+            section.appendChild(table);
+
+            Element headerRow = new Element("tr");
+            table.appendChild(headerRow);
+
+            for (String header : PARAMETER_HEADERS)
+                addChild(headerRow, "th", header);
+
+            List<String> flags = newList();
+
+            for (String name : InternalUtils.sortedKeys(parameters))
+            {
+                ParameterDescription pd = parameters.get(name);
+
+                flags.clear();
+
+                if (pd.getRequired()) flags.add("Required");
+
+                if (!pd.getCache()) flags.add("NOT Cached");
+
+                Element row = new Element("tr");
+                table.appendChild(row);
+
+                addChild(row, "td", pd.getName());
+                addChild(row, "td", pd.getType());
+                addChild(row, "td", InternalUtils.join(flags));
+                addChild(row, "td", pd.getDefaultValue());
+                addChild(row, "td", pd.getDefaultPrefix());
+                addChild(row, "td", pd.getDescription());
+            }
+        }
+
+
+        addExternalDocumentation(body, docSearchPath, className);
+
+        addChild(body, "hr");
+
+        addLink(addChild(body, "p"), pathToRefRoot + "index.html", "Back to index");
+
+        Document document = new Document(root);
+
+
+        getLog().info(String.format("Writing %s", outputFile));
+
+        FileOutputStream fos = new FileOutputStream(outputFile);
+
+        BufferedOutputStream bos = new BufferedOutputStream(fos);
+
+        PrintWriter writer = new PrintWriter(bos);
+
+        writer.print(document.toXML());
+
+        writer.close();
+    }
+
+    private void addExternalDocumentation(Element body, List<File> docSearchPath, String className)
+            throws ParsingException, IOException
+    {
+        String classNamePath = toPath(className);
+
+
+        String pathExtension = classNamePath + ".xdoc";
+
+        for (File path : docSearchPath)
+        {
+            File file = new File(path, pathExtension);
+
+            getLog().debug(String.format("Checking for %s", file));
+
+            if (!file.exists()) continue;
+
+            getLog().info(String.format("Reading extra documentation from %s", file));
+
+            Builder builder = new Builder();
+
+            Document doc = builder.build(file);
+
+            // Transfer the nodes inside document/body into our body
+
+            Element incomingBody = doc.getRootElement().getFirstChildElement("body");
+
+            for (int i = 0; i < incomingBody.getChildCount(); i++)
+            {
+                Node incoming = incomingBody.getChild(i).copy();
+
+                body.appendChild(incoming);
+            }
+
+            Nodes nodes = doc.query("//img/@src");
+
+            int lastslashx = classNamePath.lastIndexOf('/');
+            String packagePath = classNamePath.substring(0, lastslashx);
+
+            File generatedRefRoot = new File(generatedResourcesDirectory, REFERENCE_DIR);
+            File generatedPackageRoot = new File(generatedRefRoot, packagePath);
+
+            for (int i = 0; i < nodes.size(); i++)
+            {
+                Node src = nodes.get(i);
+
+                String srcPath = src.getValue();
+
+                File imgFile = new File(path, packagePath + "/" + srcPath);
+                File imgTargetFile = new File(generatedPackageRoot, srcPath);
+
+                copy(imgFile, imgTargetFile);
+            }
+
+
+            return;
+        }
+    }
+
+    private void copy(File sourceFile, File targetFile) throws IOException
+    {
+        getLog().info(String.format("Copying image file %s to %s", sourceFile, targetFile));
+
+        targetFile.getParentFile().mkdirs();
+
+        byte[] buffer = new byte[20000];
+
+        InputStream in = new BufferedInputStream(new FileInputStream(sourceFile));
+        OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile));
+
+        while (true)
+        {
+            int length = in.read(buffer);
+
+            if (length < 0) break;
+
+            out.write(buffer, 0, length);
+        }
+
+        in.close();
+        out.close();
+    }
+
+
+    private Map<String, ClassDescription> runJavadoc() throws MavenReportException
+    {
+        getLog().info("Running JavaDoc to collect component parameter data ...");
+
+        Commandline command = new Commandline();
+
+        try
+        {
+            command.setExecutable(pathToJavadoc());
+        }
+        catch (IOException ex)
+        {
+            throw new MavenReportException("Unable to locate javadoc command: " + ex.getMessage(), ex);
+        }
+
+        String parametersPath = workDirectory + File.separator + "component-parameters.xml";
+
+        String[] arguments = {"-private", "-o", parametersPath,
+
+                "-subpackages", rootPackage,
+
+                "-doclet", ParametersDoclet.class.getName(),
+
+                "-docletpath", docletPath(),
+
+                "-sourcepath", sourcePath(),
+
+                "-classpath", classPath()};
+
+        command.addArguments(arguments);
+
+        executeCommand(command);
+
+        return readXML(parametersPath);
+    }
+
+    @SuppressWarnings("unchecked")
+    private String sourcePath()
+    {
+        List<String> roots = project.getCompileSourceRoots();
+
+        return toArgumentPath(roots);
+    }
+
+    /**
+     * Needed to help locate this plugin's local JAR file for the -doclet argument.
+     *
+     * @parameter default-value="${localRepository}"
+     * @read-only
+     */
+    private ArtifactRepository localRepository;
+
+    /**
+     * Needed to help locate this plugin's local JAR file for the -doclet argument.
+     *
+     * @parameter default-value="${plugin.groupId}"
+     * @read-only
+     */
+    private String pluginGroupId;
+
+    /**
+     * Needed to help locate this plugin's local JAR file for the -doclet argument.
+     *
+     * @parameter default-value="${plugin.artifactId}"
+     * @read-only
+     */
+    private String pluginArtifactId;
+
+    /**
+     * Needed to help locate this plugin's local JAR file for the -doclet argument.
+     *
+     * @parameter default-value="${plugin.version}"
+     * @read-only
+     */
+    private String pluginVersion;
+
+    @SuppressWarnings("unchecked")
+    private String docletPath() throws MavenReportException
+    {
+        File file = new File(localRepository.getBasedir());
+
+        for (String term : pluginGroupId.split("\\."))
+            file = new File(file, term);
+
+        file = new File(file, pluginArtifactId);
+        file = new File(file, pluginVersion);
+
+        file = new File(file, String.format("%s-%s.jar", pluginArtifactId, pluginVersion));
+
+        return file.getAbsolutePath();
+    }
+
+    @SuppressWarnings("unchecked")
+    private String classPath() throws MavenReportException
+    {
+        List<Artifact> artifacts = project.getCompileArtifacts();
+
+        return artifactsToArgumentPath(artifacts);
+    }
+
+    private String artifactsToArgumentPath(List<Artifact> artifacts) throws MavenReportException
+    {
+        List<String> paths = newList();
+
+        for (Artifact artifact : artifacts)
+        {
+            if (artifact.getScope().equals("test")) continue;
+
+            File file = artifact.getFile();
+
+            if (file == null) throw new MavenReportException(
+                    "Unable to execute Javadoc: compile dependencies are not fully resolved.");
+
+            paths.add(file.getAbsolutePath());
+        }
+
+        return toArgumentPath(paths);
+    }
+
+    private void executeCommand(Commandline command) throws MavenReportException
+    {
+        getLog().debug(command.toString());
+
+        CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
+
+        try
+        {
+            int exitCode = CommandLineUtils.executeCommandLine(command, new DefaultConsumer(), err);
+
+            if (exitCode != 0)
+            {
+                String message = String.format("Javadoc exit code: %d - %s\nCommand line was: %s", exitCode,
+                                               err.getOutput(), command);
+
+                throw new MavenReportException(message);
+            }
+        }
+        catch (CommandLineException ex)
+        {
+            throw new MavenReportException("Unable to execute javadoc command: " + ex.getMessage(), ex);
+        }
+
+        // ----------------------------------------------------------------------
+        // Handle Javadoc warnings
+        // ----------------------------------------------------------------------
+
+        if (StringUtils.isNotEmpty(err.getOutput()))
+        {
+            getLog().info("Javadoc Warnings");
+
+            StringTokenizer token = new StringTokenizer(err.getOutput(), "\n");
+            while (token.hasMoreTokens())
+            {
+                String current = token.nextToken().trim();
+
+                getLog().warn(current);
+            }
+        }
+    }
+
+    private String pathToJavadoc() throws IOException, MavenReportException
+    {
+        String executableName = SystemUtils.IS_OS_WINDOWS ? "javadoc.exe" : "javadoc";
+
+        File executable = initialGuessAtJavadocFile(executableName);
+
+        if (!executable.exists() || !executable.isFile())
+            throw new MavenReportException(String.format("Path %s does not exist or is not a file.", executable));
+
+        return executable.getAbsolutePath();
+    }
+
+    private File initialGuessAtJavadocFile(String executableName)
+    {
+        if (SystemUtils.IS_OS_MAC_OSX)
+            return new File(SystemUtils.getJavaHome() + File.separator + "bin", executableName);
+
+        return new File(SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "bin", executableName);
+    }
+
+    private String toArgumentPath(List<String> paths)
+    {
+        StringBuilder builder = new StringBuilder();
+
+        String sep = "";
+
+        for (String path : paths)
+        {
+            builder.append(sep);
+            builder.append(path);
+
+            sep = SystemUtils.PATH_SEPARATOR;
+        }
+
+        return builder.toString();
+    }
+
+    public Map<String, ClassDescription> readXML(String path) throws MavenReportException
+    {
+        try
+        {
+            Builder builder = new Builder(false);
+
+            File input = new File(path);
+
+            Document doc = builder.build(input);
+
+            return buildMapFromDocument(doc);
+        }
+        catch (Exception ex)
+        {
+            throw new MavenReportException(String.format("Failure reading from %s: %s", path, ex
+                    .getMessage()), ex);
+        }
+    }
+
+    private Map<String, ClassDescription> buildMapFromDocument(Document doc)
+    {
+        Map<String, ClassDescription> result = newMap();
+
+        Elements elements = doc.getRootElement().getChildElements("class");
+
+        for (int i = 0; i < elements.size(); i++)
+        {
+            Element element = elements.get(i);
+
+            String description = element.getFirstChildElement("description").getValue();
+
+            String className = element.getAttributeValue("name");
+            String superClassName = element.getAttributeValue("super-class");
+
+            ClassDescription cd = new ClassDescription(className, superClassName, description);
+
+            result.put(className, cd);
+
+            readParameters(cd, element);
+        }
+
+        return result;
+    }
+
+    private void readParameters(ClassDescription cd, Element classElement)
+    {
+        Elements elements = classElement.getChildElements("parameter");
+
+        for (int i = 0; i < elements.size(); i++)
+        {
+            Element node = elements.get(i);
+
+            String name = node.getAttributeValue("name");
+            String type = node.getAttributeValue("type");
+
+            int dotx = type.lastIndexOf('.');
+            if (dotx > 0 && type.substring(0, dotx).equals("java.lang")) type = type.substring(dotx + 1);
+
+            String defaultValue = node.getAttributeValue("default");
+            boolean required = Boolean.parseBoolean(node.getAttributeValue("required"));
+            boolean cache = Boolean.parseBoolean(node.getAttributeValue("cache"));
+            String defaultPrefix = node.getAttributeValue("default-prefix");
+            String description = node.getValue();
+
+            ParameterDescription pd = new ParameterDescription(name, type, defaultValue, defaultPrefix, required, cache,
+                                                               description);
+
+            cd.getParameters().put(name, pd);
+        }
+    }
+
+    private Element addSection(Element container, String name)
+    {
+        Element section = new Element("section");
+        container.appendChild(section);
+
+        section.addAttribute(new Attribute("name", name));
+
+        return section;
+    }
+
+    private Element addLink(Element container, String URL, String text)
+    {
+        Element link = addChild(container, "a", text);
+
+        link.addAttribute(new Attribute("href", URL));
+
+        return link;
+    }
+
+    private Element addChild(Element container, String elementName)
+    {
+        Element child = new Element(elementName);
+        container.appendChild(child);
+
+        return child;
+    }
+
+    private Element addChild(Element container, String elementName, String text)
+    {
+        Element child = new Element(elementName);
+        container.appendChild(child);
+
+        child.appendChild(text);
+
+        return child;
+    }
+}
diff --git a/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java
new file mode 100644
index 0000000..77d48ba
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParameterDescription.java
@@ -0,0 +1,80 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.mojo;
+
+public class ParameterDescription
+{
+    private final String name;
+
+    private final String type;
+
+    private final String defaultValue;
+
+    private final String defaultPrefix;
+
+    private final boolean required;
+
+    private final boolean cache;
+
+    private final String description;
+
+    public ParameterDescription(String name, String type, String defaultValue,
+                                String defaultPrefix, boolean required, boolean cache, String description)
+    {
+        this.name = name;
+        this.type = type;
+        this.defaultValue = defaultValue;
+        this.defaultPrefix = defaultPrefix;
+        this.required = required;
+        this.cache = cache;
+        this.description = description;
+    }
+
+    public boolean getCache()
+    {
+        return cache;
+    }
+
+    public String getDefaultPrefix()
+    {
+        return defaultPrefix;
+    }
+
+    public String getDefaultValue()
+    {
+        return defaultValue;
+    }
+
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public boolean getRequired()
+    {
+        return required;
+    }
+
+    public String getType()
+    {
+        return type;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParametersDoclet.java b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParametersDoclet.java
new file mode 100644
index 0000000..aa57dc2
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ParametersDoclet.java
@@ -0,0 +1,248 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.mojo;
+
+import com.sun.javadoc.*;
+import com.sun.javadoc.AnnotationDesc.ElementValuePair;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Generates an XML file that identifies all the classes that contain parameters, and all the parameters within each
+ * component class. This XML is later converted into part of the Maven generated HTML site.
+ * <p/>
+ * To keep the -doclet parameter passed to javadoc simple, this class should not have any outside dependencies.
+ */
+public class ParametersDoclet extends Doclet
+{
+    static String OUTPUT_PATH_OPTION = "-o";
+
+    static String outputPath;
+
+    static class Worker
+    {
+        private PrintWriter out;
+
+        private final Pattern stripper = Pattern.compile("(<.*?>|&.*?;)", Pattern.DOTALL);
+
+        public void run(String outputPath, RootDoc root) throws Exception
+        {
+            File output = new File(outputPath);
+
+            out = new PrintWriter(output);
+
+            println("<component-parameters>");
+
+            for (ClassDoc cd : root.classes())
+                emitClass(cd);
+
+            println("</component-parameters>");
+
+            out.close();
+        }
+
+        private void emitClass(ClassDoc classDoc)
+        {
+            if (!classDoc.isPublic()) return;
+
+            // Components must be root classes, not nested classes.
+            if (classDoc.containingClass() != null) return;
+
+            // Check for a no-args public constructor
+
+            boolean found = false;
+
+            for (ConstructorDoc cons : classDoc.constructors())
+            {
+                if (cons.isPublic() && cons.parameters().length == 0)
+                {
+                    found = true;
+                    break;
+                }
+            }
+
+            if (!found) return;
+
+            println("<class name=\"%s\" super-class=\"%s\">", classDoc.qualifiedTypeName(),
+                    classDoc.superclass().qualifiedTypeName());
+            print("<description>");
+            printDescription(classDoc);
+            println("</description>", classDoc.commentText());
+
+            for (FieldDoc fd : classDoc.fields())
+            {
+                if (fd.isStatic()) continue;
+
+                if (!fd.isPrivate()) continue;
+
+                Map<String, String> annotationValues = findParameterAnnotation(fd);
+
+                if (annotationValues == null) continue;
+
+                String name = annotationValues.get("name");
+                if (name == null) name = fd.name().replaceAll("^[$_]*", "");
+
+                print("<parameter name=\"%s\" type=\"%s\" default=\"%s\" required=\"%s\" cache=\"%s\" default-prefix=\"%s\">",
+                      name, fd.type().qualifiedTypeName(), get(annotationValues, "value", ""),
+                      get(annotationValues, "required", "false"), get(annotationValues, "cache", "true"),
+                      get(annotationValues, "defaultPrefix", "prop"));
+
+                // Body of a parameter is the comment text.
+
+                printDescription(fd);
+
+                println("\n</parameter>");
+            }
+
+            println("</class>");
+        }
+
+        private String get(Map<String, String> map, String key, String defaultValue)
+        {
+            if (map.containsKey(key)) return map.get(key);
+
+            return defaultValue;
+        }
+
+        private Map<String, String> findParameterAnnotation(FieldDoc fd)
+        {
+            for (AnnotationDesc annotation : fd.annotations())
+            {
+                if (annotation.annotationType().qualifiedTypeName().equals("org.apache.tapestry.annotation.Parameter"))
+                {
+                    Map<String, String> result = new HashMap<String, String>();
+
+                    for (ElementValuePair pair : annotation.elementValues())
+                        result.put(pair.element().name(), pair.value().value().toString());
+
+                    return result;
+                }
+            }
+
+            return null;
+        }
+
+        private void print(String format, Object... arguments)
+        {
+            String line = String.format(format, arguments);
+
+            out.print(line);
+        }
+
+        private void println(String format, Object... arguments)
+        {
+            print(format, arguments);
+
+            out.println();
+        }
+
+        private void printDescription(Doc holder)
+        {
+            StringBuilder builder = new StringBuilder();
+
+            for (Tag tag : holder.inlineTags())
+            {
+                if (tag.name().equals("Text"))
+                {
+                    builder.append(tag.text());
+                    continue;
+                }
+
+                if (tag.name().equals("@link"))
+                {
+                    SeeTag seeTag = (SeeTag) tag;
+
+                    String label = seeTag.label();
+                    if (label != null && !label.equals(""))
+                    {
+                        builder.append(label);
+                        continue;
+                    }
+
+                    if (seeTag.referencedClassName() != null) builder.append(seeTag.referencedClassName());
+
+                    if (seeTag.referencedMemberName() != null)
+                    {
+                        builder.append("#");
+                        builder.append(seeTag.referencedMemberName());
+                    }
+                }
+            }
+
+            String text = builder.toString();
+
+            // Fix it up a little.
+
+            // Remove any simple open or close tags found in the text, as well as any XML entities.
+
+            String stripped = stripper.matcher(text).replaceAll("");
+
+            out.print(stripped);
+        }
+    }
+
+    /**
+     * Yes we are interested in annotations, etc.
+     */
+    public static LanguageVersion languageVersion()
+    {
+        return LanguageVersion.JAVA_1_5;
+    }
+
+    public static int optionLength(String option)
+    {
+        if (option.equals(OUTPUT_PATH_OPTION)) return 2;
+
+        return 0;
+    }
+
+    public static boolean validOptions(String options[][], DocErrorReporter reporter)
+    {
+        for (String[] group : options)
+        {
+            if (group[0].equals(OUTPUT_PATH_OPTION)) outputPath = group[1];
+
+            // Do we need to check for other unexpected options?
+            // TODO: Check for duplicate -o?
+        }
+
+        if (outputPath == null) reporter.printError(String.format("Usage: javadoc %s path", OUTPUT_PATH_OPTION));
+
+        return true;
+    }
+
+    public static boolean start(RootDoc root)
+    {
+        // Enough of this static method bullshit. What the fuck were they thinking?
+
+        try
+        {
+            new Worker().run(outputPath, root);
+        }
+        catch (Exception ex)
+        {
+            root.printError(ex.getMessage());
+
+            return false;
+        }
+
+        return true;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-component-report/src/site/apt/index.apt b/hlship-20080520/tapestry-component-report/src/site/apt/index.apt
new file mode 100644
index 0000000..5fe500a
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/site/apt/index.apt
@@ -0,0 +1,81 @@
+ ----
+ Tapestry Component Parameters Report
+ ----
+ 
+Tapestry Component Parameters Report
+
+  This report generates a comprehensive listing of all the components in your module (either a component library or
+  a Tapestry application). For each component, the inheritance, description and complete set of parameters (including inherited parameters)
+  are displayed.
+
+  The documentation is generated from a mix of JavaDoc and annotations on the classes themselves, and from
+  external documentation you may provide.
+
+
+* Providing External Documentation
+
+  The external documentation is optional, and takes the form of a file, stored in the same package
+  as the component class, with the extension ".xdoc".
+
+  External documentation is in the {{{http://maven.apache.org/doxia/references/xdoc-format.html}Maven XDoc Format}},
+  which can be thought of as a somewhat rigid, stripped down version of XHTML.
+
+  The component report will extract the content of the \<body\> element and add it to the documention it
+  automatically generates.  It will also copy any images (the <<<src>>> attribute of any \<img\> element)
+  to the corresponding output folder.
+
+  The documentation is generated into a directory structure that mimics the package structure; thus links
+  to component documentation for components in the same package is just a link to another file (with a .html extension)
+  in the same folder.
+
+  Example:
+
+----
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li><a href="Foo.html">Foo</a></ul>
+                <li><a href="Bar.html">Bar</a></ul>
+            </ul>
+         </section>
+
+         <section name="Examples">
+
+            <p>The Baz component can be used to generate a gloop style of interface:</p>
+
+            <p><img src="baz_ref.png"/></p>
+
+            . . .
+----  
+
+
+  External documentation files (the .xdoc files and any related image files)
+  can be either on the Java main path (i.e., src/main/java) or on the resources path
+  (src/main/resources).  At this time, you should place them under src/main/java such that
+  the files are not packaged in your library JAR or application WAR.
+  
+* Generating the Report
+
+  Just add the following to the reporting/plugins section of your POM:
+  
++---+
+<plugin>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-component-report</artifactId>
+    <version>5.0.x</version>
+    <configuration>
+        <rootPackage>org.example.myapp</rootPackage>
+    </configuration>                
+</plugin>
++---+
+
+  Be sure the update the \<version\> element with the current version of the Maven plugin, and update the
+  \<rootPackage\> element with the value for your application (this will match the value you configure inside
+  your
+  {{{../tapestry-core/conf.html}web.xml}}).
+  
+* Limitations
+  
+  Doesn't have any way to generate parameters for base classes from another library; the tools assume that the components
+  are entirely self-contained within the current model.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-component-report/src/site/site.xml b/hlship-20080520/tapestry-component-report/src/site/site.xml
new file mode 100644
index 0000000..cbec6a0
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/site/site.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Core">
+    <bannerLeft>
+        <name>Tapestry</name>
+        <href>http://tapestry.apache.org/</href>
+        <src>images/tapestry_banner.gif</src>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache</name>
+        <href>http://www.apache.org</href>
+        <src>images/asf_logo_wide.gif</src>
+    </bannerRight>
+    <skin>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>maven-skin</artifactId>
+        <version>1.1</version>
+    </skin>
+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+
+        <menu name="Tapestry Component Report">
+            <item name="Usage" href="index.html"/>
+        </menu>
+
+        <menu ref="reports"/>
+
+    </body>
+</project>
diff --git a/hlship-20080520/tapestry-component-report/src/test/conf/testng.xml b/hlship-20080520/tapestry-component-report/src/test/conf/testng.xml
new file mode 100644
index 0000000..e73e47b
--- /dev/null
+++ b/hlship-20080520/tapestry-component-report/src/test/conf/testng.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!--
+   Copyright 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Component Report" annotations="1.5" verbose="2">
+    <!-- This avoids a build error when performing a non-clean build.  Just another Maven fuckup to be worked around. -->
+    <test name="Placeholder (no tests)"/>
+</suite>
diff --git a/hlship-20080520/tapestry-core/.classpath b/hlship-20080520/tapestry-core/.classpath
new file mode 100644
index 0000000..df0c639
--- /dev/null
+++ b/hlship-20080520/tapestry-core/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="src" output="bin-test" path="src/test/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="lib" path="src/test/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-core/.project b/hlship-20080520/tapestry-core/.project
new file mode 100644
index 0000000..5d3d5cd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-core</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-core/.settings/org.eclipse.ajdt.core.prefs b/hlship-20080520/tapestry-core/.settings/org.eclipse.ajdt.core.prefs
new file mode 100644
index 0000000..b825d8b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/.settings/org.eclipse.ajdt.core.prefs
@@ -0,0 +1,37 @@
+#Tue Sep 19 11:09:16 PDT 2006

+eclipse.preferences.version=1

+org.aspectj.ajdt.core.compiler.BuildOptions.buildAsm=true

+org.aspectj.ajdt.core.compiler.BuildOptions.incrementalMode=true

+org.aspectj.ajdt.core.compiler.BuildOptions.showweavemessages=true

+org.aspectj.ajdt.core.compiler.lint.BrokeSerialVersionCompatibility=ignore

+org.aspectj.ajdt.core.compiler.lint.CannotImplementLazyTJP=ignore

+org.aspectj.ajdt.core.compiler.lint.InvalidAbsoluteTypeName=warning

+org.aspectj.ajdt.core.compiler.lint.NeedSerialVersionUIDField=ignore

+org.aspectj.ajdt.core.compiler.lint.NoInterfaceCtorJoinpoint=warning

+org.aspectj.ajdt.core.compiler.lint.ShadowNotInStructure=ignore

+org.aspectj.ajdt.core.compiler.lint.TypeNotExposedToWeaver=warning

+org.aspectj.ajdt.core.compiler.lint.UnresolvableMember=warning

+org.aspectj.ajdt.core.compiler.lint.WildcardTypeName=ignore

+org.aspectj.ajdt.core.compiler.lint.adviceDidNotMatch=warning

+org.aspectj.ajdt.core.compiler.lint.annotationAsTargetForDecpIgnored=warning

+org.aspectj.ajdt.core.compiler.lint.cantMatchArrayTypeOnVarargs=ignore

+org.aspectj.ajdt.core.compiler.lint.elementAlreadyAnnotated=warning

+org.aspectj.ajdt.core.compiler.lint.enumAsTargetForDecpIgnored=warning

+org.aspectj.ajdt.core.compiler.lint.invalidTargetForAnnotation=warning

+org.aspectj.ajdt.core.compiler.lint.multipleAdviceStoppingLazyTjp=ignore

+org.aspectj.ajdt.core.compiler.lint.noExplicitConstructorCall=warning

+org.aspectj.ajdt.core.compiler.lint.noGuardForLazyTjp=ignore

+org.aspectj.ajdt.core.compiler.lint.noJoinpointsForBridgeMethods=warning

+org.aspectj.ajdt.core.compiler.lint.runtimeExceptionNotSoftened=warning

+org.aspectj.ajdt.core.compiler.lint.swallowedExceptionInCatchBlock=ignore

+org.aspectj.ajdt.core.compiler.lint.uncheckedAdviceConversion=warning

+org.aspectj.ajdt.core.compiler.lint.uncheckedArgument=warning

+org.aspectj.ajdt.core.compiler.lint.unmatchedTargetKind=warning

+org.aspectj.ajdt.core.compiler.lint.unorderedAdviceAtShadow=ignore

+org.aspectj.ajdt.core.compiler.list.UnmatchedSuperTypeInCall=warning

+org.aspectj.ajdt.core.compiler.weaver.XHasMember=false

+org.aspectj.ajdt.core.compiler.weaver.XNoInline=true

+org.aspectj.ajdt.core.compiler.weaver.XNotReweavable=false

+org.aspectj.ajdt.core.compiler.weaver.XSerializableAspects=false

+org.aspectj.ajdt.core.complier.lint.aspectExcludedByConfiguration=ignore

+org.eclipse.ajdt.core.compiler.useProjectSettings=true

diff --git a/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.core.prefs b/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..cf6476b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,305 @@
+#Sun Apr 15 08:16:56 PDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=_
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=_
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=48
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
diff --git a/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.ui.prefs b/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..926ebbd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,15 @@
+#Thu Mar 08 12:41:58 PST 2007
+eclipse.preferences.version=1
+formatter_profile=_Tapestry Project
+formatter_settings_version=10
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=ex
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=\#;java;javax;org;com;
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
diff --git a/hlship-20080520/tapestry-core/LICENSE.txt b/hlship-20080520/tapestry-core/LICENSE.txt
new file mode 100644
index 0000000..75248b8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/LICENSE.txt
@@ -0,0 +1,437 @@
+
+                                 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.
+
+-------------------------------------------------------------------------------
+
+This module, tapestry-core, includes a number of resources with seperate copyrights and licenses.
+
+-------------------------------------------------------------------------------
+
+JAVASSIST
+
+Javassist is not bundled with tapestry-core, but tapestry-core is not functional without Javassist.
+Javassist is distributed under a dual license: Mozilla Public License or LGPL (Lesser Gnu Public License). Tapestry
+invokes the MPL for compatibility with the Apache Software License.
+
+MOZILLA PUBLIC LICENSE
+Version 1.1
+
+1. Definitions.
+
+      1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party.
+
+      1.1. ''Contributor'' means each entity that creates or contributes to the creation of Modifications.
+
+      1.2. ''Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor.
+
+      1.3. ''Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof.
+
+      1.4. ''Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data.
+
+      1.5. ''Executable'' means Covered Code in any form other than Source Code.
+
+      1.6. ''Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A.
+
+      1.7. ''Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License.
+
+      1.8. ''License'' means this document.
+
+      1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+
+      1.9. ''Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is:
+            A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications.
+
+            B. Any new file that contains any part of the Original Code or previous Modifications.
+             
+      1.10. ''Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License.
+
+      1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation,  method, process, and apparatus claims, in any patent Licensable by grantor.
+
+      1.11. ''Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge.
+
+      1.12. "You'' (or "Your")  means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+
+      2.1. The Initial Developer Grant.
+      The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:
+            (a)  under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and
+
+            (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof).
+            (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License.
+
+            (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code;  or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices.
+             
+      2.2. Contributor Grant.
+      Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license
+
+            (a)  under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and
+
+            (b) under Patent Claims infringed by the making, using, or selling of  Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of  Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+
+            (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code.
+
+            (d)    Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2)  separate from the Contributor Version;  3)  for infringements caused by: i) third party modifications of Contributor Version or ii)  the combination of Modifications made by that Contributor with other software  (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor.
+
+
+3. Distribution Obligations.
+
+      3.1. Application of License.
+      The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5.
+
+      3.2. Availability of Source Code.
+      Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.
+
+      3.3. Description of Modifications.
+      You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code.
+
+      3.4. Intellectual Property Matters
+            (a) Third Party Claims.
+            If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained.
+
+            (b) Contributor APIs.
+            If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file.
+             
+                (c)    Representations.
+            Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License.
+
+
+      3.5. Required Notices.
+      You must duplicate the notice in Exhibit A in each file of the Source Code.  If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice.  If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A.  You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code.  You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
+
+      3.6. Distribution of Executable Versions.
+      You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
+
+      3.7. Larger Works.
+      You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+      If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Application of this License.
+
+      This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+      6.1. New Versions.
+      Netscape Communications Corporation (''Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.
+
+      6.2. Effect of New Versions.
+      Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License.
+
+      6.3. Derivative Works.
+      If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+      COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+      8.1.  This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+
+      8.2.  If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant")  alleging that:
+
+      (a)  such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i)  agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant.  If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above.
+
+      (b)  any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant.
+
+      8.3.  If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+      8.4.  In the event of termination under Sections 8.1 or 8.2 above,  all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+      UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+      The Covered Code is a ''commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and ''commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein.
+
+11. MISCELLANEOUS.
+
+      This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+      As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+      Initial Developer may designate portions of the Covered Code as ÒMultiple-Licensed?.  ÒMultiple-Licensed? means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A.
+
+
+EXHIBIT A -Mozilla Public License.
+
+      The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+      http://www.mozilla.org/MPL/
+
+      Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+      ANY KIND, either express or implied. See the License for the specific language governing rights and
+      limitations under the License.
+
+      The Original Code is Javassist.
+
+      The Initial Developer of the Original Code is Shigeru Chiba. Portions created by the Initial Developer are
+        Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
+
+      Contributor(s): ______________________________________.
+
+      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.
+
+
+-------------------------------------------------------------------------------
+
+PROTOTYPE
+
+Copyright (c) 2005-2007 Sam Stephenson
+
+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 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.
+
+-------------------------------------------------------------------------------
+
+SCRIPTACULOUS
+
+Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+
+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.
+
+-------------------------------------------------------------------------------
+
+WEBFX DATEPICKER
+
+Distributed under the terms of the Apache Software License 2.0.
+  
+  
diff --git a/hlship-20080520/tapestry-core/NOTICE.txt b/hlship-20080520/tapestry-core/NOTICE.txt
new file mode 100644
index 0000000..9002788
--- /dev/null
+++ b/hlship-20080520/tapestry-core/NOTICE.txt
@@ -0,0 +1,23 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product makes use of the Javassist library, distributed under the terms of the Mozilla Public License.
+http://www.jboss.com/products/javassist
+
+This product includes the script.aculo.us JavaScript library, distributed under the terms of an MIT-style license.
+http://script.aculo.us
+
+This product includes the prototype JavaScript library, distributed under the terms of an MIT-style license.
+http://prototypejs.org/
+
+This product includes modified versions of Java classes from the JSON library, which is freely available.
+http://json.org/
+
+This product includes the WebFX DatePicker, a JavaScript library released under the Apache Software License 2.0
+http://webfx.eae.net/dhtml/datepicker/datepicker.html
+
+This product includes images from the Silk icon set, distributed under the terms of the Creative Commons Attribution 2.5 License.
+http://www.famfamfam.com/lab/icons/silk/
+
+
+
diff --git a/hlship-20080520/tapestry-core/pom.xml b/hlship-20080520/tapestry-core/pom.xml
new file mode 100644
index 0000000..4d93c6e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/pom.xml
@@ -0,0 +1,107 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-core</artifactId>
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <name>Tapestry Core Library</name>
+    <description>
+        Central module for Tapestry, containing interfaces to the Java
+        Servlet API and all core services and components.
+    </description>
+    <inceptionYear>2006</inceptionYear>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-ioc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-test</artifactId>
+            <!-- This would be test, but we provide a few base classes that depend on TestNG, which is provided by tapestry-test. -->
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+            <!-- This gets the plugin to clean up the cobertura.ser file left
+        in the root directory. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-component-report</artifactId>
+                <version>${project.version}</version>
+                <configuration>
+                    <rootPackage>org.apache.tapestry.corelib</rootPackage>
+                    <apidocs>../apidocs</apidocs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-core/src/images/deselect.psd b/hlship-20080520/tapestry-core/src/images/deselect.psd
new file mode 100644
index 0000000..0e99228
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/images/deselect.psd
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/images/move_down.psd b/hlship-20080520/tapestry-core/src/images/move_down.psd
new file mode 100644
index 0000000..f6324a3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/images/move_down.psd
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/images/move_up.psd b/hlship-20080520/tapestry-core/src/images/move_up.psd
new file mode 100644
index 0000000..473c2f1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/images/move_up.psd
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/images/select.psd b/hlship-20080520/tapestry-core/src/images/select.psd
new file mode 100644
index 0000000..c903c51
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/images/select.psd
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/AbstractOptionModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/AbstractOptionModel.java
new file mode 100644
index 0000000..9ee5850
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/AbstractOptionModel.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import java.util.Map;
+
+/**
+ * Base class for implementing {@link OptionModel}.  Subclasses must implement {@link
+ * org.apache.tapestry.OptionModel#getLabel()} and {@link org.apache.tapestry.OptionModel#getValue()} }.
+ */
+public abstract class AbstractOptionModel implements OptionModel
+{
+    /**
+     * Returns false.
+     */
+    public boolean isDisabled()
+    {
+        return false;
+    }
+
+    /**
+     * Returns null.
+     */
+    public Map<String, String> getAttributes()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Asset.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Asset.java
new file mode 100644
index 0000000..a333dd3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Asset.java
@@ -0,0 +1,41 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.Resource;
+
+/**
+ * An Asset is any kind of resource that can be exposed to the client web browser. Although quite often an Asset is a
+ * resource in a web application's context folder, within Tapestry, Assets may also be resources on the classpath (i.e.,
+ * packaged inside JARs).
+ * <p/>
+ * An Asset's toString() will return the URL for the resource (the same value as {@link #toClientURL()}).
+ */
+public interface Asset
+{
+    /**
+     * Returns a URL that can be passed, unchanged, to the client in order for it to access the resource. The same value
+     * is returned from <code>toString()</code>.
+     * <p/>
+     * Note that the returned value may be {@linkplain SymbolConstants#FORCE_ABSOLUTE_URIS request dependent}. You may
+     * cache instances of Asset, but do not cache the client URL path as it may change.
+     */
+    String toClientURL();
+
+    /**
+     * Returns the underlying Resource for the Asset.
+     */
+    Resource getResource();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BaseValidationDecorator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BaseValidationDecorator.java
new file mode 100644
index 0000000..c04e60c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BaseValidationDecorator.java
@@ -0,0 +1,50 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.dom.Element;
+
+/**
+ * Base implementation of {@link ValidationDecorator} that does nothing. Subclasses may override specific methods,
+ * knowing that all other methods do nothing at all.
+ */
+public class BaseValidationDecorator implements ValidationDecorator
+{
+
+    public void beforeLabel(Field field)
+    {
+    }
+
+    public void afterLabel(Field field)
+    {
+    }
+
+    public void afterField(Field field)
+    {
+    }
+
+    public void beforeField(Field field)
+    {
+    }
+
+    public void insideField(Field field)
+    {
+    }
+
+    public void insideLabel(Field field, Element labelElement)
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Binding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Binding.java
new file mode 100644
index 0000000..467f657
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Binding.java
@@ -0,0 +1,56 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+/**
+ * A binding is a connection between a component and its container (another component), that allows the embedded
+ * component to gain access to <em>resources</em> defined by the container. Resources can represent any kind of value
+ * that can be obtained from the parent component, but is often a JavaBean property that can be read and updated.
+ * Different implementations of Binding as used to access different kinds of resources of the container.
+ * <p/>
+ * A binding ultimately must provide access to the underlying annotations. In most cases, there are no annotations, but
+ * bindings that ultimate invoke methods or read and update fields must provide access to those annotations.
+ */
+public interface Binding extends AnnotationProvider
+{
+    /**
+     * Reads the current value of the property (or other resource). When reading properties of objects that are
+     * primitive types, this will return an instance of the wrapper type. In some cases, a binding is read only and this
+     * method will throw a runtime exception.
+     */
+    Object get();
+
+    /**
+     * Updates the current value. Most types of bindings are read-only, and this method will throw a runtime exception.
+     * It is the caller's responsibility to ensure that the value passed in is of the appropriate type.
+     *
+     * @param value
+     */
+    void set(Object value);
+
+    /**
+     * Returns true if the value of the binding does not ever change. Components will often cache such values
+     * aggressively.
+     */
+    boolean isInvariant();
+
+    /**
+     * Returns the type of the binding, either the type of resource exposed by the binding, or the type of the property
+     * bound.
+     */
+    Class getBindingType();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BindingConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BindingConstants.java
new file mode 100644
index 0000000..cfd30af
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BindingConstants.java
@@ -0,0 +1,34 @@
+package org.apache.tapestry;
+
+/**
+ * Constants for the built-in binding prefixes.  These are often used with the {@link
+ * org.apache.tapestry.annotation.Parameter#defaultPrefix()} annotation attribute.
+ */
+public class BindingConstants
+{
+    /**
+     * Binding expression prefix used for literal strings.
+     */
+    public static final String LITERAL = "literal";
+    /**
+     * Binding expression prefix used to bind to a property of the component. When {@link
+     * org.apache.tapestry.annotation.Parameter#defaultPrefix()} is not specified, the default is PROP.
+     */
+    public static final String PROP = "prop";
+
+    public static final String NULLFIELDSTRATEGY = "nullfieldstrategy";
+
+    public static final String COMPONENT = "component";
+
+    public static final String MESSAGE = "message";
+
+    public static final String VALIDATE = "validate";
+
+    public static final String TRANSLATE = "translate";
+
+    public static final String BLOCK = "block";
+
+    public static final String ASSET = "asset";
+
+    public static final String VAR = "var";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Block.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Block.java
new file mode 100644
index 0000000..86da774
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Block.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * A block is a collection of static text and elements, and components, derived from a component template. In the
+ * template, a block is demarcated using the &lt;t:block&gt; or &lt;t:parameter&gt; elements. The interface defines no
+ * methods, but the provided implementations of Block are capable of rendering their contents on demand.
+ */
+public interface Block
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BlockNotFoundException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BlockNotFoundException.java
new file mode 100644
index 0000000..5d1092f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/BlockNotFoundException.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Exception thrown when a {@link Block} is requested but not found.
+ */
+public class BlockNotFoundException extends RuntimeException implements Locatable
+{
+    private static final long serialVersionUID = 81221040659940576L;
+
+    private final Location location;
+
+    public BlockNotFoundException(String message, Location location)
+    {
+        super(message);
+
+        this.location = location;
+    }
+
+    public Location getLocation()
+    {
+        return location;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/CSSClassConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/CSSClassConstants.java
new file mode 100644
index 0000000..ed18e9d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/CSSClassConstants.java
@@ -0,0 +1,16 @@
+package org.apache.tapestry;
+
+/**
+ * Constants used when rendering a CSS class attribute.
+ */
+public class CSSClassConstants
+{
+    /**
+     * CSS class name that causes a rendered element to be invisible on the client side.
+     */
+    public static final String INVISIBLE = "t-invisible";
+    /**
+     * All purpose CSS class name for anything related to Tapestry errors.
+     */
+    public static final String ERROR = "t-error";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ClientElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ClientElement.java
new file mode 100644
index 0000000..c734bab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ClientElement.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+
+/**
+ * Interface for any kind of object (typically, a component) that can provide a {@linkplain #getClientId() client-side
+ * id}, typically used in the generation of client-side (JavaScript) logic. For components, the client id will be null
+ * or innaccurate until after the component has rendered itself. Inside of any kind of loop, the clientId property is
+ * only accurate just after the component has rendered, and before it renders again.
+ * <p/>
+ * Some components must be configured to provide a client id. In many cases, the client id matches the component's
+ * {@linkplain ComponentResourcesCommon#getId() component id}, typically passed through {@link
+ * RenderSupport#allocateClientId(String)} to ensure uniqueness.
+ */
+public interface ClientElement
+{
+    /**
+     * Returns a unique id for the element. This value will be unique for any given rendering of a page. This value is
+     * intended for use as the id attribute of the client-side element, and will be used with any DHTML/Ajax related
+     * JavaScript.
+     */
+    String getClientId();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentAction.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentAction.java
new file mode 100644
index 0000000..b81605a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentAction.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry;

+

+import java.io.Serializable;

+

+/**

+ * An action that is associated with a component. This is used in several areas of Tapestry and is primarily an attempt

+ * to externalize state for a component so that it can be recorded outside the object.

+ * <p/>

+ * ComponentActions should be immutable. They are often created during one request and associated with a particular

+ * component instance. They are then used in a later request (with an equivalent component instance).

+ * <p/>

+ * ComponentActions are serializable (they are often serialized into Base64 strings for storage on the client).

+ */

+public interface ComponentAction<T> extends Serializable

+{

+    /**

+     * Passed a component instance, the action should operate upon the instance.

+     */

+    void execute(T component);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java
new file mode 100644
index 0000000..ce15c7e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentEventCallback.java
@@ -0,0 +1,37 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Callback interface for a {@linkplain org.apache.tapestry.runtime.Event render phase event) or {@link
+ * org.apache.tapestry.runtime.ComponentEvent}, notified when a non-null value is returned from some event handler
+ * method.
+ */
+public interface ComponentEventCallback<T>
+{
+    /**
+     * Invoked to handle a non-null event handler method result. The handler should determine whether the value is
+     * acceptible, and throw an exception if not.  Any thrown exception will be wrapped to identify the component and
+     * method from which the value was returned.
+     * <p/>
+     * Boolean values are <em>not</em> passed to the handler.  Booleans are used to indicate that the event has been
+     * handled (true) or that a further search for handlers should continue (true).  If a component event method returns
+     * true, then {@link org.apache.tapestry.runtime.Event#isAborted()} will return true.
+     *
+     * @param result the result value return from the event handler method
+     * @return true if the event is aborted, false if the event may continue
+     */
+    boolean handleResult(T result);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
new file mode 100644
index 0000000..399ce4b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
@@ -0,0 +1,202 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Provides a component instance with the resources provided by the framework. In many circumstances, the resources
+ * object can be considered the component itself; in others, it is the {@link #getComponent() component property}, and
+ * instance of a class provided by the application developer (though transformed in many ways while being loaded) that
+ * is the true component. In reality, it is the combination of the resources object with the lifecycle instance.
+ */
+public interface ComponentResources extends ComponentResourcesCommon
+{
+    /**
+     * Returns the base resource for the component, which will represent the class's location within the classpath (this
+     * is used to resolve relative assets).
+     */
+    Resource getBaseResource();
+
+    /**
+     * Returns the component model object that defines the behavior of the component.
+     */
+    ComponentModel getComponentModel();
+
+    /**
+     * Returns the component this object provides resources for.
+     */
+    Component getComponent();
+
+    /**
+     * Returns the component which contains this component, or null for the root component. For mixins, this returns the
+     * componet to which the mixin is attached.
+     */
+    Component getContainer();
+
+    /**
+     * Returns the {@link ComponentResources} for the container, or null if the this is the root component (that has no
+     * container). As a special case, for a mixin, this returns the core component's resources.
+     */
+    ComponentResources getContainerResources();
+
+    /**
+     * Returns the {@link Messages} from the container, or null if this is the root component (with no container). As a
+     * special case, for a mixin, this return the core component's messages.
+     */
+    Messages getContainerMessages();
+
+    /**
+     * Returns the page that contains this component. Technically, the page itself is an internal object in Tapestry and
+     * this returns the root component of the actual page, but from an application developer point of view, this is the
+     * page.
+     */
+    Component getPage();
+
+    /**
+     * Returns an embedded component, given the component's id.
+     *
+     * @param embeddedId selects the embedded component (case is ignored)
+     * @throws IllegalArgumentException if this component does not contain a component with the given id
+     */
+
+    Component getEmbeddedComponent(String embeddedId);
+
+    /**
+     * Returns true if the named parameter is bound, false if not.
+     */
+    boolean isBound(String parameterName);
+
+    /**
+     * Obtains an annotation provided by a parameter.
+     *
+     * @param parameterName  name of parameter to search for the annotation
+     * @param annotationType the type of annotation
+     * @return the annotation if found or null otherwise
+     */
+    <T extends Annotation> T getParameterAnnotation(String parameterName, Class<T> annotationType);
+
+    /**
+     * Indentifies all parameters that are not formal parameters and writes each as a attribute/value pair into the
+     * current element of the markup writer.
+     *
+     * @param writer to which {@link MarkupWriter#attributes(Object[]) attributes} will be written
+     */
+    void renderInformalParameters(MarkupWriter writer);
+
+    /**
+     * Returns the message catalog for this component.
+     */
+    Messages getMessages();
+
+    /**
+     * Returns the actual type of the bound parameter, or null if the parameter is not bound. This is primarily used
+     * with property bindings, and is used to determine the actual type of the property, rather than the type of
+     * parameter (remember that type coercion automatically occurs, which can mask significant differences between the
+     * parameter type and the bound property type).
+     *
+     * @param parameterName used to select the parameter (case is ignored)
+     * @return the type of the bound parameter, or null if the parameter is not bound
+     * @see Binding#getBindingType()
+     */
+    Class getBoundType(String parameterName);
+
+    /**
+     * Returns an annotation provider, used to obtain annotations related to the parameter.
+     *
+     * @param parameterName used to select the parameter (case is ignored)
+     * @return the annotation provider, or null if the parameter is not bound
+     */
+    AnnotationProvider getAnnotationProvider(String parameterName);
+
+    /**
+     * Used to access an informal parameter that's a Block.
+     *
+     * @param parameterName the name of the informal parameter (case is ignored)
+     * @return the informal Block parameter, or null if not bound
+     */
+    Block getBlockParameter(String parameterName);
+
+    /**
+     * Returns a previously stored render variable.
+     *
+     * @param name of the variable (case will be ignored)
+     * @return the variable's value
+     * @throws IllegalArgumentException if the name doesn't correspond to a stored value
+     */
+    Object getRenderVariable(String name);
+
+    /**
+     * Stores a render variable, accessible with the provided name.
+     *
+     * @param name  of value to store
+     * @param value value to store (may not be null)
+     * @throws IllegalStateException if the component is not currently rendering
+     */
+    void storeRenderVariable(String name, Object value);
+
+    /**
+     * Adds a listener object that will be notified about page lifecycle events.
+     */
+    void addPageLifecycleListener(PageLifecycleListener listener);
+
+
+    /**
+     * Creates a component action request link as a callback for this component. The event type and context (as well as
+     * the page name and nested component id) will be encoded into a URL. A request for the URL will {@linkplain
+     * #triggerEvent(String, Object[], ComponentEventCallback)}  trigger} the named event on the component.
+     *
+     * @param eventType the type of event to be triggered.  Event types should be Java identifiers (contain only
+     *                  letters, numbers and the underscore).
+     * @param forForm   if true, the link will be used as the eventType for an HTML form submission, which may affect
+     *                  what information is encoded into the link
+     * @param context   additional objects to be encoded into the path portion of the link; each is converted to a
+     *                  string and URI encoded
+     * @return link object for the callback
+     */
+    Link createActionLink(String eventType, boolean forForm, Object... context);
+
+    /**
+     * Creates a render request link to a specific page.
+     *
+     * @param pageName the logical name of the page to link to
+     * @param override if true, the context is used even if empty (normally, the target page is allowed to passivate,
+     *                 providing a context, when the provided context is empty)
+     * @param context  the activation context for the page. If omitted, the activation context is obtained from the
+     *                 target paget
+     */
+    Link createPageLink(String pageName, boolean override, Object... context);
+
+    /**
+     * Discards all persistent field changes for the page containing the component.  Changes are eliminated from
+     * persistent storage (such as the {@link org.apache.tapestry.services.Session}) which will take effect in the
+     * <em>next</em> request (the attached page instance is not affected).
+     */
+    void discardPersistentFieldChanges();
+
+    /**
+     * Returns the name of element that represents the component in its template, or null if not known.
+     *
+     * @return the element name or null
+     */
+    String getElementName();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
new file mode 100644
index 0000000..83a26a8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
@@ -0,0 +1,145 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.Locatable;
+import org.slf4j.Logger;
+
+import java.util.Locale;
+
+/**
+ * Operations shared by the public {@link org.apache.tapestry.ComponentResources} interface and {@link
+ * org.apache.tapestry.internal.structure.ComponentPageElement} interface (on the internal side).
+ */
+public interface ComponentResourcesCommon extends Locatable
+{
+    /**
+     * Returns the id of the component. The id will be unique within the component's immediate container. For a page's
+     * root component, the value null is returned.
+     */
+    String getId();
+
+    /**
+     * Return a string consisting the concatinated ids of all containing components, separated by periods. In addition,
+     * nested ids are always all lower case. I.e., "foo.bar.baz". Returns null for the root component of a  page.
+     */
+    String getNestedId();
+
+
+    /**
+     * Returns a string consisting of the logical name of the containing page, and the {@link #getNestedId() nested id}
+     * of this component, separated by a colon. I.e., "mypage:foo.bar.baz". For a page, returns just the page's logical
+     * name.
+     * <p/>
+     * This value is often used to obtain an equivalent component instance in a later request.
+     *
+     * @see org.apache.tapestry.services.ComponentSource#getComponent(String)
+     */
+
+    String getCompleteId();
+
+    /**
+     * A convienience for invoking {@link #triggerContextEvent(String, EventContext , ComponentEventCallback)}. Wraps
+     * the context values into an {@link org.apache.tapestry.EventContext}.
+     *
+     * @param eventType event type (as determined from the request, or otherwise by design)
+     * @param context   Values that may be provided to the event handler method as method parameters, or null if no
+     *                  context values are available
+     * @param callback  the handler to be informed of the result, or null if the event is a notification that does not
+     *                  support return values from event handler methods (the value true is allowed even if the handler
+     *                  is null).
+     * @return true if any event handler was invoked (even if no event handler method returns a non-null value)
+     * @throws org.apache.tapestry.runtime.ComponentEventException
+     *          if an event handler method throws a checked or unchecked exception
+     * @see org.apache.tapestry.internal.transform.OnEventWorker
+     * @see org.apache.tapestry.annotation.OnEvent
+     */
+    boolean triggerEvent(String eventType, Object[] contextValues, ComponentEventCallback callback);
+
+    /**
+     * Triggers a component event. A search for an event handling method will occur, first in the component, then its
+     * container, and so on. When a matching event handler method is located, it is invoked. If the method returns a
+     * value, the value is passed to the callback (if callback is null, then it is an error for a method to return a
+     * non-null value).
+     * <p/>
+     * Resolution of event type to event handler methods is case insensitive.
+     *
+     * @param eventType event type (as determined from the request, or otherwise by design)
+     * @param context   the context (as extracted from the request, or provided by the triggering component); these
+     *                  values may be provided to event handler methods via their parameters (may not be null)
+     * @param callback  the handler to be informed of the result, or null if the event is a notification that does not
+     *                  support return values from event handler methods (the value true is allowed even if the handler
+     *                  is null).
+     * @return true if any event handler was invoked (even if no event handler method returns a non-null value)
+     * @throws org.apache.tapestry.runtime.ComponentEventException
+     *          if an event handler method throws a checked or unchecked exception
+     * @see org.apache.tapestry.internal.transform.OnEventWorker
+     * @see org.apache.tapestry.annotation.OnEvent
+     */
+    boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback);
+
+    /**
+     * Returns true if the component is currently rendering, false otherwise. This is most often used to determine if
+     * parameter values should be cached.
+     */
+    boolean isRendering();
+
+    /**
+     * Returns the log instance associated with the component (which is based on the component or mixin's class name).
+     *
+     * @see org.apache.tapestry.model.ComponentModel#getLogger()
+     */
+    Logger getLogger();
+
+    /**
+     * Returns the locale for the page containing this component.
+     */
+    Locale getLocale();
+
+    /**
+     * Returns the name of element that represents the component in its template, or the provided default element name
+     * if the element was a component type (in the Tapestry namespace).
+     *
+     * @param defaultElementName element name to return if the element name is not known (may be null)
+     * @return the element name
+     */
+    String getElementName(String defaultElementName);
+
+    /**
+     * Returns a block from the component's template, referenced by its id.
+     *
+     * @param blockId the id of the block (case insensitive)
+     * @return the identified Block
+     * @throws BlockNotFoundException if no block with the given id exists
+     * @see #findBlock(String)
+     */
+    Block getBlock(String blockId);
+
+    /**
+     * As with {@link #getBlock(String)}, but returns null if the block is not found.
+     *
+     * @param blockId the id of the block (case insensitive)
+     * @return the block, or null
+     */
+    Block findBlock(String blockId);
+
+    /**
+     * Returns the <em>logical</em> name of the page containing this component. This is the short name (it often appears
+     * in URLs)
+     *
+     * @return the logical name of the page which contains this component
+     */
+    String getPageName();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ContentType.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ContentType.java
new file mode 100644
index 0000000..e0eb3c1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ContentType.java
@@ -0,0 +1,204 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Represents an HTTP content type. Allows to set various elements like the mime type, the character set, and other
+ * parameters. This is similar to a number of other implementations of the same concept in JAF, etc. We have created
+ * this simple implementation to avoid including the whole libraries.
+ */
+public final class ContentType
+{
+    private String baseType = "";
+
+    private String subType = "";
+
+    private final Map<String, String> parameters = CollectionFactory.newCaseInsensitiveMap();
+
+    /**
+     * Creates a new empty content type.
+     */
+    public ContentType()
+    {
+    }
+
+    /**
+     * Creates a new content type from the argument. The format of the argument has to be basetype/subtype(;key=value)*
+     *
+     * @param contentType the content type that needs to be represented
+     */
+    public ContentType(String contentType)
+    {
+        parse(contentType);
+    }
+
+    /**
+     * Returns true only if the other object is another instance of ContentType, and has the ssame baseType, subType and
+     * set of parameters.
+     */
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o == null) return false;
+
+        if (o.getClass() != this.getClass()) return false;
+
+        ContentType ct = (ContentType) o;
+
+        return baseType.equals(ct.baseType) && subType.equals(ct.subType) && parameters.equals(ct.parameters);
+    }
+
+    /**
+     * @return the base type of the content type
+     */
+    public String getBaseType()
+    {
+        return baseType;
+    }
+
+    /**
+     * @param baseType
+     */
+    public void setBaseType(String baseType)
+    {
+        Defense.notNull(baseType, "baseType");
+
+        this.baseType = baseType;
+    }
+
+    /**
+     * @return the sub-type of the content type
+     */
+    public String getSubType()
+    {
+        return subType;
+    }
+
+    /**
+     * @param subType
+     */
+    public void setSubType(String subType)
+    {
+        Defense.notNull(subType, "subType");
+
+        this.subType = subType;
+    }
+
+    /**
+     * @return the MIME type of the content type
+     */
+    public String getMimeType()
+    {
+        return baseType + "/" + subType;
+    }
+
+    /**
+     * @return the list of names of parameters in this content type, in alphabetical order.
+     */
+    public List<String> getParameterNames()
+    {
+        return InternalUtils.sortedKeys(parameters);
+    }
+
+    /**
+     * @param key the name of the content type parameter
+     * @return the value of the content type parameter
+     */
+    public String getParameter(String key)
+    {
+        Defense.notNull(key, "key");
+
+        return parameters.get(key);
+    }
+
+    /**
+     * @param key   the name of the content type parameter
+     * @param value the value of the content type parameter
+     */
+    public void setParameter(String key, String value)
+    {
+        Defense.notNull(key, "key");
+        Defense.notNull(value, "value");
+
+        parameters.put(key, value);
+    }
+
+    /**
+     * Parses the argument and configures the content type accordingly. The format of the argument has to be
+     * type/subtype(;key=value)*
+     *
+     * @param contentType the content type that needs to be represented
+     */
+    public void parse(String contentType)
+    {
+        baseType = "";
+        subType = "";
+        parameters.clear();
+
+        StringTokenizer tokens = new StringTokenizer(contentType, ";");
+        if (!tokens.hasMoreTokens()) return;
+
+        String mimeType = tokens.nextToken();
+        StringTokenizer mimeTokens = new StringTokenizer(mimeType, "/");
+        setBaseType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken() : "");
+        setSubType(mimeTokens.hasMoreTokens() ? mimeTokens.nextToken() : "");
+
+        while (tokens.hasMoreTokens())
+        {
+            String parameter = tokens.nextToken();
+
+            StringTokenizer parameterTokens = new StringTokenizer(parameter, "=");
+            String key = parameterTokens.hasMoreTokens() ? parameterTokens.nextToken() : "";
+            String value = parameterTokens.hasMoreTokens() ? parameterTokens.nextToken() : "";
+            setParameter(key, value);
+        }
+    }
+
+    /**
+     * @return the string representation of this content type
+     */
+    public String unparse()
+    {
+        StringBuilder buffer = new StringBuilder(getMimeType());
+
+        for (String parameterName : getParameterNames())
+        {
+            buffer.append(";");
+            buffer.append(parameterName);
+            buffer.append("=");
+            buffer.append(parameters.get(parameterName));
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * @return the string representation of this content type. Same as unparse().
+     */
+    @Override
+    public String toString()
+    {
+        return unparse();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventConstants.java
new file mode 100644
index 0000000..4fa21d6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventConstants.java
@@ -0,0 +1,23 @@
+package org.apache.tapestry;
+
+/**
+ * Constant values for common event names fired by Tapestry components.
+ */
+public class EventConstants
+{
+    /**
+     * Default client event name, "action", used in most situations.
+     */
+    public static final String ACTION = "action";
+    /**
+     * Event triggered when a page is activated (for rendering). The component event handler will be passed the context
+     * provided by the passivate event.
+     */
+    public static final String ACTIVATE = "activate";
+    /**
+     * Event triggered when a link for a page is generated. The event handler for the page may provide an object, or an
+     * array of objects, as the context for the page. These values will become part of the page's context, and will be
+     * provided back when the page is activated.
+     */
+    public static final String PASSIVATE = "passivate";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java
new file mode 100644
index 0000000..f65549f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/EventContext.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * A collection of parameters that may eventually be passed to an event handler method.  Includes the ability to coerce
+ * or encode parameters as needed.
+ *
+ * @see org.apache.tapestry.ioc.services.TypeCoercer
+ * @see org.apache.tapestry.ValueEncoder
+ */
+public interface EventContext
+{
+    /**
+     * Returns the number of parameter values that can be extracted.
+     */
+    int getCount();
+
+    /**
+     * Extracts a parameter value and coerces or decodes it to the desired type.
+     *
+     * @param desiredType the type of value required
+     * @param index       identifies which parameter value to extract
+     * @return the value extracted and converted or coerced
+     * @throws RuntimeException if the value can't be converted or the index is out of range
+     */
+    <T> T get(Class<T> desiredType, int index);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Field.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Field.java
new file mode 100644
index 0000000..78c1ec8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Field.java
@@ -0,0 +1,60 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Defines a field within a form.  Fields have a <a href="http://www.w3.org/TR/html4/interact/forms.html#control-name">control
+ * name</a> that is used when rendering and, later, when the form is submitted, to identify the query parameter.
+ * <p/>
+ * Timing is important, as components may render multiple times, due to looping and other factors. Generally, a
+ * component's {@link #getControlName()} will only be accurate after it has rendered.  In some cases, when generating
+ * JavaScript for example, it is necessary to {@linkplain org.apache.tapestry.services.Heartbeat#defer(Runnable) wait
+ * until the end of the current Heartbeat} to ensure that all components have had thier chance to render.
+ */
+public interface Field extends ClientElement
+{
+    /**
+     * Returns the value used as the name attribute of the rendered element. This value will be unique within an
+     * enclosing form, even if the same component renders multiple times.
+     *
+     * @see org.apache.tapestry.services.FormSupport#allocateControlName(String)
+     */
+    String getControlName();
+
+    /**
+     * Returns a user presentable (localized) label for the field, which may be used inside &lt;label&gt; elements on
+     * the client, and inside client or server-side validation error messages.
+     *
+     * @return the label
+     * @see org.apache.tapestry.corelib.components.Label
+     */
+    String getLabel();
+
+    /**
+     * Returns true if the field is disabled; A disabled field will render a disabled attribute so that it is
+     * non-responsive on the client (at least, until its disabled status is changed on the client using JavaScript). A
+     * disabled field will ignore any value passed up in a form submit request. Care must be taken if the disabled
+     * status of a field can change between the time the field is rendered and the time the enclosing form is
+     * submitted.
+     */
+    boolean isDisabled();
+
+    /**
+     * Returns true if this field required (as per {@link org.apache.tapestry.FieldValidator#isRequired()}).
+     *
+     * @return true if a non-blank value is required for the field
+     */
+    boolean isRequired();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidationSupport.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidationSupport.java
new file mode 100644
index 0000000..bb636b5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidationSupport.java
@@ -0,0 +1,69 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Services to help with field {@linkplain org.apache.tapestry.Validator validation} and {@linkplain
+ * org.apache.tapestry.Translator translation}. This service encapsulates the logic that mixes normal
+ * configured/declared validation/translation with events triggered on the component.
+ */
+public interface FieldValidationSupport
+{
+    /**
+     * A wrapper around {@link org.apache.tapestry.Translator#toClient(Object)} that first fires a "toclient" event on
+     * the component to see if it can perform the conversion. If the value is null, then no event is fired and the
+     * translator is <em>not</em> invoked, the return value is simply null.
+     *
+     * @param value              to be converted to a client-side string, which may be null
+     * @param componentResources used to fire events on the component
+     * @param translator         used if the component does not provide a non-null value
+     * @param nullFieldStrategy  used to convert a null server side value to an appropriate client side value
+     * @return the translated value  or null if the value is null
+     * @see org.apache.tapestry.Translator#toClient(Object)
+     */
+    String toClient(Object value, ComponentResources componentResources, Translator translator,
+                    NullFieldStrategy nullFieldStrategy);
+
+    /**
+     * A wrapper around {@link org.apache.tapestry.Translator#parseClient(String, org.apache.tapestry.ioc.Messages)}.
+     * First a "parseclient" event is fired; the translator is only invoked if that returns null (typically because
+     * there is not handler for the event).
+     *
+     * @param clientValue        the value provided by the client (not null)
+     * @param componentResources used to trigger events
+     * @param translator         translator that will do the work if the component event returns null
+     * @param nullFieldStrategy  used to convert null/blank values from client into non-null server side values
+     * @return the input parsed to an object
+     * @throws org.apache.tapestry.ValidationException
+     *          if the value can't be parsed
+     * @see org.apache.tapestry.Translator#parseClient(String, org.apache.tapestry.ioc.Messages)
+     */
+    Object parseClient(String clientValue, ComponentResources componentResources, Translator translator,
+                       NullFieldStrategy nullFieldStrategy)
+            throws ValidationException;
+
+    /**
+     * Performs validation on a parsed value from the client.  Normal validations occur first, then a "validate" event
+     * is triggered on the component.
+     *
+     * @param value              parsed value from the client, possibly null
+     * @param componentResources used to trigger events
+     * @param validator          performs normal validations
+     * @throws ValidationException if the value is not valid
+     * @see org.apache.tapestry.Validator#validate(Field, Object, org.apache.tapestry.ioc.MessageFormatter, Object)
+     */
+    void validate(Object value, ComponentResources componentResources, FieldValidator validator)
+            throws ValidationException;
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidator.java
new file mode 100644
index 0000000..fe117d4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FieldValidator.java
@@ -0,0 +1,54 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Responsible for validation of a single field.
+ *
+ * @param <T>
+ * @see Validator
+ * @see org.apache.tapestry.services.FieldValidatorDefaultSource
+ */
+public interface FieldValidator<T>
+{
+    /**
+     * Invoked after the client-submitted value has been {@link Translator translated} to check that the value conforms
+     * to expectations (often, in terms of minimum or maximum value). If and only if the value is approved by all
+     * Validators is the value applied by the field.
+     *
+     * @param value the translated value supplied by the user
+     * @throws ValidationException if the value violates the constraint
+     */
+    void validate(T value) throws ValidationException;
+
+    /**
+     * Invokes {@link Validator#render(Field, Object, org.apache.tapestry.ioc.MessageFormatter, MarkupWriter,
+     * org.apache.tapestry.services.FormSupport)}. This is called at a point "inside" the tag, so that additional
+     * attributes may be added.  In many cases, the underlying {@link org.apache.tapestry.Validator} may write
+     * client-side JavaScript to enforce the constraint as well.
+     *
+     * @param writer markup writer to direct output to.
+     * @see org.apache.tapestry.MarkupWriter#attributes(Object[])
+     */
+    void render(MarkupWriter writer);
+
+    /**
+     * Returns true if any underlying {@link org.apache.tapestry.Validator} returns true from {@link
+     * org.apache.tapestry.Validator#isRequired()}.
+     *
+     * @return true if the field is required   (a non-blank value is expected)
+     */
+    boolean isRequired();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FormValidationControl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FormValidationControl.java
new file mode 100644
index 0000000..c204e29
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/FormValidationControl.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Allows control over validation concerns of a Form component.
+ */
+public interface FormValidationControl
+{
+    /**
+     * A convienience for invoking {@link ValidationTracker#recordError(String)}.
+     */
+    public abstract void recordError(String errorMessage);
+
+    /**
+     * A convienience for invoking {@link ValidationTracker#recordError(Field, String)}.
+     */
+    public abstract void recordError(Field field, String errorMessage);
+
+    /**
+     * Returns true if the form's {@link ValidationTracker} contains any {@link ValidationTracker#getHasErrors()
+     * errors}.
+     */
+    public abstract boolean getHasErrors();
+
+    /**
+     * Returns true if the form's {@link ValidationTracker} does not contain any {@link ValidationTracker#getHasErrors()
+     * errors}.
+     */
+    public abstract boolean isValid();
+
+    /**
+     * Invokes {@link ValidationTracker#clear()}.
+     */
+    public abstract void clearErrors();
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Link.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Link.java
new file mode 100644
index 0000000..59375ea
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Link.java
@@ -0,0 +1,93 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.commons.codec.net.URLCodec;
+
+import java.util.List;
+
+/**
+ * A link is the Tapestry representation of a URL or URI that triggers dynamic behavior. This link is in three parts: a
+ * path portion, an optional anchor, and a set of query parameters. A request for a link will ultimately be recognized
+ * by a {@link org.apache.tapestry.services.Dispatcher}.
+ * <p/>
+ * Query parameter values are kept separate from the path portion to support encoding those values into hidden form
+ * fields (where appropriate).
+ */
+public interface Link
+{
+    /**
+     * Returns the names of any additional query parameters for the URI. Query parameters store less regular or less
+     * often used values that can not be expressed in the path. They also are used to store, or link to, persistent
+     * state.
+     *
+     * @return list of query parameter names, is alphabetical order
+     */
+    List<String> getParameterNames();
+
+    /**
+     * Returns the value of a specifically named query parameter, or <tt>null</tt> if no such query parameter is stored
+     * in the link.
+     *
+     * @return the value of the named parameter
+     */
+    String getParameterValue(String name);
+
+    /**
+     * Adds a parameter value. The value will be added, as is, to the URL. In many cases, the value should be URL
+     * encoded via {@link URLCodec}.
+     *
+     * @param parameterName the name of the parameter to store
+     * @param value         the value to store
+     * @throws IllegalArgumentException if the link already has a parameter with the given name
+     */
+    void addParameter(String parameterName, String value);
+
+    /**
+     * Returns the URI portion of the link. When the link is created for a form, this will not include query parameters.
+     * This is the same value returned from toString().  In some circumstances, this may be a relative URI (relative to
+     * the current Request's URI).
+     *
+     * @return the URI, ready to be added as an element attribute
+     */
+    String toURI();
+
+    /**
+     * Returns the link as a redirect URI. The URI includes any query parameters.
+     */
+    String toRedirectURI();
+
+    /**
+     * Returns the link anchor. If this link does not have an anchor, this method returns <tt>null</tt>.
+     *
+     * @return the link anchor
+     */
+    String getAnchor();
+
+    /**
+     * Sets the link anchor. Null and empty anchors will be ignored when building the link URI.
+     *
+     * @param anchor the link anchor
+     */
+    void setAnchor(String anchor);
+
+    /**
+     * Converts the link to an absolute URI, a complete path, starting with a leading slash. This is necessary in many
+     * cases for client-side JavaScript that must send a request to application via XMLHttpRequest.
+     *
+     * @return the complete URI (not abbreviated relative to the current request path)
+     */
+    String toAbsoluteURI();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupUtils.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupUtils.java
new file mode 100644
index 0000000..e23727e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupUtils.java
@@ -0,0 +1,105 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Utility methods related to generating markup.
+ */
+public class MarkupUtils
+{
+    static final char APOS = '\'';
+    static final char QUOTE = '"';
+    static final char SLASH = '\\';
+
+    /**
+     * Quotes the provided value as a JavaScript string literal. The input value is surrounded by single quotes and any
+     * interior backslash, single or double quotes are escaped (a preceding backslash is added).
+     *
+     * @param text
+     * @return quoted text
+     */
+    public static String quote(String text)
+    {
+        StringBuilder result = new StringBuilder(text.length() * 2);
+
+        result.append(APOS);
+
+        for (char ch : text.toCharArray())
+        {
+            switch (ch)
+            {
+                case APOS:
+                case QUOTE:
+                case SLASH:
+
+                    result.append(SLASH);
+
+                default:
+                    result.append(ch);
+                    break;
+            }
+        }
+
+        result.append(APOS);
+
+        return result.toString();
+    }
+
+    /**
+     * Joins together several strings, sorting them alphabetically and separating them with spaces. This is often used
+     * when setting the CSS class attribute of an element.
+     */
+    public static String join(String... values)
+    {
+        List<String> list = CollectionFactory.newList(values);
+
+        return sortAndJoin(list);
+    }
+
+    /**
+     * Joins together several strings, sorting them alphabetically and separating them with spaces. This is often used
+     * when setting the CSS class attribute of an element.
+     */
+    public static String join(List<String> values)
+    {
+        List<String> copy = CollectionFactory.newList(values);
+
+        return sortAndJoin(copy);
+    }
+
+    static String sortAndJoin(List<String> list)
+    {
+        Collections.sort(list);
+
+        StringBuilder builder = new StringBuilder(10 * list.size());
+
+        String sep = "";
+
+        for (String name : list)
+        {
+            builder.append(sep);
+            builder.append(name);
+
+            sep = " ";
+        }
+
+        return builder.toString();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriter.java
new file mode 100644
index 0000000..aff7458
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriter.java
@@ -0,0 +1,151 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.dom.MarkupModel;
+import org.apache.tapestry.dom.Raw;
+
+import java.io.PrintWriter;
+
+/**
+ * An interface used by objects, such as Tapestry components, that need to render themselves as some form of XML markup.
+ * A markup writer maintains the idea of a current element. Attributes are added to the current element, and new text
+ * and elements are placed inside the current element. In this way, the markup writer maintains a facade that XML markup
+ * is generated as a stream, even though the implementation builds a kind of DOM tree. The DOM tree can be also be
+ * manipulated. This solves a number of problems from Tapestry 4 (and earlier) where random access to the DOM was
+ * desired and had to be simulated through complex buffering.
+ */
+public interface MarkupWriter
+{
+    /**
+     * Begins a new element as a child of the current element. The new element becomes the current element. The new
+     * Element is returned and can be directly manipulated (possibly at a later date). Optionally, attributes for the
+     * new element can be specified directly.
+     * <p/>
+     *
+     * @param name       the name of the element to create
+     * @param attributes an even number of values, alternating names and values
+     * @return the new DOM Element node
+     * @see #attributes(Object[])
+     */
+    Element element(String name, Object... attributes);
+
+    /**
+     * Ends the current element. The new current element will be the parent element. Returns the new current element
+     * (which may be null when ending the root element for the document).
+     */
+
+    Element end();
+
+    /**
+     * Writes the text as a child of the current element.
+     */
+
+    void write(String text);
+
+    /**
+     * Writes a formatted string.
+     */
+    void writef(String format, Object... args);
+
+    /**
+     * Writes <em>raw</em> text, text with existing markup that should be passed through the client without change. This
+     * can be useful when the markup is read from an external source (a file or a database) and is simply to be
+     * included.
+     *
+     * @param text
+     * @see Raw
+     */
+    void writeRaw(String text);
+
+    /**
+     * Adds an XML comment. The text should be just the comment content, the comment delimiters will be provided.
+     */
+    void comment(String text);
+
+
+    /**
+     * Adds parsed character content. This will be enclosed in a CDATA block if supported.  When not supported, this is
+     * the same as {@link #write(String)}.
+     *
+     * @param content pre-parsed content
+     */
+    void cdata(String content);
+
+    /**
+     * Adds a series of attributes and values. Null values are quietly skipped. If a name already has a value, then the
+     * new value is <em>ignored</em>.
+     */
+    void attributes(Object... namesAndValues);
+
+    /**
+     * Converts the collected markup into an markup stream (according to rules provided by the {@link Document}'s {@link
+     * MarkupModel}). The markup stream is sent to the writer.
+     */
+    void toMarkup(PrintWriter writer);
+
+    /**
+     * Returns the Document into which this writer creates elements or other nodes.
+     */
+    Document getDocument();
+
+    /**
+     * Returns the currently active element.
+     */
+    Element getElement();
+
+    /**
+     * Defines a namespace for the currently active element. The namespace URI will be mapped to the provided namespace
+     * prefix within the Element.
+     *
+     * @param namespace       the namespace URI
+     * @param namespacePrefix the prefix for elements and attributes associated with the namespace    (may be the empty
+     *                        string for the default namespace)
+     * @return the currently active element
+     */
+    Element defineNamespace(String namespace, String namespacePrefix);
+
+    /**
+     * Starts an element within the given namespace. The correct namespace prefix will be identified and used. Must be
+     * balanced by a call to {@link #end()}.
+     *
+     * @param namespace   URI containing the element
+     * @param elementName name of the element within the namespace
+     * @return the new Element
+     */
+    Element elementNS(String namespace, String elementName);
+
+    /**
+     * Creates an attribute within the namespace for the current element.
+     *
+     * @param namespace      URI containing the element
+     * @param attributeName  name of the attribute within the namespace
+     * @param attributeValue the value for the attribute
+     * @return the currently active element
+     */
+    Element attributeNS(String namespace, String attributeName, String attributeValue);
+
+    /**
+     * Adds a markup writer listener that will be notified as elements are started and ended.
+     */
+    void addListener(MarkupWriterListener listener);
+
+    /**
+     * Removes a previously added listener.
+     */
+    void removeListener(MarkupWriterListener listener);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterAdapter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterAdapter.java
new file mode 100644
index 0000000..40343d1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterAdapter.java
@@ -0,0 +1,31 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.dom.Element;
+
+/**
+ * Default, empty implementation of {@link org.apache.tapestry.MarkupWriterListener}.
+ */
+public class MarkupWriterAdapter implements MarkupWriterListener
+{
+    public void elementDidStart(Element element)
+    {
+    }
+
+    public void elementDidEnd(Element element)
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterListener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterListener.java
new file mode 100644
index 0000000..d56108b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MarkupWriterListener.java
@@ -0,0 +1,41 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.dom.Element;
+
+
+/**
+ * An interface that allows objects to be alerted when after an element is started, and after an element is ended.
+ */
+public interface MarkupWriterListener
+{
+    /**
+     * Invoked just after an element and its initial set of attributes has been written.
+     *
+     * @param element element just created and populated with attributes
+     * @see org.apache.tapestry.MarkupWriter#element(String, Object[])
+     * @see org.apache.tapestry.MarkupWriter#elementNS(String, String)
+     */
+    void elementDidStart(Element element);
+
+    /**
+     * Invoked just after an element has ended.
+     *
+     * @param element just ended
+     * @see org.apache.tapestry.MarkupWriter#end()
+     */
+    void elementDidEnd(Element element);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MetaDataConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MetaDataConstants.java
new file mode 100644
index 0000000..83c448d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/MetaDataConstants.java
@@ -0,0 +1,25 @@
+package org.apache.tapestry;
+
+/**
+ * Meta-data keys that are applied to components and pages.
+ *
+ * @see org.apache.tapestry.services.MetaDataLocator
+ */
+public class MetaDataConstants
+{
+    /**
+     * Meta data key applied to pages that sets the response content type. A factory default provides the value
+     * "text/html" when not overridden.
+     */
+    public static final String RESPONSE_CONTENT_TYPE = "tapestry.response-content-type";
+    /**
+     * Meta data key applied to pages that may only be accessed via secure methods (HTTPS).
+     */
+    public static final String SECURE_PAGE = "tapestry.secure-page";
+    /**
+     * Meta data key applied to pages that sets the response encoding. A factory default provides the value "UTF-8" when
+     * not overriden. Content type may also be specified in the {@link #RESPONSE_CONTENT_TYPE content type} as parameter
+     * "charset", i.e., "text/html;charset=UTF-8".
+     */
+    public static final String RESPONSE_ENCODING = "tapestry.response-encoding";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/NullFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/NullFieldStrategy.java
new file mode 100644
index 0000000..001c745
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/NullFieldStrategy.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Defines a strategy, used by {@link Field} components such as {@link org.apache.tapestry.corelib.components.TextField},
+ * to handle the case where either the server-side value to be sent (as a string) to the client, or the client-side
+ * string passed back up to the server, is null or blank.
+ *
+ * @see org.apache.tapestry.services.NullFieldStrategySource
+ */
+public interface NullFieldStrategy
+{
+    /**
+     * Provides a replacement value for null, when converting the server-side object to a client-side string. The
+     * replacement value, if non-null, will be passed to {@link org.apache.tapestry.Translator#toClient(Object)}.
+     */
+    Object replaceToClient();
+
+    /**
+     * Provides a replacement value for a null or blank string passed from the client to the server as part of a form
+     * submission. This replacement value will be passed to {@link org.apache.tapestry.Translator#parseClient(String,
+     * org.apache.tapestry.ioc.Messages)}  as if it were the value supplied by the user.
+     *
+     * @return replacement value (this must not be null)
+     */
+    String replaceFromClient();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionGroupModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionGroupModel.java
new file mode 100644
index 0000000..745156f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionGroupModel.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Defines a group of related options. Options may be enabled or disabled as a group. Corresponds to the [X]HTML element
+ * &lt;optgroup&gt;.
+ */
+public interface OptionGroupModel
+{
+    /**
+     * Localized, user-presentable label for the group.
+     */
+    String getLabel();
+
+    /**
+     * If true, the group (and all options within it) will be disabled. Note that some browsers do not honor the
+     * disabled attribute property.
+     *
+     * @return true if a disabled attribute should be rendered.
+     */
+    boolean isDisabled();
+
+    /**
+     * Additional attributes to render with the &lt;optgroup&gt;. This is often used to render the CSS class attribute.
+     * May return null.
+     */
+    Map<String, String> getAttributes();
+
+    /**
+     * The list of options within the group.
+     */
+    List<OptionModel> getOptions();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionModel.java
new file mode 100644
index 0000000..a88c036
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/OptionModel.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import java.util.Map;
+
+/**
+ * A single option within a {@link OptionGroupModel}. Corresponds closely to the [X]HTML &lt;option&gt; element.
+ */
+public interface OptionModel
+{
+    /**
+     * The localized, user-presentable label for the option.
+     */
+    String getLabel();
+
+    /**
+     * If true, then a disabled attribute will be rendered with the &lt;option&gt;.
+     */
+    boolean isDisabled();
+
+    /**
+     * Additional attributes to render within the &lt;option&gt;. May return null.
+     */
+    Map<String, String> getAttributes();
+
+    /**
+     * The server-side value represented by this option. This is used to determine which option will be selected. It is
+     * also used, via {@link ValueEncoder#toClient(Object)}, to generate the client-side value attribute.
+     */
+    Object getValue();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PersistenceConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PersistenceConstants.java
new file mode 100644
index 0000000..eedf884
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PersistenceConstants.java
@@ -0,0 +1,14 @@
+package org.apache.tapestry;
+
+/**
+ * Constants for persistent field strategies.
+ *
+ * @see org.apache.tapestry.annotation.Persist#value()
+ */
+public class PersistenceConstants
+{
+    /**
+     * The page field persistence strategy that stores data in the session until the next request.
+     */
+    public static final String FLASH = "flash";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java
new file mode 100644
index 0000000..6b82977
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java
@@ -0,0 +1,57 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.corelib.components.Loop;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Used by {@link Loop} and similar components to extract out an identifier, here termed a "primary key", that can be
+ * stored on the client and later used to recover the same, or equivalent, server side object.
+ *
+ * @param <K> the type of the primary key, used to identify the value (which must be serializable)
+ * @param <V> the type of value identified by the key
+ * @see ValueEncoder
+ */
+public interface PrimaryKeyEncoder<K extends Serializable, V>
+{
+    /**
+     * Given a particular value, this method extracts and returns the primary key that identifies the value. The key
+     * will later be converted back into a value using {@link #toValue(Serializable)}.
+     *
+     * @param value whose primary key is needed
+     * @return the key for the value
+     */
+    K toKey(V value);
+
+    /**
+     * Invoked as part of a form submission to alert the encoder that a series of keys may be converted back to values.
+     * This is advisory only, and the keys passed to {@link #toValue(Serializable)} may not include all keys in the
+     * list, or may include keys not in the list. In general, though, the keys passed in will match the actual keys to
+     * be converted, giving the encoder a chance to efficiently fetch the necessary value objects as a group.
+     */
+    void prepareForKeys(List<K> keys);
+
+    /**
+     * For a particular primary key, previously obtained via {@link #toKey(Object)}, this method returns the same or
+     * equivalent object.
+     *
+     * @param key used to identify the object
+     * @return the value object for the key
+     */
+    V toValue(K key);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PropertyConduit.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PropertyConduit.java
new file mode 100644
index 0000000..029d34f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/PropertyConduit.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+/**
+ * Used to read or update the value associated with a property. A PropertyConduit provides access to the annotations on
+ * the underlying getter and/or setter methods.
+ */
+public interface PropertyConduit extends AnnotationProvider
+{
+    /**
+     * Reads the property from the instance.
+     *
+     * @param instance object containing the property
+     * @return the current value of the property
+     */
+    Object get(Object instance);
+
+    /**
+     * Changes the current value of the property.
+     *
+     * @param instance object containing the property
+     * @param value    to change the property to
+     */
+    void set(Object instance, Object value);
+
+    /**
+     * Returns the type of the property read or updated by the conduit.
+     */
+    Class getPropertyType();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RadioContainer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RadioContainer.java
new file mode 100644
index 0000000..774f504
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RadioContainer.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.corelib.components.Radio;
+
+/**
+ * A container of {@link Radio} components, used to identify the element name used when rendering the individual radio
+ * buttons (all buttons in a group share the same element name) and to
+ */
+public interface RadioContainer
+{
+    /**
+     * Returns the value used as the name attribute of the rendered element. This value will be unique within an
+     * enclosing form, even if the same component renders multiple times.
+     */
+    String getElementName();
+
+    /**
+     * If true, then all buttons within the container should also be disabled.
+     */
+    boolean isDisabled();
+
+    /**
+     * Converts an object to a client-side string representation of that value.
+     *
+     * @param value to convert (may be null)
+     * @return string representation of the value
+     * @see ValueEncoder#toClient(Object)
+     */
+    String toClient(Object value);
+
+    /**
+     * Returns true if the value is the current selected value.
+     */
+    boolean isSelected(Object value);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RenderSupport.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RenderSupport.java
new file mode 100644
index 0000000..d11afbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/RenderSupport.java
@@ -0,0 +1,112 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+
+/**
+ * Provides support to all components that render. This is primarily about generating unique client-side ids (very
+ * important for JavaScript generation) as well as accumulating JavaScript to be sent to the client. PageRenderSupport
+ * also allows for the incremental addition of stylesheets.
+ */
+public interface RenderSupport
+{
+    /**
+     * Allocates a unique id based on the component's id. In some cases, the return value will not precisely match the
+     * input value (an underscore and a unique index value may be appended).
+     *
+     * @param id the component id from which a unique id will be generated
+     * @return a unique id for this rendering of the page
+     * @see org.apache.tapestry.ioc.internal.util.IdAllocator
+     */
+    String allocateClientId(String id);
+
+    /**
+     * As with {@link #allocateClientId(String)} but uses the id of the component extracted from the resources.
+     *
+     * @param resources of the component which requires an id
+     * @return a unique id for this rendering of the page
+     */
+    String allocateClientId(ComponentResources resources);
+
+    /**
+     * Adds one or more new script assets to the page. Assets are added uniquely, and appear as &lt;script&gt; elements
+     * just inside the &lt;body&gt; element of the rendered page. Duplicate requests to add the same script are quietly
+     * ignored.
+     *
+     * @param scriptAssets asset to the script to add
+     */
+    void addScriptLink(Asset... scriptAssets);
+
+    /**
+     * Used to add scripts that are stored on the classpath. Each element has {@linkplain SymbolSource symbols
+     * expanded}, then is {@linkplain AssetSource converted to an asset} and added as a script link.
+     *
+     * @param classpaths array of paths. Symbols in the paths are expanded, then the paths are each converted into an
+     *                   asset.
+     */
+    void addClasspathScriptLink(String... classpaths);
+
+    /**
+     * Adds a link to a CSS stylesheet. As with JavaScript libraries, each stylesheet is added at most once. Stylesheets
+     * added this way will be ordered before any other content in the &lt;head&gt; element of the document. The
+     * &lt;head&gt; element will be created, if necessary.
+     *
+     * @param stylesheet the asset referencing the stylesheet
+     * @param media      the media value for the stylesheet, or null to not specify a specific media type
+     */
+
+    void addStylesheetLink(Asset stylesheet, String media);
+
+    /**
+     * Adds a script statement to the page's script block (which appears at the end of the page, just before the
+     * &lt/body&gt; tag).
+     *
+     * @param format    base string format, to be passed through String.format
+     * @param arguments additional arguments formatted to form the final script
+     */
+    void addScript(String format, Object... arguments);
+
+    /**
+     * Add an initialization call.
+     *
+     * @param functionName  the name of the function (on the client-side Tapestry.Initializer object) to invoke.
+     * @param parameterList list of parameters for the method invocation.
+     * @see #addScript(String, Object[])
+     */
+    void addInit(String functionName, JSONArray parameterList);
+
+    /**
+     * Alternate version of {@link #addInit(String, org.apache.tapestry5.json.JSONArray)} where just a single object is
+     * passed.
+     *
+     * @param functionName the name of the function (on the client-side Tapestry object) to invoke.
+     * @param parameter    the object to pass to the function
+     */
+    void addInit(String functionName, JSONObject parameter);
+
+    /**
+     * Alternate version of {@link #addInit(String, org.apache.tapestry5.json.JSONArray)} where one or more strings are
+     * passed.  A single string is added to the initialization call as itself; otherwise, the parameters are combined to
+     * form a {@link JSONArray}.
+     *
+     * @param functionName the name of the function (on the client-side Tapestry object) to invoke.
+     * @param parameters
+     */
+    void addInit(String functionName, String... parameters);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Renderable.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Renderable.java
new file mode 100644
index 0000000..742a203
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Renderable.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry;

+

+/**

+ * Base interface for objects that can render markup output using a {@link org.apache.tapestry.MarkupWriter}.

+ */

+public interface Renderable

+{

+    void render(MarkupWriter writer);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModel.java
new file mode 100644
index 0000000..8579422
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModel.java
@@ -0,0 +1,49 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import java.util.List;
+
+/**
+ * Defines the possible options and option groups for a &lt;select&gt; [X]HTML element.
+ * <p/>
+ * Primarily used by the {@link org.apache.tapestry.corelib.components.Select} component, but potentially used by
+ * anything similar, that needs to present a list of options to the user. Generally paired with a {@link
+ * org.apache.tapestry.ValueEncoder} to create client-side representations of server-side values.
+ *
+ * @see org.apache.tapestry.corelib.components.Palette
+ */
+public interface SelectModel
+{
+    /**
+     * The list of groups, each containing some number of individual options.
+     *
+     * @return the groups, or null
+     */
+    List<OptionGroupModel> getOptionGroups();
+
+    /**
+     * The list of ungrouped options, which appear after any grouped options. Generally, a model will either provide
+     * option groups or ungrouped options, but not both.
+     *
+     * @return the ungrouped options, or null
+     */
+    List<OptionModel> getOptions();
+
+    /**
+     * Allows access to all the {@link OptionGroupModel}s and {@link OptionModel}s within the SelectModel.
+     */
+    void visit(SelectModelVisitor visitor);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModelVisitor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModelVisitor.java
new file mode 100644
index 0000000..f2182e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SelectModelVisitor.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Callback interface that allows for visiting the option groups and option models of a select model in correct render
+ * order.
+ */
+public interface SelectModelVisitor
+{
+    /**
+     * Invoked once for each {@link OptionGroupModel}, just before invoking {@link #option(OptionModel)} for each
+     * embedded option within the group.
+     */
+    void beginOptionGroup(OptionGroupModel groupModel);
+
+    /**
+     * Invoked for each option within a group, and at the end, for each ungrouped option.
+     *
+     * @param optionModel
+     */
+    void option(OptionModel optionModel);
+
+    /**
+     * Invoked after all options within the group have been visited.
+     */
+    void endOptionGroup(OptionGroupModel groupModel);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/StreamResponse.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/StreamResponse.java
new file mode 100644
index 0000000..6f1ccaa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/StreamResponse.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.services.Response;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An alternate response from a component event handler method used to directly provide a stream of data to be sent to
+ * the client, rather than indicating what page to send a render redirect request to.
+ */
+public interface StreamResponse
+{
+    /**
+     * Returns the content type to be reported to the client.
+     */
+    String getContentType();
+
+    /**
+     * Returns the stream of bytes to be sent to the client. The stream will be closed when the end of the stream is
+     * reached. The provided stream will be wrapped in a {@link BufferedInputStream} for efficiency.
+     */
+    InputStream getStream() throws IOException;
+
+
+    /**
+     * Prepare response before it is sent to the client. This is the place to set any response headers (e.g.
+     * content-disposition)
+     *
+     * @param response Response that will be sent.
+     */
+    void prepareResponse(Response response);
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SymbolConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SymbolConstants.java
new file mode 100644
index 0000000..82dd139
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/SymbolConstants.java
@@ -0,0 +1,48 @@
+package org.apache.tapestry;
+
+/**
+ * Defines the names of symbols used to configure Tapestry.
+ *
+ * @see org.apache.tapestry.ioc.services.SymbolSource
+ */
+public class SymbolConstants
+{
+    /**
+     * Indicates whether Tapestry is running in production mode or developer mode.  The primary difference is how
+     * exceptions are reported.
+     */
+    public static final String PRODUCTION_MODE = "tapestry.production-mode";
+    /**
+     * Symbol which may be set to "true" to force the use of absolute URIs (not relative URIs) exclusively.
+     */
+    public static final String FORCE_ABSOLUTE_URIS = "tapestry.force-absolute-uris";
+    /**
+     * If set to true, then action requests will render a page markup response immediately, rather than sending a
+     * redirect to render the response.
+     */
+    public static final String SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS = "tapestry.suppress-redirect-from-action-requests";
+    /**
+     * The list of locales supported by the application; locales identified in the incoming request are "narrowed" to
+     * one of these values.
+     */
+    public static final String SUPPORTED_LOCALES = "tapestry.supported-locales";
+    /**
+     * Controls whether whitespace is compressed by default in templates, or left as is. The factory default is to
+     * compress whitespace. This can be overridden using the xml:space attribute inside template elements.
+     */
+    public static final String COMPRESS_WHITESPACE = "tapestry.compress-whitespace";
+    /**
+     * Time interval defining how often Tapestry will check for updates to local files (including classes). This number
+     * can be raised in a production environment.
+     */
+    public static final String FILE_CHECK_INTERVAL = "tapestry.file-check-interval";
+    /**
+     * Time interval that sets how long Tapestry will wait to obtain the exclusive lock needed to check local files.
+     */
+    public static final String FILE_CHECK_UPDATE_TIMEOUT = "tapestry.file-check-update-timeout";
+    /**
+     * The version number of the core Tapestry framework, or UNKNOWN if the version number is not available (which
+     * should only occur when developing Tapestry).
+     */
+    public static final String TAPESTRY_VERSION = "tapestry.version";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/TapestryFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/TapestryFilter.java
new file mode 100644
index 0000000..c6cfdee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/TapestryFilter.java
@@ -0,0 +1,203 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.internal.ServletContextSymbolProvider;
+import org.apache.tapestry.internal.TapestryAppInitializer;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.services.HttpServletRequestHandler;
+import org.apache.tapestry.services.ServletApplicationInitializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Formatter;
+import java.util.List;
+
+/**
+ * The TapestryFilter is responsible for intercepting all requests into the web application. It identifies the requests
+ * that are relevant to Tapestry, and lets the servlet container handle the rest. It is also responsible for
+ * initializing Tapestry.
+ * <p/>
+ * <p/>
+ * The application is configured via context-level init parameters.
+ * <p/>
+ * <dl> <dt>  tapestry.app-package</dt> <dd> The application package (used to search for pages, components, etc.)</dd>
+ * </dl>
+ */
+public class TapestryFilter implements Filter
+{
+    private final Logger logger = LoggerFactory.getLogger(TapestryFilter.class);
+
+    private FilterConfig config;
+
+    private Registry registry;
+
+    private HttpServletRequestHandler handler;
+
+    /**
+     * Initializes the filter using the {@link TapestryAppInitializer}. The application name is the capitalization of
+     * the filter name (as specified in web.xml).
+     */
+    public final void init(FilterConfig filterConfig) throws ServletException
+    {
+        config = filterConfig;
+
+        ServletContext context = config.getServletContext();
+
+        String filterName = config.getFilterName();
+
+        SymbolProvider provider = new ServletContextSymbolProvider(context);
+
+        TapestryAppInitializer appInitializer = new TapestryAppInitializer(provider, filterName, "servlet");
+
+        appInitializer.addModules(provideExtraModuleDefs(context));
+
+        registry = appInitializer.getRegistry();
+
+        long start = appInitializer.getStartTime();
+
+        long toRegistry = appInitializer.getRegistryCreatedTime();
+
+        ServletApplicationInitializer ai = registry.getService("ServletApplicationInitializer",
+                                                               ServletApplicationInitializer.class);
+
+        ai.initializeApplication(filterConfig.getServletContext());
+
+        registry.performRegistryStartup();
+
+        handler = registry.getService("HttpServletRequestHandler", HttpServletRequestHandler.class);
+
+        init(registry);
+
+        long toFinish = System.currentTimeMillis();
+
+        StringBuilder buffer = new StringBuilder("Startup status:\n\n");
+        Formatter f = new Formatter(buffer);
+
+        f.format("Startup time: %,d ms to build IoC Registry, %,d ms overall." + "\n\nStartup services status:\n",
+                 toRegistry - start, toFinish - start);
+
+        int unrealized = 0;
+
+        ServiceActivityScoreboard scoreboard = registry
+                .getService(ServiceActivityScoreboard.class);
+
+        List<ServiceActivity> serviceActivity = scoreboard.getServiceActivity();
+
+        int longest = 0;
+
+        // One pass to find the longest name, and to count the unrealized services.
+
+        for (ServiceActivity activity : serviceActivity)
+        {
+            Status status = activity.getStatus();
+
+            longest = Math.max(longest, activity.getServiceId().length());
+
+            if (status == Status.DEFINED || status == Status.VIRTUAL) unrealized++;
+
+        }
+
+        String formatString = "%" + longest + "s: %s\n";
+
+        // A second pass to output all the services
+
+        for (ServiceActivity activity : serviceActivity)
+        {
+            f.format(formatString, activity.getServiceId(), activity.getStatus().name());
+        }
+
+        f.format("\n%4.2f%% unrealized services (%d/%d)\n", 100. * unrealized / serviceActivity.size(), unrealized,
+                 serviceActivity.size());
+
+        logger.info(buffer.toString());
+    }
+
+    protected final FilterConfig getFilterConfig()
+    {
+        return config;
+    }
+
+    /**
+     * Invoked from {@link #init(FilterConfig)} after the Registry has been created, to allow any additional
+     * initialization to occur. This implementation does nothing, and my be overriden in subclasses.
+     *
+     * @param registry from which services may be extracted
+     * @throws ServletException
+     */
+    protected void init(Registry registry) throws ServletException
+    {
+
+    }
+
+    /**
+     * Overridden in subclasses to provide additional module definitions beyond those normally located. This
+     * implementation returns an empty array.
+     */
+    protected ModuleDef[] provideExtraModuleDefs(ServletContext context)
+    {
+        return new ModuleDef[0];
+    }
+
+    public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException
+    {
+        try
+        {
+            boolean handled = handler.service((HttpServletRequest) request, (HttpServletResponse) response);
+
+            if (!handled) chain.doFilter(request, response);
+        }
+        finally
+        {
+            registry.cleanupThread();
+        }
+    }
+
+    /**
+     * Shuts down and discards the registry.
+     */
+    public final void destroy()
+    {
+        destroy(registry);
+
+        registry.shutdown();
+
+        registry = null;
+        config = null;
+        handler = null;
+    }
+
+    /**
+     * Invoked from {@link #destroy()} to allow subclasses to add additional shutdown logic to the filter. The Registry
+     * will be shutdown after this call. This implementation does nothing, and may be overridden in subclasses.
+     *
+     * @param registry
+     */
+    protected void destroy(Registry registry)
+    {
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Translator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Translator.java
new file mode 100644
index 0000000..c106e3c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Translator.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.ValidationMessagesSource;
+
+/**
+ * Translates between client-side and server-side values. Client-side values are always strings.
+ *
+ * @param <T>
+ * @see org.apache.tapestry.services.TranslatorDefaultSource
+ * @see FieldValidationSupport
+ */
+public interface Translator<T>
+{
+    /**
+     * Converts a server-side value to a client-side string. This allows for formatting of the value in a way
+     * appropriate to the end user. The output client value should be parsable by {@link #parseClient(String,
+     * Messages)}.
+     *
+     * @param value the server side value (which will not be null)
+     * @return client-side value to present to the user
+     */
+    String toClient(T value);
+
+    /**
+     * Returns the type of  the server-side value.
+     *
+     * @return a type
+     */
+    Class<T> getType();
+
+    /**
+     * Converts a submitted request value into an appropriate server side value.
+     *
+     * @param clientValue to convert to a server value; this will not be null, but may be blank
+     * @param messages    validator messages assembled by {@link ValidationMessagesSource}
+     * @return equivalent server-side value (possibly null)
+     * @throws ValidationException if the value can not be parsed
+     */
+    T parseClient(String clientValue, Messages messages) throws ValidationException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationDecorator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationDecorator.java
new file mode 100644
index 0000000..bbaba40
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationDecorator.java
@@ -0,0 +1,75 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.dom.Element;
+
+/**
+ * An object responsible for performing decorations around fields and field labels. The decorator is notified at
+ * intervals by the fields and labels.
+ * <p/>
+ * In most western languages (written left to right) the label will render before the field, so the properties of the
+ * Field may not be set yet (or may reflect a previous looping's rendering). It may be necessary to {@linkplain
+ * org.apache.tapestry.services.Heartbeat#defer(Runnable)} defer any rendering} until after the Label and the Field have
+ * both had their change to initialize and render.
+ */
+public interface ValidationDecorator
+{
+    /**
+     * Invoked by a {@link org.apache.tapestry.corelib.components.Label} before rendering itself.
+     *
+     * @param field for this label
+     */
+    void beforeLabel(Field field);
+
+    /**
+     * Invoked after the label has rendered its tag, but before it has rendered content inside the tag, to allow the
+     * decorator to write additional attributes.
+     *
+     * @param field        the field corresponding to the label
+     * @param labelElement the element for this label
+     */
+    void insideLabel(Field field, Element labelElement);
+
+
+    /**
+     * Invoked by {@link org.apache.tapestry.corelib.components.Label} after rendering itself.
+     *
+     * @param field
+     */
+    void afterLabel(Field field);
+
+    /**
+     * Renders immediately before the field itself. The field will typically render a single element, though a complex
+     * field may render multiple elements or even some JavaScript.
+     *
+     * @param field
+     */
+    void beforeField(Field field);
+
+    /**
+     * Invoked at a point where the decorator may write additional attributes into the field. Generally speaking, you
+     * will want to {@linkplain ComponentResources#renderInformalParameters(MarkupWriter) render informal parameters}
+     * <strong>before</strong> invoking this method.
+     *
+     * @param field
+     */
+    void insideField(Field field);
+
+    /**
+     * Invoked after the field has completed rendering itself.
+     */
+    void afterField(Field field);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationException.java
new file mode 100644
index 0000000..72784c4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationException.java
@@ -0,0 +1,28 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * An exception associated with parsing client input, or validating the input against a constraint.
+ */
+public class ValidationException extends Exception
+{
+    private static final long serialVersionUID = -6195763584437441540L;
+
+    public ValidationException(String message)
+    {
+        super(message);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java
new file mode 100644
index 0000000..d125162
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java
@@ -0,0 +1,98 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.corelib.components.Loop;
+
+import java.util.List;
+
+/**
+ * Tracks information related to user input validations. This information is: <ul> <li>The input values provided by the
+ * user. <li>Any validation exceptions associated with input fields. </ul>
+ * <p/>
+ * The tracker must differentiate between components (which will implement the {@link Field} interfaces) and fields. It
+ * is a one to many relationship, because each field may be called upon to render itself multiple times within a
+ * request, because of {@link Loop} or other similar components.
+ * <p/>
+ * Internally, the tracker indexes its information in terms of the {@linkplain Field#getControlName() control name} for
+ * each rendering of the component (the mechanics of Tapestry ensures that this is unique within the form).
+ * <p/>
+ * Validation trackers must be serializable, as they will almost always be stored into the HttpSession.
+ * <p/>
+ * Trackers are used by only a single form within a single page; they are not threadsafe.
+ */
+public interface ValidationTracker
+{
+    /**
+     * Called by a field to record the exact input from the user, prior to any validation. If the form is redisplayed
+     * (to present errors), the input value will be sent back to the user for correction.
+     *
+     * @param field the field recording the input
+     * @param input the value obtained from the forms submission
+     */
+    void recordInput(Field field, String input);
+
+    /**
+     * Returns a previously recorded input value.
+     */
+    String getInput(Field field);
+
+    /**
+     * Records an error message for a field. The error message is primarily derived from a {@link ValidationException}
+     * thrown by a {@link Validator} or {@link Translator}.
+     *
+     * @param field
+     * @param errorMessage
+     */
+    void recordError(Field field, String errorMessage);
+
+    /**
+     * Records an error message that is not associated with any specific field. This often reflects some amount of
+     * cross-form validation.
+     *
+     * @param errorMessage
+     */
+    void recordError(String errorMessage);
+
+    /**
+     * For a given field, determines if the field is "in error", meaning that an error message has been previously
+     * recorded for the field.
+     *
+     * @param field
+     * @return true if an error message is present
+     */
+    boolean inError(Field field);
+
+    /**
+     * Returns a previously recorded error message.
+     */
+    String getError(Field field);
+
+    /**
+     * Returns true if any field contains an error.
+     */
+    boolean getHasErrors();
+
+    /**
+     * Returns a list of all error messages. The messages are stored in the order that they were added to the tracker,
+     * except that unassociated errors (unassociated with any field) are listed first.
+     */
+    List<String> getErrors();
+
+    /**
+     * Clears all information stored by the tracker.
+     */
+    void clear();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java
new file mode 100644
index 0000000..692d5be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java
@@ -0,0 +1,174 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Standard implmentation of {@link ValidationTracker}. Works pretty hard to ensure a minimum amount of data is stored
+ * in the HttpSession.
+ */
+public final class ValidationTrackerImpl implements ValidationTracker, Serializable
+{
+    private static final long serialVersionUID = -8029192726659275677L;
+
+    private static class FieldTracker implements Serializable
+    {
+        private static final long serialVersionUID = -3653306147088451811L;
+
+        private final String fieldName;
+
+        private String input;
+
+        private String errorMessage;
+
+        FieldTracker(String fieldName)
+        {
+            this.fieldName = fieldName;
+        }
+    }
+
+    private List<String> extraErrors;
+
+    private List<FieldTracker> fieldTrackers;
+
+    // Rebuilt on-demand
+
+    private transient Map<String, FieldTracker> fieldToTracker;
+
+    private void refreshFieldToTracker()
+    {
+        if (fieldToTracker != null)
+            return;
+
+        if (fieldTrackers == null)
+            return;
+
+        fieldToTracker = CollectionFactory.newMap();
+
+        for (FieldTracker ft : fieldTrackers)
+            fieldToTracker.put(ft.fieldName, ft);
+    }
+
+    private FieldTracker get(Field field)
+    {
+        String key = field.getControlName();
+
+        refreshFieldToTracker();
+
+        FieldTracker result = InternalUtils.get(fieldToTracker, key);
+
+        if (result == null)
+            result = new FieldTracker(key);
+
+        return result;
+    }
+
+    private void store(FieldTracker fieldTracker)
+    {
+        if (fieldTrackers == null)
+            fieldTrackers = CollectionFactory.newList();
+
+        refreshFieldToTracker();
+
+        String key = fieldTracker.fieldName;
+
+        if (!fieldToTracker.containsKey(key))
+        {
+            fieldTrackers.add(fieldTracker);
+            fieldToTracker.put(key, fieldTracker);
+        }
+    }
+
+    public void clear()
+    {
+        extraErrors = null;
+        fieldTrackers = null;
+        fieldToTracker = null;
+    }
+
+    public String getError(Field field)
+    {
+        return get(field).errorMessage;
+    }
+
+    public List<String> getErrors()
+    {
+        List<String> result = CollectionFactory.newList();
+
+        if (extraErrors != null)
+            result.addAll(extraErrors);
+
+        if (fieldTrackers != null)
+        {
+            for (FieldTracker ft : fieldTrackers)
+            {
+                String errorMessage = ft.errorMessage;
+
+                if (errorMessage != null)
+                    result.add(errorMessage);
+            }
+        }
+
+        return result;
+    }
+
+    public boolean getHasErrors()
+    {
+        return !getErrors().isEmpty();
+    }
+
+    public String getInput(Field field)
+    {
+        return get(field).input;
+    }
+
+    public boolean inError(Field field)
+    {
+        return InternalUtils.isNonBlank(get(field).errorMessage);
+    }
+
+    public void recordError(Field field, String errorMessage)
+    {
+        FieldTracker ft = get(field);
+
+        ft.errorMessage = errorMessage;
+
+        store(ft);
+    }
+
+    public void recordError(String errorMessage)
+    {
+        if (extraErrors == null)
+            extraErrors = CollectionFactory.newList();
+
+        extraErrors.add(errorMessage);
+    }
+
+    public void recordInput(Field field, String input)
+    {
+        FieldTracker ft = get(field);
+
+        ft.input = input;
+
+        store(ft);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Validator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Validator.java
new file mode 100644
index 0000000..1a62cc3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/Validator.java
@@ -0,0 +1,87 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.ValidationMessagesSource;
+
+/**
+ * Used by a {@link Field} to enforce a <strong>constraint</strong> related to a form submission. Validators themselves
+ * are stateless singletons.
+ * <p/>
+ * Validators are usually encapsulated inside a {@link FieldValidator}.
+ *
+ * @see FieldValidationSupport
+ * @see org.apache.tapestry.services.FieldValidatorDefaultSource
+ */
+public interface Validator<C, T>
+{
+    /**
+     * Returns the type of constraint value used with this validator. Constraint values are used to parameterize a
+     * validator, for example a "maxLength" validator will have a constraint value of type int (the maximum length
+     * allowed). For constraints that do not have a constraint value, this method returns null.
+     */
+    Class<C> getConstraintType();
+
+    /**
+     * Returns the value type associated with this validator. {@link #validate(Field, Object, MessageFormatter, Object)}
+     * will only be invoked when the value is assignable to the validator's value type.
+     */
+    Class<T> getValueType();
+
+    /**
+     * Returns the message key, within the validiation messages, normally used by this validator. This is used to
+     * provide the {@link MessageFormatter} passed to {@link #validate(Field, Object, MessageFormatter, Object)} (unless
+     * overridden).
+     *
+     * @return a message key
+     * @see ValidationMessagesSource
+     */
+    String getMessageKey();
+
+    /**
+     * Invoked after the client-submitted value has been {@link org.apache.tapestry.Translator translated} to check that
+     * the value conforms to expectations (often, in terms of minimum or maximum value). If and only if the value is
+     * approved by all Validators is the value applied by the field.
+     *
+     * @param field           the field for which a client submitted value is being validated
+     * @param constraintValue the value used to constrain
+     * @param formatter       Validation messages, in the appropriate locale
+     * @param value           the translated value supplied by the user
+     * @throws ValidationException if the value violates the constraint
+     */
+    void validate(Field field, C constraintValue, MessageFormatter formatter, T value) throws ValidationException;
+
+    /**
+     * Returns true if the validator should be invoked for null or blank (empty string) values. This is generally false,
+     * but is true for validators that enforce that a non-blank value is required.  This is the basis of the {@link
+     * org.apache.tapestry.Field#isRequired()} property.
+     */
+    boolean isRequired();
+
+    /**
+     * Hook used by components to allow the validator to contribute additional attribute or (more often) client-side
+     * JavaScript (via the {@link RenderSupport}).
+     *
+     * @param field           the field which is currently being rendered
+     * @param constraintValue the value used to constrain input
+     * @param formatter       validation message, in the appropriate locale
+     * @param writer          markup writer, allowing additional attributes to be written into the active element
+     * @param formSupport
+     */
+    void render(Field field, C constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                FormSupport formSupport);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java
new file mode 100644
index 0000000..0b9867b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java
@@ -0,0 +1,48 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Used to convert server side values to client-side strings.  This is used when generating a {@link
+ * org.apache.tapestry.EventContext} as part of a URL, or when components (such as {@link
+ * org.apache.tapestry.corelib.components.Select}) generated other client-side strings.
+ * <p/>
+ * Often a custom implementation is needed for entity type objects, where the {@link #toClient(Object)} method extracts
+ * a primary key, and the {@link #toValue(String)} re-acquires the corresponding entity object.
+ *
+ * @see SelectModel
+ * @see org.apache.tapestry.services.ValueEncoderSource
+ * @see PrimaryKeyEncoder
+ */
+public interface ValueEncoder<V>
+{
+    /**
+     * Converts a value into a client-side representation. The value should be parseable by {@link #toValue(String)}. In
+     * some cases, what is returned is an identifier used to locate the true object, rather than a string representation
+     * of the value itself.
+     *
+     * @param value to be encoded
+     * @return a string representation of the value, or the value's identity
+     */
+    String toClient(V value);
+
+    /**
+     * Converts a client-side representation, provided by {@link #toClient(Object)}, back into a server-side value.
+     *
+     * @param clientValue string representation of the value's identity
+     * @return the corresponding entity, or null if not found
+     */
+    V toValue(String clientValue);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/VersionUtils.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/VersionUtils.java
new file mode 100644
index 0000000..095abb0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/VersionUtils.java
@@ -0,0 +1,73 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Utility methods related to managing framework version numbers.
+ */
+public class VersionUtils
+{
+
+    /**
+     * Reads a version number from a properties file on the classpath.  These files are generally created by Maven.  For
+     * example, tapestry-core's properties file is <code>META-INF/maven/org.apache.tapestry/tapestry-core/pom.properties</code>.
+     * The Maven generated properties files include the artifact id and group id as well as the version.
+     * <p/>
+     * The resource is located using the Thread's context class loader.
+     *
+     * @param resourcePath the complete path to the resource, including a leading slash.
+     * @return the version number read from the properties file, or "UNKNOWN" if the version number is not present or
+     *         the file can not be opened
+     */
+    public static String readVersionNumber(String resourcePath)
+    {
+        String result = "UNKNOWN";
+
+        InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(
+                resourcePath);
+
+
+        if (stream != null)
+        {
+            Properties properties = new Properties();
+
+
+            try
+            {
+                stream = new BufferedInputStream(stream);
+
+                properties.load(stream);
+            }
+            catch (IOException ex)
+            {
+                // Just ignore it.
+            }
+
+            String version = properties.getProperty("version");
+
+            // Since the file, if it exists, is created by Maven and will have the key, I can't see
+            // how version would EVER be null, unless there's a problem reading the properties.
+
+            if (version != null) result = version;
+        }
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRender.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRender.java
new file mode 100644
index 0000000..428736e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRender.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for methods associated with the AfterRender phase. This corresponds closely to {@link
+ * org.apache.tapestry.annotation.BeginRender}, but occurs after the template and body of the component have been
+ * rendered. Often, this is used to render a close tag. Return void or true (the default) to advance to the {@link
+ * org.apache.tapestry.annotation.CleanupRender} phase. Return false to return to the {@link
+ * org.apache.tapestry.annotation.BeginRender} phase.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface AfterRender
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderBody.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderBody.java
new file mode 100644
index 0000000..5bea3b7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderBody.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Corresponds to {@link BeforeRenderBody}, allowing additional markup after rendering the body of a component, but

+ * before rendering the rest of the component's template. Return true (the default) to progress to the {@link

+ * AfterRenderTemplate} or {@link AfterRender} phase (depending on whether the component does or does not have a

+ * template). Return false to return to the {@link BeforeRenderBody} phase.

+ */

+@Target(ElementType.METHOD)

+@Retention(RUNTIME)

+@Documented

+public @interface AfterRenderBody

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderTemplate.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderTemplate.java
new file mode 100644
index 0000000..5897972
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/AfterRenderTemplate.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Corresponds to {@link BeforeRenderTemplate}, allowing additional markup after rendering the component's template.
+ * Returning true (the default), will progress to the {@link AfterRender} phase. Return false to return to the {@link
+ * BeforeRenderTemplate} phase.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface AfterRenderTemplate
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ApplicationState.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ApplicationState.java
new file mode 100644
index 0000000..a0fb219
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ApplicationState.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.services.ApplicationStateManager;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for a field that is an <em>application state object</em> as controlled by the {@link
+ * ApplicationStateManager}.
+ * <p/>
+ * An ASO file may have a companion field, of type boolean, used to see if the ASO has been created yet. If another
+ * field exists with the same name, suffixed with "Exists" (i.e., "_aso" for the ASO field, and "_asoExists" for the
+ * companion field) and the type of that field is boolean, then access to the field will determine whether the ASO has
+ * already been created. This is necessary because even a null check ("_aso != null") will force the ASO to be created.
+ * Instead, check the companion boolean field ("_asoExists").
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface ApplicationState
+{
+    /**
+     * If true (the default), then referencing an field marked with the annotation will create the ASO.  If false, then
+     * accessing the field will not create the ASO, it will only allow access to it if it already exists.
+     */
+    boolean create() default true;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderBody.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderBody.java
new file mode 100644
index 0000000..1b8a613
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderBody.java
@@ -0,0 +1,41 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Marks methods to be invoked when the component rendering state machine hits the point in the component's template

+ * where the body element occurs. Such methods may optionally take a {@link org.apache.tapestry.MarkupWriter} parameter,

+ * and may return void or boolean.

+ * <p/>

+ * Returning true (or void) will queue up the component's body for rendering.

+ * <p/>

+ * Returning false will skip the component's body, but continue rendering the template. The {@link

+ * org.apache.tapestry.annotation.AfterRenderBody} phase will still execute after the template finishes rendering.

+ * <p/>

+ * This phase is skipped for components which do not have a body.

+ */

+@Target(ElementType.METHOD)

+@Retention(RUNTIME)

+@Documented

+public @interface BeforeRenderBody

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderTemplate.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderTemplate.java
new file mode 100644
index 0000000..4215232
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeforeRenderTemplate.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Associated with components that have a template, this phase is invoked to allow the component to decorate its

+ * template with additional markup. Returning true will cause the component's template to render (possibly including

+ * additional components, or this component's body), and eventually reach the {@link AfterRenderTemplate} phase. Return

+ * false to skip the template and body, and jump directly to the {@link AfterRenderTemplate} phase.

+ */

+@Target(ElementType.METHOD)

+@Retention(RUNTIME)

+@Documented

+public @interface BeforeRenderTemplate

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeginRender.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeginRender.java
new file mode 100644
index 0000000..a5c076f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/BeginRender.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for methods that should be executed at the start of rendering the component. This usually includes
+ * rendering of the component's start tag.
+ * <p/>
+ * Such methods may optionally take a {@link org.apache.tapestry.MarkupWriter} parameter, and may return void or
+ * boolean. Returning true or void will allow the component to advance into the render template / render body phase. If
+ * a body is present, the {@link org.apache.tapestry.annotation.BeforeRenderBody} phase will execute. If a component has
+ * a template, the {@link BeforeRenderTemplate} phase will execute (and the render body will only occur if the template
+ * directs so).
+ * <p/>
+ * Either way, the {@link org.apache.tapestry.annotation.AfterRender} phase will execute after the template and/or body
+ * have rendered. A component with a body but without a template will still see the {@link
+ * org.apache.tapestry.annotation.BeforeRenderBody} phase execute.
+ * <p/>
+ * Returning false will skip rendering of the template and/or body, and jump directly to the {@link AfterRender} phase.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface BeginRender
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Cached.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Cached.java
new file mode 100644
index 0000000..2f29544
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Cached.java
@@ -0,0 +1,38 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that a method should only be evaluated once and the result cached. All further calls to the method will
+ * return the cached result. Note that this annotation is inheritence-safe; if a subclass calls a superclass method that
+ * has \@Cached then the value the subclass method gets is the cached value.
+ * <p/>
+ * The watch parameter can be passed a binding expression which will be evaluated each time the method is called. The
+ * method will then only be executed the first time it is called and after that only when the value of the binding
+ * changes. This can be used, for instance, to have the method only evaluated once per iteration of a loop by setting
+ * watch to the value or index of the loop.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Cached
+{
+    /**
+     * The optional binding to watch (default binding prefix is "prop").
+     */
+    String watch() default "";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/CleanupRender.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/CleanupRender.java
new file mode 100644
index 0000000..6843895
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/CleanupRender.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for component methods associated with the terminal phase for the component rendering state machine.
+ * Methods may optionally take a {@link org.apache.tapestry.MarkupWriter} annotation. Generally, methods marked with
+ * this annotation are used to perform post-render cleanup. In addition, a method may return false to return to the
+ * {@link org.apache.tapestry.annotation.SetupRender} phase. Returning void or true (the default), is the normal
+ * course.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface CleanupRender
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Component.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Component.java
new file mode 100644
index 0000000..dce1e0e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Component.java
@@ -0,0 +1,54 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.FIELD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Used to define an <em>embedded component</em> within another component.

+ */

+@Target(FIELD)

+@Documented

+@Retention(RUNTIME)

+public @interface Component

+{

+

+    /**

+     * The id of the component. When left blank (the default), the component id is determined from the field name.

+     */

+    String id() default "";

+

+    /**

+     * The component type. When this is left unspecified, then the annotated field's type is used directly as the

+     * component type.

+     */

+    String type() default "";

+

+    /**

+     * Parameter bindings for the component. Each value in the array is of the form "name=value". The value is a binding

+     * expression, with a default binding prefix of "prop:".

+     */

+    String[] parameters() default {};

+

+    /**

+     * If true, then the component will inherit all informal parameters from its parent component. The default is

+     * false.

+     */

+    boolean inheritInformalParameters() default false;

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ContentType.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ContentType.java
new file mode 100644
index 0000000..a255de6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ContentType.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * An annotation on a page component used to identify the content type the page returns. An alternative to the {@link
+ * org.apache.tapestry.annotation.Meta} annotation with the {@link org.apache.tapestry.MetaDataConstants#RESPONSE_CONTENT_TYPE}
+ * key.
+ *
+ * @see org.apache.tapestry.annotation.ResponseEncoding
+ */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ContentType
+{
+    /**
+     * The content type for the page.  Typically, something like "text/html".
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Environmental.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Environmental.java
new file mode 100644
index 0000000..13b1464
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Environmental.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.services.Environment;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Defines a field that is replaced at runtime with a read-only value obtained from the {@link Environment} service.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Environmental
+{
+    /**
+     * The value determines if the environmental service to be injected is required or not. In most cases, it is, so the
+     * default is true.
+     */
+    boolean value() default true;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Id.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Id.java
new file mode 100644
index 0000000..c2695e6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Id.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Optional annotation, used with {@link Inject}, which exists to provide the id of an object when it can not be
+ * determined by other means (such as from the field name). Currently, this is used when injecting a {@link Block}.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Id
+{
+    /**
+     * The id.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeJavaScriptLibrary.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeJavaScriptLibrary.java
new file mode 100644
index 0000000..8e5c087
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeJavaScriptLibrary.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Allows for the inclusion of one or more JavaScript libraries.  The libraries are assets, usually (but not always)
+ * stored on the classpath with the component.
+ *
+ * @see org.apache.tapestry.annotation.IncludeStylesheet
+ * @see org.apache.tapestry.annotation.Path
+ */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IncludeJavaScriptLibrary
+{
+    /**
+     * The paths to the JavaScript library assets.  Symbols in the paths are expanded.  The library may be localized.
+     */
+    String[] value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeStylesheet.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeStylesheet.java
new file mode 100644
index 0000000..38583f4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/IncludeStylesheet.java
@@ -0,0 +1,43 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Used to automatically include a CSS stylesheet when rendering the page.  The value is an asset reference; relative
+ * paths are relative to the Java class, or a "context:" prefix can be used to reference resources in the web
+ * application.
+ * <p/>
+ * This saves the work of injecting the asset into a field and injecting the PageRenderSupport environmental service,
+ * and invoking the method.
+ * <p/>
+ * Does not support setting a media type; if that is required. use {@link org.apache.tapestry.RenderSupport#addStylesheetLink(org.apache.tapestry.Asset,
+ * String)} directly.
+ *
+ * @see org.apache.tapestry.annotation.Path
+ * @see org.apache.tapestry.annotation.IncludeJavaScriptLibrary
+ */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IncludeStylesheet
+{
+    /**
+     * One or more paths to be injected. Symbols in the path will be expanded. The stylesheets may be localized.
+     */
+    String[] value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectComponent.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectComponent.java
new file mode 100644
index 0000000..cc39595
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectComponent.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Allows components defined in the template to be injected as read-only properties.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface InjectComponent
+{
+    /**
+     * The name of the component to inject. Defaults to the name of the annotated field.
+     */
+    String value() default "";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectContainer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectContainer.java
new file mode 100644
index 0000000..f26466b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectContainer.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used in inject the container of a component as a field of the component. The container of a mixin is the component to
+ * which the mixin is attached.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface InjectContainer
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectPage.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectPage.java
new file mode 100644
index 0000000..4c7ab04
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/InjectPage.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Allows a a page (really, the root component of the page) to be injected into another component as a read-only field.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface InjectPage
+{
+    /**
+     * The name of the page to inject, which is used when the field type is not sufficient to identify the page (for
+     * example, when the field type is an interface implemented by the page). A non-blank value here overrides the
+     * lookup by class name (from the field type).
+     */
+    String value() default "";
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Log.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Log.java
new file mode 100644
index 0000000..373c8ed
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Log.java
@@ -0,0 +1,31 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Marker annotation for component methods to enable debug-level logging. Annotated methods will log method entry (with
+ * parameters), method exit (with return value, for non-void methods) and any thrown exceptions.
+ *
+ * @see org.apache.tapestry.internal.transform.LogWorker
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Meta.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Meta.java
new file mode 100644
index 0000000..5beb8d6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Meta.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.model.ComponentModel;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Allows for the specification of per-component meta-data. Meta data can later be accessed via {@link
+ * ComponentModel#getMeta(String)}. Meta data keys are case insensitive. Meta data defined by a subclass overrides meta
+ * data for the super class (where the keys conflict).
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface Meta
+{
+    /**
+     * The meta data as a list of "name=value" elements.
+     */
+    String[] value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixin.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixin.java
new file mode 100644
index 0000000..ba77eba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixin.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.FIELD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Defines an <em>implementation</em> mixin for a component.

+ */

+@Target(FIELD)

+@Documented

+@Retention(RUNTIME)

+public @interface Mixin

+{

+

+    /**

+     * Defines the type of mixin, using a logical mixin name. This value takes precedence over the type of field (to

+     * which the annotation is attached). In such cases, it is presumed that the field's type is an interface

+     * implemented by the actual mixin. The default value (the empty string) directs Tapestry to use the field type as

+     * the mixin class to instantiate and attach to the component.

+     */

+    String value() default "";

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinAfter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinAfter.java
new file mode 100644
index 0000000..56f730b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinAfter.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * A marker annotation applied to a mixin to indicate that the mixin's render state behavior is deferred until after the
+ * the behavior of the component to which the mixin is attached. Normally, mixins occur before the component. This
+ * divides each phase in the render state machine into three virtual phases: before the component, the component itself,
+ * and after the component.
+ */
+@Target(TYPE)
+@Documented
+@Retention(RUNTIME)
+@Inherited
+public @interface MixinAfter
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinClasses.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinClasses.java
new file mode 100644
index 0000000..f060e82
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/MixinClasses.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.FIELD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Used to attach one or more instance mixins to an embedded component. Each mixin is specified as a specific class.

+ * This annotation is only recognized when used in conjuction with the {@link Component} annotation.

+ *

+ * @see Mixins

+ */

+@Target(FIELD)

+@Documented

+@Retention(RUNTIME)

+public @interface MixinClasses

+{

+    Class[] value();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixins.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixins.java
new file mode 100644
index 0000000..5c5beb8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Mixins.java
@@ -0,0 +1,39 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.FIELD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Used to attach one ore more instance mixin to an embedded component. Each mixin is specified in terms of a logical

+ * mixin type name. This annotation is only recognized when used in conjuction with the {@link Component} annotation.

+ *

+ * @see MixinClasses

+ */

+@Target(FIELD)

+@Documented

+@Retention(RUNTIME)

+public @interface Mixins

+{

+

+    /**

+     * One or more mixin type names, from which actual mixin class names can be resolved.

+     */

+    String[] value();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/OnEvent.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/OnEvent.java
new file mode 100644
index 0000000..cd41368
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/OnEvent.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.EventConstants;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method as a handler for a client side event. The handler method will be invoked when a component triggers an
+ * event. Filters on the type of event and on the originating component ensure that only the appropriate methods are
+ * invoked.
+ * <p/>
+ * Client events include a <em>context</em> of one or more values. These context values are included in the action URI.
+ * The values are optionally supplied to the handler method as parameters. Automatic {@linkplain
+ * org.apache.tapestry.ValueEncoder conversion} from string to the type of the actual parameter occur.
+ * <p/>
+ * Handlers may return a value. Returning a non-null value will abort the handling of the event, and will usually
+ * control the response sent to the client web browser. The details are somewhat specific to the type of event and the
+ * component involved.
+ * <p/>
+ * If a handler is not found within the originating component (or no handler aborts the event handling), then handlers
+ * within the containing component will be searched. This continues up the page hierarchy. In some cases, having no
+ * handlers (or no aborting handlers) is considered acceptible; in others, it is an error. Again, this is defined by the
+ * type of originating component, and the type of event.
+ * <p/>
+ * <strong>If you fail to provide filters on either component or event type, then your method will be invoked for all
+ * component events, possibly including events that bubble up from embedded sub-components. </strong>
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface OnEvent
+{
+
+    /**
+     * The event type to match. The handler will only be invoked if the client event type matches the value. The default
+     * value is "action".  Matching is case-insensitive.
+     *
+     * @see org.apache.tapestry.EventConstants
+     */
+    String value() default EventConstants.ACTION;
+
+    /**
+     * The local id of the component from which the event originates. If not specified, then the default is to match any
+     * component. If an event from a component is not handled in the component's container, it is re-triggered inside
+     * the component's grand-container and will appear to originate from the container. Thus events that escape a
+     * component will appear to originate in the component's container, and so forth.
+     * <p/>
+     * <p/>
+     * Matching by component id is case insensitive.
+     */
+    String component() default "";
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageAttached.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageAttached.java
new file mode 100644
index 0000000..37e26e9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageAttached.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Method annotation used for methods that should be invoked when the page is first attached to a request. This is
+ * useful for initializations that should occur on each request that involves the page. Often, such initializations will
+ * be balanced by cleanups when the page is detached.
+ * <p/>
+ * PageAttached methods should take no parameters and return void. They must either have this annotation, or be named
+ * "pageAttached".
+ *
+ * @see PageDetached
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface PageAttached
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageDetached.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageDetached.java
new file mode 100644
index 0000000..ae14053
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageDetached.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Method annotation used for methods that should be invoked when the page is detached at the end of a request, before
+ * it is returned to the page pool for later reuse.
+ * <p/>
+ * PageDetached methods should take no parameters and return void. They must either have this annotation, or be named
+ * "pageDetached".
+ *
+ * @see PageAttached
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface PageDetached
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageLoaded.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageLoaded.java
new file mode 100644
index 0000000..a762365
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/PageLoaded.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Method annotation used for methods that should be invoked once the page is fully loaded. This is useful for one-time
+ * component initializations that can't be done at instantance initialzation time, such as refrerences to embedded
+ * components or blocks.
+ * <p/>
+ * PageLoaded methods should take no parameters and return void. They must either have this annotation, or be named
+ * "pageLoaded".
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface PageLoaded
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Parameter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Parameter.java
new file mode 100644
index 0000000..978064c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Parameter.java
@@ -0,0 +1,81 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.services.BindingFactory;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation placed on a field to indicate that it is, in fact, an parameter. Parameters may be optional or required.
+ * Required parameters must be bound.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Parameter
+{
+
+    /**
+     * The name of the parameter. If not specified, the name of the parameter is derived from the name of the field
+     * (after stripping off leading punctuation) from the field name.
+     */
+    String name() default "";
+
+    /**
+     * If true, the parameter is required and and must be bound. If false (the default), then the parameter is
+     * optional.
+     */
+    boolean required() default false;
+
+    /**
+     * If true (the default), then the value for the parameter is cached while the component is, itself, rendering.
+     * Values from invariant bindings (such as literal strings) are always cached, regardless of this setting. Set this
+     * attribute to false to force the parameter to be {@link org.apache.tapestry.Binding#get() re-read} every time the
+     * field is accessed, even while the component is rendering.
+     */
+    boolean cache() default true;
+
+    /**
+     * The default value for the parameter if not bound (at not the empty string). This is a binding expression,
+     * typically the name of a property of the component to bind.
+     */
+    String value() default "";
+
+    /**
+     * The default binding prefix for the parameter, if no specific binding prefix is provided with the binding. There
+     * is <em>rarely</em> a reason to override this. Typically, non-standard default binding prefixes are paired with
+     * specific {@link BindingFactory} implementations, and used with parameters whose name reflects the binding
+     * prefix.
+     *
+     * @see org.apache.tapestry.BindingConstants
+     */
+    String defaultPrefix() default BindingConstants.PROP;
+
+    /**
+     * Used to mark a parameter as requiring earlier initialization than other parameters. This is used when default
+     * bindings for secondary parameters rely on a principal parameter, which itself may have a default value. This
+     * ensures that the binding for the principal parameter(s) are initialized, possibly involving a defaulter method,
+     * before the secondary parameters are initialized (as they may need to know if the principal parameter is bound,
+     * and what type of value it is bound to). This is rarely used, and it is highly unlikely a single component would
+     * have more than a single principal parameter.
+     */
+    boolean principal() default false;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Path.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Path.java
new file mode 100644
index 0000000..edfbcc5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Path.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used in conjunction with the {@link Inject} annotation to inject an {@link Asset} based on a path.
+ */
+@Target(
+        { FIELD, PARAMETER })
+@Documented
+@Retention(RUNTIME)
+public @interface Path
+{
+    /**
+     * The path to the resource; if prefixed (say with "classpath:") then its a complete path within the identified
+     * namespace; otherwise it's a relative path from the class containing the annotation. Symbols will be expanded.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Persist.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Persist.java
new file mode 100644
index 0000000..2c712c4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Persist.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.Session;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Identifies a field as persistent, meaning its value persists from one request to the next. Different strategies exist
+ * for how this is accomplished, the most common being the default, "session", which stores the field's value in the
+ * {@link Session}.
+ * <p/>
+ * In most cases, the value will be omitted and will default to the empty string. This forces a search for the correct
+ * strategy. Starting with the component (or mixin) itself, a check is made for the {@link Meta meta data property}
+ * <code>tapestry.persistence-strategy</code>. If a value is found, it is used, otherwise the search continues up the
+ * inheritance hierarchy, towards the page. If not found, then the "session" strategy is used.
+ * <p/>
+ * In this way, the session persistence strategy for a component and all of its sub-components can be controlled by the
+ * containing component.
+ *
+ * @see MetaDataLocator
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Persist
+{
+
+    /**
+     * The strategy used to persist the value. The default value, the empty string, allows persistence to be decided by
+     * the containing component and component hierarchy.
+     */
+    String value() default "";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Property.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Property.java
new file mode 100644
index 0000000..d29ce1d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Property.java
@@ -0,0 +1,42 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for fields for which accessor methods (getters and setters) should be created.  This can help when
+ * defining the kind of placeholder properties often used in components, though the disadvantage is that you can't
+ * access the fields in a unit test, and you may get compiler warnings about unused private variables.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Property
+{
+    /**
+     * Whether to create a readable property (i.e., generate a getter method).
+     */
+    boolean read() default true;
+
+    /**
+     * Whether to create a writeable property (i.e., generate a setter method).
+     */
+    boolean write() default true;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ResponseEncoding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ResponseEncoding.java
new file mode 100644
index 0000000..4233024
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/ResponseEncoding.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * An annotation on a page component used to identify the respones encoding (the character set of the text sent in the
+ * response). An alternative to the {@link org.apache.tapestry.annotation.Meta} annotation with the {@link
+ * org.apache.tapestry.MetaDataConstants#RESPONSE_ENCODING} key.
+ *
+ * @see org.apache.tapestry.annotation.ContentType
+ */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ResponseEncoding
+{
+    /**
+     * The response encoding, a value such as "utf-8".
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Retain.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Retain.java
new file mode 100644
index 0000000..bbf9ad8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Retain.java
@@ -0,0 +1,40 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.FIELD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Marker annotation placed on fields whose value should be retained past the end of the request. This is most often

+ * associated with fields that are <em>lazily loaded</em>. By marking such fields with the Retain annotation, the fields

+ * will <em>not</em> be discarded at the end of the request.

+ * <p/>

+ * This is quite different from {@link Persist}, because the value that's allowed to be retained is not stored

+ * persistently; it is simply not cleared out. A subsequent request, even from the same user, may be processed by a

+ * different instance of the page where the value is still null.

+ * <p/>

+ * This annotation should only be used with lazily-evaluated objects that contain no client-specific information.

+ */

+@Target(FIELD)

+@Retention(RUNTIME)

+@Documented

+public @interface Retain

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Secure.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Secure.java
new file mode 100644
index 0000000..e7fedd3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Secure.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * A marker annotation that indicates that the page in question may only be accessed via HTTPS.
+ *
+ * @see org.apache.tapestry.MetaDataConstants#SECURE_PAGE
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface Secure
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Service.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Service.java
new file mode 100644
index 0000000..66e7485
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/Service.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used in conjunction with the {@link Inject} annotation to identify a service <em>by name</em> and not by type. This
+ * is most useful when there are multiple services with the same service interface and a particular one needs to be
+ * selected.
+ */
+@Target(
+        { FIELD, PARAMETER })
+@Documented
+@Retention(RUNTIME)
+public @interface Service
+{
+    /**
+     * The name of the service. Symbols will be expanded and case is not relevant.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SetupRender.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SetupRender.java
new file mode 100644
index 0000000..30bf5c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SetupRender.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for methods that should be executed during the SetupRender phase. Such methods may optionally take
+ * a {@link org.apache.tapestry.MarkupWriter} parameter, and may return void or boolean. Returning true or void will
+ * advance to the {@link org.apache.tapestry.annotation.BeginRender} phase. Return false to skip the BeginRender phase
+ * and procede directly to the {@link org.apache.tapestry.annotation.CleanupRender} phase.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface SetupRender
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SupportsInformalParameters.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SupportsInformalParameters.java
new file mode 100644
index 0000000..04a473a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/annotation/SupportsInformalParameters.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotation;
+
+import org.apache.tapestry.model.ComponentModel;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to identify a component that can support informal parameters. By default, components do not support informal
+ * parameters.
+ *
+ * @see ComponentModel#getSupportsInformalParameters()
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+@Inherited
+public @interface SupportsInformalParameters
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java
new file mode 100644
index 0000000..d3dc12c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/BeanModel.java
@@ -0,0 +1,143 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import org.apache.tapestry.PropertyConduit;
+
+import java.util.List;
+
+/**
+ * Provides the information necessary to build a user interface to view, create or edit an instance of a particular
+ * type.
+ * <p/>
+ * BeanModels are not thread-safe, they are also not serializable.
+ * <p/>
+ * Here, and in {@link org.apache.tapestry.beaneditor.PropertyModel}, the term "propertyName" is used for simplicitly.
+ * However, a full {@linkplain org.apache.tapestry.services.PropertyConduitSource#create(Class, String) property
+ * expression} may be utilized when {@linkplain #add(String) adding new properties to an existing BeanModel}.
+ *
+ * @see org.apache.tapestry.services.BeanModelSource
+ */
+public interface BeanModel<T>
+{
+    /**
+     * Returns the type of bean for which this model was initially created.
+     */
+    Class<T> getBeanType();
+
+
+    /**
+     * Creates a new bean instance.  This is based on {@link org.apache.tapestry.ioc.ObjectLocator#autobuild(Class)}, so
+     * a public constructor will be used, and dependencies injected.
+     *
+     * @return new instance of the bean
+     */
+    T newInstance();
+
+    /**
+     * Returns a list of the editable properties of the bean, in <em>presentation</em> order.
+     */
+    List<String> getPropertyNames();
+
+    /**
+     * Returns the named model.
+     *
+     * @param propertyName name of property to retrieve model for (case is ignored)
+     * @return the model for the property
+     * @throws RuntimeException if the bean editor model does not have a property model for the provided name
+     */
+    PropertyModel get(String propertyName);
+
+    /**
+     * Returns the identified model.  Property ids are a stripped version of the property name. Case is ignored.
+     *
+     * @param propertyId matched caselessly against {@link org.apache.tapestry.beaneditor.PropertyModel#getId()}
+     * @throws RuntimeException if the bean editor model does not have a property model with the indicated id
+     */
+    PropertyModel getById(String propertyId);
+
+    /**
+     * Adds a new property to the model, returning its mutable model for further refinement. The property is added to
+     * the <em>end</em> of the list of properties.
+     *
+     * @param propertyName name of property to add
+     * @return the new property model (for further configuration)
+     * @throws RuntimeException if the property already exists
+     */
+    PropertyModel add(String propertyName);
+
+    /**
+     * Adds a new property to the model, ordered before or after an existing property.
+     *
+     * @param position             controls whether the new property is ordered before or after the existing property
+     * @param existingPropertyName the name of an existing property (this must exist)
+     * @param propertyName         the new property to add
+     * @return the new property model (for further configuration)
+     * @throws RuntimeException if the existing property does not exist, or if the new property already does exist
+     */
+    PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName);
+
+    /**
+     * Adds a new property to the model, ordered before or after an existing property.
+     *
+     * @param position             controls whether the new property is ordered before or after the existing property
+     * @param existingPropertyName the name of an existing property (this must exist)
+     * @param propertyName         the new property to add
+     * @param conduit              conduit used to read or update the property; this may be null for a synthetic or
+     *                             placeholder property
+     * @return the new property model (for further configuration)
+     * @throws RuntimeException if the existing property does not exist, or if the new property already does exist
+     */
+    PropertyModel add(RelativePosition position, String existingPropertyName, String propertyName,
+                      PropertyConduit conduit);
+
+    /**
+     * Adds a new property to the model, returning its mutable model for further refinement.
+     *
+     * @param propertyName name of property to add
+     * @param conduit      the conduit used to read or update the property; this may be null for a synthetic or
+     *                     placeholder property
+     * @return the model for the property
+     * @throws RuntimeException if the property already exists
+     */
+    PropertyModel add(String propertyName, PropertyConduit conduit);
+
+    /**
+     * Removes the named properties from the model, if present. It is not considered an error to remove a property that
+     * does not exist.
+     *
+     * @param propertyNames the names of properties to be removed (case insensitive)
+     * @return the model for further modifications
+     */
+    BeanModel exclude(String... propertyNames);
+
+    /**
+     * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are
+     * retained, but ordered to the end of the list.
+     *
+     * @param propertyNames property names in order they should be displayed (case insensitive)
+     * @return the model for further modifications
+     */
+    BeanModel reorder(String... propertyNames);
+
+    /**
+     * Re-orders the properties of the model into the specified order. Existing properties that are not indicated are
+     * <<removed>>.
+     *
+     * @param propertyNames the names of properties to be retained
+     * @return the model for further modifications
+     */
+    BeanModel include(String... propertyNames);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java
new file mode 100644
index 0000000..bc2c50d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/beaneditor/PropertyModel.java
@@ -0,0 +1,97 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.beaneditor;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+/**
+ * Part of a {@link org.apache.tapestry.beaneditor.BeanModel} that defines the attributes of a single property of a
+ * bean.
+ * <p/>
+ * <p/>
+ * A PropertyModel is also an {@link AnnotationProvider}, as long as the {@link org.apache.tapestry.PropertyConduit} is
+ * non-null.  When there is no property conduit, then {@link org.apache.tapestry.ioc.AnnotationProvider#getAnnotation(Class)}
+ * will return null.
+ */
+public interface PropertyModel extends AnnotationProvider
+{
+    /**
+     * Returns the name of the property (which may, in fact, be a property expression).
+     */
+    String getPropertyName();
+
+    /**
+     * Returns the id used to access other resources (this is based on the property name, but with any excess
+     * punctuation stripped out).
+     */
+    String getId();
+
+    /**
+     * Returns a user-presentable label for the property.
+     */
+    String getLabel();
+
+    /**
+     * Returns the type of the property.
+     */
+    Class getPropertyType();
+
+    /**
+     * Returns a logical name for the type of UI needed to view or edit the property. This is initially determined from
+     * the property type.
+     */
+    String getDataType();
+
+    /**
+     * Changes the data type for the property.
+     *
+     * @param dataType
+     * @return the property model, for further changes
+     */
+    PropertyModel dataType(String dataType);
+
+    /**
+     * Returns an object used to read or update the property. For virtual properties (properties that do not actually
+     * exist on the bean), the conduit may be null.
+     */
+    PropertyConduit getConduit();
+
+    /**
+     * Changes the label for the property to the provided value.
+     *
+     * @param label new label for property
+     * @return the property model, for further changes
+     */
+    PropertyModel label(String label);
+
+    /**
+     * Returns the containing model, often used for "fluent" construction of the model.
+     */
+    BeanModel model();
+
+    /**
+     * Returns true if the property can be used for sorting. By default, this is true only if the property type
+     * implements Comparable.
+     */
+    boolean isSortable();
+
+    /**
+     * Updates sortable and returns the model for further changes.
+     *
+     * @return the property model, for further changes
+     */
+    PropertyModel sortable(boolean sortable);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java
new file mode 100644
index 0000000..74a8438
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java
@@ -0,0 +1,74 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+
+import java.util.List;
+
+/**
+ * Base class for link-generating components that are based on a component event request. Such events have an event
+ * context and may also update a {@link org.apache.tapestry.corelib.components.Zone}.
+ */
+public abstract class AbstractComponentEventLink extends AbstractLink
+{
+    /**
+     * The context for the link (optional parameter). This list of values will be converted into strings and included in
+     * the URI. The strings will be coerced back to whatever their values are and made available to event handler
+     * methods.
+     */
+    @Parameter
+    private List<?> context;
+
+    /**
+     * Binding the zone parameter turns the link into a an Ajax control that causes the related zone to be updated.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String zone;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (isDisabled()) return;
+
+        Object[] contextArray = context == null ? new Object[0] : context.toArray();
+
+        Link link = createLink(contextArray);
+
+        writeLink(writer, link);
+
+        if (zone != null) clientBehaviorSupport.linkZone(getClientId(), zone);
+    }
+
+    /**
+     * Invoked to create the Link that will become the href attribute of the output.
+     */
+    protected abstract Link createLink(Object[] eventContext);
+
+    void afterRender(MarkupWriter writer)
+    {
+        if (isDisabled()) return;
+
+        writer.end(); // <a>
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
new file mode 100644
index 0000000..2159f20
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
@@ -0,0 +1,250 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.corelib.mixins.DiscardBody;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.corelib.mixins.RenderInformals;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.FormSupport;
+
+import java.io.Serializable;
+
+/**
+ * Provides initialization of the clientId and elementName properties. In addition, adds the {@link RenderInformals},
+ * {@link RenderDisabled} and {@link DiscardBody} mixins.
+ */
+@SupportsInformalParameters
+public abstract class AbstractField implements Field
+{
+    /**
+     * The user presentable label for the field. If not provided, a reasonable label is generated from the component's
+     * id, first by looking for a message key named "id-label" (substituting the component's actual id), then by
+     * converting the actual id to a presentable string (for example, "userId" to "User Id").
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String label;
+
+    /**
+     * If true, then the field will render out with a disabled attribute (to turn off client-side behavior). Further, a
+     * disabled field ignores any value in the request when the form is submitted.
+     */
+    @Parameter("false")
+    private boolean disabled;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private DiscardBody discardBody;
+
+    @Environmental
+    private ValidationDecorator decorator;
+
+    protected static final FieldValidator NOOP_VALIDATOR = new FieldValidator()
+    {
+        public void validate(Object value) throws ValidationException
+        {
+            // Do nothing
+        }
+
+        public void render(MarkupWriter writer)
+        {
+        }
+
+        public boolean isRequired()
+        {
+            return false;
+        }
+    };
+
+    static class SetupAction implements ComponentAction<AbstractField>, Serializable
+    {
+        private static final long serialVersionUID = 2690270808212097020L;
+
+        private final String controlName;
+
+        public SetupAction(String controlName)
+        {
+            this.controlName = controlName;
+        }
+
+        public void execute(AbstractField component)
+        {
+            component.setupControlName(controlName);
+        }
+    }
+
+    static class ProcessSubmissionAction implements ComponentAction<AbstractField>, Serializable
+    {
+        private static final long serialVersionUID = -4346426414137434418L;
+
+        public void execute(AbstractField component)
+        {
+            component.processSubmission();
+        }
+    }
+
+    /**
+     * Used a shared instance for all types of fields, for efficiency.
+     */
+    private static final ProcessSubmissionAction PROCESS_SUBMISSION_ACTION = new ProcessSubmissionAction();
+
+    /**
+     * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
+     * times, a suffix will be appended to the to id to ensure uniqueness. The uniqued value may be accessed via the
+     * {@link #getClientId() clientId property}.
+     */
+    @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
+    private String clientId;
+
+    private String assignedClientId;
+
+    private String controlName;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    final String defaultLabel()
+    {
+        return defaultProvider.defaultLabel(resources);
+    }
+
+    public final String getLabel()
+    {
+        return label;
+    }
+
+    @SetupRender
+    final void setup()
+    {
+        // By default, use the component id as the (base) client id. If the clientid
+        // parameter is bound, then that is the value to use.
+
+        String id = clientId;
+
+        // Often, these controlName and clientId will end up as the same value. There are many
+        // exceptions, including a form that renders inside a loop, or a form inside a component
+        // that is used multiple times.
+
+        assignedClientId = renderSupport.allocateClientId(id);
+        String controlName = formSupport.allocateControlName(id);
+
+        formSupport.storeAndExecute(this, new SetupAction(controlName));
+        formSupport.store(this, PROCESS_SUBMISSION_ACTION);
+    }
+
+    public final String getClientId()
+    {
+        return assignedClientId;
+    }
+
+    public final String getControlName()
+    {
+        return controlName;
+    }
+
+    public final boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    /**
+     * Invoked from within a ComponentCommand callback, to restore the component's elementName.
+     */
+    private void setupControlName(String controlName)
+    {
+        this.controlName = controlName;
+    }
+
+    private void processSubmission()
+    {
+        if (!disabled) processSubmission(controlName);
+    }
+
+    /**
+     * Used by subclasses to create a default binding to a property of the container matching the component id.
+     *
+     * @return a binding to the property, or null if the container does not have a corresponding property
+     */
+    protected final Binding createDefaultParameterBinding(String parameterName)
+    {
+        return defaultProvider.defaultBinding(parameterName, resources);
+    }
+
+    /**
+     * Method implemented by subclasses to actually do the work of processing the submission of the form. The element's
+     * elementName property will already have been set. This method is only invoked if the field is <strong>not {@link
+     * #isDisabled() disabled}</strong>.
+     *
+     * @param elementName the name of the element (used to find the correct parameter in the request)
+     */
+    protected abstract void processSubmission(String elementName);
+
+    /**
+     * Allows the validation decorator to write markup before the field itself writes markup.
+     */
+    @BeginRender
+    final void beforeDecorator()
+    {
+        decorator.beforeField(this);
+    }
+
+    /**
+     * Allows the validation decorator to write markup after the field has written all of its markup.
+     */
+    @AfterRender
+    final void afterDecorator()
+    {
+        decorator.afterField(this);
+    }
+
+    /**
+     * Invoked from subclasses after they have written their tag and (where appropriate) their informal parameters
+     * <em>and</em> have allowed their {@link Validator} to write markup as well.
+     */
+    protected final void decorateInsideField()
+    {
+        decorator.insideField(this);
+    }
+
+    protected final void setDecorator(ValidationDecorator decorator)
+    {
+        this.decorator = decorator;
+    }
+
+    protected final void setFormSupport(FormSupport formSupport)
+    {
+        this.formSupport = formSupport;
+    }
+
+    /**
+     * Returns false; most components do not support declarative validation.
+     */
+    public boolean isRequired()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractLink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractLink.java
new file mode 100644
index 0000000..20a9798
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractLink.java
@@ -0,0 +1,149 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SetupRender;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Provides base utilities for classes that generate clickable links.
+ */
+@SupportsInformalParameters
+public abstract class AbstractLink implements ClientElement
+{
+    @Inject
+    private ComponentInvocationMap componentInvocationMap;
+
+    /**
+     * An anchor value to append to the generated URL (the hash separator will be added automatically).
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String anchor;
+
+    /**
+     * If true, then then no link element is rendered (and no informal parameters as well). The body is, however, still
+     * rendered.
+     */
+    @Parameter("false")
+    private boolean disabled;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private RenderSupport renderSupport;
+
+    private Link link;
+
+    private Element element;
+
+    private String clientId;
+
+    private String buildHref(Link link)
+    {
+        String href = link.toURI();
+
+        if (anchor == null) return href;
+
+        return href + "#" + anchor;
+    }
+
+
+    @SetupRender
+    void resetElementAndClientId()
+    {
+        element = null;
+        clientId = null;
+    }
+
+    /**
+     * Writes an &lt;a&gt; element with the provided link as the href attribute.  A call to {@link
+     * org.apache.tapestry.MarkupWriter#end()} is <em>not</em> provided.            Automatically appends an anchor if
+     * the component's anchor parameter is non-null.  Informal parameters are rendered as well.
+     *
+     * @param writer         to write markup to
+     * @param link           the link that will form the href
+     * @param namesAndValues additional attributes to write
+     */
+    protected final void writeLink(MarkupWriter writer, Link link, Object... namesAndValues)
+    {
+        element = writer.element("a", "href", buildHref(link));
+
+        writer.attributes(namesAndValues);
+
+        resources.renderInformalParameters(writer);
+
+        componentInvocationMap.store(element, link);
+
+        this.link = link;
+    }
+
+    /**
+     * Returns the most recently rendered {@link org.apache.tapestry.Link} for this component.  Subclasses calculate
+     * their link value as they render, and the value is valid until the end of the request, or the next time the same
+     * component renders itself (if inside a loop).
+     *
+     * @return the most recent link, or null
+     */
+    public Link getLink()
+    {
+        return link;
+    }
+
+    /**
+     * Returns the unique client id for this element. This is valid only after the component has rendered (its start
+     * tag).  A client id is generated the first time this method is invoked, after the link renders its start tag.
+     */
+    public final String getClientId()
+    {
+        if (clientId == null)
+        {
+            if (element == null)
+                throw new IllegalStateException(
+                        String.format("Client id for %s is not available as it did not render yet (or was disabled).",
+                                      resources.getCompleteId()));
+
+            clientId = renderSupport.allocateClientId(resources);
+
+            element.forceAttributes("id", clientId);
+        }
+
+        return clientId;
+    }
+
+    /**
+     * Returns true if the component is disabled (as per its disabled parameter). Disabled link components should not
+     * render a tag, but should still render their body.
+     */
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    /**
+     * Used for testing.
+     */
+    final void inject(String anchor, ComponentInvocationMap map, ComponentResources resources)
+    {
+        this.anchor = anchor;
+        componentInvocationMap = map;
+        this.resources = resources;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractPropertyOutput.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractPropertyOutput.java
new file mode 100644
index 0000000..0668339
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractPropertyOutput.java
@@ -0,0 +1,175 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.PropertyOutputContext;
+
+/**
+ * Base class for components that output a property value using a {@link PropertyModel}. There's a relationship between
+ * such a component and its container, as the container may provide messages in its message catalog needed by the {@link
+ * Block}s that render the values. In addition, the component may be passed Block parameters that are output overrides
+ * for specified properties.
+ * <p/>
+ * Subclasses will implement a <code>beginRender()</code> method that invokes {@link #renderPropertyValue(MarkupWriter,
+ * String)}.
+ *
+ * @see BeanBlockSource
+ */
+public abstract class AbstractPropertyOutput
+{
+    /**
+     * Model for property displayed by the cell.
+     */
+    @Parameter(required = true)
+    private PropertyModel model;
+
+    /**
+     * Resources used to search for block parameter overrides (this is normally the enclosing Grid component's
+     * resources).
+     */
+    @Parameter(required = true)
+    private ComponentResources overrides;
+
+    /**
+     * Identifies the object being rendered. The component will extract a property from the object and render its value
+     * (or delegate to a {@link org.apache.tapestry.Block} that will do so).
+     */
+    @Parameter(required = true)
+    private Object object;
+
+    @Inject
+    private BeanBlockSource beanBlockSource;
+
+    @Inject
+    private Environment environment;
+
+    private boolean mustPopEnvironment;
+
+    protected PropertyModel getPropertyModel()
+    {
+        return model;
+    }
+
+    /**
+     * Invoked from subclasses to do the rendering. The subclass controls the naming convention for locating an
+     * overriding Block parameter (it is the name of the property possibly suffixed with a value).
+     */
+    protected Object renderPropertyValue(MarkupWriter writer, String overrideBlockId)
+    {
+        Block override = overrides.getBlockParameter(overrideBlockId);
+
+        if (override != null) return override;
+
+        String datatype = model.getDataType();
+
+        if (beanBlockSource.hasDisplayBlock(datatype))
+        {
+            PropertyOutputContext context = new PropertyOutputContext()
+            {
+                public Messages getMessages()
+                {
+                    return getOverrideMessages();
+                }
+
+                public Object getPropertyValue()
+                {
+                    return readPropertyForObject();
+                }
+
+                public String getPropertyId()
+                {
+                    return model.getId();
+                }
+
+                public String getPropertyName()
+                {
+                    return model.getPropertyName();
+                }
+            };
+
+            environment.push(PropertyOutputContext.class, context);
+            mustPopEnvironment = true;
+
+            return beanBlockSource.getDisplayBlock(datatype);
+        }
+
+        Object value = readPropertyForObject();
+
+        if (value == null)
+        {
+            writer.writeRaw("&nbsp;");
+            return false;
+        }
+
+        writer.write(value.toString());
+
+        // Don't render anything else
+
+        return false;
+    }
+
+    Object readPropertyForObject()
+    {
+        PropertyConduit conduit = model.getConduit();
+
+        try
+        {
+            return conduit == null ? null : conduit.get(object);
+        }
+        catch (final NullPointerException ex)
+        {
+            throw new NullPointerException(BaseMessages.nullValueInPath(model.getPropertyName()));
+        }
+    }
+
+    private Messages getOverrideMessages()
+    {
+        return overrides.getContainerMessages();
+    }
+
+    /**
+     * Returns false; there's no template and this prevents the body from rendering.
+     */
+    boolean beforeRenderTemplate()
+    {
+        return false;
+    }
+
+    void afterRender()
+    {
+        if (mustPopEnvironment)
+        {
+            environment.pop(PropertyOutputContext.class);
+            mustPopEnvironment = false;
+        }
+    }
+
+    // Used for testing.
+    void inject(final PropertyModel model, final Object object)
+    {
+        this.model = model;
+        this.object = object;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java
new file mode 100644
index 0000000..f6c11a2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java
@@ -0,0 +1,239 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.beaneditor.Width;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.FieldValidatorDefaultSource;
+import org.apache.tapestry.services.Request;
+
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+
+/**
+ * Abstract class for a variety of components that render some variation of a text field. Most of the hooks for user
+ * input validation are in this class.
+ * <p/>
+ * In particular, all subclasses support the "toclient" and "parseclient" events.  These two events allow the normal
+ * {@link Translator} (specified by the translate parameter, but often automatically derived by Tapestry) to be
+ * augmented.
+ * <p/>
+ * If the component container (i.e., the page) provides an event handler method for the "toclient" event, and that
+ * handler returns a non-null string, that will be the string value sent to the client. The context passed to the event
+ * handler method is t he current value of the value parameter.
+ * <p/>
+ * Likewise, on a form submit, the "parseclient" event handler method will be passed the string provided by the client,
+ * and may provide a non-null value as the parsed value.  Returning null allows the normal translator to operate.  The
+ * event handler may also throw {@link org.apache.tapestry.ValidationException}.
+ */
+public abstract class AbstractTextField extends AbstractField
+{
+    /**
+     * The value to be read and updated. This is not necessarily a string, a translator may be provided to convert
+     * between client side and server side representations. If not bound, a default binding is made to a property of the
+     * container matching the component's id. If no such property exists, then you will see a runtime exception due to
+     * the unbound value parameter.
+     */
+    @Parameter(required = true, principal = true)
+    private Object value;
+
+    /**
+     * The object which will perform translation between server-side and client-side representations. If not specified,
+     * a value will usually be generated based on the type of the value parameter.
+     */
+    @Parameter(required = true)
+    private Translator<Object> translate;
+
+    /**
+     * The object that will perform input validation (which occurs after translation). The translate binding prefix is
+     * generally used to provide this object in a declarative fashion.
+     */
+    @Parameter(defaultPrefix = BindingConstants.VALIDATE)
+    @SuppressWarnings("unchecked")
+    private FieldValidator<Object> validate;
+
+    /**
+     * Provider of annotations used for some defaults.  Annotation are usually provided in terms of the value parameter
+     * (i.e., from the getter and/or setter bound to the value parameter).
+     *
+     * @see org.apache.tapestry.beaneditor.Width
+     */
+    @Parameter
+    private AnnotationProvider annotationProvider;
+
+    /**
+     * Defines how nulls on the server side, or sent from the client side, are treated. The selected strategy may
+     * replace the nulls with some other value. The default strategy leaves nulls alone.  Another built-in strategy,
+     * zero, replaces nulls with the value 0.
+     */
+    @Parameter(defaultPrefix = BindingConstants.NULLFIELDSTRATEGY, value = "default")
+    private NullFieldStrategy nulls;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    @Inject
+    private FieldValidatorDefaultSource fieldValidatorDefaultSource;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private Locale locale;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private FieldValidationSupport fieldValidationSupport;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    /**
+     * Computes a default value for the "translate" parameter using {@link org.apache.tapestry.services.ComponentDefaultProvider#defaultTranslator(String,
+     * org.apache.tapestry.ComponentResources)}.
+     */
+    final Translator defaultTranslate()
+    {
+        return defaultProvider.defaultTranslator("value", resources);
+    }
+
+    final AnnotationProvider defaultAnnotationProvider()
+    {
+        return new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return resources.getParameterAnnotation("value", annotationClass);
+            }
+        };
+    }
+
+    /**
+     * Computes a default value for the "validate" parameter using {@link org.apache.tapestry.services.FieldValidatorDefaultSource}.
+     */
+    final FieldValidator defaultValidate()
+    {
+        Class type = resources.getBoundType("value");
+
+        if (type == null) return NOOP_VALIDATOR;
+
+        return fieldValidatorDefaultSource.createDefaultValidator(this, resources.getId(),
+                                                                  resources.getContainerMessages(), locale, type,
+                                                                  resources.getAnnotationProvider("value"));
+    }
+
+    /**
+     * The default value is a property of the container whose name matches the component's id. May return null if the
+     * container does not have a matching property.
+     */
+    final Binding defaultValue()
+    {
+        return createDefaultParameterBinding("value");
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @BeginRender
+    final void begin(MarkupWriter writer)
+    {
+        String value = tracker.getInput(this);
+
+        // If this is a response to a form submission, and the user provided a value.
+        // then send that exact value back at them.
+
+        if (value == null)
+        {
+            // Otherwise, get the value from the parameter ...
+            // Then let the translator and or various triggered events get it into
+            // a format ready to be sent to the client.
+
+            value = fieldValidationSupport.toClient(this.value, resources, translate, nulls);
+        }
+
+        writeFieldTag(writer, value);
+
+        validate.render(writer);
+
+        resources.renderInformalParameters(writer);
+
+        decorateInsideField();
+    }
+
+    /**
+     * Invoked from {@link #begin(MarkupWriter)} to write out the element and attributes (typically, &lt;input&gt;). The
+     * {@linkplain AbstractField#getControlName() controlName} and {@linkplain AbstractField#getClientId() clientId}
+     * properties will already have been set or updated.
+     * <p/>
+     * Generally, the subclass will invoke {@link MarkupWriter#element(String, Object[])}, and will be responsible for
+     * including an {@link AfterRender} phase method to invoke {@link MarkupWriter#end()}.
+     *
+     * @param writer markup write to send output to
+     * @param value  the value (either obtained and translated from the value parameter, or obtained from the tracker)
+     */
+    protected abstract void writeFieldTag(MarkupWriter writer, String value);
+
+    @SuppressWarnings({ "unchecked" })
+    @Override
+    protected final void processSubmission(String elementName)
+    {
+        String rawValue = request.getParameter(elementName);
+
+        tracker.recordInput(this, rawValue);
+
+        try
+        {
+            Object translated = fieldValidationSupport.parseClient(rawValue, resources, translate, nulls);
+
+            fieldValidationSupport.validate(translated, resources, validate);
+
+            value = translated;
+        }
+        catch (ValidationException ex)
+        {
+            tracker.recordError(this, ex.getMessage());
+        }
+    }
+
+    @Override
+    public boolean isRequired()
+    {
+        return validate.isRequired();
+    }
+
+    /**
+     * Looks for a {@link org.apache.tapestry.beaneditor.Width} annotation and, if present, returns its value as a
+     * string.
+     *
+     * @return the indicated width, or null if the annotation is not present
+     */
+    protected final String getWidth()
+    {
+        Width width = annotationProvider.getAnnotation(Width.class);
+
+        if (width == null) return null;
+
+        return Integer.toString(width.value());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/BaseMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/BaseMessages.java
new file mode 100644
index 0000000..d8263bf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/BaseMessages.java
@@ -0,0 +1,28 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+public final class BaseMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(BaseMessages.class);
+
+    public static String nullValueInPath(final String path)
+    {
+        return MESSAGES.format("null-value-in-path", path);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java
new file mode 100644
index 0000000..adfae2b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.corelib.base.AbstractComponentEventLink;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Component that triggers an action on the server with a subsequent full page refresh.
+ */
+public class ActionLink extends AbstractComponentEventLink
+{
+    @Inject
+    private ComponentResources resources;
+
+    protected Link createLink(Object[] contextArray)
+    {
+        return resources.createActionLink(EventConstants.ACTION, false, contextArray);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.xdoc
new file mode 100644
index 0000000..4c1e980
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ActionLink.xdoc
@@ -0,0 +1,141 @@
+<document>
+    <body>
+
+        <section name="Examples">
+
+            <p>
+                In this example, we are showing part of a page to view and Account object, with an option to
+                delete the Account.
+            </p>
+
+
+            <subsection name="Account.java">
+                <source><![CDATA[
+public class Account
+{
+    private long _id;
+
+    private String _userName;
+
+    // etc., etc., ...
+
+    // Getters and setters omitted ...
+    
+}]]></source>
+            </subsection>
+
+            <subsection name="ViewAccount.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>View Account #${account.id}</h1>
+
+        <t:beandisplay object="account"/>
+
+        <p>
+          [<t:actionlink t:id="delete" context="account.id">delete</t:actionlink>
+        </p>
+    </body>
+</html>
+]]></source>
+
+                <p>
+                    We store the account's id as
+                    <em>event context</em>
+                    inside the URL. The account's id will
+                    be part of the URL and will be accessible when the event request is later triggered.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="ViewAccount.java">
+                <source><![CDATA[
+public class ViewAccount
+{
+    @Persist
+    private Account _account;
+
+    @InjectPage
+    private AccountsSummary _accountsSummaryPage;
+
+    @Inject
+    private AccountDAO _accountDAO;
+
+    public Account getAccount() { return _account; }
+
+    Object onActionFromDelete(long accountId)
+    {
+        _accountDAO.delete(accountId);
+
+        _accountsSummaryPage.setMessage(String.format("Account #%d has been deleted.", accountId));
+
+        return _accountsSummaryPage;
+    }
+}
+]]></source>
+
+                <p>
+                    The ActionLink component triggers an "action" event, which is matched by the
+                    onActionFromDelete() method. A real application might have other action links on the page, for (say)
+                    creating new accounts or other operations, thus we use the component's id ("delete")
+                    to ensure that the method is only invoked under the expected circumstances.
+                </p>
+
+                <p>
+                    Notice how the context (from when the link was rendered) now becomes parameters
+                    to the event handler method.
+                </p>
+
+                <p>
+                    The AccountDAO (data access object) service is responsible for the work, we
+                    then set a message on another page (the field for this message should be persistent) and return
+                    the page. Tapestry will send a redirect request to the client to display the page.
+                </p>
+
+
+            </subsection>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                Rarely, you might need to pass more information in the context. For example, perhaps
+                account id is not enought to uniquely identify the Account object in question - hypothetically,
+                you may need to include a company id as well as the account id. You can
+                build an object array to contain both values:
+            </p>
+
+            <source><![CDATA[
+    public Object[] getAccountContext()
+    {
+        return new Object[] { account.companyId, account.id };
+    }
+
+    Object onActionFromDelete(long companyId, long accountId)
+    {
+        _accountDAO.delete(companyId, accountId);
+
+        _accountsSummaryPage.setMessage(String.format("Account #%d has been deleted.", accountId));
+
+        return _accountsSummaryPage;
+    }]]></source>
+
+            <p>
+                In the template, this would be referenced as:
+            </p>
+            <source><![CDATA[
+        <p>
+          [<t:actionlink t:id="delete" context="accountContext">delete</t:actionlink>
+        </p>]]></source>
+
+            <p>
+                This highlights the use of the component class: any complicated processing should be offloaded
+                out of the template and into the class.
+            </p>
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Any.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Any.java
new file mode 100644
index 0000000..871ea89
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Any.java
@@ -0,0 +1,93 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Renders an arbitrary element including informal parameters.
+ */
+@SupportsInformalParameters
+public class Any implements ClientElement
+{
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String element;
+
+    /**
+     * The desired client id, which defaults to the components id.
+     */
+    @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
+    private String clientId;
+
+    private Element anyElement;
+
+    private String uniqueId;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private RenderSupport renderSupport;
+
+    String defaultElement()
+    {
+        return resources.getElementName("div");
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        anyElement = writer.element(element);
+
+        uniqueId = null;
+
+        resources.renderInformalParameters(writer);
+    }
+
+    /**
+     * Returns the client id.  This has side effects: this first time this is called (after the Any component renders
+     * its start tag), a unique id is allocated (based on, and typically the same as, the clientId parameter, which
+     * defaults to the component's id). The rendered element is updated, with its id attribute set to the unique client
+     * id, which is then returned.
+     *
+     * @return unique client id for this component
+     */
+    public String getClientId()
+    {
+        if (uniqueId == null)
+        {
+            uniqueId = renderSupport.allocateClientId(clientId);
+            anyElement.forceAttributes("id", clientId);
+        }
+
+        return uniqueId;
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // the element
+    }
+
+    void inject(RenderSupport support, ComponentResources resources, String element, String clientId)
+    {
+        this.renderSupport = support;
+        this.resources = resources;
+        this.element = element;
+        this.clientId = clientId;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.java
new file mode 100644
index 0000000..8244d10
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.java
@@ -0,0 +1,152 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.internal.beaneditor.BeanModelUtils;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+
+/**
+ * Used to display the properties of a bean, using an underlying {@link BeanModel}. The output is a series of
+ * &lt;div&gt; elements for the property names and property values.   Only properties that have a known data type are
+ * displayed.
+ *
+ * @see org.apache.tapestry.beaneditor.DataType
+ * @see BeanModel
+ */
+@SupportsInformalParameters
+public class BeanDisplay
+{
+
+    /**
+     * The object to be rendered; if not explicitly bound, a default binding to a property whose name matches this
+     * component's id will be used.
+     */
+    @Parameter(required = true)
+    @Property(write = false)
+    private Object object;
+
+    /**
+     * If true, then &lt;span&gt; tags around each output property will be omitted. If false, then a span tag (to
+     * identify the id of each property as the CSS class attribute) will be included.
+     */
+    @Parameter(value = "false")
+    private boolean lean;
+
+    /**
+     * The model that identifies the parameters to be displayed, their order, and every other aspect. If not specified,
+     * a default bean model will be created from the type of the object bound to the object parameter.
+     */
+    @Parameter
+    @Property(write = false)
+    private BeanModel model;
+
+    /**
+     * A comma-separated list of property names to be retained from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * Only these properties will be retained, and the properties will also be reordered. The names are
+     * case-insensitive.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String include;
+
+    /**
+     * A comma-separated list of property names to be removed from the {@link BeanModel}. The names are
+     * case-insensitive.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String exclude;
+
+    /**
+     * A comma-separated list of property names indicating the order in which the properties should be presented. The
+     * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
+     * order.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String reorder;
+
+    /**
+     * Where to search for local overrides of property display blocks as block parameters. Further, the container of the
+     * overrides is used as the source for overridden validation messages. This is normally the component itself, but
+     * when the component is used within a BeanEditForm, it will be the BeanEditForm's block parameter that will be
+     * searched.
+     */
+    @Parameter(value = "componentResources")
+    @Property(write = false)
+    private ComponentResources overrides;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private BeanModelSource modelSource;
+
+    @Property
+    private String propertyName;
+
+    /**
+     * Defaults the object parameter to a property of the container matching the BeanEditForm's id.
+     */
+    Binding defaultObject()
+    {
+        return defaultProvider.defaultBinding("object", resources);
+    }
+
+    void setupRender()
+    {
+        if (model == null) model = modelSource.create(object.getClass(), false, overrides
+                .getContainerResources());
+
+        BeanModelUtils.modify(model, null, include, exclude, reorder);
+    }
+
+    /**
+     * Returns the property model for the current property.
+     */
+    public PropertyModel getPropertyModel()
+    {
+        return model.get(propertyName);
+    }
+
+    public String getLabelClass()
+    {
+        return generateClassValue("t-beandisplay-label");
+    }
+
+    private String generateClassValue(String className)
+    {
+        if (lean) return className;
+
+        return className + " " + getPropertyModel().getId();
+    }
+
+    public String getValueClass()
+    {
+        return generateClassValue("t-beandisplay-value");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.xdoc
new file mode 100644
index 0000000..d358e7a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanDisplay.xdoc
@@ -0,0 +1,163 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="BeanEditForm.html">BeanEditForm</a>
+                </li>
+                <li>
+                    <a href="Grid.html">Grid</a>
+                </li>
+            </ul>
+
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                Here, we'll display a User object, consisting
+                of a first name, last name and age. We'll also customize the output of the last name property, to
+                display the name in all upper-case. The result:
+            </p>
+
+            <p>
+                <img src="beandisplay_ref.png"/>
+            </p>
+
+            <subsection name="User.java">
+                <source><![CDATA[
+public class User
+{
+    private long _id;
+    
+    private String _firstName;
+
+    private String _lastName;
+
+    private int _age;
+
+    public long getId() { return _id; }
+
+    @NonVisual
+    public void setId(long id) { _id = id; }
+
+    public String getFirstName() { return _firstName; }
+
+    public void setFirstName(String firstName) { _firstName = firstName; }
+
+    public String getLastName() { return _lastName; }
+
+    public void setLastName(String lastName) { _lastName = lastName; }
+
+    public int getAge() { return _age; }
+
+    public void setAge(int age) { _age = age; }
+}]]></source>
+
+                <p>The @NonVisual annotation prevents the id property from being displayed.</p>
+
+            </subsection>
+
+            <subsection name="ViewUser.java">
+                <source><![CDATA[
+public class ViewUser
+{
+    @Persist
+    private User _user;
+
+    public User getUser()
+    {
+        return _user;
+    }
+
+    public void setUser(User user)
+    {
+        _user = user;
+    }
+}]]></source>
+
+                <p>
+                    Presumably, some other page is obtaining the User instance and invoking the setUser() method.
+                </p>
+
+            </subsection>
+
+
+            <subsection name="ViewUser.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>View User</h1>
+
+        <t:beandisplay object="user">
+            <t:parameter name="lastname">
+                ${bean.lastname.toUpperCase()}
+            </t:parameter>
+        </t:beandisplay>
+    </body>
+</html>
+]]></source>
+
+                <p>
+                    The
+                    <code><![CDATA[<t:parameter>]]></code>
+                    element is an
+                    <em>override</em>
+                    for the property. The name is
+                    matched against a property of the bean.
+                </p>
+
+                <p>
+                    Here we are leveraging the ability to invoke methods as part of a property expression.
+                    We are also highlighting Tapestry's case insensitivity ("lastname" vs. "lastName").
+                </p>
+
+            </subsection>
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                You can re-order the properties using the reorder parameter:
+            </p>
+
+            <source><![CDATA[<t:beandisplay object="user" reorder="lastname,firstname"/>]]></source>
+
+            <p>
+                You can accomplish the same thing by changing the order of the
+                getter methods in the bean class.  The default order for properties is not alphabetical,
+                it is the order of the getter methods.
+            </p>
+
+
+            <p>
+                You can also remove properties with the exclude parameter, which is equivalent to the
+                @NonVisual annotation.
+            </p>
+
+            <p>
+                You might find
+                <code><![CDATA[<t:beandisplay object="this"/>]]></code>
+                useful on occasion. It will display all the properties of the current page.
+            </p>
+
+            <p>
+                As with the
+                <a href="BeanEditForm.html">BeanEditForm</a>
+                component,
+                you may override the labels displayed for the fields using
+                the page's message catalog.
+            </p>
+
+            <p>
+                Please refer to the
+                <a href="PageLink.html">PageLink</a>
+                component documentation for an alternate way to manage the _user field.
+            </p>
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
new file mode 100644
index 0000000..696e989
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
@@ -0,0 +1,182 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.internal.beaneditor.BeanModelUtils;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+
+/**
+ * A component that creates an entire form editing the properties of a particular bean. Inspired by <a
+ * href="http://www.trailsframework.org/">Trails</a> and <a href="http://beanform.sourceforge.net/">BeanForm</a> (both
+ * for Tapestry 4). Generates a simple UI for editing the properties of a JavaBean, with the flavor of UI for each
+ * property (text field, checkbox, drop down list) determined from the property type, and the order and validation for
+ * the properties determined from annotations on the property's getter and setter methods.
+ * <p/>
+ * You may add &lt;t:parameter&gt;s to the component; when the name matches (case insensitive) the name of a property,
+ * then the corresponding Block is renderered, rather than any of the built in property editor blocks. This allows you
+ * to override specific properties with your own customized UI, for cases where the default UI is insufficient, or no
+ * built-in editor type is appropriate.
+ *
+ * @see BeanModel
+ * @see BeanModelSource
+ * @see PropertyEditor
+ */
+@SupportsInformalParameters
+public class BeanEditForm implements ClientElement, FormValidationControl
+{
+    /**
+     * The text label for the submit button of the form, by default "Create/Update".
+     */
+    @Parameter(value = "message:submit-label", defaultPrefix = BindingConstants.LITERAL)
+    @Property
+    private String submitLabel;
+
+    /**
+     * The object to be edited. This will be read when the component renders and updated when the form for the component
+     * is submitted. Typically, the container will listen for a "prepare" event, in order to ensure that a non-null
+     * value is ready to be read or updated. Often, the BeanEditForm can create the object as needed (assuming a public,
+     * no arguments constructor).  The object property defaults to a property with the same name as the component id.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(required = true)
+    @Property
+    private Object object;
+
+    /**
+     * A comma-separated list of property names to be retained from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * Only these properties will be retained, and the properties will also be reordered. The names are
+     * case-insensitive.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String include;
+
+    /**
+     * A comma-separated list of property names to be removed from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * The names are case-insensitive.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String exclude;
+
+    /**
+     * A comma-separated list of property names indicating the order in which the properties should be presented. The
+     * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
+     * order.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String reorder;
+
+    /**
+     * If true, the default, then the embedded Form component will use client-side validation.
+     */
+    @Parameter
+    private boolean clientValidation = true;
+
+    /**
+     * Binding the zone parameter will cause the form submission to be handled as an Ajax request that updates the
+     * indicated zone.  Often a BeanEditForm will update the same zone that contains it.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String zone;
+
+    @Component(parameters = { "clientValidation=inherit:clientValidation", "zone=inherit:zone" })
+    private Form form;
+
+    /**
+     * The model that identifies the parameters to be edited, their order, and every other aspect. If not specified, a
+     * default bean model will be created from the type of the object bound to the object parameter.
+     */
+    @SuppressWarnings("unused")
+    @Parameter
+    @Property
+    private BeanModel model;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private BeanModelSource beanModelSource;
+
+    /**
+     * Defaults the object parameter to a property of the container matching the BeanEditForm's id.
+     */
+    Binding defaultObject()
+    {
+        return defaultProvider.defaultBinding("object", resources);
+    }
+
+
+    void onPrepareFromForm()
+    {
+        resources.triggerEvent(Form.PREPARE, null, null);
+
+        if (model == null)
+        {
+            Class beanType = resources.getBoundType("object");
+
+            model = beanModelSource.create(beanType, true, resources.getContainerResources());
+        }
+
+        BeanModelUtils.modify(model, null, include, exclude, reorder);
+    }
+
+
+    /**
+     * Returns the client id of the embedded form.
+     */
+    public String getClientId()
+    {
+        return form.getClientId();
+    }
+
+    public void clearErrors()
+    {
+        form.clearErrors();
+    }
+
+    public boolean getHasErrors()
+    {
+        return form.getHasErrors();
+    }
+
+    public boolean isValid()
+    {
+        return form.isValid();
+    }
+
+    public void recordError(Field field, String errorMessage)
+    {
+        form.recordError(field, errorMessage);
+    }
+
+    public void recordError(String errorMessage)
+    {
+        form.recordError(errorMessage);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.xdoc
new file mode 100644
index 0000000..8b211eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.xdoc
@@ -0,0 +1,316 @@
+<document>
+    <body>
+
+        <p>
+            The BeanEditForm component is a convienent wrapper around three components:
+            <a href="Form.html">Form</a>,
+            <a href="Errors.html">Errors</a>
+            and
+            <a href="BeanEditor.html">BeanEditor</a>.
+        </p>
+
+
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="BeanDisplay.html">BeanDisplay</a>
+                </li>
+                <li>
+                    <a href="Grid.html">Grid</a>
+                </li>
+            </ul>
+
+        </section>
+
+        <section name="Simple Example">
+
+            <p>
+                Using the bean editor, we can easily create a simple form for collecting information
+                from the user. In this example, we'll collect a little bit of data about a User:
+            </p>
+
+            <p>
+                <img src="beaneditform_ref_simple.png"/>
+            </p>
+
+            <p>
+                The bean to edit will be a property of the containing page.
+            </p>
+
+            <subsection name="User.java">
+                <source><![CDATA[
+public class User
+{
+    private long _id;
+
+    private String _firstName;
+
+    private String _lastName;
+
+    private int _age;
+
+    public long getId() { return _id; }
+
+    @NonVisual
+    public void setId(long id) { _id = id; }
+
+    public String getFirstName() { return _firstName; }
+
+    public void setFirstName(String firstName) { _firstName = firstName; }
+
+    public String getLastName() { return _lastName; }
+
+    public void setLastName(String lastName) { _lastName = lastName; }
+
+    public int getAge() { return _age; }
+
+    public void setAge(int age) { _age = age; }
+}]]></source>
+
+                <p>The @NonVisual annotation prevents the id from being displayed.</p>
+
+            </subsection>
+
+
+            <subsection name="CreateUser.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Create New User</h1>
+
+        <t:beaneditform t:id="user" submitlabel="message:create-user"/>
+    </body>
+</html>
+]]></source>
+
+                <p>
+                    Nominally, we should have to bind the object parameter of the BeanEditForm component. However, as
+                    a convienience, Tapestry has defaulted the object parameter
+                    based on the component id. This works because the CreateUser class
+                    includes a property named "user", which matches the BeanEditForm component's id.
+
+                </p>
+
+                <p>
+                    When the object to be editted is not a direct property of the page,
+                    it will be necessary to bind the object parameter explicitly. For example,
+                    <code>object="registration.address"</code>
+                    to create or edit the address
+                    property of the page's registration property. Component ids may not contain periods,
+                    so there's no way to specify this without the object parameter. A best practice is to still
+                    explicitly set the component's id, thus:
+                    <code><![CDATA[<t:beaneditform t:id="address" object="registration.address"/>]]></code>
+                </p>
+
+
+            </subsection>
+
+            <subsection name="CreateUser.properties">
+
+                <source><![CDATA[
+create-user=Create New User
+firstname-label=Given Name
+lastname-label=Family Name]]></source>
+
+                <p>
+                    We are using the page's message catalog to supply a messages. Externalizing such messages
+                    make them easier to work with, especially for an application that may be localized.
+                </p>
+
+                <p>
+                    The
+                    <code>create-user</code>
+                    key is explicitly referenced (<code>submitlabel="message:create-user"</code>).
+                    This becomes the label on the submit button for the generated form.
+                </p>
+
+                <p>
+                    The two label keys will be picked up and used as the labels for the corresponding properties
+                    (in both the rendered &lt;label&gt; elements, and in any error messages).
+                </p>
+
+                <p>
+                    In many cases, common entries can be moved up to an application-wide message catalog. In that case,
+                    the page's own message catalog becomes a local override.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="CreateUser.java">
+                <source><![CDATA[
+public class CreateUser
+{
+    @Persist
+    private User _user;
+
+    @Inject
+    private UserDAO _userDAO;
+
+    public User getUser()
+    {
+      return _user;
+    }
+
+    public void setUser(User user)
+    {
+      _user = user;
+    }
+
+    Object onSuccess()
+    {
+        _userDAO.add(_user);
+
+        return UserAdmin.class;
+    }
+}]]></source>
+
+
+                <p>
+                    Notice that we don't instantiate the User object ourselves; instead we let the BeanEditForm
+                    component
+                    do that for us. It's capable of doing so because the User class has a default public no arguments
+                    constructor.
+                </p>
+
+                <p>
+                    The onSuccess() method is invoked when the form is submitted with no validation errors (although
+                    client validation is enabled by default, server-side validation is
+                    <em>always</em>
+                    enforced).
+                    The UserDAO service is used to add the new user.
+                </p>
+
+                <p>
+                    Returning a class from an event handler method (<code>UserAdmin.class</code>) will
+                    activate the indicated page as the response page. As always, a redirect to to the response page is
+                    sent to the client.
+                </p>
+
+            </subsection>
+
+        </section>
+
+        <section name="Validations and Overrides">
+
+            <p>
+                By placing some annotations on the properties of the User class, we can enable client-side
+                validations. In addition, we can override the default editor components for a property
+                to add some additional instructions.
+            </p>
+
+            <subsection name="User.java (partial)">
+
+                <source><![CDATA[
+    @Validate("required")
+    public String getFirstName() { return _firstName; }
+
+    public void setFirstName(String firstName) { _firstName = firstName; }
+
+    @Validate("required")
+    public String getLastName() { return _lastName; }
+
+    public void setLastName(String lastName) { _lastName = lastName; }
+
+    @Validate("min=18,max=99")
+    public int getAge() { return _age; }
+
+    public void setAge(int age) { _age = age; }]]>    </source>
+
+                <p>
+                    The new @Validate annotations added to the first name and last name properties indicates that a
+                    non-blank
+                    value must be provided. For the age property we are setting minimum and maximum values as well.
+                </p>
+
+                <p>
+                    Validation for each field occurs when the form is submitted, and when the user tabs out of a field.
+                    If you submit
+                    immediately, Tapestry will display popup bubbles for each field identifying the error:
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_validation1.png"/>
+                </p>
+
+                <p>
+                    In addition, fields with errors are marked with a red X, the font for the first turns red, and the
+                    label
+                    for the field turns red. We're providing a lot of feedback to the user.
+                    After a moment, all the bubbles except for the current field fade. Bubbles fade in and out as you
+                    tab from field to field.
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_validation2.png"/>
+                </p>
+
+
+            </subsection>
+
+
+            <subsection name="CreateUser.tml (partial)">
+
+                <p>
+                    We can customize how individual properties are editted. Here we'll
+                    add a small reminder next to the age property:
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_customized.png"/>
+                </p>
+
+                <source><![CDATA[
+        <t:beaneditform t:id="user" submitlabel="message:create-user">
+            <t:parameter name="age">
+                <t:label for="age"/>
+                <t:textfield t:id="age" value="user.age"/>
+                <em>
+                    Users must be between 18 and 99.
+                </em>
+            </t:parameter>
+        </t:beaneditform>]]></source>
+
+                <p>
+                    The
+                    <code><![CDATA[<t:parameter>]]></code>
+                    element
+                    is an
+                    <em>override</em>
+                    for the property. The name is
+                    matched against a property of the bean. We need to provide a
+                    <a href="Label.html">Label</a>
+                    component, and an appropriate
+                    editor component.
+                </p>
+
+            </subsection>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                You can re-order the properties using the reorder parameter:
+            </p>
+
+            <source><![CDATA[<t:beaneditform t:id="user" reorder="lastname,firstname"/>]]></source>
+
+            <p>
+                You can accomplish the same thing by changing the order of the
+                getter methods in the bean class.  The default order for properties is not alphabetical,
+                it is the order of the getter methods.
+            </p>
+
+            <p>
+                You can also remove properties with the exclude parameter, which is equivalent to the
+                @NonVisual annotation.
+            </p>
+
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.java
new file mode 100644
index 0000000..c44fe7c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.java
@@ -0,0 +1,176 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.corelib.internal.InternalMessages;
+import org.apache.tapestry.internal.beaneditor.BeanModelUtils;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * A component that generates a user interface for editing the properties of a bean. This is the central component of
+ * the {@link BeanEditForm}, and utilizes a {@link PropertyEditor} for much of its functionality.
+ */
+@SupportsInformalParameters
+public class BeanEditor
+{
+    public static class Prepare implements ComponentAction<BeanEditor>
+    {
+        private static final long serialVersionUID = 6273600092955522585L;
+
+        public void execute(BeanEditor component)
+        {
+            component.doPrepare();
+        }
+    }
+
+    /**
+     * The object to be edited by the BeanEditor. This will be read when the component renders and updated when the form
+     * for the component is submitted. Typically, the container will listen for a "prepare" event, in order to ensure
+     * that a non-null value is ready to be read or updated.
+     */
+    @Parameter
+    private Object object;
+
+    /**
+     * A comma-separated list of property names to be retained from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * Only these properties will be retained, and the properties will also be reordered. The names are
+     * case-insensitive.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String include;
+
+    /**
+     * A comma-separated list of property names to be removed from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * The names are case-insensitive.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String exclude;
+
+    /**
+     * A comma-separated list of property names indicating the order in which the properties should be presented. The
+     * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
+     * order.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String reorder;
+
+    /**
+     * The model that identifies the parameters to be edited, their order, and every other aspect. If not specified, a
+     * default bean model will be created from the type of the object bound to the object parameter.
+     */
+    @Parameter
+    @Property(write = false)
+    private BeanModel model;
+
+    /**
+     * Where to search for local overrides of property editing blocks as block parameters. Further, the container of the
+     * overrides is used as the source for overridden validation messages. This is normally the BeanEditor component
+     * itself, but when the component is used within a BeanEditForm, it will be the BeanEditForm's resources that will
+     * be searched.
+     */
+    @Parameter(value = "componentResources")
+    @Property(write = false)
+    private ComponentResources overrides;
+
+    @Inject
+    private BeanModelSource modelSource;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    // Value that change with each change to the current property:
+
+    @Property
+    private String propertyName;
+
+    /**
+     * Defaults the object parameter to a property of the container matching the BeanEditForm's id.
+     */
+    Binding defaultObject()
+    {
+        return defaultProvider.defaultBinding("object", resources);
+    }
+
+    // Needed for testing as well
+
+    public Object getObject()
+    {
+        return object;
+    }
+
+    void setupRender()
+    {
+        formSupport.storeAndExecute(this, new Prepare());
+    }
+
+    void doPrepare()
+    {
+        if (model == null)
+        {
+            Class type = resources.getBoundType("object");
+            model = modelSource.create(type, true, overrides.getContainerResources());
+        }
+
+        BeanModelUtils.modify(model, null, include, exclude, reorder);
+
+        // The only problem here is that if the bound property is backed by a persistent field, it
+        // is assigned (and stored to the session, and propagated around the cluster) first,
+        // before values are assigned.
+
+        if (object == null)
+        {
+            try
+            {
+                object = model.newInstance();
+            }
+            catch (Exception ex)
+            {
+                String message = InternalMessages.failureInstantiatingObject(model.getBeanType(),
+                                                                             resources.getCompleteId(),
+                                                                             ex);
+                throw new TapestryException(message, resources.getLocation(), ex);
+            }
+        }
+
+    }
+
+    // For testing
+    void inject(ComponentResources resources, ComponentResources overrides, BeanModelSource source)
+    {
+        this.resources = resources;
+        this.overrides = overrides;
+        modelSource = source;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc
new file mode 100644
index 0000000..522580c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc
@@ -0,0 +1,11 @@
+<document>
+    <body>
+        <p>See the
+            <a href="BeanEditForm.html">BeanEditForm</a>
+            documentation for examples of how to use and customize this component. A further
+            example is available in the documentation for the
+            <a href="FormFragment.html">FormFragment</a>
+            component.
+        </p>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
new file mode 100644
index 0000000..68f280b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
@@ -0,0 +1,95 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationTracker;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.Request;
+
+/**
+ * A Checkbox component is simply a &lt;input type="checkbox"&gt;.
+ */
+public class Checkbox extends AbstractField
+{
+    /**
+     * The value to be read or updated. If not bound, the Checkbox will attempt to edit a property of its container
+     * whose name matches the component's id.
+     */
+    @Parameter(required = true)
+    private boolean value;
+
+    @Inject
+    private Request request;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    Binding defaultValue()
+    {
+        return createDefaultParameterBinding("value");
+    }
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        String asSubmitted = tracker.getInput(this);
+
+        boolean checked = asSubmitted != null ? Boolean.parseBoolean(asSubmitted) : value;
+
+        writer.element("input", "type", "checkbox",
+
+                       "name", getControlName(),
+
+                       "id", getClientId(),
+
+                       "checked", checked ? "checked" : null);
+
+        resources.renderInformalParameters(writer);
+
+        decorateInsideField();
+    }
+
+    @AfterRender
+    void after(MarkupWriter writer)
+    {
+        writer.end(); // input
+    }
+
+    @Override
+    protected void processSubmission(String elementName)
+    {
+        String postedValue = request.getParameter(elementName);
+
+        // record as "true" or "false"
+
+        tracker.recordInput(this, Boolean.toString(postedValue != null));
+
+        value = postedValue != null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.xdoc
new file mode 100644
index 0000000..1b6e814
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.xdoc
@@ -0,0 +1,91 @@
+<document>
+    <body>
+        <section name="Examples">
+
+
+            <p>
+                In this example, a Checkbox will be used alone to manipulate a property of the page.
+            </p>
+
+            <subsection name="ViewAccounts.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>View Accounts</h1>
+
+        <t:form>
+            <t:checkbox t:id="showall" onclick="this.form.submit();"/> <t:label for="showall"/>
+        </t:form>
+
+        <t:grid t:id="accounts"/>
+
+    </body>
+</html>
+]]></source>
+
+                <p>
+                    The Grid component will do most of the work in terms of displaying the account data.
+                </p>
+
+                <p>
+                    Normally, we should bind the value parameter explicitly; here the component's id, "showAll",
+                    matches against a property of the page and the value parameter is automatically bound
+                    as a convienience.
+                </p>
+
+                <p>
+                    A small amount of JavaScript is provided in-line to submit the form when the checkbox is clicked.
+                </p>
+
+                <p>
+                    All Tapestry form control element components must be enclosed by a Form component.
+                </p>
+
+                <p>
+                    The Label component is responsible for rendering a &lt;label&gt; element connected to the checkbox.
+                    This
+                    is good for accessibility, it also provides a larger "target" to click on.
+                    The label's text will be "Show All", derived from the property name. Using a Label component is
+                    optional
+                    but recommended.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="ViewAccounts.java">
+
+                <source><![CDATA[
+public class ViewAccount
+{
+    @Persist
+    private boolean _showAll;
+
+    @Inject
+    private AccountDAO _accountDAO;
+
+    public boolean isShowAll() { return _showAll; }
+
+    public void setShowAll(boolean showAll) { _showAll = showAll; }
+
+    public List<Account> getAccounts()
+    {
+        return _showAll ? _accountDAO.getAllAccounts() : _accountDAO.getActiveAccounts();
+    }
+}]]></source>
+
+                <p>
+                    The component updates the _showAll field, and that's used to determine which
+                    set of accounts should be provided to the Grid component. As always in Tapestry, you
+                    must be careful to mark fields persistent if they need to hold their value between
+                    the action request (the form submission) and the render request.
+                </p>
+
+
+            </subsection>
+
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
new file mode 100644
index 0000000..c50546b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
@@ -0,0 +1,233 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.IncludeJavaScriptLibrary;
+import org.apache.tapestry.annotation.IncludeStylesheet;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.FieldValidatorDefaultSource;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry5.json.JSONObject;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A component used to collect a provided date from the user using a client-side JavaScript calendar. Non-JavaScript
+ * clients can simply type into a text field..
+ */
+// TODO: More testing; see https://issues.apache.org/jira/browse/TAPESTRY-1844
+@IncludeStylesheet("${tapestry.datepicker}/css/datepicker.css")
+@IncludeJavaScriptLibrary({ "${tapestry.datepicker}/js/datepicker.js", "datefield.js" })
+public class DateField extends AbstractField
+{
+    /**
+     * The value parameter of a DateField must be a {@link Date}.
+     */
+    @Parameter(required = true, principal = true)
+    private Date value;
+
+    /**
+     * The object that will perform input validation (which occurs after translation). The translate binding prefix is
+     * generally used to provide this object in a declarative fashion.
+     */
+    @Parameter(defaultPrefix = "validate")
+    @SuppressWarnings("unchecked")
+    private FieldValidator<Object> validate = NOOP_VALIDATOR;
+
+    @Parameter(defaultPrefix = BindingConstants.ASSET, value = "datefield.gif")
+    private Asset icon;
+
+    @Environmental
+    private RenderSupport support;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private Messages messages;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private Locale locale;
+
+    @Inject
+    private FieldValidatorDefaultSource fieldValidatorDefaultSource;
+
+    @Inject
+    private FieldValidationSupport fieldValidationSupport;
+
+    /**
+     * For output, format nicely and unambiguously as four digits.
+     */
+    private final DateFormat outputFormat = new SimpleDateFormat("MM/dd/yyyy");
+
+    /**
+     * When the user types a value, they may only type two digits for the year; SimpleDateFormat will do something
+     * reasonable.  If they use the popup, it will be unambiguously 4 digits.
+     */
+    private final DateFormat inputFormat = new SimpleDateFormat("MM/dd/yy");
+
+    /**
+     * The default value is a property of the container whose name matches the component's id. May return null if the
+     * container does not have a matching property.
+     */
+    final Binding defaultValue()
+    {
+        return createDefaultParameterBinding("value");
+    }
+
+    /**
+     * Computes a default value for the "validate" parameter using {@link FieldValidatorDefaultSource}.
+     */
+    final FieldValidator defaultValidate()
+    {
+
+        return fieldValidatorDefaultSource.createDefaultValidator(this, resources.getId(),
+                                                                  resources.getContainerMessages(), locale,
+                                                                  Date.class,
+                                                                  resources.getAnnotationProvider("value"));
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        String value = tracker.getInput(this);
+
+        if (value == null) value = formatCurrentValue();
+
+        String clientId = getClientId();
+        String triggerId = clientId + ":trigger";
+
+        writer.element("input",
+
+                       "type", "text",
+
+                       "name", getControlName(),
+
+                       "id", clientId,
+
+                       "value", value);
+
+        writeDisabled(writer);
+
+        validate.render(writer);
+
+        resources.renderInformalParameters(writer);
+
+        decorateInsideField();
+
+        writer.end();
+
+        // Now the trigger icon.
+
+        writer.element("img",
+
+                       "id", triggerId,
+
+                       "class", "t-calendar-trigger",
+
+                       "src", icon.toClientURL(),
+
+                       "alt", "[Show]");
+        writer.end(); // img
+
+        // The setup parameters passed to Calendar.setup():
+
+        JSONObject setup = new JSONObject();
+
+        setup.put("field", clientId);
+
+        // TODO: consolodate DatePicker initialization across the page.
+
+        support.addScript("new Tapestry.DateField(%s);", setup);
+    }
+
+    private void writeDisabled(MarkupWriter writer)
+    {
+        if (isDisabled()) writer.attributes("disabled", "disabled");
+    }
+
+
+    private String formatCurrentValue()
+    {
+        if (value == null) return "";
+
+        return outputFormat.format(value);
+    }
+
+    @Override
+    protected void processSubmission(String elementName)
+    {
+        String value = request.getParameter(elementName);
+
+        tracker.recordInput(this, value);
+
+        Date parsedValue = null;
+
+        try
+        {
+            if (InternalUtils.isNonBlank(value))
+                parsedValue =
+                        inputFormat.parse(value);
+
+        }
+        catch (ParseException ex)
+        {
+            tracker.recordError(this, "Date value is not parseable.");
+            return;
+        }
+
+        try
+        {
+            fieldValidationSupport.validate(parsedValue, resources, validate);
+
+            this.value = parsedValue;
+        }
+        catch (ValidationException ex)
+        {
+            tracker.recordError(this, ex.getMessage());
+        }
+    }
+
+    void injectResources(ComponentResources resources)
+    {
+        this.resources = resources;
+    }
+
+    void injectMessages(Messages messages)
+    {
+        this.messages = messages;
+    }
+
+    @Override
+    public boolean isRequired()
+    {
+        return validate.isRequired();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.xdoc
new file mode 100644
index 0000000..a0341c7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.xdoc
@@ -0,0 +1,68 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="TextField.html">TextField</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+            <p>
+                The DateField component is very easy to use, all the JavaScript is generated for you. Then end result
+                looks like:
+            </p>
+
+            <p>
+                <img src="datefield_ref1.png"/>
+            </p>
+
+            <p>
+                Clicking the icon raises the popup calendar:
+            </p>
+
+            <p>
+                <img src="datefield_ref2.png"/>
+            </p>
+
+            <subsection name="DateFieldDemo.tml">
+                <source><![CDATA[<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <t:form>
+            <div class="t-beaneditor">
+                <div class="t-beaneditrow">
+                    <t:label for="date"/>
+                    <t:datefield t:id="date"/>
+                </div>
+                <div class="t-beaneditrow">
+                    <input type="submit" value="Update"/>
+                </div>
+            </div>
+        </t:form>
+    </body>
+</html>]]></source>
+            </subsection>
+
+            <p>
+                The use of the extra &lt;div&gt; elements is to trigger the CSS styles that are
+                usually used as part of a<a href="BeanEditForm.html">BeanEditForm</a>. Just the
+                <code><![CDATA[<t:datefield>]]></code>
+                element is all that's really necessary.
+            </p>
+        </section>
+
+        <section name="Notes">
+
+            <p>The DateField component is based on the open source
+                <a href="http://webfx.eae.net/dhtml/datepicker/usage.html">WebFX DatePicker</a>
+                widget.
+            </p>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.java
new file mode 100644
index 0000000..1f5b84b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.java
@@ -0,0 +1,37 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * A component that does not do any rendering of its own, but will delegate to some other object that can do rendering.
+ * This other object may be a component or a {@link Block} (among other things).
+ */
+public class Delegate
+{
+    /**
+     * The object which will be rendered in place of the Delegate component. This is typically a specific component
+     * instance, or a {@link Block}.
+     */
+    @Parameter(required = true)
+    private Object to;
+
+    Object beginRender()
+    {
+        return to;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.xdoc
new file mode 100644
index 0000000..0baa02d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Delegate.xdoc
@@ -0,0 +1,111 @@
+<document>
+    <body>
+
+        <section name="Examples">
+
+            <p>
+                The Delegate component allows us to be very flexible in how and what gets rendered, and
+                in what order. In some cases, the object to be rendered may come from an entirely
+                different page.
+            </p>
+
+            <p>
+                This example is simpler, and could easily be accomplished using an If component. We'll create
+                a page that can be used for viewing or editting an object.
+            </p>
+
+            <subsection name="ViewAccount.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>View Account</h1>
+
+        <t:delegate to="activeBlock"/>
+
+        <t:block id="view">
+            <t:beandisplay object="account"/>
+
+            <p><t:actionlink t:id="edit">Edit this account</t:actionlink></p>
+        </t:block>
+
+        <t:block id="edit">
+            <t:beaneditform t:id="account"/>
+        </t:block>
+    </body>
+</html>]]></source>
+
+                <p>
+                    So we end up with a display of the Account's properties, and a link to activate edit mode.
+                    In edit mode, we use the other block and show a BeanEditForm.
+                </p>
+
+            </subsection>
+
+            <subsection name="ViewAccount.java">
+                <source><![CDATA[
+public class ViewAccount
+{
+    @Persist
+    private Account _account;
+
+    @Persist
+    private boolean _editMode;
+
+    @Inject
+    private Block _view;
+
+    @Inject
+    private Block _edit;
+
+    @Inject
+    private AccountDAO _accountDAO;
+
+    public Account getAccount()
+    {
+        return _account;
+    }
+
+    public void setAccount(Account account)
+    {
+        _account = account;
+        _editMode = false;
+    }
+
+    void onSuccess()
+    {
+         _accountDAO.update(_account);
+
+        _editMode = false;
+    }
+
+    void onActionFromEdit()
+    {
+        _editMode = true;
+    }
+
+    public Object getActiveBlock()
+    {
+        return _editMode ? _edit : _view;
+    }
+}]]></source>
+
+                <p>
+                    The use of the @Inject annotation on a field of type Block is used to access a
+                    <code><![CDATA[<t:block>]]></code>
+                    element from the template. The field name,
+                    stripped of leading underscores, is matched against the block's id.
+                </p>
+
+                <p>
+                    The rest is concerned with handling the form submission, turning on edit mode,
+                    and determining which block will be the one to render.
+                </p>
+
+
+            </subsection>
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java
new file mode 100644
index 0000000..0be77c1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java
@@ -0,0 +1,89 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.CSSClassConstants;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationTracker;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.internal.InternalMessages;
+import org.apache.tapestry.services.FormSupport;
+
+import java.util.List;
+
+/**
+ * Standard validation error presenter. Must be enclosed by a {@link org.apache.tapestry.corelib.components.Form}
+ * component. If errors are present, renders a div element around a banner message and around an unnumbered list of
+ * error messages. Renders nothing if the {@link org.apache.tapestry.ValidationTracker} shows no errors.
+ */
+public class Errors
+{
+    /**
+     * The banner message displayed above the errors. The default value is "You must correct the following errors before
+     * you may continue.".
+     */
+    @Parameter("message:default-banner")
+    private String banner;
+
+    /**
+     * The CSS class for the div element rendered by the component. The default value is "t-error".
+     */
+    @Parameter(name = "class")
+    private String className = CSSClassConstants.ERROR;
+
+    // Allow null so we can generate a better error message if missing
+    @Environmental(false)
+    private ValidationTracker tracker;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (tracker == null) throw new RuntimeException(InternalMessages.encloseErrorsInForm());
+
+        if (!tracker.getHasErrors()) return;
+
+        writer.element("div", "class", className);
+
+        // Inner div for the banner text
+        writer.element("div");
+        writer.write(banner);
+        writer.end();
+
+        List<String> errors = tracker.getErrors();
+
+        if (!errors.isEmpty())
+        {
+            // Only write out the <UL> if it will contain <LI> elements. An empty <UL> is not
+            // valid XHTML.
+
+            writer.element("ul");
+
+            for (String message : errors)
+            {
+                writer.element("li");
+                writer.write(message);
+                writer.end();
+            }
+
+            writer.end(); // ul
+        }
+
+        writer.end(); // div
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.xdoc
new file mode 100644
index 0000000..bc6a0eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.xdoc
@@ -0,0 +1,39 @@
+<document>
+    <body>
+        <section name="Examples">
+
+            <p>
+                The Errors component automatically connects with the Form that encloses it. Just place the
+                component inside a Form.
+            </p>
+
+            <subsection name="Search.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+
+    <t:form>
+
+        <t:errors>
+
+        <t:label for="search"/>
+        <t:textfield t:id="search"/>
+
+        <input type="submit" value="Search"/>
+
+    </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    The Errors component here will display any validation errors that occur when the form is submitted.
+                </p>
+
+            </subsection>
+
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.java
new file mode 100644
index 0000000..dee048a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.java
@@ -0,0 +1,58 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.base.AbstractComponentEventLink;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * A close relative of {@link org.apache.tapestry.corelib.components.ActionLink} except in two ways.
+ * <p/>
+ * First, the event that it triggers is explicitly controlled, rather than always "action".
+ * <p/>
+ * Second, the event is triggered in its container.
+ * <p/>
+ * This allows slightly shorter URLs but also allows multiple components within the same container to generate identical
+ * URLs for common actions.
+ */
+public class EventLink extends AbstractComponentEventLink
+{
+    /**
+     * The name of the event to be triggered in the parent component. Defaults to the id of the component. An {@link
+     * org.apache.tapestry.corelib.components.ActionLink} triggers an "action" event on itself, and EventLink component
+     * triggers any arbitrary event on <em>its container</em>.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String event;
+
+    @Inject
+    private ComponentResources resources;
+
+    String defaultEvent()
+    {
+        return resources.getId();
+    }
+
+    protected Link createLink(Object[] eventContext)
+    {
+        ComponentResources containerResources = resources.getContainerResources();
+
+        return containerResources.createActionLink(event, false, eventContext);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.xdoc
new file mode 100644
index 0000000..8895a77
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/EventLink.xdoc
@@ -0,0 +1,81 @@
+<document>
+    <body>
+        <section name="Examples">
+
+            <p>
+                This example is from Tapestry itself, from the GridColumns component that displays the columns
+                titles across to the top of a Grid. We've simplified the example somewhat to focus in on
+                the use of the EventLink component.
+            </p>
+
+            <subsection name="GridColumns.tml">
+                <source><![CDATA[
+<thead xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <tr>
+        <th t:type="Loop" source="columnNames" value="columnName">
+            <a t:id="sort">${columnModel.label}</a>
+            <a t:id="sort2">
+                <img src="${icon}" id="${columnModel.id}:sort" class="t-sort-icon" alt="${iconLabel}"/>
+            </a>
+        </th>
+    </tr>
+</thead>]]></source>
+
+            </subsection>
+
+            <subsection name="GridColumns.java (partial)">
+                <source><![CDATA[
+public class GridColumns
+{
+    . . .
+
+    @Component(parameters = {"event=sort", "context=columnModel.id"})
+    private EventLink _sort, _sort2;
+
+    void onSort(String columnId)
+    {
+        if (columnId.equals(_sortColumnId))
+        {
+            _sortAscending = !_sortAscending;
+        }
+        else
+        {
+            _sortColumnId = columnId;
+            _sortAscending = true;
+        }
+    }
+
+}]]></source>
+
+                <p>
+                    The advantage of the EventLink component is that instead of having two identical event handler
+                    methods,
+                    onActionFromSort() and onActionFromSort2(), we have a single event handler method,
+                    onSort(), that covers events triggered by either component. In addition, the URLs for the two
+                    components
+                    will be identical, whereas if using ActionLink components, the URLs would be slightly different, to
+                    reflect to two different component ids.
+                </p>
+
+                <p>
+                    This example also shows the advantages of defining the component in the Java class,
+                    using the
+                    @Component annotation, rather than in the template (as we do in most examples). We can
+                    simply define two fields with the same configuration.
+                </p>
+
+
+            </subsection>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                The event parameter is often omitted; it defaults to the component's id ... you will often specify
+                the component id, or a specific event name, but not both.
+            </p>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ExceptionDisplay.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ExceptionDisplay.java
new file mode 100644
index 0000000..0f14f81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ExceptionDisplay.java
@@ -0,0 +1,86 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.services.ExceptionAnalysis;
+import org.apache.tapestry.ioc.services.ExceptionAnalyzer;
+import org.apache.tapestry.ioc.services.ExceptionInfo;
+
+import java.util.List;
+
+/**
+ * Integral part of the default {@link org.apache.tapestry.corelib.pages.ExceptionReport} page used to break apart and
+ * display the properties of the exception.
+ *
+ * @see org.apache.tapestry.ioc.services.ExceptionAnalyzer
+ */
+public class ExceptionDisplay
+{
+    /**
+     * Exception to report.
+     */
+    @Parameter(required = true)
+    private Throwable exception;
+
+    @Inject
+    private ExceptionAnalyzer analyzer;
+
+    @Inject
+    @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
+    private String appPackage;
+
+    @Property
+    private ExceptionInfo info;
+
+    @Property
+    private String propertyName;
+
+    @Property
+    private StackTraceElement frame;
+
+    @Property
+    private List<ExceptionInfo> stack;
+
+    void setupRender()
+    {
+        ExceptionAnalysis analysis = analyzer.analyze(exception);
+
+        stack = analysis.getExceptionInfos();
+    }
+
+    public boolean getShowPropertyList()
+    {
+        // True if either is non-empty
+
+        return !(info.getPropertyNames().isEmpty() && info.getStackTrace().isEmpty());
+    }
+
+    public Object getPropertyValue()
+    {
+        return info.getProperty(propertyName);
+    }
+
+    public String getFrameClass()
+    {
+        if (frame.getClassName().startsWith(appPackage) && frame.getLineNumber() > 0) return "t-usercode-frame";
+
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
new file mode 100644
index 0000000..96b64ac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
@@ -0,0 +1,474 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.corelib.internal.FormSupportImpl;
+import org.apache.tapestry.corelib.mixins.RenderInformals;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.ComponentResultProcessorWrapper;
+import org.apache.tapestry.internal.services.HeartbeatImpl;
+import org.apache.tapestry.internal.util.Base64ObjectInputStream;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.*;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.List;
+
+/**
+ * An HTML form, which will enclose other components to render out the various types of fields.
+ * <p/>
+ * A Form emits many notification events. When it renders, it fires a {@link #PREPARE_FOR_RENDER} notification, followed
+ * by a {@link #PREPARE} notification.
+ * <p/>
+ * When the form is submitted, the component emits several notifications: first a {@link #PREPARE_FOR_SUBMIT}, then a
+ * {@link #PREPARE}: these allow the page to update its state as necessary to prepare for the form submission, then
+ * (after components enclosed by the form have operated), a {@link #VALIDATE_FORM}event is emitted, to allow for
+ * cross-form validation. After that, either a {@link #SUCCESS} OR {@link #FAILURE} event (depending on whether the
+ * {@link ValidationTracker} has recorded any errors). Lastly, a {@link #SUBMIT} event, for any listeners that care only
+ * about form submission, regardless of success or failure.
+ * <p/>
+ * For all of these notifications, the event context is derived from the <strong>context</strong> parameter. This
+ * context is encoded into the form's action URI (the parameter is not read when the form is submitted, instead the
+ * values encoded into the form are used).
+ */
+public class Form implements ClientElement, FormValidationControl
+{
+    /**
+     * Invoked before {@link #PREPARE} when rendering out the form.
+     */
+    public static final String PREPARE_FOR_RENDER = "prepareForRender";
+
+    /**
+     * Invoked before {@link #PREPARE} when the form is submitted.
+     */
+    public static final String PREPARE_FOR_SUBMIT = "prepareForSubmit";
+
+    /**
+     * Invoked to let the containing component(s) prepare for the form rendering or the form submission.
+     */
+    public static final String PREPARE = "prepare";
+
+    /**
+     * Event type for a notification after the form has submitted. This event notification occurs on any form submit,
+     * without respect to "success" or "failure".
+     */
+    public static final String SUBMIT = "submit";
+
+    /**
+     * Event type for a notification to perform validation of submitted data. This allows a listener to perform
+     * cross-field validation. This occurs before the {@link #SUCCESS} or {@link #FAILURE} notification.
+     */
+    public static final String VALIDATE_FORM = "validateForm";
+
+    /**
+     * Event type for a notification after the form has submitted, when there are no errors in the validation tracker.
+     * This occurs before the {@link #SUBMIT} event.
+     */
+    public static final String SUCCESS = "success";
+
+    /**
+     * Event type for a notification after the form has been submitted, when there are errors in the validation tracker.
+     * This occurs before the {@link #SUBMIT} event.
+     */
+    public static final String FAILURE = "failure";
+
+    /**
+     * Query parameter name storing form data (the serialized commands needed to process a form submission).
+     */
+    public static final String FORM_DATA = "t:formdata";
+
+    /**
+     * The context for the link (optional parameter). This list of values will be converted into strings and included in
+     * the URI. The strings will be coerced back to whatever their values are and made available to event handler
+     * methods.
+     */
+    @Parameter
+    private List<?> context;
+
+    /**
+     * The object which will record user input and validation errors. The object must be persistent between requests
+     * (since the form submission and validation occurs in an component event request and the subsequent render occurs
+     * in a render request). The default is a persistent property of the Form component and this is sufficient for
+     * nearly all purposes (except when a Form is rendered inside a loop).
+     */
+    @Parameter("defaultTracker")
+    private ValidationTracker tracker;
+
+    /**
+     * If true (the default) then client validation is enabled for the form, and the default set of JavaScript libraries
+     * (Prototype, Scriptaculous and the Tapestry library) will be added to the rendered page, and the form will
+     * register itself for validation. This may be turned off when client validation is not desired; for example, when
+     * many validations are used that do not operate on the client side at all.
+     */
+    @Parameter("true")
+    private boolean clientValidation;
+
+    /**
+     * Binding the zone parameter will cause the form submission to be handled as an Ajax request that updates the
+     * indicated zone.  Often a Form will update the same zone that contains it.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String zone;
+
+    @Inject
+    private Environment environment;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private ComponentSource source;
+
+    @Persist(PersistenceConstants.FLASH)
+    private ValidationTracker defaultTracker;
+
+    @Inject
+    private ComponentInvocationMap componentInvocationMap;
+
+    private FormSupportImpl formSupport;
+
+    private Element form;
+
+    private Element div;
+
+    // Collects a stream of component actions. Each action goes in as a UTF string (the component
+    // component id), followed by a ComponentAction
+
+    private Base64ObjectOutputStream actions;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderInformals renderInformals;
+
+    /**
+     * Set up via the traditional or Ajax component event request handler
+     */
+    @Environmental
+    private ComponentEventResultProcessor componentEventResultProcessor;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    private String name;
+
+    public ValidationTracker getDefaultTracker()
+    {
+        if (defaultTracker == null) defaultTracker = new ValidationTrackerImpl();
+
+        return defaultTracker;
+    }
+
+    public void setDefaultTracker(ValidationTracker defaultTracker)
+    {
+        this.defaultTracker = defaultTracker;
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+
+        try
+        {
+            actions = new Base64ObjectOutputStream();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        name = renderSupport.allocateClientId(resources);
+
+        formSupport = new FormSupportImpl(name, actions, clientBehaviorSupport, clientValidation);
+
+        if (zone != null) clientBehaviorSupport.linkZone(name, zone);
+
+        // TODO: Forms should not allow to nest. Perhaps a set() method instead of a push() method
+        // for this kind of check?  
+
+        environment.push(FormSupport.class, formSupport);
+        environment.push(ValidationTracker.class, tracker);
+
+        // Now that the environment is setup, inform the component or other listeners that the form
+        // is about to render.  
+
+        Object[] contextArray = context == null ? new Object[0] : context.toArray();
+
+        resources.triggerEvent(PREPARE_FOR_RENDER, contextArray, null);
+
+        resources.triggerEvent(PREPARE, contextArray, null);
+
+        Link link = resources.createActionLink(EventConstants.ACTION, true, contextArray);
+
+        // Save the form element for later, in case we want to write an encoding type attribute.
+
+        form = writer
+                .element("form", "name", name, "id", name, "method", "post", "action", link);
+
+        componentInvocationMap.store(form, link);
+
+        resources.renderInformalParameters(writer);
+
+        div = writer.element("div", "class", CSSClassConstants.INVISIBLE);
+
+        for (String parameterName : link.getParameterNames())
+        {
+            String value = link.getParameterValue(parameterName);
+
+            writer.element("input", "type", "hidden", "name", parameterName, "value", value);
+            writer.end();
+        }
+
+        writer.end(); // div
+
+        environment.peek(Heartbeat.class).begin();
+
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        environment.peek(Heartbeat.class).end();
+
+        formSupport.executeDeferred();
+
+        String encodingType = formSupport.getEncodingType();
+
+        if (encodingType != null) form.forceAttributes("enctype", encodingType);
+
+        writer.end(); // form
+
+        // Now, inject into the div the remaining hidden field (the list of actions).
+
+        try
+        {
+            actions.close();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        div.element("input",
+
+                    "type", "hidden",
+
+                    "name", FORM_DATA,
+
+                    "value", actions.toBase64());
+    }
+
+    void cleanupRender()
+    {
+        environment.pop(FormSupport.class);
+
+        formSupport = null;
+
+        // This forces a change to the tracker, which is nice because its internal state has
+        // changed.
+        tracker = environment.pop(ValidationTracker.class);
+    }
+
+    @SuppressWarnings({ "unchecked", "InfiniteLoopStatement" })
+    Object onAction(EventContext context) throws IOException
+    {
+        tracker.clear();
+
+        formSupport = new FormSupportImpl();
+
+        environment.push(ValidationTracker.class, tracker);
+        environment.push(FormSupport.class, formSupport);
+
+        Heartbeat heartbeat = new HeartbeatImpl();
+
+        environment.push(Heartbeat.class, heartbeat);
+
+        heartbeat.begin();
+
+        try
+        {
+
+            ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(
+                    componentEventResultProcessor);
+
+            resources.triggerContextEvent(PREPARE_FOR_SUBMIT, context, callback);
+
+            if (callback.isAborted()) return true;
+
+            resources.triggerContextEvent(PREPARE, context, callback);
+
+            if (callback.isAborted()) return true;
+
+            executeStoredActions();
+
+            heartbeat.end();
+
+            ValidationTracker tracker = environment.peek(ValidationTracker.class);
+
+            // Let the listeners peform any final validations
+
+            // Update through the parameter because the tracker has almost certainly changed
+            // internal state.
+
+            this.tracker = tracker;
+
+            resources.triggerContextEvent(VALIDATE_FORM, context, callback);
+
+            if (callback.isAborted()) return true;
+
+            formSupport.executeDeferred();
+
+            // Let the listeners know about overall success or failure. Most listeners fall into
+            // one of those two camps.
+
+            // If the tracker has no errors, then clear it of any input values
+            // as well, so that the next page render will be "clean" and show
+            // true persistent data, not value from the previous form submission.
+
+            if (!this.tracker.getHasErrors()) this.tracker.clear();
+
+            resources.triggerContextEvent(tracker.getHasErrors() ? FAILURE : SUCCESS, context, callback);
+
+            // Lastly, tell anyone whose interested that the form is completely submitted.
+
+            if (callback.isAborted()) return true;
+
+            resources.triggerContextEvent(SUBMIT, context, callback);
+
+            return callback.isAborted();
+        }
+        finally
+        {
+            environment.pop(Heartbeat.class);
+            environment.pop(FormSupport.class);
+        }
+    }
+
+    /**
+     * Pulls the stored actions out of the request, converts them from MIME stream back to object stream and then
+     * objects, and executes them.
+     */
+    private void executeStoredActions()
+    {
+        String[] values = request.getParameters(FORM_DATA);
+
+        if (values == null) return;
+
+        // Due to Ajax (FormInjector) there may be multiple values here, so handle each one individually.
+
+        for (String actionsBase64 : values)
+        {
+            ObjectInputStream ois = null;
+
+            Component component = null;
+
+            try
+            {
+                ois = new Base64ObjectInputStream(actionsBase64);
+
+                while (true)
+                {
+                    String componentId = ois.readUTF();
+                    ComponentAction action = (ComponentAction) ois.readObject();
+
+                    component = source.getComponent(componentId);
+
+                    action.execute(component);
+
+                    component = null;
+                }
+            }
+            catch (EOFException ex)
+            {
+                // Expected
+            }
+            catch (Exception ex)
+            {
+                Location location = component == null ? null : component.getComponentResources().getLocation();
+
+                throw new TapestryException(ex.getMessage(), location, ex);
+            }
+            finally
+            {
+                InternalUtils.close(ois);
+            }
+        }
+    }
+
+    public void recordError(String errorMessage)
+    {
+        ValidationTracker tracker = this.tracker;
+
+        tracker.recordError(errorMessage);
+
+        this.tracker = tracker;
+    }
+
+    public void recordError(Field field, String errorMessage)
+    {
+        ValidationTracker tracker = this.tracker;
+
+        tracker.recordError(field, errorMessage);
+
+        this.tracker = tracker;
+    }
+
+    public boolean getHasErrors()
+    {
+        return tracker.getHasErrors();
+    }
+
+    public boolean isValid()
+    {
+        return !tracker.getHasErrors();
+    }
+
+    // For testing:
+
+    void setTracker(ValidationTracker tracker)
+    {
+        this.tracker = tracker;
+    }
+
+    public void clearErrors()
+    {
+        tracker.clear();
+    }
+
+    /**
+     * Forms use the same value for their name and their id attribute.
+     */
+    public String getClientId()
+    {
+        return name;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc
new file mode 100644
index 0000000..7ce4947
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc
@@ -0,0 +1,179 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="BeanEditForm.html">BeanEditForm</a>
+                </li>
+                <li>
+                    <a href="Errors.html">Errors</a>
+                </li>
+                <li>
+                    <a href="FormFragment.html">FormFragment</a>
+                </li>
+                <li>
+                    <a href="Label.html">Label</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Form Control Element Components">
+
+            <p>
+                The following components are Tapestry wrappers around client-side HTML form elements:
+            </p>
+
+            <ul>
+                <li>
+                    <a href="CheckBox.html">CheckBox</a>
+                </li>
+                <li>
+                    <a href="DateField.html">DateField</a>
+                </li>
+                <li>
+                    <a href="Palette.html">Palette</a>
+                </li>
+                <li>
+                    <a href="PasswordField.html">PasswordField</a>
+                </li>
+                <li>
+                    <a href="Radio.html">Radio</a>
+                    and
+                    <a href="RadioGroup.html">RadioGroup</a>
+                </li>
+                <li>
+                    <a href="Select.html">Select</a>
+                </li>
+                <li>
+                    <a href="Submit.html">Submit</a>
+                </li>
+                <li>
+                    <a href="TextArea.html">TextArea</a>
+                </li>
+                <li>
+                    <a href="TextField.html">TextField</a>
+                </li>
+            </ul>
+
+        </section>
+
+
+        <section name="Examples">
+
+            <p>
+                Examples of the Form component are provided in the many
+                other pages that discuss specific form control element components,
+                such as
+                <a href="Radio.html">Radio</a>
+                and<a href="TextField.html">TextField</a>.
+            </p>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                The Form component generates a seemingly bewildering number of
+                events, designed to address a wide range of needs. The goal
+                is to give you as the developer the tools necessary to
+                effeciently manage state.
+            </p>
+
+            <p>
+                All of the events that are triggered will pass along
+                the values defined by the context parameter. Most often,
+                there is no context, or the context is a single value
+                (a primary key used to identify the object being updated
+                by the form).
+            </p>
+
+
+            <subsection name="Render Events">
+
+                <p>
+                    Render event handler methods should
+                    <em>not</em>
+                    return a value, doing
+                    so will be an error. The methods are intended to allow
+                    the page to convert a primary key stored in the context
+                    back into an object ready to have its properties updated
+                    by the Form.
+                </p>
+
+                <p>
+                    The context passed to component event handler methods is provided by reading the context parameter.
+                </p>
+
+                <ul>
+                    <li>prepareForRender</li>
+                    <li>prepare</li>
+                </ul>
+
+
+            </subsection>
+
+            <subsection name="Submit Events">
+
+                <p>
+                    Submit events may return a navigational value, which will
+                    abort any remaining processing of the form submission.
+                </p>
+
+                <p>
+                    The context provided to component event handler methods
+                    originates in the form submission (it is stored in hidden form fields); the
+                    context parameter is
+                    <em>not</em>
+                    read during a form submission.
+                </p>
+
+                <ul>
+                    <li>prepareForSubmit</li>
+                    <li>prepare</li>
+                    <li>validateForm</li>
+                    <li>failure
+                        <em>or</em>
+                        success
+                    </li>
+                    <li>submit</li>
+                </ul>
+
+                <p>
+                    The validateForm event is to allow the page to
+                    perform cross-field validation. The failure or success
+                    event is fired based on whether there are or are not any
+                    validation errors.
+                </p>
+
+            </subsection>
+
+
+            <subsection name="Form Ids">
+
+                <p>
+                    It is considered a best practice to give explicit ids to
+                    Form components, and form control element components.
+                    These ids propogate down to the client side as
+                    element names and/or ids, and eventually show up
+                    as query parameters when the form is submitted.
+                </p>
+
+                <p>
+                    To achieve a more RESTful URL scheme, give the form component
+                    an id based on what it does rather than what data it updates, thus
+                    <code><![CDATA[<t:form t:id="search"/>]]></code>
+                    rather than
+                    <code><![CDATA[<t:form t:id="searchData"/>]]></code>
+                    or
+                    <code><![CDATA[<t:form t:id="searchForm"/>]]></code>.
+
+                </p>
+
+
+            </subsection>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java
new file mode 100644
index 0000000..c9d6a6b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java
@@ -0,0 +1,217 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.corelib.internal.FormSupportAdapter;
+import org.apache.tapestry.corelib.internal.WrappedComponentAction;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Request;
+
+import java.util.List;
+
+/**
+ * A SubForm is a portion of a Form that may be selectively displayed.  Form elements inside a FormFragment will
+ * automatically bypass validation when the fragment is invisible.  The trick is to also bypass server-side form
+ * processing for such fields when the form is submitted; the fragment uses a hidden field to track its client-side
+ * visibility and will bypass field component submission logic for the components it encloses.
+ *
+ * @see org.apache.tapestry.corelib.mixins.TriggerFragment
+ */
+@SupportsInformalParameters
+public class FormFragment implements ClientElement
+{
+    /**
+     * Determines if the fragment is intially visible or initially invisible (the default). This is only used when
+     * rendering; when the form is submitted, the hidden field value is used to determine whether the elements within
+     * the fragment should be processed (or ignored if still invisible).
+     */
+    @Parameter
+    private boolean visible;
+
+
+    /**
+     * Name of a function on the client-side Tapestry.ElementEffect object that is invoked to make the fragment visible.
+     * If not specified, then the default "slidedown" function is used.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String show;
+
+    /**
+     * Name of a function on the client-side Tapestry.ElementEffect object that is invoked when the fragment is to be
+     * hidden. If not specified, the default "slideup" function is used.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String hide;
+
+    @Inject
+    private Environment environment;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+
+    @Inject
+    private ComponentSource componentSource;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    private String clientId;
+
+    private String controlName;
+
+    private List<WrappedComponentAction> componentActions;
+
+    @Inject
+    private Request request;
+
+    static class HandleSubmission implements ComponentAction<FormFragment>
+    {
+        private final String controlName;
+
+        private final List<WrappedComponentAction> actions;
+
+        public HandleSubmission(String controlName, List<WrappedComponentAction> actions)
+        {
+            this.controlName = controlName;
+            this.actions = actions;
+        }
+
+        public void execute(FormFragment component)
+        {
+            component.handleSubmission(controlName, actions);
+        }
+    }
+
+
+    private void handleSubmission(String elementName, List<WrappedComponentAction> actions)
+    {
+        String value = request.getParameter(elementName);
+
+        boolean visible = Boolean.parseBoolean(value);
+
+        if (!visible) return;
+
+        // Note that we DON'T update the visible parameter, it is read only.
+
+        for (WrappedComponentAction action : actions)
+        {
+            action.execute(componentSource);
+        }
+    }
+
+    /**
+     * Renders a &lt;div&gt; tag and provides an override of the {@link org.apache.tapestry.services.FormSupport}
+     * environmental.
+     */
+    void beginRender(MarkupWriter writer)
+    {
+        FormSupport formSupport = environment.peekRequired(FormSupport.class);
+
+        String id = resources.getId();
+
+        controlName = formSupport.allocateControlName(id);
+        clientId = renderSupport.allocateClientId(id);
+
+        Element element = writer.element("div", "id", clientId);
+
+        resources.renderInformalParameters(writer);
+
+        if (!visible)
+            element.addClassName(CSSClassConstants.INVISIBLE);
+
+
+        writer.element("input",
+
+                       "type", "hidden",
+
+                       "name", controlName,
+
+                       "id", clientId + ":hidden",
+
+                       "value", String.valueOf(visible));
+        writer.end();
+
+
+        clientBehaviorSupport.addFormFragment(clientId, show, hide);
+
+        componentActions = CollectionFactory.newList();
+
+        // Here's the magic of environmentals ... we can create a wrapper around
+        // the normal FormSupport environmental that intercepts some of the behavior.
+        // Here we're setting aside all the actions inside the FormFragment so that we
+        // can control whether those actions occur when the form is submitted.
+
+        FormSupport override = new FormSupportAdapter(formSupport)
+        {
+            @Override
+            public <T> void store(T component, ComponentAction<T> action)
+            {
+                Component asComponent = Defense.cast(component, Component.class, "component");
+
+                componentActions.add(new WrappedComponentAction(asComponent, action));
+            }
+
+            @Override
+            public <T> void storeAndExecute(T component, ComponentAction<T> action)
+            {
+                store(component, action);
+
+                action.execute(component);
+            }
+        };
+
+        // Tada!  Now all the enclosed components will use our override of FormSupport,
+        // until we pop it off.
+
+        environment.push(FormSupport.class, override);
+
+    }
+
+    /**
+     * Closes the &lt;div&gt; tag and pops off the {@link org.apache.tapestry.services.FormSupport} environmental
+     * override.
+     *
+     * @param writer
+     */
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // div
+
+        environment.pop(FormSupport.class);
+
+        environment.peek(FormSupport.class).store(this, new HandleSubmission(controlName, componentActions));
+    }
+
+    public String getClientId()
+    {
+        return clientId;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc
new file mode 100644
index 0000000..567c365
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc
@@ -0,0 +1,181 @@
+<document>
+    <body>
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="../mixins/TriggerFragment.html">TriggerFragment</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                This example will collect a billing address for an order and, optionally, a separate
+                shipping address. Initially, the form will render just the billing address fields:
+            </p>
+
+            <p>
+                <img src="formfragment_ref_1.png"/>
+            </p>
+
+
+            <p>
+                Clicking the checkbox will trigger an animation that slides down the
+                remainder of the form.
+            </p>
+
+            <p>
+                <img src="formfragment_ref_2.png"/>
+            </p>
+
+
+            <p>
+                The FormFragment component ensures that client-side validation is only enabled for fields
+                that are actually visible to the user. In addition, for fields that are enclosed within the
+                FormFragment,
+                server-side validation and processing only occurs if the fields were visible to the user when the
+                client-side
+                form was submitted.
+            </p>
+
+            <subsection name="OrderAddress.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Order Address</h1>
+
+        <t:form>
+
+            <t:errors/>
+
+            <div class="t-beaneditor">
+
+                <h2>Billing Address</h2>
+
+                <t:beaneditor t:id="billingAddress"/>
+
+                <t:checkbox t:id="separateShipTo" t:mixins="triggerfragment" fragment="seperateShippingAddress"/>
+                <t:label for="separateShipTo">Separate Ship To?</t:label>
+
+                <t:formfragment t:id="seperateShippingAddress" visible="separateShipTo">
+
+                    <h2>Shipping Address</h2>
+
+                    <t:beaneditor t:id="shippingAddress"/>
+
+                </t:formfragment>
+
+
+                <div class="t-beaneditor-row">
+                    <input type="submit" value="Continue"/>
+                </div>
+            </div>
+
+        </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    The separateShipTo property is initially null, so the FormFragment is initially invisible. The
+                    BeanEditor
+                    and all of the individual fields are rendered, but the &lt;div&gt; for the FormFragment is simply
+                    invisible.
+                </p>
+
+                <p>
+                    The
+                    <a href="../mixins/TriggerFragment.html">TriggerFragment</a>
+                    mixin adds a client-side trigger that
+                    will show or hide the fragment as the checkbox is clicked by the user.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="OrderAddress.java">
+                <source><![CDATA[
+public class OrderAddress
+{
+    @Persist
+    private ShippingAddress _billingAddress;
+
+    @Persist
+    private ShippingAddress _shippingAddress;
+
+    @Persist
+    private boolean _separateShipTo;
+
+    public ShippingAddress getBillingAddress()
+    {
+        return _billingAddress;
+    }
+
+    public void setBillingAddress(ShippingAddress billingAddress)
+    {
+        _billingAddress = billingAddress;
+    }
+
+    public ShippingAddress getShippingAddress()
+    {
+        return _shippingAddress;
+    }
+
+    public void setShippingAddress(ShippingAddress shippingAddress)
+    {
+        _shippingAddress = shippingAddress;
+    }
+
+    public boolean isSeparateShipTo()
+    {
+        return _separateShipTo;
+    }
+
+    public void setSeparateShipTo(boolean separateShipTo)
+    {
+        _separateShipTo = separateShipTo;
+    }
+}]]></source>
+            </subsection>
+
+            <p>
+                The OrderAddress page is largely just a holder of the properties (for simplicity in this example,
+                there is no event handler for the success event, nor are we going into other details that would
+                be reflected in a real application).
+            </p>
+
+            <p>
+                The BeanEditor component will create default instances of billingAddress and shippingAddress.
+                If the user does not choose to use a seperate ship-to, the shippingAddress property will contain
+                an empty ShippingAddress object. The application will need to query the separateShipTo property
+                to determine how to proceed once the form is succesfully submitted.
+            </p>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                FormFragments are nestable, which can lead to complex (and perhaps, confusing) interfaces.
+            </p>
+
+            <p>
+                The FormFragment doesn't just prevent server-side input validation when invisible; it prevents
+                <em>any</em>
+                server-side processing
+                for the components it encloses, as if the components were entirely absent.
+            </p>
+
+            <p>
+                If JavaScript is disabled on the client, the application will still operate, though the user
+                will have to submit the form to have the fragment(s) update.
+            </p>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java
new file mode 100644
index 0000000..38780a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java
@@ -0,0 +1,222 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.corelib.data.InsertPosition;
+import org.apache.tapestry.corelib.internal.FormSupportImpl;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.internal.services.ComponentResultProcessorWrapper;
+import org.apache.tapestry.internal.services.PageRenderQueue;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * A way to add new content to an existing Form. The FormInjector emulates its tag from the template (or uses a
+ * &lt;div&gt;). When triggered, new content is obtained from the application and is injected before or after the
+ * element.
+ */
+@SupportsInformalParameters
+public class FormInjector implements ClientElement
+{
+    public static final String INJECT_EVENT = "inject";
+
+    public static final String FORMID_PARAMETER = "t:formid";
+
+    /**
+     * The context for the link (optional parameter). This list of values will be converted into strings and included in
+     * the URI. The strings will be coerced back to whatever their values are and made available to event handler
+     * methods.
+     */
+    @Parameter
+    private List<?> context;
+
+    @Parameter(defaultPrefix = BindingConstants.LITERAL, value = "above")
+    private InsertPosition position;
+
+    /**
+     * Name of a function on the client-side Tapestry.ElementEffect object that is invoked to make added content
+     * visible. Leaving as null uses the default function, "highlight".
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String show;
+
+    /**
+     * The element name to render, which is normally the element name used to represent the FormInjector component in
+     * the template, or "div".
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String element;
+
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    @Inject
+    @Ajax
+    private ComponentEventResultProcessor componentEventResultProcessor;
+
+
+    @Inject
+    private PageRenderQueue pageRenderQueue;
+
+    private String clientId;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private Environment environment;
+
+    String defaultElement()
+    {
+        return resources.getElementName("div");
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        clientId = renderSupport.allocateClientId(resources);
+
+        writer.element(element,
+
+                       "id", clientId);
+
+        resources.renderInformalParameters(writer);
+
+        // Now work on the JavaScript side of things.
+
+        Link link = resources.createActionLink(INJECT_EVENT, false,
+                                               context == null ? new Object[0] : context.toArray());
+
+        link.addParameter(FORMID_PARAMETER, formSupport.getClientId());
+
+        clientBehaviorSupport.addFormInjector(clientId, link, position, show);
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end();
+    }
+
+
+    /**
+     * Returns the unique client-side id of the rendered element.
+     */
+    public String getClientId()
+    {
+        return clientId;
+    }
+
+    /**
+     * Invoked via an Ajax request.  Triggers an action event and captures the return value. The return value from the
+     * event notification is what will ultimately render (typically, its a Block).  However, we do a <em>lot</em> of
+     * tricks to provide the desired FormSupport around the what renders.
+     */
+    Object onInject(EventContext context) throws IOException
+    {
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(
+                componentEventResultProcessor);
+
+        resources.triggerContextEvent(EventConstants.ACTION, context, callback);
+
+        if (!callback.isAborted()) return null;
+
+        // Here's where it gets very, very tricky.
+
+        final RenderCommand rootRenderCommand = pageRenderQueue.getRootRenderCommand();
+
+        final String formId = request.getParameter(FORMID_PARAMETER);
+
+        final Base64ObjectOutputStream actions = new Base64ObjectOutputStream();
+
+        final RenderCommand cleanup = new RenderCommand()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                try
+                {
+                    actions.close();
+                }
+                catch (IOException ex)
+                {
+                    throw new RuntimeException(ex);
+                }
+
+                environment.pop(ValidationTracker.class);
+
+                FormSupportImpl formSupport = (FormSupportImpl) environment.pop(FormSupport.class);
+
+                formSupport.executeDeferred();
+
+                writer.element("input",
+
+                               "type", "hidden",
+
+                               "name", Form.FORM_DATA,
+
+                               "value", actions.toBase64());
+            }
+        };
+
+        final RenderCommand setup = new RenderCommand()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                // Kind of ugly, but the only way to ensure we don't have name collisions on the
+                // client side is to force a unique id into each name (as well as each id, but that's
+                // RenderSupport's job).  It would be nice if we could agree on the uid, but
+                // not essential.
+
+                String uid = Long.toHexString(System.currentTimeMillis());
+
+                IdAllocator idAllocator = new IdAllocator(":" + uid);
+
+                FormSupportImpl formSupport = new FormSupportImpl(formId, actions, clientBehaviorSupport, true,
+                                                                  idAllocator);
+                environment.push(FormSupport.class, formSupport);
+
+
+                environment.push(ValidationTracker.class, new ValidationTrackerImpl());
+
+                // Queue up the root render command to execute first, and the cleanup
+                // to execute after it is done.
+
+                queue.push(cleanup);
+                queue.push(rootRenderCommand);
+            }
+        };
+
+        return setup;
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java
new file mode 100644
index 0000000..bd774c7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.java
@@ -0,0 +1,531 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.corelib.data.GridPagerPosition;
+import org.apache.tapestry.grid.*;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.beaneditor.BeanModelUtils;
+import org.apache.tapestry.internal.bindings.AbstractBinding;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Request;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A grid presents tabular data. It is a composite component, created in terms of several sub-components. The
+ * sub-components are statically wired to the Grid, as it provides access to the data and other models that they need.
+ * <p/>
+ * A Grid may operate inside a {@link org.apache.tapestry.corelib.components.Form}. By overriding the cell renderers of
+ * properties, the default output-only behavior can be changed to produce a complex form with individual control for
+ * editing properties of each row. This is currently workable but less than ideal -- if the order of rows provided by
+ * the {@link GridDataSource} changes between render and form submission, then there's the possibility that data will be
+ * applied to the wrong server-side objects.
+ *
+ * @see org.apache.tapestry.beaneditor.BeanModel
+ * @see org.apache.tapestry.services.BeanModelSource
+ * @see org.apache.tapestry.grid.GridDataSource
+ */
+@SupportsInformalParameters
+public class Grid implements GridModel
+{
+    /**
+     * The source of data for the Grid to display. This will usually be a List or array but can also be an explicit
+     * {@link GridDataSource}. For Lists and object arrays, a GridDataSource is created automatically as a wrapper
+     * around the underlying List.
+     */
+    @Parameter(required = true)
+    private GridDataSource source;
+
+    /**
+     * A wrapper around the provided GridDataSource that caches access to the availableRows property. This is the source
+     * provided to sub-components.
+     */
+    private GridDataSource cachingSource;
+
+    /**
+     * The number of rows of data displayed on each page. If there are more rows than will fit, the Grid will divide up
+     * the rows into "pages" and (normally) provide a pager to allow the user to navigate within the overall result
+     * set.
+     */
+    @Parameter("25")
+    private int rowsPerPage;
+
+    /**
+     * Defines where the pager (used to navigate within the "pages" of results) should be displayed: "top", "bottom",
+     * "both" or "none".
+     */
+    @Parameter(value = "top", defaultPrefix = BindingConstants.LITERAL)
+    private GridPagerPosition pagerPosition;
+
+    /**
+     * Used to store the current object being rendered (for the current row). This is used when parameter blocks are
+     * provided to override the default cell renderer for a particular column ... the components within the block can
+     * use the property bound to the row parameter to know what they should render.
+     */
+    @Parameter
+    private Object row;
+
+    /**
+     * The model used to identify the properties to be presented and the order of presentation. The model may be
+     * omitted, in which case a default model is generated from the first object in the data source (this implies that
+     * the objects provided by the source are uniform). The model may be explicitly specified to override the default
+     * behavior, say to reorder or rename columns or add additional columns.
+     */
+    @Parameter
+    private BeanModel model;
+
+    /**
+     * The model used to handle sorting of the Grid. This is generally not specified, and the built-in model supports
+     * only single column sorting. The sort constraints (the column that is sorted, and ascending vs. descending) is
+     * stored as persistent fields of the Grid component.
+     */
+    @Parameter
+    private GridSortModel sortModel;
+
+    /**
+     * A comma-seperated list of property names to be added to the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * Cells for added columns will be blank unless a cell override is provided.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String add;
+
+    /**
+     * A comma-separated list of property names to be retained from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * Only these properties will be retained, and the properties will also be reordered. The names are
+     * case-insensitive.
+     */
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String include;
+
+    /**
+     * A comma-separated list of property names to be removed from the {@link org.apache.tapestry.beaneditor.BeanModel}.
+     * The names are case-insensitive.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String exclude;
+
+    /**
+     * A comma-separated list of property names indicating the order in which the properties should be presented. The
+     * names are case insensitive. Any properties not indicated in the list will be appended to the end of the display
+     * order.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String reorder;
+
+    /**
+     * A Block to render instead of the table (and pager, etc.) when the source is empty. The default is simply the text
+     * "There is no data to display". This parameter is used to customize that message, possibly including components to
+     * allow the user to create new objects.
+     */
+    @Parameter(value = "block:empty")
+    private Block empty;
+
+
+    /**
+     * If true, then the CSS class on each &lt;TD&gt; and &lt;TH&gt; cell will be omitted, which can reduce the amount
+     * of output from the component overall by a considerable amount. Leave this as false, the default, when you are
+     * leveraging the CSS to customize the look and feel of particular columns.
+     */
+    @Parameter
+    private boolean lean;
+
+    /**
+     * If true and the Loop is enclosed by a Form, then the normal state persisting logic is turned off. Defaults to
+     * false, enabling state persisting within Forms. If a Grid is present for some reason within a Form, but does not
+     * contain any form control components (such as {@link TextField}), then binding volatile to false will reduce the
+     * amount of client-side state that must be persisted.
+     */
+    @Parameter(name = "volatile")
+    private boolean volatileState;
+
+    /**
+     * The CSS class for the tr element for each data row. This can be used to highlight particular rows, or cycle
+     * between CSS values (for the "zebra effect"). If null or not bound, then no particular CSS class value is used.
+     */
+    @Parameter(cache = false)
+    @Property(write = false)
+    private String rowClass;
+
+    /**
+     * CSS class for the &lt;table&gt; element.  In addition, informal parameters to the Grid are rendered in the table
+     * element.
+     */
+    @Parameter(name = "class", defaultPrefix = BindingConstants.LITERAL, value = "t-data-grid")
+    @Property(write = false)
+    private String tableClass;
+
+    /**
+     * If true, then the Grid will be wrapped in an element that acts like a {@link
+     * org.apache.tapestry.corelib.components.Zone}; all the paging and sorting links will
+     */
+    @Parameter
+    private boolean inPlace;
+
+    /**
+     * The name of the psuedo-zone that encloses the Grid.
+     */
+    @Property(write = false)
+    private String zone;
+
+    private boolean didRenderZoneDiv;
+
+    @Persist
+    private int currentPage = 1;
+
+    @Persist
+    private String sortColumnId;
+
+    @Persist
+    private boolean sortAscending = true;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private BeanModelSource modelSource;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    @SuppressWarnings("unused")
+    @Component(
+            parameters = { "lean=inherit:lean", "overrides=componentResources", "zone=zone" })
+    private GridColumns columns;
+
+    @SuppressWarnings("unused")
+    @Component(
+            parameters = { "rowClass=rowClass", "rowsPerPage=rowsPerPage", "currentPage=currentPage", "row=row", "volatile=inherit:volatile", "lean=inherit:lean" })
+    private GridRows rows;
+
+    @Component(parameters = { "source=dataSource", "rowsPerPage=rowsPerPage", "currentPage=currentPage", "zone=zone" })
+    private GridPager pager;
+
+    @SuppressWarnings("unused")
+    @Component(parameters = "to=pagerTop")
+    private Delegate pagerTop;
+
+    @SuppressWarnings("unused")
+    @Component(parameters = "to=pagerBottom")
+    private Delegate pagerBottom;
+
+    @SuppressWarnings("unused")
+    @Component(parameters = "class=tableClass", inheritInformalParameters = true)
+    private Any table;
+
+    @Environmental(false)
+    private FormSupport formSupport;
+
+    @Inject
+    private Request request;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    /**
+     * Set up via the traditional or Ajax component event request handler
+     */
+    @Environmental
+    private ComponentEventResultProcessor componentEventResultProcessor;
+
+    /**
+     * A version of GridDataSource that caches the availableRows property. This addresses TAPESTRY-2245.
+     */
+    class CachingDataSource implements GridDataSource
+    {
+        private boolean availableRowsCached;
+
+        private int availableRows;
+
+        public int getAvailableRows()
+        {
+            if (!availableRowsCached)
+            {
+                availableRows = source.getAvailableRows();
+                availableRowsCached = true;
+            }
+
+            return availableRows;
+        }
+
+        public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints)
+        {
+            source.prepare(startIndex, endIndex, sortConstraints);
+        }
+
+        public Object getRowValue(int index)
+        {
+            return source.getRowValue(index);
+        }
+
+        public Class getRowType()
+        {
+            return source.getRowType();
+        }
+    }
+
+    /**
+     * Default implementation that only allows a single column to be the sort column, and stores the sort information as
+     * persistent fields of the Grid component.
+     */
+    class DefaultGridSortModel implements GridSortModel
+    {
+        public ColumnSort getColumnSort(String columnId)
+        {
+            if (!TapestryInternalUtils.isEqual(columnId, sortColumnId))
+                return ColumnSort.UNSORTED;
+
+            return getColumnSort();
+        }
+
+        private ColumnSort getColumnSort()
+        {
+            return sortAscending ? ColumnSort.ASCENDING : ColumnSort.DESCENDING;
+        }
+
+
+        public void updateSort(String columnId)
+        {
+            Defense.notBlank(columnId, "columnId");
+
+            if (columnId.equals(sortColumnId))
+            {
+                sortAscending = !sortAscending;
+                return;
+            }
+
+            sortColumnId = columnId;
+            sortAscending = true;
+        }
+
+        public List<SortConstraint> getSortContraints()
+        {
+            if (sortColumnId == null)
+                return Collections.emptyList();
+
+            PropertyModel sortModel = model.getById(sortColumnId);
+
+            SortConstraint constraint = new SortConstraint(sortModel, getColumnSort());
+
+            return Collections.singletonList(constraint);
+        }
+
+        public void clear()
+        {
+            sortColumnId = null;
+        }
+    }
+
+    GridSortModel defaultSortModel()
+    {
+        return new DefaultGridSortModel();
+    }
+
+    Binding defaultModel()
+    {
+        final ComponentResources containerResources = resources.getContainerResources();
+
+        return new AbstractBinding()
+        {
+
+            public Object get()
+            {
+                // Get the default row type from the data source
+
+                Class rowType = source.getRowType();
+
+                if (rowType == null) throw new RuntimeException(
+                        "Unable to determine the bean type for rows from the GridDataSource. You should bind the model parameter explicitly.");
+
+                // Properties do not have to be read/write
+
+                return modelSource.create(rowType, false, containerResources);
+            }
+
+            /**
+             * Returns false. This may be overkill, but it basically exists because the model is
+             * inherently mutable and therefore may contain client-specific state and needs to be
+             * discarded at the end of the request. If the model were immutable, then we could leave
+             * invariant as true.
+             */
+            @Override
+            public boolean isInvariant()
+            {
+                return false;
+            }
+        };
+    }
+
+    static final ComponentAction<Grid> SETUP_DATA_SOURCE = new ComponentAction<Grid>()
+    {
+        private static final long serialVersionUID = 8545187927995722789L;
+
+        public void execute(Grid component)
+        {
+            component.setupDataSource();
+        }
+    };
+
+    Object setupRender()
+    {
+        if (!volatileState && formSupport != null) formSupport.store(this, SETUP_DATA_SOURCE);
+
+        setupDataSource();
+
+        return cachingSource.getAvailableRows() == 0 ? empty : null;
+    }
+
+    void setupDataSource()
+    {
+        // If there's no rows, display the empty block placeholder.
+
+        cachingSource = new CachingDataSource();
+
+        int availableRows = cachingSource.getAvailableRows();
+
+        if (availableRows == 0) return;
+
+        BeanModelUtils.modify(model, add, include, exclude, reorder);
+
+        int maxPage = ((availableRows - 1) / rowsPerPage) + 1;
+
+        // This captures when the number of rows has decreased, typically due to deletions.
+
+        if (currentPage > maxPage)
+            currentPage = maxPage;
+
+        int startIndex = (currentPage - 1) * rowsPerPage;
+
+        int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRows - 1);
+
+        cachingSource.prepare(startIndex, endIndex, sortModel.getSortContraints());
+
+    }
+
+    Object beginRender(MarkupWriter writer)
+    {
+        // Skip rendering of component (template, body, etc.) when there's nothing to display.
+        // The empty placeholder will already have rendered.
+
+        if (cachingSource.getAvailableRows() == 0) return false;
+
+        if (inPlace && zone == null)
+        {
+            zone = renderSupport.allocateClientId(resources);
+
+            writer.element("div", "id", zone);
+
+            clientBehaviorSupport.addZone(zone, null, "show");
+
+            didRenderZoneDiv = true;
+        }
+
+        return null;
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        if (didRenderZoneDiv)
+        {
+            writer.end(); // div
+            didRenderZoneDiv = false;
+        }
+    }
+
+    public BeanModel getDataModel()
+    {
+        return model;
+    }
+
+    public GridDataSource getDataSource()
+    {
+        return cachingSource;
+    }
+
+    public GridSortModel getSortModel()
+    {
+        return sortModel;
+    }
+
+    public Object getPagerTop()
+    {
+        return pagerPosition.isMatchTop() ? pager : null;
+    }
+
+    public Object getPagerBottom()
+    {
+        return pagerPosition.isMatchBottom() ? pager : null;
+    }
+
+    public int getCurrentPage()
+    {
+        return currentPage;
+    }
+
+    public void setCurrentPage(int currentPage)
+    {
+        this.currentPage = currentPage;
+    }
+
+    public int getRowsPerPage()
+    {
+        return rowsPerPage;
+    }
+
+    public Object getRow()
+    {
+        return row;
+    }
+
+    public void setRow(Object row)
+    {
+        this.row = row;
+    }
+
+    /**
+     * Resets the Grid to inital settings; this sets the current page to one, and {@linkplain
+     * org.apache.tapestry.grid.GridSortModel#clear() clears the sort model}.
+     */
+    public void reset()
+    {
+        currentPage = 1;
+        sortModel.clear();
+    }
+
+    /**
+     * Event handler for inplaceupdate event triggered from nested components when an Ajax update occurs. The event
+     * context will carry the zone, which is recorded here, to allow the Grid and its sub-components to properly
+     * re-render themselves.  Invokes {@link org.apache.tapestry.services.ComponentEventResultProcessor#processResultValue(Object)}
+     * passing this (the Grid component) as the content provider for the update.
+     */
+    void onInPlaceUpdate(String zone) throws IOException
+    {
+        this.zone = zone;
+
+        componentEventResultProcessor.processResultValue(this);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.xdoc
new file mode 100644
index 0000000..4072379
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Grid.xdoc
@@ -0,0 +1,295 @@
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="BeanEditForm">BeanEditForm</a>
+                </li>
+                <li>
+                    <a href="BeanDisplay">BeanDisplay</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Simple Example">
+
+            <p>
+                The Grid component is closely related to the BeanEditor component; they are both based on the same
+                underlying concept and share quite a bit of code.
+            </p>
+
+            <p>In this example, we'll display a list of users. We'll also show some basic customization, to convert a
+                column
+                from just text, to a clickable link.
+            </p>
+
+            <p>
+                <img src="grid_ref1.png"/>
+            </p>
+
+            <p>This example shows much of the default behavior, using a collection of randomly generated users.
+                The column order is determined by the order of the getter methods in the User class. The columns are
+                sortable, and
+                because there are more results than will fit on a single page, page navigation is included (the
+                navigation
+                disappears for small result sets).
+            </p>
+
+            <subsection name="User.java">
+                <source><![CDATA[
+public class User
+{
+    private long _id;
+
+    private String _firstName;
+
+    private String _lastName;
+
+    private int _age;
+
+    public long getId() { return _id; }
+
+    @NonVisual
+    public void setId(long id) { _id = id; }
+
+    public String getFirstName() { return _firstName; }
+
+    public void setFirstName(String firstName) { _firstName = firstName; }
+
+    public String getLastName() { return _lastName; }
+
+    public void setLastName(String lastName) { _lastName = lastName; }
+
+    public int getAge() { return _age; }
+
+    public void setAge(int age) { _age = age; }
+}]]></source>
+
+                <p>The @NonVisual annotation prevents the id property from being displayed.</p>
+
+            </subsection>
+
+            <subsection name="UserList.tml">
+
+                <p>
+                    We want to make the user's last name a clickable link to a detail page for the user.
+                </p>
+
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>List Users</h1>
+
+        <t:grid source="users" row="user">
+            <t:parameter name="lastnamecell">
+                <t:pagelink page="user/view" context="user.id">${user.lastname}</t:pagelink>
+            </t:parameter>
+        </t:grid>
+    </body>
+</html>
+]]></source>
+
+
+                <p>
+                    The parameter name
+                    <code><em>property</em>cell
+                    </code>
+                    is used to override the rendering of cells for one property. As usual, case is ignored. Here we
+                    use a PageLink component to link to a ViewUser page, passing the id of the user as
+                    activation context for the target page.
+                </p>
+
+                <p>
+                    The Grid component takes care of the &lt;td&gt; element, and the provided block parameter
+                    provides the content
+                    <em>inside</em>
+                    the &lt;td&gt;.
+                </p>
+
+                <p>
+                    For the block to know what is being rendered, we bind the row parameter of the Grid
+                    to the user property of the page. The Grid will keep updating this property
+                    just before it renders each row (using its own internal renderers, or the ones
+                    provided as parameters).
+                </p>
+
+                <p>
+                    The header for a column may be overridden in the same way, using a parameter name
+                    of
+                    <code><em>property</em>header
+                    </code>
+                    . The parameter block will provide the content
+                    inside the &lt;th&gt; element. The provided block is responsible for
+                    providing any links or icons related to sorting.
+                </p>
+
+            </subsection>
+
+            <subsection name="UserList.java">
+                <source><![CDATA[
+public class UserList
+{
+    @Inject
+    private UserDAO _userDAO;
+
+    @Property
+    private User _user;
+
+    public List<User> getUsers() { return _userDAO.findAll(); }
+}]]></source>
+
+            </subsection>
+
+            <p>
+                The UserList class exists to provide access to the UserDAO service, and to act as a holder
+                for the user property, needed when the Grid is rendering. We need it here because we've
+                overridden the rendering of the lastName property.
+            </p>
+
+        </section>
+
+        <section name="Adding Columns Example">
+
+            <p>
+                Commonly, you may want to add a column to the Grid to support a computed property, or as a placeholder
+                for an action. We'll do the latter, adding a column for deleting a user.
+            </p>
+
+
+            <p>
+                <img src="grid_ref2.png"/>
+            </p>
+
+            <subsection name="UserList.tml">
+
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>List Users</h1>
+
+        <t:grid source="users" row="user" add="delete">
+            <t:parameter name="lastnamecell">
+                <t:pagelink page="user/view" context="user.id">${user.lastname}</t:pagelink>
+            </t:parameter>
+            <t:parameter name="deletecell">
+                <t:actionlink t:id="delete" context="user.id">Delete</t:actionlink>
+            </t:parameter>
+        </t:grid>
+    </body>
+</html>
+]]></source>
+
+                <p>
+                    We now explicitly provide a column for the "delete" property, which doesn't exist. In addition, a
+                    block
+                    for the "delete" property has been added that includes an ActionLink
+                    used to delete the user for the current row. This property is a
+                    <em>virtual</em>
+                    property because it doesn't correspond to a property
+                    of the data object, User.
+                </p>
+
+            </subsection>
+
+            <subsection name="UserList.java">
+                <source><![CDATA[
+public class UserList
+{
+    @Inject
+    private UserDAO _userDAO;
+
+    @Property
+    private User _user;
+
+    public List<User> getUsers() { return _userDAO.findAll(); }
+
+    void onActionFromDelete(long userId)
+    {
+        _userDAO.remove(userId);
+    }  
+}]]></source>
+
+
+                <p>
+                    The only addition here is an event handler method for when the delete link is clicked.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="UserList.properties">
+                <source><![CDATA[
+delete-label=Delete user?]]></source>
+
+                <p>
+                    The normal column title for the "delete" property would be "Delete". Using the
+                    page's message catalog we can override that.
+                </p>
+            </subsection>
+
+
+        </section>
+
+
+        <section name="Notes">
+
+            <p>
+                Tapestry does a lot of work to help you with the source parameter. The parameter type
+                is GridDataSource, but Tapestry has built-in coercions from
+                Object[] and List. In more complicated cases, such as very large
+                queries against a database, you will want to provide your own implementation
+                of GridDataSource, to minimimze the sizes of queries and result sets.
+            </p>
+
+
+            <subsection name="CSS">
+
+                <p>The Grid component is designed to be customized via CSS. As it renders &lt;th&gt;, &lt;tr&gt; and
+                    &lt;td&gt; elements,
+                    it generates CSS class attributes for each element. You can then add customized CSS rules, even
+                    overriding the Tapestry defaults,
+                    to present the Grid as desired. This is often used to set the width of a column to a fixed value.
+                </p>
+
+                <dl>
+                    <dt>
+                        <em>propertyId</em>
+                    </dt>
+                    <dd>Added to &lt;th&gt; elements to allow customization of a particular column's header,
+                        and added to &lt;td&gt; elements to allow customization of a particular column's data cells.
+                    </dd>
+
+                    <dt>t-first</dt>
+                    <dd>Added to the first &lt;th&gt; and the first &lt;tr&gt; of the &lt;tbody&gt; (the data portion of
+                        the table).
+                    </dd>
+
+                    <dt>t-last</dt>
+                    <dd>Added to the last &lt;th&gt; and the last &lt;tr&gt;.</dd>
+
+                    <dt>t-sort-column-ascending</dt>
+                    <dd>Added to the &lt;th&gt; and all corresponding &lt;td&gt; elements for the column that is the
+                        current sort column (if any,
+                        for ascending sort).
+                    </dd>
+
+                    <dt>t-sort-column-descending</dt>
+                    <dd>As with t-soft-column-ascending, but for a descending sort.</dd>
+
+                </dl>
+
+                <p>
+                    The added CSS classes can get quite verbose; the Grid's lean parameter allows the propertyId CSS
+                    class attribute value to be omitted. Even in lean mode, the other
+                    CSS class attribute values are rendered.
+                </p>
+
+            </subsection>
+
+        </section>
+
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridCell.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridCell.java
new file mode 100644
index 0000000..5f99836
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridCell.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.corelib.base.AbstractPropertyOutput;
+
+/**
+ * Part of {@link Grid} that renders the markup inside a single data cell. GridCell is used inside a pair of loops; the
+ * outer loop for each row, the inner loop for each property of the row.
+ */
+public class GridCell extends AbstractPropertyOutput
+{
+    Object beginRender(MarkupWriter writer)
+    {
+        return renderPropertyValue(writer, getPropertyModel().getId() + "Cell");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java
new file mode 100644
index 0000000..98a0657
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridColumns.java
@@ -0,0 +1,236 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.Block;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.grid.ColumnSort;
+import org.apache.tapestry.grid.GridConstants;
+import org.apache.tapestry.grid.GridModel;
+import org.apache.tapestry.grid.GridSortModel;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+/**
+ * Renders out the column headers for the grid, including links (where appropriate) to control column sorting.
+ */
+@SupportsInformalParameters
+public class GridColumns
+{
+    /**
+     * The object that provides access to bean and data models, which is typically the enclosing Grid component.
+     */
+    @Parameter(value = "componentResources.container")
+    private GridModel gridModel;
+
+    /**
+     * If true, then the CSS class on each &lt;TH&gt; element will be omitted, which can reduce the amount of output
+     * from the component overall by a considerable amount. Leave this as false, the default, when you are leveraging
+     * the CSS to customize the look and feel of particular columns.
+     */
+    @Parameter
+    private boolean lean;
+
+    /**
+     * Where to look for informal parameter Blocks used to override column headers.  The default is to look for such
+     * overrides in the GridColumns component itself, but this is usually overridden.
+     */
+    @Parameter("componentResources")
+    private ComponentResources overrides;
+
+
+    /**
+     * If not null, then each link is output as a link to update the specified zone.
+     */
+    @Parameter
+    private String zone;
+
+    @SuppressWarnings("unused")
+    @Component(
+            parameters = { "event=sort", "disabled=sortDisabled", "context=columnContext", "class=sortLinkClass", "zone=inherit:zone" })
+    private EventLink sort, sort2;
+
+    @Inject
+    @Path("sort-asc.png")
+    private Asset ascendingAsset;
+
+    @Inject
+    @Path("sort-desc.png")
+    private Asset descendingAsset;
+
+    @Inject
+    @Path("sortable.png")
+    private Asset sortableAsset;
+
+    @Inject
+    private Messages messages;
+
+    @Inject
+    private Block standardHeader;
+
+    @Property
+    private int columnIndex;
+
+    private int lastColumnIndex;
+
+    @Property(write = false)
+    private PropertyModel columnModel;
+
+    @Inject
+    private ComponentResources resources;
+
+    void setupRender()
+    {
+        lastColumnIndex = gridModel.getDataModel().getPropertyNames().size() - 1;
+    }
+
+    public boolean isSortDisabled()
+    {
+        return !columnModel.isSortable();
+    }
+
+    public String getSortLinkClass()
+    {
+        switch (getSortForColumn())
+        {
+            case ASCENDING:
+                return GridConstants.SORT_ASCENDING_CLASS;
+
+            case DESCENDING:
+                return GridConstants.SORT_DESCENDING_CLASS;
+
+            default:
+                return null;
+        }
+    }
+
+    private ColumnSort getSortForColumn()
+    {
+        GridSortModel sortModel = gridModel.getSortModel();
+
+        String columnId = columnModel.getId();
+
+        return sortModel.getColumnSort(columnId);
+    }
+
+    public String getHeaderClass()
+    {
+        List<String> classes = CollectionFactory.newList();
+
+        if (!lean) classes.add(columnModel.getId());
+
+        String sort = getSortLinkClass();
+
+        if (sort != null) classes.add(sort);
+
+        if (columnIndex == 0) classes.add(GridConstants.FIRST_CLASS);
+
+        if (columnIndex == lastColumnIndex) classes.add(GridConstants.LAST_CLASS);
+
+        return TapestryInternalUtils.toClassAttributeValue(classes);
+    }
+
+    public boolean isActiveSortColumn()
+    {
+        return getSortForColumn() != ColumnSort.UNSORTED;
+    }
+
+    /**
+     * Normal, non-Ajax event handler.
+     */
+
+    void onSort(String columnId)
+    {
+        gridModel.getSortModel().updateSort(columnId);
+    }
+
+    /**
+     * Ajax event handler, which carries the zone id.
+     */
+    boolean onSort(String columnId, String zone)
+    {
+        onSort(columnId);
+
+        resources.triggerEvent(InternalConstants.GRID_INPLACE_UPDATE, new Object[] { zone }, null);
+
+        // Event is handled, don't trigger further event handler methods.
+
+        return true;
+    }
+
+    public Asset getIcon()
+    {
+        switch (getSortForColumn())
+        {
+            case ASCENDING:
+                return ascendingAsset;
+
+            case DESCENDING:
+                return descendingAsset;
+
+            default:
+                return sortableAsset;
+        }
+    }
+
+    public Object getColumnContext()
+    {
+        if (zone == null) return columnModel.getId();
+
+        return new Object[] { columnModel.getId(), zone };
+    }
+
+    public String getIconLabel()
+    {
+        switch (getSortForColumn())
+        {
+            case ASCENDING:
+                return messages.get("ascending");
+            case DESCENDING:
+                return messages.get("descending");
+            default:
+                return messages.get("sortable");
+        }
+    }
+
+    public List<String> getColumnNames()
+    {
+        return gridModel.getDataModel().getPropertyNames();
+    }
+
+
+    public void setColumnName(String columnName)
+    {
+        columnModel = gridModel.getDataModel().get(columnName);
+    }
+
+
+    public Block getBlockForColumn()
+    {
+        Block override = overrides.getBlockParameter(columnModel.getId() + "Header");
+
+        if (override != null) return override;
+
+        return standardHeader;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridPager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridPager.java
new file mode 100644
index 0000000..5448f33
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridPager.java
@@ -0,0 +1,181 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.grid.GridDataSource;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Generates a series of links used to jump to a particular page index within the overall data set.
+ */
+public class GridPager
+{
+    /**
+     * The source of the data displayed by the grid (this is used to determine {@link GridDataSource#getAvailableRows()
+     * how many rows are available}, which in turn determines the page count).
+     */
+    @Parameter(required = true)
+    private GridDataSource source;
+
+    /**
+     * The number of rows displayed per page.
+     */
+    @Parameter(required = true)
+    private int rowsPerPage;
+
+    /**
+     * The current page number (indexed from 1).
+     */
+    @Parameter(required = true)
+    private int currentPage;
+
+    /**
+     * Number of pages before and after the current page in the range. The pager always displays links for 2 * range + 1
+     * pages, unless that's more than the total number of available pages.
+     */
+    @Parameter("5")
+    private int range;
+
+    /**
+     * If not null, then each link is output as a link to update the specified zone.
+     */
+    @Parameter
+    private String zone;
+
+    private int lastIndex;
+
+    private int maxPages;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private Messages messages;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    void beginRender(MarkupWriter writer)
+    {
+        int availableRows = source.getAvailableRows();
+
+        maxPages = ((availableRows - 1) / rowsPerPage) + 1;
+
+        if (maxPages < 2) return;
+
+        writer.element("div", "class", "t-data-grid-pager");
+
+        lastIndex = 0;
+
+        for (int i = 1; i <= 2; i++)
+            writePageLink(writer, i);
+
+        int low = currentPage - range;
+        int high = currentPage + range;
+
+        if (low < 1)
+        {
+            low = 1;
+            high = 2 * range + 1;
+        }
+        else
+        {
+            if (high > maxPages)
+            {
+                high = maxPages;
+                low = high - 2 * range;
+            }
+        }
+
+        for (int i = low; i <= high; i++)
+            writePageLink(writer, i);
+
+        for (int i = maxPages - 1; i <= maxPages; i++)
+            writePageLink(writer, i);
+
+        writer.end();
+    }
+
+    private void writePageLink(MarkupWriter writer, int pageIndex)
+    {
+        if (pageIndex < 1 || pageIndex > maxPages) return;
+
+        if (pageIndex <= lastIndex) return;
+
+        if (pageIndex != lastIndex + 1) writer.write(" ... ");
+
+        lastIndex = pageIndex;
+
+        if (pageIndex == currentPage)
+        {
+            writer.element("span", "class", "current");
+            writer.write(Integer.toString(pageIndex));
+            writer.end();
+            return;
+        }
+
+        Object[] context = zone == null
+                           ? new Object[] { pageIndex }
+                           : new Object[] { pageIndex, zone };
+
+        Link link = resources.createActionLink(EventConstants.ACTION, false, context);
+
+        Element element = writer.element("a", "href", link, "title", messages.format("goto-page", pageIndex));
+
+        writer.write(Integer.toString(pageIndex));
+        writer.end();
+
+        if (zone != null)
+        {
+            String id = renderSupport.allocateClientId(resources);
+
+            element.attribute("id", id);
+
+            clientBehaviorSupport.linkZone(id, zone);
+        }
+    }
+
+    /**
+     * Normal, non-Ajax event handler.
+     */
+    void onAction(int newPage)
+    {
+        // TODO: Validate newPage in range
+
+        currentPage = newPage;
+    }
+
+    /**
+     * Akjax event handler, passing the zone along.
+     */
+    boolean onAction(int newPage, String zone)
+    {
+        onAction(newPage);
+
+        resources.triggerEvent(InternalConstants.GRID_INPLACE_UPDATE, new Object[] { zone }, null);
+
+        return true; // abort event
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java
new file mode 100644
index 0000000..799953b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/GridRows.java
@@ -0,0 +1,230 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.grid.GridConstants;
+import org.apache.tapestry.grid.GridDataSource;
+import org.apache.tapestry.grid.GridModel;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.FormSupport;
+
+import java.util.List;
+
+/**
+ * Renders out a series of rows within the table.
+ * <p/>
+ * Inside a {@link Form}, a series of row index numbers are stored into the form ( {@linkplain FormSupport#store(Object,
+ * ComponentAction) as ComponentActions}). This is not ideal ... in a situation where the data set can shift between the
+ * form render and the form submission, this can cause unexpected results, including applying changes to the wrong
+ * objects.
+ */
+public class GridRows
+{
+    private int startRow;
+
+    static class SetupForRow implements ComponentAction<GridRows>
+    {
+        private static final long serialVersionUID = -3216282071752371975L;
+
+        private final int rowIndex;
+
+        public SetupForRow(int rowIndex)
+        {
+            this.rowIndex = rowIndex;
+        }
+
+        public void execute(GridRows component)
+        {
+            component.setupForRow(rowIndex);
+        }
+    }
+
+    /**
+     * Parameter used to set the CSS class for each row (each &lt;tr&gt; element) within the &lt;tbody&gt;). This is not
+     * cached, so it will be recomputed for each row.
+     */
+    @Parameter(cache = false)
+    private String rowClass;
+
+    /**
+     * Object that provides access to the bean and data models used to render the Grid.
+     */
+    @Parameter(value = "componentResources.container")
+    private GridModel gridModel;
+
+    /**
+     * Number of rows displayed on each page. Long result sets are split across multiple pages.
+     */
+    @Parameter(required = true)
+    private int rowsPerPage;
+
+    /**
+     * The current page number within the available pages (indexed from 1).
+     */
+    @Parameter(required = true)
+    private int currentPage;
+
+    /**
+     * The current row being rendered, this is primarily an output parameter used to allow the Grid, and the Grid's
+     * container, to know what object is being rendered.
+     */
+    @Parameter(required = true)
+    @Property(write = false)
+    private Object row;
+
+    /**
+     * If true, then the CSS class on each &lt;TD&gt; cell will be omitted, which can reduce the amount of output from
+     * the component overall by a considerable amount. Leave this as false, the default, when you are leveraging the CSS
+     * to customize the look and feel of particular columns.
+     */
+    @Parameter
+    private boolean lean;
+
+    /**
+     * If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off. Defaults to false,
+     * enabling state saving logic within Forms.
+     */
+    @Parameter(name = "volatile")
+    private boolean volatileState;
+
+    @Environmental(false)
+    private FormSupport formSupport;
+
+    private boolean recordingStateInsideForm;
+
+    private int endRow;
+
+    private int rowIndex;
+
+    private String propertyName;
+
+    @Property(write = false)
+    private PropertyModel columnModel;
+
+    public String getRowClass()
+    {
+        List<String> classes = CollectionFactory.newList();
+
+        // Not a cached parameter, so careful to only access it once.
+
+        String rc = rowClass;
+
+        if (rc != null) classes.add(rc);
+
+        if (rowIndex == startRow) classes.add(GridConstants.FIRST_CLASS);
+
+        if (rowIndex == endRow) classes.add(GridConstants.LAST_CLASS);
+
+        return TapestryInternalUtils.toClassAttributeValue(classes);
+    }
+
+    public String getCellClass()
+    {
+        List<String> classes = CollectionFactory.newList();
+
+        String id = gridModel.getDataModel().get(propertyName).getId();
+
+        if (!lean)
+        {
+            classes.add(id);
+
+            switch (gridModel.getSortModel().getColumnSort(id))
+            {
+                case ASCENDING:
+                    classes.add(GridConstants.SORT_ASCENDING_CLASS);
+                    break;
+
+                case DESCENDING:
+                    classes.add(GridConstants.SORT_DESCENDING_CLASS);
+                    break;
+
+                default:
+            }
+        }
+
+
+        return TapestryInternalUtils.toClassAttributeValue(classes);
+    }
+
+    void setupRender()
+    {
+        GridDataSource dataSource = gridModel.getDataSource();
+
+        int availableRows = dataSource.getAvailableRows();
+
+        int maxPages = ((availableRows - 1) / rowsPerPage) + 1;
+
+        // This can sometimes happen when the number of items shifts between requests.
+
+        if (currentPage > maxPages) currentPage = maxPages;
+
+        startRow = (currentPage - 1) * rowsPerPage;
+        endRow = Math.min(availableRows - 1, startRow + rowsPerPage - 1);
+
+        rowIndex = startRow;
+
+        recordingStateInsideForm = !volatileState && formSupport != null;
+    }
+
+    /**
+     * Callback method, used when recording state to a form, or called directly when not recording state.
+     */
+    void setupForRow(int rowIndex)
+    {
+        row = gridModel.getDataSource().getRowValue(rowIndex);
+
+    }
+
+    void beginRender()
+    {
+        // When needed, store a callback used when the form is submitted.
+
+        if (recordingStateInsideForm) formSupport.store(this, new SetupForRow(rowIndex));
+
+        // And do it now for the render.
+
+        setupForRow(rowIndex);
+    }
+
+    boolean afterRender()
+    {
+        rowIndex++;
+
+        return rowIndex > endRow;
+    }
+
+    public List<String> getPropertyNames()
+    {
+        return gridModel.getDataModel().getPropertyNames();
+    }
+
+    public String getPropertyName()
+    {
+        return propertyName;
+    }
+
+    public void setPropertyName(String propertyName)
+    {
+        this.propertyName = propertyName;
+
+        columnModel = gridModel.getDataModel().get(propertyName);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.java
new file mode 100644
index 0000000..50d7c7b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * Conditionally renders its body.
+ */
+public class If
+{
+    /**
+     * If true, then the body of the If component is rendered. If false, the body is omitted.
+     */
+    @Parameter(required = true)
+    private boolean test;
+
+    /**
+     * Optional parameter to invert the test. If true, then the body is rendered when the test parameter is false (not
+     * true).
+     *
+     * @see Unless
+     */
+    @Parameter
+    private boolean negate;
+
+    /**
+     * An alternate {@link org.apache.tapestry.Block} to render if the test parameter is false. The default, null, means
+     * render nothing in that situation.
+     */
+    @Parameter(name = "else")
+    private Block elseBlock;
+
+    /**
+     * Returns null if the test parameter is true, which allows normal rendering (of the body). If the test parameter is
+     * false, returns the else parameter (this may also be null).
+     */
+    Object beginRender()
+    {
+        return test != negate ? null : elseBlock;
+    }
+
+    /**
+     * If the test parameter is true, then the body is rendered, otherwise not. The component does not have a template
+     * or do any other rendering besides its body.
+     */
+    boolean beforeRenderBody()
+    {
+        return test != negate;
+    }
+
+    void setup(boolean test, boolean negate, Block elseBlock)
+    {
+        this.test = test;
+        this.negate = negate;
+        this.elseBlock = elseBlock;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.xdoc
new file mode 100644
index 0000000..7aa13a9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/If.xdoc
@@ -0,0 +1,55 @@
+<document>
+    <body>
+        <section name="Examples">
+
+            <subsection name="Start.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Welcome!</h1>
+
+        <t:if test="user">
+            Welcome back, ${user.firstName}
+            <t:parameter name="else">
+                <t:pagelink name="login">Login</t:pagelink> /
+                <t:pagelink name="register">Register</t:pagelink>
+            </t:parameter>
+        </t:if>
+        
+        . . .
+
+</html>]]></source>
+
+                <p>
+                    Here, the main text is rendered if the user is logged in (the user property will
+                    be non-null after the user logs in). Otherwise, links to a login and register
+                    page are rendered.
+                </p>
+
+            </subsection>
+
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                Tapestry has many builtin coercions to boolean:
+            </p>
+
+            <dl>
+                <dt>String</dt>
+                <dd>True if non-blank and not the literal string "false" (case insensitive)</dd>
+                <dt>Number</dt>
+                <dd>True if non-zero</dd>
+                <dt>Collection</dt>
+                <dd>True if non-empty</dd>
+                <dt>Object</dt>
+                <dd>True (as long as its not null)</dd>
+            </dl>
+
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.java
new file mode 100644
index 0000000..3b93666
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.java
@@ -0,0 +1,100 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationDecorator;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Heartbeat;
+
+/**
+ * Generates a &lt;label&gt; element for a particular field.
+ * <p/>
+ * A Label will render its body, if it has one.  However, in most cases it will not have a body, and will render its
+ * {@linkplain org.apache.tapestry.Field#getLabel() field's label} as it's body. Remember, however, that it is the field
+ * label that will be used in any error messages. The Label component allows for client- and server-side validation
+ * error decorations.
+ */
+@SupportsInformalParameters
+public class Label
+{
+    /**
+     * The for parameter is used to identify the {@link Field} linked to this label (it is named this way because it
+     * results in the for attribute of the label element).
+     */
+    @Parameter(name = "for", required = true, defaultPrefix = "component")
+    private Field field;
+
+    @Environmental
+    private Heartbeat heartbeat;
+
+    @Environmental
+    private ValidationDecorator decorator;
+
+    @Inject
+    private ComponentResources resources;
+
+    private Element labelElement;
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        final Field field = this.field;
+
+        decorator.beforeLabel(field);
+
+        labelElement = writer.element("label");
+
+        resources.renderInformalParameters(writer);
+
+        // Since we don't know if the field has rendered yet, we need to defer writing the for and id
+        // attributes until we know the field has rendered (and set its clientId property). That's
+        // exactly what Heartbeat is for.
+
+        Runnable command = new Runnable()
+        {
+            public void run()
+            {
+                String fieldId = field.getClientId();
+
+                labelElement.forceAttributes("for", fieldId, "id", fieldId + ":label");
+
+                decorator.insideLabel(field, labelElement);
+            }
+        };
+
+        heartbeat.defer(command);
+    }
+
+    @AfterRender
+    void after(MarkupWriter writer)
+    {
+        // If the Label element has a body that renders some non-blank output, that takes precendence
+        // over the label string provided by the field.
+
+        boolean bodyIsBlank = InternalUtils.isBlank(labelElement.getChildMarkup());
+
+        if (bodyIsBlank) writer.write(field.getLabel());
+
+        writer.end(); // label
+
+        decorator.afterLabel(field);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.xdoc
new file mode 100644
index 0000000..66cd130
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Label.xdoc
@@ -0,0 +1,50 @@
+<document>
+    <body>
+        <section name="Examples">
+
+            <subsection name="Search.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+
+        <t:form>
+            <t:label for="search"/>
+            <t:textfield t:id="search" size="50"/>
+
+            <t:checkbox t:id="all"/>
+            <t:label for="all">
+                Include out of date records
+            </t:label>
+
+        . . .
+
+</html>]]></source>
+
+                <p>
+                    This demonstrates that the Label can come before
+                    or after the form control element component (the TextField and Checkbox components).
+                    When a Label has a body, that takes precendence over the field's label, though the field's
+                    label is what's used in any error messages.
+                </p>
+
+            </subsection>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                The Label component is very important for user accessiblity. A user will be able to click
+                on the label to move the cursor into the corresponding field.
+            </p>
+
+            <p>
+                The Label component supports informal parameters; this can be very useful
+                for adding the
+                <code>accesskey</code>
+                attribute supported by most browsers.
+            </p>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java
new file mode 100644
index 0000000..98de695
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java
@@ -0,0 +1,390 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.ioc.annotation.Inject;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Heartbeat;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Basic looping class; loops over a number of items (provided by its source parameter), rendering its body for each
+ * one. It turns out that gettting the component to <em>not</em> store its state in the Form is very tricky and, in
+ * fact, a series of commands for starting and ending heartbeats, and advancing through the iterator, are still stored.
+ * For a non-volatile Loop inside the form, the Loop stores a series of commands that start and end heartbeats and store
+ * state (either as full objects when there the encoder parameter is not bound, or as client-side objects when there is
+ * an encoder).
+ */
+@SupportsInformalParameters
+public class Loop
+{
+    /**
+     * Setup command for non-volatile rendering.
+     */
+    private static final ComponentAction<Loop> RESET_INDEX = new ComponentAction<Loop>()
+    {
+        private static final long serialVersionUID = 6477493424977597345L;
+
+        public void execute(Loop component)
+        {
+            component.resetIndex();
+        }
+    };
+
+    /**
+     * Setup command for volatile rendering. Volatile rendering relies on re-acquiring the Iterator and working our way
+     * through it (and hoping for the best!).
+     */
+    private static final ComponentAction<Loop> SETUP_FOR_VOLATILE = new ComponentAction<Loop>()
+    {
+        private static final long serialVersionUID = -977168791667037377L;
+
+        public void execute(Loop component)
+        {
+            component.setupForVolatile();
+        }
+
+    };
+
+    /**
+     * Advances to next value in a volatile way. So, the <em>number</em> of steps is intrinsically stored in the Form
+     * (as the number of ADVANCE_VOLATILE commands), but the actual values are expressly stored only on the server.
+     */
+    private static final ComponentAction<Loop> ADVANCE_VOLATILE = new ComponentAction<Loop>()
+    {
+        private static final long serialVersionUID = -4600281573714776832L;
+
+        public void execute(Loop component)
+        {
+            component.advanceVolatile();
+        }
+    };
+
+    /**
+     * Used in both volatile and non-volatile mode to end the current heartbeat (started by either ADVANCE_VOLATILE or
+     * one of the RestoreState commands). Also increments the index.
+     */
+    private static final ComponentAction<Loop> END_HEARTBEAT = new ComponentAction<Loop>()
+    {
+        private static final long serialVersionUID = -977168791667037377L;
+
+        public void execute(Loop component)
+        {
+            component.endHeartbeat();
+        }
+
+    };
+
+    /**
+     * Restores a state value (this is the case when there is no encoder and the complete value is stored).
+     */
+    static class RestoreState implements ComponentAction<Loop>
+    {
+        private static final long serialVersionUID = -3926831611368720764L;
+
+        private final Object storedValue;
+
+        public RestoreState(final Object storedValue)
+        {
+            this.storedValue = storedValue;
+        }
+
+        public void execute(Loop component)
+        {
+            component.restoreState(storedValue);
+        }
+    }
+
+    /**
+     * Restores the value using a stored primary key via {@link PrimaryKeyEncoder#toValue(Serializable)}.
+     */
+    static class RestoreStateViaEncodedPrimaryKey implements ComponentAction<Loop>
+    {
+        private static final long serialVersionUID = -2422790241589517336L;
+
+        private final Serializable primaryKey;
+
+        public RestoreStateViaEncodedPrimaryKey(final Serializable primaryKey)
+        {
+            this.primaryKey = primaryKey;
+        }
+
+        public void execute(Loop component)
+        {
+            component.restoreStateViaEncodedPrimaryKey(primaryKey);
+        }
+    }
+
+    /**
+     * Stores a list of keys to be passed to {@link PrimaryKeyEncoder#prepareForKeys(List)}.
+     */
+    static class PrepareForKeys implements ComponentAction<Loop>
+    {
+        private static final long serialVersionUID = -6515255627142956828L;
+
+        /**
+         * The variable is final, the contents are mutable while the Loop renders.
+         */
+        private final List<Serializable> keys;
+
+        public PrepareForKeys(final List<Serializable> keys)
+        {
+            this.keys = keys;
+        }
+
+        public void execute(Loop component)
+        {
+            component.prepareForKeys(keys);
+        }
+    }
+
+    /**
+     * Defines the collection of values for the loop to iterate over. If not specified, defaults to a property of the
+     * container whose name
+     */
+    @Parameter(required = true, principal = true)
+    private Iterable<?> source;
+
+    /**
+     * Optional primary key converter; if provided and inside a form and not volatile, then each iterated value is
+     * converted and stored into the form.
+     */
+    @Parameter
+    private PrimaryKeyEncoder<Serializable, Object> encoder;
+
+    /**
+     * If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off. Defaults to false,
+     * enabling state saving logic within Forms.
+     */
+    @Parameter(name = "volatile")
+    private boolean volatileState;
+
+    @Environmental(false)
+    private FormSupport formSupport;
+
+    /**
+     * The element to render. If not null, then the loop will render the indicated element around its body (on each pass
+     * through the loop). The default is derived from the component template.
+     */
+    @Parameter(value = "prop:componentResources.elementName", defaultPrefix = BindingConstants.LITERAL)
+    private String element;
+
+    /**
+     * The current value, set before the component renders its body.
+     */
+    @Parameter
+    private Object value;
+
+    /**
+     * The index into the source items.
+     */
+    @Parameter
+    private int index;
+
+    private Iterator<?> iterator;
+
+    @Environmental
+    private Heartbeat heartbeat;
+
+    private boolean storeRenderStateInForm;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private ComponentDefaultProvider componentDefaultProvider;
+
+    Binding defaultSource()
+    {
+        return componentDefaultProvider.defaultBinding("source", resources);
+    }
+
+    @SetupRender
+    boolean setup()
+    {
+        index = 0;
+
+        if (source == null) return false;
+
+        iterator = source.iterator();
+
+        storeRenderStateInForm = formSupport != null && !volatileState;
+
+        // Only render the body if there is something to iterate over
+
+        boolean result = iterator.hasNext();
+
+        if (formSupport != null && result)
+        {
+
+            formSupport.store(this, volatileState ? SETUP_FOR_VOLATILE : RESET_INDEX);
+
+            if (encoder != null)
+            {
+                List<Serializable> keyList = newList();
+
+                // We'll keep updating the _keyList while the Loop renders, the values will "lock
+                // down" when the Form serializes all the data.
+
+                formSupport.store(this, new PrepareForKeys(keyList));
+            }
+        }
+
+        return result;
+    }
+
+    private void prepareForKeys(List<Serializable> keys)
+    {
+        // Again, the encoder existed when we rendered, we better have another available
+        // when the enclosing Form is submitted.
+
+        encoder.prepareForKeys(keys);
+    }
+
+    private void setupForVolatile()
+    {
+        index = 0;
+        iterator = source.iterator();
+    }
+
+    private void advanceVolatile()
+    {
+        value = iterator.next();
+
+        startHeartbeat();
+    }
+
+    /**
+     * Begins a new heartbeat.
+     */
+    @BeginRender
+    void begin()
+    {
+        value = iterator.next();
+
+        if (storeRenderStateInForm)
+        {
+            if (encoder == null)
+            {
+                formSupport.store(this, new RestoreState(value));
+            }
+            else
+            {
+                Serializable primaryKey = encoder.toKey(value);
+                formSupport.store(this, new RestoreStateViaEncodedPrimaryKey(primaryKey));
+            }
+        }
+
+        if (formSupport != null && volatileState) formSupport.store(this, ADVANCE_VOLATILE);
+
+        startHeartbeat();
+    }
+
+    private void startHeartbeat()
+    {
+        heartbeat.begin();
+    }
+
+    void beforeRenderBody(MarkupWriter writer)
+    {
+        if (element != null)
+        {
+            writer.element(element);
+            resources.renderInformalParameters(writer);
+        }
+    }
+
+    void afterRenderBody(MarkupWriter writer)
+    {
+        if (element != null) writer.end();
+    }
+
+    /**
+     * Ends the current heartbeat.
+     */
+    @AfterRender
+    boolean after()
+    {
+        endHeartbeat();
+
+        if (formSupport != null) formSupport.store(this, END_HEARTBEAT);
+
+        return !iterator.hasNext();
+    }
+
+    private void endHeartbeat()
+    {
+        heartbeat.end();
+
+        index++;
+    }
+
+    private void resetIndex()
+    {
+        index = 0;
+    }
+
+    /**
+     * Restores state previously stored by the Loop into a Form.
+     */
+    private void restoreState(Object storedValue)
+    {
+        value = storedValue;
+
+        startHeartbeat();
+    }
+
+    /**
+     * Restores state previously encoded by the Loop and stored into the Form.
+     */
+    private void restoreStateViaEncodedPrimaryKey(Serializable primaryKey)
+    {
+        // We assume that if a encoder is available when we rendered, that one will be available
+        // when the form is submitted. TODO: Check for this.
+
+        Object restoredValue = encoder.toValue(primaryKey);
+
+        restoreState(restoredValue);
+    }
+
+    // For testing:
+
+    int getIndex()
+    {
+        return index;
+    }
+
+    Object getValue()
+    {
+        return value;
+    }
+
+    void setSource(Iterable<?> source)
+    {
+        this.source = source;
+    }
+
+    void setHeartbeat(Heartbeat heartbeat)
+    {
+        this.heartbeat = heartbeat;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.xdoc
new file mode 100644
index 0000000..dfb5690
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.xdoc
@@ -0,0 +1,220 @@
+<document>
+    <body>
+        <section name="Basic Example">
+
+            <p>
+                This example is based around a NavBar component that generates a set
+                of links to other pages in the applilcation.
+            </p>
+
+            <subsection name="NavBar.tml">
+
+                <source><![CDATA[
+<table class="navigation" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+   <tr>
+        <t:loop source="pageNames" value="pageName">
+            <td class="${tabClass}">
+                <t:pagelink page="pageName">${pageName}</t:pagelink>
+            </td>
+        </t:loop>
+    </tr>
+
+</table>]]></source>
+
+                <p>
+                    We are assuming that the NavBar component
+                    has a pageNames property (possibly a parameter). The Loop will
+                    iterate over those page names and store each into its value parameter.
+                </p>
+
+
+            </subsection>
+
+
+            <subsection name="NavBar.java">
+
+                <source><![CDATA[
+public class NavBar
+{
+    @Parameter(defaultPrefix="literal", required=true)
+    private String _pages;
+
+    @Inject
+    private ComponentResources _resources;
+
+    private String _pageName;
+
+    public String getPageName() { return _pageName; }
+
+    public void setPageName(String pageName) { _pageName = pageName; }
+
+    public String[] getPageNames()
+    {
+        return _pages.split(",");
+    }
+
+    public String getTabClass()
+    {
+        if (_pageName.equalsIgnoreCase(_resources.getPageName())
+            return "current";
+
+        return null;
+    }
+}
+]]></source>
+
+                <p>
+                    The component converts its pages parameter into the pageNames property
+                    by splitting it at the commas. It tracks the current pageName of the loop
+                    not just to generate the links, but to calculate the CSS class of each
+                    &lt;td&gt; element on the fly. This way we can give the tab corresponding
+                    to the current page a special look or highlight.
+                </p>
+
+            </subsection>
+
+        </section>
+
+        <section name="Invisible Instrumentation">
+
+            <p>We can fold together the Loop component and the &lt;td&gt; element:</p>
+
+            <subsection name="NavBar.tml">
+
+                <source><![CDATA[
+<table class="navigation" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+   <tr>
+        <td t:type="loop" source="pageNames" value="pageName" class="${tabClass}">
+            <t:pagelink page="pageName">${pageName}</t:pagelink>
+        </td>
+    </tr>
+
+</table>]]></source>
+
+                <p>Using the
+                    <code>t:type="loop"</code>
+                    attribute, the other way to identify a template
+                    element as a component, allows the Loop component to render the element's tag,
+                    the &lt;td&gt; on each iteration, along with informal parameters (the class attribute). This is
+                    called<em>invisible instrumentation</em>, and it is more concise and more
+                    editor/preview friendly than Tapestry's typical markup.
+                </p>
+            </subsection>
+        </section>
+
+        <section name="Forms and Loops Example">
+
+            <p>
+                Tapestry form control element components (TextField, etc.) work inside loops. However,
+                some additional configuration is needed to make this work efficiently.
+            </p>
+
+            <p>
+                With no extra configuration, each value object will be serialized into the form (if
+                you view the rendered markup, you'll see a hidden form field containing serialized data needed by
+                Tapestry to process the form). This can become very bloated, or may not work if the objects being
+                iterated
+                are not serializable.
+            </p>
+
+            <p>
+                The typical case is database driven; you are editting objects from a database and need
+                those objects back when the form is submitted. All that should be stored
+                on the client is the
+                <em>ids</em>
+                of those objects. Thats what the encoder
+                parameter is for.
+            </p>
+
+            <subsection name="EditOrder.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+
+        <h1>Edit Order Quantities</h1>
+
+        <t:form>
+
+            <t:errors/>
+
+            <t:loop source="items" value="item" encoder="encoder">
+                <div class="line-item">
+                    <t:label for="quantity">${item.product.name}</t:label>
+                    <t:textfield t:id="quantity" value="item.quantity"/>
+                </div>
+            </t:loop>
+
+            <input type="submit" value="Update"/>
+        </t:form>
+    </body>
+</html>]]></source>
+
+                <p>
+                    The TextField component is rendered multiple times, once
+                    for each LineItem in the Order.
+                </p>
+            </subsection>
+
+            <subsection name="EditOrder.java">
+                <source><![CDATA[
+public class EditOrder
+{
+    @Inject
+    private OrderDAO _orderDAO;
+
+    private final PrimaryKeyEncoder<Long,LineItem> _encoder = new PrimaryKeyEncoder<Long,LineItem>()
+    {
+        public Long toKey(LineItem value) { return value.getId(); }
+
+        public void prepareForKeys(List<Long> keys) { }
+
+        public LineItem toValue(Long key)
+        {
+            return _orderDAO.getLineItem(key);
+        }
+    };
+
+    @Persist
+    private long _orderId;
+
+    private LineItem _item;
+
+    public PrimaryKeyEncoder getEncoder() { return _encoder ; }
+
+    public List<LineItem> getItems()
+    {
+        return _orderDAO.getLineItemsForOrder(_orderId);
+    }
+
+    public LineItem getItem() { return _item; }
+
+    public void setLineItem(LineItem item) { _item = item; }
+}]]></source>
+
+                <p>
+                    Here, we expect the OrderDAO service to do most of the work,
+                    and we create a wrapper around it, in the form of the
+                    PrimeryKeyEncoder instance.
+                </p>
+
+                <p>
+                    We've glossed over a few issues here, including how to handle
+                    the case that a particular item has been deleted or changed
+                    between the render request and the form submission.
+                </p>
+
+                <p>
+                    Accounting for those situations would largely be encapsulated inside
+                    the PrimeryKeyEncoder instance.
+                </p>
+
+
+            </subsection>
+
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Output.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Output.java
new file mode 100644
index 0000000..a93c583
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Output.java
@@ -0,0 +1,106 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+
+import java.text.Format;
+
+/**
+ * A component for formatting output. If the component is represented in the template using an element, then the element
+ * (plus any informal parameters) will be output around the formatted value.
+ */
+@SupportsInformalParameters
+public class Output
+{
+    /**
+     * The value to be output (before formatting). If the formatted value is blank, no output is produced.
+     */
+    @Parameter(required = true)
+    private Object value;
+
+    /**
+     * The format to be applied to the object.
+     */
+    @Parameter(required = true)
+    private Format format;
+
+    /**
+     * If true, the default, then output is filtered, escaping any reserved characters. If false, the output is written
+     * raw.
+     */
+    @Parameter
+    private boolean filter = true;
+
+    /**
+     * The element name, derived from the component template. This can even be overridden manually if desired (for
+     * example, to sometimes render a surrounding element and other times not).
+     */
+    @Parameter("componentResources.elementName")
+    private String elementName;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    Binding defaultValue()
+    {
+        return defaultProvider.defaultBinding("value", resources);
+    }
+
+    boolean beginRender(MarkupWriter writer)
+    {
+        if (value == null) return false;
+
+        String formatted = format.format(value);
+
+        if (InternalUtils.isNonBlank(formatted))
+        {
+            if (elementName != null)
+            {
+                writer.element(elementName);
+
+                resources.renderInformalParameters(writer);
+            }
+
+            if (filter) writer.write(formatted);
+            else writer.writeRaw(formatted);
+
+            if (elementName != null) writer.end();
+        }
+
+        return false;
+    }
+
+    // For testing.
+
+    void setup(Object value, Format format, boolean filter, String elementName, ComponentResources resources)
+    {
+        this.value = value;
+        this.format = format;
+        this.filter = filter;
+        this.elementName = elementName;
+        this.resources = resources;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/OutputRaw.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/OutputRaw.java
new file mode 100644
index 0000000..49ea45f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/OutputRaw.java
@@ -0,0 +1,67 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+
+/**
+ * Used to output raw markup to the client. Unlike, say, an expansion, the output from OutputRaw is unfiltered, with any
+ * special characters or entities left exactly as is. This is used in situations where the markup is provided
+ * externally, rather than constructed within Tapestry.
+ *
+ * @see MarkupWriter#writeRaw(String)
+ */
+public class OutputRaw
+{
+    /**
+     * The value to to render. If unbound, and a property of the container matches the component's id, then that
+     * property will be the source of the value.
+     */
+    @Parameter(required = true)
+    private String value;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    Binding defaultValue()
+    {
+        return defaultProvider.defaultBinding("value", resources);
+    }
+
+    boolean beginRender(MarkupWriter writer)
+    {
+        if (value != null && value.length() > 0) writer.writeRaw(value);
+
+        // Abort the rest of the render.
+
+        return false;
+    }
+
+    // For testing:
+
+    void setValue(String value)
+    {
+        this.value = value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
new file mode 100644
index 0000000..8d3f394
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
@@ -0,0 +1,71 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.base.AbstractLink;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+/**
+ * Generates a render request link to some other page in the application. If an activation context is supplied (as the
+ * context parameter), then the context values will be encoded into the URL. If no context is supplied, then the target
+ * page itself will supply the context via a passivate event.
+ * <p/>
+ * Pages are not required to have an activation context. When a page does have an activation context, the value
+ * typically represents the identity of some object displayed or otherwise manipulated by the page.
+ */
+public class PageLink extends AbstractLink
+{
+    /**
+     * The logical name of the page to link to.
+     */
+    @Parameter(required = true, defaultPrefix = "literal")
+    private String page;
+
+    @Inject
+    private ComponentResources resources;
+
+    /**
+     * If provided, this is the activation context for the target page (the information will be encoded into the URL).
+     * If not provided, then the target page will provide its own activation context.
+     */
+    @Parameter
+    private List context;
+
+    private final Object[] emptyContext = new Object[0];
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (isDisabled()) return;
+
+        Object[] activationContext = context != null ? context.toArray() : emptyContext;
+
+        Link link = resources.createPageLink(page, resources.isBound("context"), activationContext);
+
+        writeLink(writer, link);
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        if (isDisabled()) return;
+
+        writer.end(); // <a>
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.xdoc
new file mode 100644
index 0000000..bb830df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.xdoc
@@ -0,0 +1,89 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="ActionLink.html">ActionLink</a>
+                </li>
+                <li>
+                    <a href="EventLink.html">EventLink</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                We're continuing with the example introduced in the
+                <a href="Grid.html">Grid</a>
+                examples.
+            </p>
+
+            <p>
+                The UserList page renders a series of page links, passing the user id as the context:
+            </p>
+
+            <subsection name="UserList.html (partial)">
+                <source><![CDATA[
+        <t:grid source="users" row="user" model="model">
+            <t:parameter name="lastnamecell">
+                <t:pagelink page="user/view" context="user.id">${user.lastname}</t:pagelink>
+            </t:parameter>
+
+        </t:grid>]]></source>
+            </subsection>
+
+
+            <subsection name="ViewUser.java">
+
+                <p>
+                    The ViewUser page is responsible for converting that user id back into a User instance,
+                    by providing an event handler method for the "activate" event.
+                </p>
+
+                <source><![CDATA[
+public class ViewUser
+{
+    private User _user;
+
+    @Inject
+    private UserDAO _userDAO;
+
+    public User getUser()
+    {
+        return _user;
+    }
+
+    void onActivate(long userId)
+    {
+        _user = _userDAO.findById(userId);
+    }
+}
+            ]]></source>
+
+            </subsection>
+
+            <subsection name="ViewUser.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>View User</h1>
+
+        <t:beandisplay object="user"/>
+    </body>
+</html>]]></source>
+
+                <p>
+                    Rendering out the User object, using a
+                    <a href="BeanDisplay.html">BeanDisplay</a>
+                    component, is easy, and the template doesn't have to know or
+                    care about the page activation context; it just reads the user property.
+                </p>
+
+            </subsection>
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
new file mode 100644
index 0000000..af4bebf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
@@ -0,0 +1,401 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.IncludeJavaScriptLibrary;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.internal.util.SelectModelRenderer;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry5.json.JSONArray;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Multiple selection component. Generates a UI consisting of two &lt;select&gt; elements configured for multiple
+ * selection; the one on the left is the list of "available" elements, the one on the right is "selected". Elements can
+ * be moved between the lists by clicking a button, or double clicking an option (and eventually, via drag and drop).
+ * <p/>
+ * The items in the available list are kept ordered as per {@link SelectModel} order. When items are moved from the
+ * selected list to the available list, they items are inserted back into their proper positions.
+ * <p/>
+ * The Palette may operate in normal or re-orderable mode, controlled by the reorder parameter.
+ * <p/>
+ * In normal mode, the items in the selected list are kept in the same "natural" order as the items in the available
+ * list.
+ * <p/>
+ * In re-order mode, items moved to the selected list are simply added to the bottom of the list. In addition, two extra
+ * buttons appear to move items up and down within the selected list.
+ * <p/>
+ * Much of the look and feel is driven by CSS, the default Tapestry CSS is used to set up the columns, etc. By default,
+ * the &lt;select&gt; element's widths are 200px, and  it is common to override this to a specific value:
+ * <p/>
+ * <pre>
+ * &lt;style&gt;
+ * DIV.t-palette SELECT { width: 300px; }
+ * &lt;/style&gt;
+ * </pre>
+ * <p/>
+ * You'll want to ensure that both &lt;select&gt; in each column is the same width, otherwise the display will update
+ * poorly as options are moved from one column to the other.
+ * <p/>
+ * Option groups within the {@link SelectModel} will be rendered, but are not supported by many browsers, and are not
+ * fully handled on the client side.
+ */
+@IncludeJavaScriptLibrary("palette.js")
+public class Palette extends AbstractField
+{
+    // These all started as anonymous inner classes, and were refactored out to here.
+    // I was chasing down one of those perplexing bytecode errors.
+
+    private final class AvailableRenderer implements Renderable
+    {
+        public void render(MarkupWriter writer)
+        {
+            writer.element("select", "id", getClientId() + ":avail", "multiple", "multiple", "size", getSize(), "name",
+                           getControlName() + ":avail");
+
+            writeDisabled(writer, isDisabled());
+
+            for (Runnable r : availableOptions)
+                r.run();
+
+            writer.end();
+        }
+    }
+
+    private final class OptionGroupEnd implements Runnable
+    {
+        private final OptionGroupModel model;
+
+        private OptionGroupEnd(OptionGroupModel model)
+        {
+            this.model = model;
+        }
+
+        public void run()
+        {
+            renderer.endOptionGroup(model);
+        }
+    }
+
+    private final class OptionGroupStart implements Runnable
+    {
+        private final OptionGroupModel model;
+
+        private OptionGroupStart(OptionGroupModel model)
+        {
+            this.model = model;
+        }
+
+        public void run()
+        {
+            renderer.beginOptionGroup(model);
+        }
+    }
+
+    private final class RenderOption implements Runnable
+    {
+        private final OptionModel model;
+
+        private RenderOption(OptionModel model)
+        {
+            this.model = model;
+        }
+
+        public void run()
+        {
+            renderer.option(model);
+        }
+    }
+
+    private final class SelectedRenderer implements Renderable
+    {
+        public void render(MarkupWriter writer)
+        {
+            writer.element("select", "id", getClientId(), "multiple", "multiple", "size", getSize(), "name",
+                           getControlName());
+
+            writeDisabled(writer, isDisabled());
+
+            for (Object value : getSelected())
+            {
+                OptionModel model = valueToOptionModel.get(value);
+
+                renderer.option(model);
+            }
+
+            writer.end();
+        }
+    }
+
+    /**
+     * List of Runnable commands to render the available options.
+     */
+    private List<Runnable> availableOptions;
+
+    /**
+     * The image to use for the deselect button (the default is a left pointing arrow).
+     */
+    @Parameter(value = "asset:deselect.png")
+    @Property(write = false)
+    private Asset deselect;
+
+    /**
+     * Encoder used to translate between server-side objects and client-side strings.
+     */
+    @Parameter(required = true)
+    private ValueEncoder<Object> encoder;
+
+    /**
+     * Model used to define the values and labels used when rendering.
+     */
+    @Parameter(required = true)
+    private SelectModel model;
+
+    /**
+     * The image to use for the move down button (the default is a downward pointing arrow).
+     */
+    @Parameter(value = "asset:move_down.png")
+    @Property(write = false)
+    private Asset moveDown;
+
+    /**
+     * The image to use for the move up button (the default is an upward pointing arrow).
+     */
+    @Parameter(value = "asset:move_up.png")
+    @Property(write = false)
+    private Asset moveUp;
+
+    /**
+     * Used to include scripting code in the rendered page.
+     */
+    @Environmental
+    private RenderSupport renderSupport;
+
+    /**
+     * Needed to access query parameters when processing form submission.
+     */
+    @Inject
+    private Request request;
+
+    private SelectModelRenderer renderer;
+
+    /**
+     * The image to use for the select button (the default is a right pointing arrow).
+     */
+    @Parameter(value = "asset:select.png")
+    @Property(write = false)
+    private Asset select;
+
+    /**
+     * The list of selected values from the {@link SelectModel}. This will be updated when the form is submitted. If the
+     * value for the parameter is null, a new list will be created, otherwise the existing list will be cleared. If
+     * unbound, defaults to a property of the container matching this component's id.
+     */
+    @Parameter(required = true)
+    private List<Object> selected;
+
+    /**
+     * If true, then additional buttons are provided on the client-side to allow for re-ordering of the values.
+     */
+    @Parameter("false")
+    @Property(write = false)
+    private boolean reorder;
+
+    /**
+     * Used during rendering to identify the options corresponding to selected values (from the selected parameter), in
+     * the order they should be displayed on the page.
+     */
+    private List<OptionModel> selectedOptions;
+
+    private Map<Object, OptionModel> valueToOptionModel;
+
+    /**
+     * Number of rows to display.
+     */
+    @Parameter(value = "10")
+    private int size;
+
+    /**
+     * The natural order of elements, in terms of their client ids.
+     */
+    private List<String> naturalOrder;
+
+    /**
+     * Defaults the selected parameter to a container property whose name matches this component's id.
+     */
+    final Binding defaultSelected()
+    {
+        return createDefaultParameterBinding("selected");
+    }
+
+    public Renderable getAvailableRenderer()
+    {
+        return new AvailableRenderer();
+    }
+
+    public Renderable getSelectedRenderer()
+    {
+        return new SelectedRenderer();
+    }
+
+    @Override
+    protected void processSubmission(String elementName)
+    {
+        String parameterValue = request.getParameter(elementName + ":values");
+        JSONArray values = new JSONArray(parameterValue);
+
+        // Use a couple of local variables to cut down on access via bindings
+
+        List<Object> selected = this.selected;
+
+        if (selected == null) selected = newList();
+        else selected.clear();
+
+        ValueEncoder encoder = this.encoder;
+
+
+        int count = values.length();
+        for (int i = 0; i < count; i++)
+        {
+            String value = values.getString(i);
+
+            Object objectValue = encoder.toValue(value);
+
+            selected.add(objectValue);
+        }
+
+        this.selected = selected;
+    }
+
+    private void writeDisabled(MarkupWriter writer, boolean disabled)
+    {
+        if (disabled) writer.attributes("disabled", "disabled");
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        JSONArray selectedValues = new JSONArray();
+
+        for (OptionModel selected : selectedOptions)
+        {
+
+            Object value = selected.getValue();
+            String clientValue = encoder.toClient(value);
+
+            selectedValues.put(clientValue);
+        }
+
+        JSONArray naturalOrder = new JSONArray();
+
+        for (String value : this.naturalOrder)
+        {
+            naturalOrder.put(value);
+        }
+
+        String clientId = getClientId();
+
+        renderSupport.addScript("new Tapestry.Palette('%s', %s, %s);", clientId, reorder, naturalOrder);
+
+        writer.element("input", "type", "hidden", "id", clientId + ":values", "name", getControlName() + ":values",
+                       "value", selectedValues);
+        writer.end();
+    }
+
+    /**
+     * Prevent the body from rendering.
+     */
+    boolean beforeRenderBody()
+    {
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+    void setupRender(MarkupWriter writer)
+    {
+        valueToOptionModel = CollectionFactory.newMap();
+        availableOptions = CollectionFactory.newList();
+        selectedOptions = CollectionFactory.newList();
+        naturalOrder = CollectionFactory.newList();
+        renderer = new SelectModelRenderer(writer, encoder);
+
+        final Set selectedSet = newSet(getSelected());
+
+        SelectModelVisitor visitor = new SelectModelVisitor()
+        {
+            public void beginOptionGroup(OptionGroupModel groupModel)
+            {
+                availableOptions.add(new OptionGroupStart(groupModel));
+            }
+
+            public void endOptionGroup(OptionGroupModel groupModel)
+            {
+                availableOptions.add(new OptionGroupEnd(groupModel));
+            }
+
+            public void option(OptionModel optionModel)
+            {
+                Object value = optionModel.getValue();
+
+                boolean isSelected = selectedSet.contains(value);
+
+                String clientValue = toClient(value);
+
+                naturalOrder.add(clientValue);
+
+                if (isSelected)
+                {
+                    selectedOptions.add(optionModel);
+                    valueToOptionModel.put(value, optionModel);
+                    return;
+                }
+
+                availableOptions.add(new RenderOption(optionModel));
+            }
+
+        };
+
+        model.visit(visitor);
+    }
+
+    // Avoids a strange Javassist bytecode error, c'est lavie!
+    int getSize()
+    {
+        return size;
+    }
+
+    String toClient(Object value)
+    {
+        return encoder.toClient(value);
+    }
+
+    List<Object> getSelected()
+    {
+        if (selected == null) return Collections.emptyList();
+
+        return selected;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.xdoc
new file mode 100644
index 0000000..a464dc2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.xdoc
@@ -0,0 +1,148 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="Select.html">Select</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                For this example, we'll implement a page from an e-commerce order wizard; the page collects information
+                about special handling for the order:
+            </p>
+
+            <p>
+                <br/>
+                <img src="palette_ref.png"/>
+            </p>
+
+            <p>
+                This single screen shot doesn't capture the full richness of the user experience provided
+                by the Palette component. The buttons enable and disable
+                themselves based on what's selected. You can move items by double clicking, and you can move multiple
+                items by selecting
+                them and and then clicking the button.
+            </p>
+
+            <p>
+                This is a far better experience than using &lt;select&gt; with multiple enabled, as its very difficult
+                to navigate
+                a large list when using a traditional &lt;select&gt; and very easy to accidentally lose your selection.
+                The price of this
+                is the requirement for JavaScript on the client side.
+            </p>
+
+            <subsection name="SpecialHandling.java">
+                <source><![CDATA[
+public enum SpecialHandling
+{
+    EXPRESS_SERVICE, GIFT_WRAP, GIFT_BASKET, CUSTOM_ENGRAVING, SHIPPING_INSURANCE,
+    EXTENDED_WARRANTY
+}]]>        </source>
+
+                <p>
+                    In this contrived example, the possible types of special handling are defined using
+                    an enum. It's more likely, in the real world, that this would be defined in terms
+                    of a database entity.
+                </p>
+            </subsection>
+
+            <subsection name="OrderHandling.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Special Handling</h1>
+
+        <t:form>
+
+            <t:palette t:id="handling" encoder="encoder" model="model"/>
+
+            <br/>
+
+            <input type="submit" value="Continue"/>
+
+        </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    Here we are able to omit the selected parameter (the list of selected items) because the Palette
+                    component's id matches a property of the page.
+                </p>
+
+                <p>
+                    The model parameter will define the available options that can be selected. The encoder parameter
+                    will define how to translate server side values (the enum values) into client side strings and back.
+                </p>
+
+            </subsection>
+
+            <subsection name="OrderHandling.java">
+                <source><![CDATA[
+public class OrderHandling
+{
+    @Persist
+    private List<SpecialHandling> _handling;
+
+    @Inject
+    private Messages _messages;
+
+    private final ValueEncoder<SpecialHandling> _encoder = new EnumValueEncoder(SpecialHandling.class);
+
+    private final SelectModel _model = new EnumSelectModel(SpecialHandling.class, _messages);
+
+    public List<SpecialHandling> getHandling()
+    {
+        return _handling;
+    }
+
+    public void setHandling(List<SpecialHandling> handling)
+    {
+        _handling = handling;
+    }
+
+    public ValueEncoder<SpecialHandling> getEncoder() { return _encoder; }
+
+    public SelectModel getModel() { return _model; }
+}]]></source>
+
+                <p>
+                    Tapestry has built-in public classes that help convert enum types into value encoders
+                    and select models.
+                </p>
+
+                <p>
+                    Injecting a Messages object gives a component access to its own message catalog.
+                </p>
+
+                <p>
+                    The Palette component will read the handling property when rendering (it's ok for it to be null).
+                    When the form is submitted, it will create a new List and update the handling property.
+                </p>
+
+            </subsection>
+        </section>
+
+        <section name="Notes">
+            <p>
+                The Palette can also be used to order, not just select, items, by binding the reorder
+                parameter to true. In that case, additional buttons are added that allow selected items to
+                be moved up or down the list.
+            </p>
+
+            <p>
+                The Palette can be further customized through a mix of CSS and by replacing the images
+                used for its various buttons.
+            </p>
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java
new file mode 100644
index 0000000..7b90f03
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java
@@ -0,0 +1,51 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.corelib.base.AbstractTextField;
+
+/**
+ * A version of {@link TextField}, but rendered out as an &lt;input type="password"&gt; element. Further, the output
+ * value for a PasswordField is always blank.
+ * <p/>
+ * Includes the <code>size</code> attribute, if a {@link org.apache.tapestry.beaneditor.Width} annotation is present on
+ * the property bound to the value parameter.
+ */
+public class PasswordField extends AbstractTextField
+{
+
+    @Override
+    protected final void writeFieldTag(MarkupWriter writer, String value)
+    {
+        writer.element("input",
+
+                       "type", "password",
+
+                       "name", getControlName(),
+
+                       "id", getClientId(),
+
+                       "value", "",
+
+                       "size", getWidth());
+    }
+
+    final void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // input
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.xdoc
new file mode 100644
index 0000000..2508550
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.xdoc
@@ -0,0 +1,18 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="TextField.html">TextField</a>
+                </li>
+                <li>
+                    <a href="TextArea.html">TextArea</a>
+                </li>
+            </ul>
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyDisplay.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyDisplay.java
new file mode 100644
index 0000000..d0df959
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyDisplay.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.corelib.base.AbstractPropertyOutput;
+
+/**
+ * Outputs a single property value. Overrides for individual properties come from block parameters whose name matches
+ * the {@linkplain PropertyModel#getId() property id}. This component is rarely used on its own, but is a critical piece
+ * of the {@link BeanDisplay} component.
+ */
+public class PropertyDisplay extends AbstractPropertyOutput
+{
+    Object beginRender(MarkupWriter writer)
+    {
+        return renderPropertyValue(writer, getPropertyModel().getId());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
new file mode 100644
index 0000000..48109f2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PropertyEditor.java
@@ -0,0 +1,262 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.*;
+
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+
+/**
+ * Used to edit a single property of a bean. This is used primarily by {@link BeanEditForm}. Unlike BeanEditForm, the
+ * object to be edited must already exist and the {@linkplain BeanModel model} must be passed in explicitly.
+ */
+public class PropertyEditor
+{
+    /**
+     * Configures and stores a {@link PropertyEditContext} into the {@link Environment}.
+     */
+    static class SetupEnvironment implements ComponentAction<PropertyEditor>
+    {
+        private static final long serialVersionUID = 5337049721509981997L;
+
+        private final String property;
+
+        public SetupEnvironment(String property)
+        {
+            this.property = property;
+        }
+
+        public void execute(PropertyEditor component)
+        {
+            component.setupEnvironment(property);
+        }
+    }
+
+    static class CleanupEnvironment implements ComponentAction<PropertyEditor>
+    {
+        private static final long serialVersionUID = 7878694042753046523L;
+
+        public void execute(PropertyEditor component)
+        {
+            component.cleanupEnvironment();
+        }
+    }
+
+    /**
+     * The object to be edited by the BeanEditor. This will be read when the component renders and updated when the form
+     * for the component is submitted. Typically, the container will listen for a "prepare" event, in order to ensure
+     * that a non-null value is ready to be read or updated.
+     */
+    @Parameter(required = true)
+    private Object object;
+
+    /**
+     * Where to search for local overrides of property editing blocks as block parameters. This is normally the
+     * containing component of the PropertyEditor, but when the component is used within a BeanEditor, it will be the
+     * BeanEditForm's block parameters that will be searched.
+     */
+    @Parameter(value = "componentResources")
+    private ComponentResources overrides;
+
+    /**
+     * Identifies the property to be edited by the editor.
+     */
+    @Parameter(required = true)
+    private String property;
+
+    /**
+     * The model that identifies the parameters to be edited, their order, and every other aspect.
+     */
+    @Parameter(required = true)
+    private BeanModel model;
+
+    @Inject
+    private FieldValidatorDefaultSource fieldValidatorDefaultSource;
+
+    @Inject
+    private Environment environment;
+
+    @Inject
+    private BeanBlockSource beanBlockSource;
+
+    @Inject
+    private Messages messages;
+
+    @Inject
+    private Locale locale;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    private PropertyModel propertyModel;
+
+    @Inject
+    private TranslatorSource translatorSource;
+
+    /**
+     * Creates a {@link org.apache.tapestry.services.PropertyEditContext} and pushes it onto the {@link
+     * org.apache.tapestry.services.Environment} stack.
+     */
+    void setupEnvironment(final String propertyName)
+    {
+        propertyModel = model.get(propertyName);
+
+        PropertyEditContext context = new PropertyEditContext()
+        {
+            public Messages getContainerMessages()
+            {
+                return overrides.getContainerMessages();
+            }
+
+            public String getLabel()
+            {
+                return propertyModel.getLabel();
+            }
+
+            public String getPropertyId()
+            {
+                return propertyModel.getId();
+            }
+
+            public Class getPropertyType()
+            {
+                return propertyModel.getPropertyType();
+            }
+
+            public Object getPropertyValue()
+            {
+                return propertyModel.getConduit().get(object);
+            }
+
+            public Translator getTranslator()
+            {
+                return translatorSource.getByType(propertyModel.getPropertyType());
+            }
+
+            public FieldValidator getValidator(Field field)
+            {
+                return fieldValidatorDefaultSource.createDefaultValidator(field, propertyName,
+                                                                          overrides.getContainerMessages(), locale,
+                                                                          propertyModel.getPropertyType(),
+                                                                          propertyModel.getConduit());
+            }
+
+            public void setPropertyValue(Object value)
+            {
+                propertyModel.getConduit().set(object, value);
+            }
+
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return propertyModel.getAnnotation(annotationClass);
+            }
+        };
+
+        environment.push(PropertyEditContext.class, context);
+    }
+
+    /**
+     * Called at the end of the form render (or at the end of the form submission) to clean up the {@link Environment}
+     * stack.
+     */
+    void cleanupEnvironment()
+    {
+        environment.pop(PropertyEditContext.class);
+    }
+
+    /**
+     * Record into the Form what's needed to process the property.
+     */
+    void setupRender()
+    {
+        // Sets up the PropertyEditContext for the duration of the render of this component
+        // (which will include the duration of the editor block).
+
+        formSupport.storeAndExecute(this, new SetupEnvironment(property));
+    }
+
+    /**
+     * Records into the Form the cleanup logic for the property.
+     */
+    void cleanupRender()
+    {
+        // Removes the PropertyEditContext after this component (including the editor block)
+        // has rendered.
+
+        formSupport.storeAndExecute(this, new CleanupEnvironment());
+    }
+
+    /**
+     * Returns a Block for rendering the property. The Block will be able to access the {@link PropertyEditContext} via
+     * the {@link Environmental} annotation.
+     */
+    Block beginRender()
+    {
+        Block override = overrides.getBlockParameter(propertyModel.getId());
+
+        if (override != null)
+        {
+            return override;
+        }
+
+        String dataType = propertyModel.getDataType();
+
+        try
+        {
+            return beanBlockSource.getEditBlock(dataType);
+        }
+        catch (RuntimeException ex)
+        {
+            String message = messages.format("block-error", propertyModel.getPropertyName(), dataType, object, ex);
+
+            throw new TapestryException(message, resources.getLocation(), ex);
+        }
+
+    }
+
+    /**
+     * Returns false, to prevent the rendering of the body of the component. PropertyEditor should not have a body.
+     */
+    boolean beforeRenderBody()
+    {
+        return false;
+    }
+
+    /**
+     * Used for testing.
+     */
+    void inject(ComponentResources resources, ComponentResources overrides, PropertyModel propertyModel,
+                BeanBlockSource beanBlockSource, Messages messages, Object object)
+    {
+        this.resources = resources;
+        this.overrides = overrides;
+        this.propertyModel = propertyModel;
+        this.beanBlockSource = beanBlockSource;
+        this.messages = messages;
+        this.object = object;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java
new file mode 100644
index 0000000..7d2d97e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java
@@ -0,0 +1,147 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.mixins.DiscardBody;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.corelib.mixins.RenderInformals;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+
+/**
+ * A radio button (i.e., &lt;input type="radio"&gt;). Radio buttons <strong>must</strong> operate within a {@link
+ * RadioContainer} (normally, the {@link RadioGroup} component).
+ * <p/>
+ * If the value parameter is not bound, then the default value is a property of the container component whose name
+ * matches the Radio component's id.
+ */
+public class Radio implements Field
+{
+    @Environmental
+    private RadioContainer container;
+
+    /**
+     * The user presentable label for the field. If not provided, a reasonable label is generated from the component's
+     * id, first by looking for a message key named "id-label" (substituting the component's actual id), then by
+     * converting the actual id to a presentable string (for example, "userId" to "User Id").
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String label;
+
+    /**
+     * The value associated with this radio button. This is used to determine which radio button will be selected when
+     * the page is rendered, and also becomes the value assigned when the form is submitted.
+     */
+    @Parameter(required = true, principal = true)
+    private Object value;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderInformals renderInformals;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private DiscardBody discardBody;
+
+    @Inject
+    private RenderSupport renderSupport;
+
+    private String clientId;
+
+    private String controlName;
+
+    /**
+     * If true, then the field will render out with a disabled attribute (to turn off client-side behavior). Further, a
+     * disabled field ignores any value in the request when the form is submitted.
+     */
+    @Parameter("false")
+    private boolean disabled;
+
+    String defaultLabel()
+    {
+        return defaultProvider.defaultLabel(resources);
+    }
+
+    Binding defaultValue()
+    {
+        return defaultProvider.defaultBinding("value", resources);
+    }
+
+    /**
+     * Returns the control name provided by the containing {@link org.apache.tapestry.RadioContainer}.
+     */
+    public String getControlName()
+    {
+        return controlName;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    /**
+     * Returns true if this component has been expressly disabled (via its disabled parameter), or if the {@link
+     * RadioContainer container} has been disabled.
+     */
+    public boolean isDisabled()
+    {
+        return disabled || container.isDisabled();
+    }
+
+    public String getClientId()
+    {
+        return clientId;
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        String value = container.toClient(this.value);
+
+        clientId = renderSupport.allocateClientId(resources);
+        controlName = container.getElementName();
+
+        writer.element("input", "type", "radio", "id", clientId, "name", controlName, "value", value);
+
+        if (container.isSelected(this.value)) writer.attributes("checked", "checked");
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end();
+    }
+
+    /**
+     * Returns false; the RadioComponent component does not support declarative field validation.
+     */
+    public boolean isRequired()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.xdoc
new file mode 100644
index 0000000..a024178
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.xdoc
@@ -0,0 +1,158 @@
+<document>
+    <body>
+
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="RadioGroup.html">RadioGroup</a>
+                </li>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="Select.html">Select</a>
+                </li>
+            </ul>
+
+        </section>
+
+        <section name="Examples">
+            <p>
+                Radio components are always used in conjunction with
+                a RadioGroup component. The RadioGroup defines the property
+                that will be read and updated, and the individual Radio
+                components determine what value will be assigned to the property.
+            </p>
+
+            <p>
+                Our example will be part of a page that collects credit card information.
+                We'll just be showing the portions related to
+                a set of radio buttons for choosing the type of credit card.
+            </p>
+
+            <p>
+                <img src="radio_ref.png"/>
+            </p>
+
+            <subsection name="CardType.java">
+
+                <source><![CDATA[
+public enum CardType
+{
+    MASTER_CARD, VISA, AMERICAN_EXPRESS, DINERS_CLUB, DISCOVER
+}
+]]></source>
+
+            </subsection>
+
+            <subsection name="Payment.tml">
+
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Order Payment</h1>
+
+        <t:form>
+            <t:label for="cardNumber"/>:
+
+            <t:textfield t:id="cardNumber" size="16"/>
+
+            <br/>
+
+            <t:label for="type"/>:
+
+            <t:radiogroup t:id="type">
+                <t:radio t:id="masterCard"/>
+                <t:label for="masterCard"/>
+                <t:radio t:id="visa"/>
+                <t:label for="visa"/>
+                <t:radio t:id="amex"/>
+                <t:label for="amex"/>
+                <t:radio t:id="dinersClub"/>
+                <t:label for="dinersClub"/>
+                <t:radio t:id="discover"/>
+                <t:label for="discover"/>
+            </t:radiogroup>
+
+        </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    The advantage of using radio buttons here, rather than a drop down list,
+                    is that we could extend the labels to use a small image of each
+                    type of supported card.
+                </p>
+
+                <p>
+                    We're once again using the trick of matching the component's id
+                    to a property of the containing page. The RadioGroup's value parameter
+                    will be bound to the page's type property. Likewise, each of the
+                    Radio components will be matched to a property of the page.
+                </p>
+
+            </subsection>
+
+            <subsection name="Payment.java (partial)">
+
+                <source><![CDATA[
+
+public class Payment
+{
+    . . .
+
+    @Persist
+    private CardType _type;
+
+    public CardType getType() { return _type; }
+
+    public void setType(CardType type) { _type = type; }
+
+    public CardType getMasterCard() { return CardType.MASTER_CARD; }
+
+    public CardType getVisa() { return CardType.VISA; }
+
+    public CardType getAmex() { return CardType.AMERICAN_EXPRESS; }
+
+    public CardType getDinersClub() { return CardType.DINERS_CLUB; }
+
+    public CardType getDiscover() { return CardType.DISCOVER; }
+
+    . . .
+}]]></source>
+
+
+                <p>
+                    We use a number of read-only properties to provide
+                    each Radio component with its corresponding enum value, that will
+                    ultimately be assigned to the page's type property
+                    (if that corresponding Radio component is selected by the user).
+                </p>
+
+                <p>
+                    This is far from the only pattern of usage; it is much more likely
+                    that you will use a Loop component around a single Radio component
+                    than you will use a whole array of Radio components as in this example.
+                </p>
+
+            </subsection>
+
+            <subsection name="Payment.properties">
+
+                <p>
+                    We override the default generated labels for a few fields and enum values:
+                </p>
+
+                <source><![CDATA[
+cardnumber-label=Credit Card Number
+type-label=Credit Card Type
+dinersclub-label=Diner's Club]]></source>
+            </subsection>
+
+        </section>
+
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java
new file mode 100644
index 0000000..282fe81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java
@@ -0,0 +1,220 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.*;
+
+public class RadioGroup implements Field
+{
+    /**
+     * The property read and updated by the group as a whole.
+     */
+    @Parameter(required = true, principal = true)
+    private Object value;
+
+    /**
+     * If true, then the field will render out with a disabled attribute (to turn off client-side behavior). Further, a
+     * disabled field ignores any value in the request when the form is submitted.
+     */
+    @Parameter("false")
+    private boolean disabled;
+
+    /**
+     * The user presentable label for the field. If not provided, a reasonable label is generated from the component's
+     * id, first by looking for a message key named "id-label" (substituting the component's actual id), then by
+     * converting the actual id to a presentable string (for example, "userId" to "User Id").
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String label;
+
+    /**
+     * Allows a specific implementation of {@link ValueEncoder} to be supplied. This is used to create client-side
+     * string values for the different radio button values.
+     *
+     * @see ValueEncoderSource
+     */
+    @Parameter(required = true)
+    private ValueEncoder encoder;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    @Inject
+    private Environment environment;
+
+    @Inject
+    private Request request;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    private String controlName;
+
+    final Binding defaultValue()
+    {
+        return defaultProvider.defaultBinding("value", resources);
+    }
+
+    String defaultLabel()
+    {
+        return defaultProvider.defaultLabel(resources);
+    }
+
+    final ValueEncoder defaultEncoder()
+    {
+        return defaultProvider.defaultValueEncoder("value", resources);
+    }
+
+    private static class Setup implements ComponentAction<RadioGroup>
+    {
+        private static final long serialVersionUID = -7984673040135949374L;
+
+        private final String controlName;
+
+        Setup(String controlName)
+        {
+            this.controlName = controlName;
+        }
+
+        public void execute(RadioGroup component)
+        {
+            component.setup(controlName);
+        }
+    }
+
+    private static final ComponentAction<RadioGroup> PROCESS_SUBMISSION = new ComponentAction<RadioGroup>()
+    {
+        private static final long serialVersionUID = -3857110108918776386L;
+
+        public void execute(RadioGroup component)
+        {
+            component.processSubmission();
+        }
+    };
+
+    private void setup(String elementName)
+    {
+        controlName = elementName;
+    }
+
+    private void processSubmission()
+    {
+        String clientValue = request.getParameter(controlName);
+
+        tracker.recordInput(this, clientValue);
+
+        value = encoder.toValue(clientValue);
+    }
+
+    /**
+     * Obtains the element name for the group, and stores a {@link RadioContainer} into the {@link Environment} (so that
+     * the {@link Radio} components can find it).
+     */
+    final void setupRender()
+    {
+        String name = formSupport.allocateControlName(resources.getId());
+
+        ComponentAction<RadioGroup> action = new Setup(name);
+
+        formSupport.storeAndExecute(this, action);
+
+        String submittedValue = tracker.getInput(this);
+
+        final String selectedValue = submittedValue != null ? submittedValue : encoder.toClient(value);
+
+
+        environment.push(RadioContainer.class, new RadioContainer()
+        {
+            public String getElementName()
+            {
+                return controlName;
+            }
+
+            public boolean isDisabled()
+            {
+                return disabled;
+            }
+
+            @SuppressWarnings("unchecked")
+            public String toClient(Object value)
+            {
+                // TODO: Ensure that value is of the expected type?
+
+                return encoder.toClient(value);
+            }
+
+            public boolean isSelected(Object value)
+            {
+                return TapestryInternalUtils.isEqual(encoder.toClient(value), selectedValue);
+            }
+
+        });
+
+        formSupport.store(this, PROCESS_SUBMISSION);
+    }
+
+    /**
+     * Pops the {@link RadioContainer} off the Environment.
+     */
+    final void afterRender()
+    {
+        environment.pop(RadioContainer.class);
+    }
+
+    public String getControlName()
+    {
+        return controlName;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    /**
+     * Returns null; the radio group does not render as a tag and so doesn't have an id to share.  RadioGroup implements
+     * {@link org.apache.tapestry.Field} only so it can interact with the {@link org.apache.tapestry.ValidationTracker}.
+     *
+     * @return null
+     */
+    public String getClientId()
+    {
+        return null;
+    }
+
+    /**
+     * Returns false; RadioGroup does not support declarative validation.
+     */
+    public boolean isRequired()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.xdoc
new file mode 100644
index 0000000..06046f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.xdoc
@@ -0,0 +1,9 @@
+<document>
+    <body>
+        <p>
+            Examples are provided with the documentation of the
+            <a href="Radio.html">Radio</a>
+            component.
+        </p>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RenderObject.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RenderObject.java
new file mode 100644
index 0000000..a834a2f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RenderObject.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.pages.ExceptionReport;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+/**
+ * Renders out an object using the {@link ObjectRenderer} service. Used primarily on the {@link ExceptionReport} page.
+ * This is focused on objects that have a specific {@link ObjectRenderer} strategy. The {@link BeanDisplay} component is
+ * used for displaying the contents of arbitrary objects in terms of a series of property names and values.
+ */
+public class RenderObject
+{
+    @Parameter(required = true)
+    private Object object;
+
+    @Inject
+    @Primary
+    private ObjectRenderer<Object> renderer;
+
+    boolean beginRender(MarkupWriter writer)
+    {
+        renderer.render(object, writer);
+
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
new file mode 100644
index 0000000..559bac0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
@@ -0,0 +1,306 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.BeforeRenderTemplate;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.corelib.data.BlankOption;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.util.SelectModelRenderer;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.*;
+import org.apache.tapestry.util.EnumSelectModel;
+
+import java.util.Locale;
+
+/**
+ * Select an item from a list of values, using an [X]HTML &lt;select&gt; element on the client side. An validation
+ * decorations will go around the entire &lt;select&gt; element.
+ * <p/>
+ * A core part of this component is the {@link ValueEncoder} (the encoder parameter) that is used to convert between
+ * server-side values and client-side strings. In many cases, a {@link ValueEncoder} can be generated automatically from
+ * the type of the value parameter. The {@link ValueEncoderSource} service provides an encoder in these situations; it
+ * can be overriden by binding the encoder parameter, or extended by contributing a {@link ValueEncoderFactory} into the
+ * service's configuration.
+ */
+public final class Select extends AbstractField
+{
+    private class Renderer extends SelectModelRenderer
+    {
+
+        public Renderer(MarkupWriter writer)
+        {
+            super(writer, encoder);
+        }
+
+        @Override
+        protected boolean isOptionSelected(OptionModel optionModel, String clientValue)
+        {
+            return isSelected(clientValue);
+        }
+    }
+
+    /**
+     * Allows a specific implementation of {@link ValueEncoder} to be supplied. This is used to create client-side
+     * string values for the different options.
+     *
+     * @see ValueEncoderSource
+     */
+    @Parameter
+    private ValueEncoder encoder;
+
+    @Inject
+    private ComponentDefaultProvider defaultProvider;
+
+    @Inject
+    private FieldValidatorDefaultSource fieldValidatorDefaultSource;
+
+    @Inject
+    private Locale locale;
+
+    // Maybe this should default to property "<componentId>Model"?
+    /**
+     * The model used to identify the option groups and options to be presented to the user. This can be generated
+     * automatically for Enum types.
+     */
+    @Parameter(required = true)
+    private SelectModel model;
+
+    /**
+     * Controls whether an additional blank option is provided. The blank option precedes all other options and is never
+     * selected.  The value for the blank option is always the empty string, the label may be the blank string; the
+     * label is from the blankLabel parameter (and is often also the empty string).
+     */
+    @Parameter(value = "auto", defaultPrefix = BindingConstants.LITERAL)
+    private BlankOption blankOption;
+
+    /**
+     * The label to use for the blank option, if rendered.  If not specified, the container's message catalog is
+     * searched for a key, <code><em>id</em>-blanklabel</code>.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String blankLabel;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private ValidationTracker tracker;
+
+    /**
+     * Performs input validation on the value supplied by the user in the form submission.
+     */
+    @Parameter(defaultPrefix = "validate")
+    @SuppressWarnings("unchecked")
+    private FieldValidator<Object> validate = NOOP_VALIDATOR;
+
+    /**
+     * The value to read or update.
+     */
+    @Parameter(required = true, principal = true)
+    private Object value;
+
+    @Inject
+    private FieldValidationSupport fieldValidationSupport;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+
+    private String selectedClientValue;
+
+    private boolean isSelected(String clientValue)
+    {
+        return TapestryInternalUtils.isEqual(clientValue, selectedClientValue);
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Override
+    protected void processSubmission(String elementName)
+    {
+        String submittedValue = request.getParameter(elementName);
+
+        tracker.recordInput(this, submittedValue);
+
+        Object selectedValue = InternalUtils.isBlank(submittedValue)
+                               ? null :
+                               encoder.toValue(submittedValue);
+
+        try
+        {
+            fieldValidationSupport.validate(selectedValue, resources, validate);
+
+            value = selectedValue;
+        }
+        catch (ValidationException ex)
+        {
+            tracker.recordError(this, ex.getMessage());
+        }
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end();
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        writer.element("select", "name", getControlName(), "id", getClientId());
+
+        validate.render(writer);
+
+        resources.renderInformalParameters(writer);
+
+        // Disabled is via a mixin
+    }
+
+    @SuppressWarnings("unchecked")
+    ValueEncoder defaultEncoder()
+    {
+        return defaultProvider.defaultValueEncoder("value", resources);
+    }
+
+    @SuppressWarnings("unchecked")
+    SelectModel defaultModel()
+    {
+        Class valueType = resources.getBoundType("value");
+
+        if (valueType == null) return null;
+
+        if (Enum.class.isAssignableFrom(valueType))
+            return new EnumSelectModel(valueType, resources.getContainerMessages());
+
+        return null;
+    }
+
+    /**
+     * Computes a default value for the "validate" parameter using {@link FieldValidatorDefaultSource}.
+     */
+    FieldValidator defaultValidate()
+    {
+        Class type = resources.getBoundType("value");
+
+        if (type == null) return null;
+
+        return fieldValidatorDefaultSource.createDefaultValidator(this, resources.getId(),
+                                                                  resources.getContainerMessages(), locale, type,
+                                                                  resources.getAnnotationProvider("value"));
+    }
+
+    Binding defaultValue()
+    {
+        return createDefaultParameterBinding("value");
+    }
+
+    Object defaultBlankLabel()
+    {
+        Messages containerMessages = resources.getContainerMessages();
+
+        String key = resources.getId() + "-blanklabel";
+
+        if (containerMessages.contains(key)) return containerMessages.get(key);
+
+        return null;
+    }
+
+    /**
+     * Renders the options, including the blank option.
+     */
+    @BeforeRenderTemplate
+    void options(MarkupWriter writer)
+    {
+        selectedClientValue = tracker.getInput(this);
+
+        // Use the value passed up in the form submission, if available.
+        // Failing that, see if there is a current value (via the value parameter), and
+        // convert that to a client value for later comparison.
+
+        if (selectedClientValue == null) selectedClientValue = value == null ? null : encoder.toClient(value);
+
+        if (showBlankOption())
+        {
+            writer.element("option", "value", "");
+            writer.write(blankLabel);
+            writer.end();
+        }
+
+
+        SelectModelVisitor renderer = new Renderer(writer);
+
+        model.visit(renderer);
+    }
+
+    @Override
+    public boolean isRequired()
+    {
+        return validate.isRequired();
+    }
+
+    private boolean showBlankOption()
+    {
+        switch (blankOption)
+        {
+            case ALWAYS:
+                return true;
+
+            case NEVER:
+                return false;
+
+            default:
+                return !isRequired();
+        }
+    }
+
+    // For testing.
+
+    void setModel(SelectModel model)
+    {
+        this.model = model;
+        blankOption = BlankOption.NEVER;
+    }
+
+    void setValue(Object value)
+    {
+        this.value = value;
+    }
+
+    void setValueEncoder(ValueEncoder encoder)
+    {
+        this.encoder = encoder;
+    }
+
+    void setValidationTracker(ValidationTracker tracker)
+    {
+        this.tracker = tracker;
+    }
+
+    void setBlankOption(BlankOption option, String label)
+    {
+        blankOption = option;
+        blankLabel = label;
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.xdoc
new file mode 100644
index 0000000..2e218f4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.xdoc
@@ -0,0 +1,175 @@
+<document>
+    <body>
+        <section name="Simple Example">
+
+            <p>
+                A simple example, selecting one of three strings:
+            </p>
+
+            <subsection name="SelectColor.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Select Color</h1>
+
+        <t:form>
+
+            <t:label for="color"/>:
+            <t:select t:id="color" model="literal:Red,Green,Blue"/>
+
+            <br/>
+
+            <input type="submit" value="Continue"/>
+        </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    When the model parameter is a string, it is split apart at the commas.
+                </p>
+
+                <p>
+                    When using this approach, you'll commonly put the list into the message catalog,
+                    and reference it using a "message:" binding.
+                </p>
+
+                <p>
+                    Here the label displayed to the user is the same as the value used to update the property, but that
+                    doesn't
+                    have to be the case. By specifying a value and a label, we can control the server side value without
+                    changing how the UI appears to the user:
+                </p>
+
+                <source>
+                    <![CDATA[
+            <t:select t:id="color" model="literal:FF0000=Red,00FF00=Green,0000FF=Blue"/>
+]]>
+                </source>
+
+
+            </subsection>
+
+<subsection name="SelectColor.java">
+
+<source><![CDATA[
+public class SelectColor
+{
+  private String _color;
+
+  @Validate("required")
+  public String getColor() { return _color; }
+
+  public void setColor(String color) { _color = color; }
+}]]></source>
+
+    <p>
+        Placing the @Validate annotation on the field indicates that it is required.  This prevents the
+        select component from including a blank option for the field (though this can be overridden).
+        Without the @Validate, it would be possible for the user to select a blank value, and null would
+        be assigned to the color property of SelectColor.  This might be appropriate for a search form, but
+        not for an edit form.
+    </p>
+
+</subsection>
+
+        </section>
+
+        <section name="Enum Example">
+
+            <p>Working with Enums is, amazingly, even easier (and more so than with the Radio component).</p>
+
+            <p>
+                Most of this example is the same as for the
+                <a href="Radio.html">Radio</a>
+                component, except that
+                we're using a single Select component instead of multiple Radio components:
+            </p>
+
+            <p>
+                <img src="select_ref2.png"/>
+            </p>
+
+            <subsection name="CardType.java">
+
+                <source><![CDATA[
+public enum CardType
+{
+    MASTER_CARD, VISA, AMERICAN_EXPRESS, DINERS_CLUB, DISCOVER
+}
+]]></source>
+
+            </subsection>
+
+            <subsection name="Payment.tml (partial)">
+
+                <p>
+                    In the Radio example, we used a Label and a Radio component for each enum value.
+                    With Select we use a single Label and a single Select component:
+                </p>
+
+                <source><![CDATA[
+    <t:label for="type"/>:
+    <t:select t:id="type"/>]]></source>
+
+
+                <p>
+                    Here again, Tapestry is binding the value parameter to the type property, based on the component's
+                    id.
+                    In addition, because the property type of the property in question is an enum, a SelectModel
+                    is automatically generated.
+                </p>
+
+            </subsection>
+
+            <subsection name="Payment.java (partial)">
+
+                <source><![CDATA[                                                                   
+public class Payment
+{
+    . . .
+
+    @Persist
+    private CardType _type;
+
+    @Validate("required")
+    public CardType getType() { return _type; }
+
+    public void setType(CardType type) { _type = type; }
+
+    . . .
+}]]></source>
+
+
+            </subsection>
+
+            <subsection name="Payment.properties">
+
+                <p>
+                    Once again, we need to slightly customize Tapestry's guess at the label for the enum value
+                    DINERS_CLUB.
+                    In the Radio example, we overrode the label for the dinersClub<em>component</em>. Here there is just
+                    the Select component,
+                    but we still have an option: override how the DINERS_CLUB enum value is displayed:
+                </p>
+
+                <source><![CDATA[DINERS_CLUB=Diner's Club]]></source>
+
+                <p>Tapestry looks inside a component's message catalog for entries before "humanizing" the name. In the
+                    <em>very rare</em>
+                    event that there's a naming conflict, you may qualify the enum value with its class name:
+                </p>
+
+
+                <source><![CDATA[CardType.DINERS_CLUB=Diner's Club]]></source>
+
+                <p>And, of course, all of this is case insensitive. The use of case here helps to identify how the
+                    values
+                    are to be used.
+                </p>
+            </subsection>
+
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java
new file mode 100644
index 0000000..696dc06
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java
@@ -0,0 +1,119 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.base.AbstractField;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Heartbeat;
+import org.apache.tapestry.services.Request;
+
+/**
+ * Corresponds to &lt;input type="submit"&gt;, a client-side element that can force the enclosing form to submit. The
+ * submit responsible for the form submission will post a notification that allows the application to know that it was
+ * the responsible entity. The notification is named "selected" and has no context.
+ */
+public final class Submit extends AbstractField
+{
+    static final String SELECTED_EVENT = "selected";
+
+    /**
+     * If true (the default), then any notification sent by the component will be deferred until the end of the form
+     * submission (this is usually desirable).
+     */
+    @Parameter
+    private boolean defer = true;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    @Environmental
+    private Heartbeat heartbeat;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private Request request;
+
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+
+    public Submit()
+    {
+    }
+
+    Submit(Request request)
+    {
+        this.request = request;
+    }
+
+    void beginRender(MarkupWriter writer)
+    {
+        writer.element("input", "type", "submit", "name", getControlName(), "id", getClientId());
+
+        resources.renderInformalParameters(writer);
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end();
+    }
+
+    @Override
+    protected void processSubmission(String elementName)
+    {
+        String value = request.getParameter(elementName);
+
+        if (value == null) return;
+
+        Runnable sendNotification = new Runnable()
+        {
+            public void run()
+            {
+                resources.triggerEvent(SELECTED_EVENT, null, null);
+            }
+        };
+
+        // When not deferred, don't wait, fire the event now (actually, at the end of the current
+        // heartbeat). This is most likely because the Submit is inside a Loop and some contextual
+        // information will change if we defer.
+
+        if (defer) formSupport.defer(sendNotification);
+        else heartbeat.defer(sendNotification);
+
+    }
+
+    // For testing:
+
+    void setDefer(boolean defer)
+    {
+        this.defer = defer;
+    }
+
+    void setup(ComponentResources resources, FormSupport support, Heartbeat heartbeat)
+    {
+        this.resources = resources;
+        formSupport = support;
+        this.heartbeat = heartbeat;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.xdoc
new file mode 100644
index 0000000..2e7a24b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.xdoc
@@ -0,0 +1,69 @@
+<document>
+    <body>
+        <section name="Examples">
+
+            <p>
+                The thing to remember is that the Submit component will trigger its "selected" event in the
+                <em>middle</em>
+                of the form submission, before the form triggers its "validate", "success" (or "failure") and "submit"
+                events.
+                Thus the best thing to do is to store in a temporary field what should be done inside the "success"
+                event handler.
+            </p>
+
+            <subsection name="EditUser.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+
+        <h1>Edit User</h1>
+
+        <t:form>
+
+            <t:errors/>
+
+            <t:beaneditor t:id="user"/>
+
+            <p>
+                <input type="submit" value="Update User"/>
+                <t:submit t:id="delete" value="Delete User"/>
+            </p>
+
+        </t:form>
+</html>]]></source>
+            </subsection>
+
+
+            <subsection name="EditUser.java">
+                <source><![CDATA[
+public class EditUser
+{
+    @Inject
+    private UserDAO _userDAO;
+
+    @Persist
+    private User _user;
+
+    private boolean _deleteUser;
+
+    void onSelectedFromDelete() { _deleteUser = true; }
+
+    Object onSuccess()
+    {
+        if (_deleteUser)
+            _userDAO.delete(user.getId());
+        else
+            _userDAO.update(user);
+
+        return UserList.class;
+    }
+
+    public void setUser(User user) { _user = user; }
+
+    public User getUser() { return _user; }
+}]]></source>
+            </subsection>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java
new file mode 100644
index 0000000..bc2e33a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * A non visual component used to provide notifications to its container during a form submission. Records actions into
+ * the form on {@link org.apache.tapestry.annotation.BeginRender} and {@link org.apache.tapestry.annotation.AfterRender}
+ * that (during the form submission) triggers "BeginSubmit" and "AfterSubmit" events.  The container can receive these
+ * events to perform setup before a group of components process their submission, and perform cleanup afterwards.
+ */
+public class SubmitNotifier
+{
+    private static final class TriggerEvent implements ComponentAction<SubmitNotifier>
+    {
+        private final String eventType;
+
+        public TriggerEvent(String eventType)
+        {
+            this.eventType = eventType;
+        }
+
+        public void execute(SubmitNotifier component)
+        {
+            component.trigger(eventType);
+        }
+    }
+
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private FormSupport formSupport;
+
+    void beginRender()
+    {
+        formSupport.store(this, new TriggerEvent("BeginSubmit"));
+    }
+
+    void afterRender()
+    {
+        formSupport.store(this, new TriggerEvent("AfterSubmit"));
+    }
+
+    private void trigger(String eventType)
+    {
+        resources.triggerEvent(eventType, null, null);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
new file mode 100644
index 0000000..7d37108
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
@@ -0,0 +1,58 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.corelib.base.AbstractTextField;
+
+/**
+ * TextArea component corresponds to a &lt;textarea&gt; element. The value parameter is almost always bound to a string,
+ * but this is not an absolute requirement.
+ * <p/>
+ * Includes the <code>cols</code> attribute, if a {@link org.apache.tapestry.beaneditor.Width} annotation is present on
+ * the property bound to the value parameter.
+ *
+ * @see org.apache.tapestry.corelib.components.TextOutput
+ */
+public final class TextArea extends AbstractTextField
+{
+    private String value;
+
+    @Override
+    protected final void writeFieldTag(MarkupWriter writer, String value)
+    {
+        writer.element("textarea",
+
+                       "name", getControlName(),
+
+                       "id", getClientId(),
+
+                       "cols", getWidth());
+
+        // Save until needed in after()
+
+        this.value = value;
+    }
+
+    final void afterRender(MarkupWriter writer)
+    {
+        // TextArea will not have a template.
+
+        if (value != null) writer.write(value);
+
+        writer.end(); // textarea
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.xdoc
new file mode 100644
index 0000000..f7232be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.xdoc
@@ -0,0 +1,26 @@
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="TextOutput.html">TextOutput</a>
+                </li>
+                <li>
+                    <a href="TextField.html">TextField</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                The TextArea component accepts informal parameters, which can be used to set the standard
+                rows and cols attributes.
+            </p>
+        </section>
+
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java
new file mode 100644
index 0000000..1e12cee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java
@@ -0,0 +1,51 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.corelib.base.AbstractTextField;
+
+/**
+ * TextField component corresponds to &lt;input type="text"&gt; element. The value parameter will be editted. TextField
+ * is generally used with string values, but other values are acceptible, as long as they can be freely converted back
+ * and forth to strings.
+ * <p/>
+ * Includes the <code>size</code> attribute, if a {@link org.apache.tapestry.beaneditor.Width} annotation is present on
+ * the property bound to the value parameter.
+ */
+public final class TextField extends AbstractTextField
+{
+    @Override
+    protected final void writeFieldTag(MarkupWriter writer, String value)
+    {
+        writer.element("input",
+
+                       "type", "text",
+
+                       "name", getControlName(),
+
+                       "id", getClientId(),
+
+                       "value", value,
+
+                       "size", getWidth());
+    }
+
+    final void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // input
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.xdoc
new file mode 100644
index 0000000..ddf22b4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.xdoc
@@ -0,0 +1,74 @@
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+                <li>
+                    <a href="PasswordField.html">PasswordField</a>
+                </li>
+                <li>
+                    <a href="TextArea.html">TextArea</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                Once again, we're basing the example on the order payment screen
+                from the
+                <a href="Radio.html">Radio</a>
+                examples. This time we're focusing in on
+                the text field used for entering the credit card number, and we're going to validate
+                that number using a regular expression:
+            </p>
+
+            <p>
+                <img src="textfield_ref.png"/>
+            </p>
+
+            <subsection name="Payment.tml (partial)">
+                <source><![CDATA[
+            <t:label for="cardNumber"/>:
+            <t:textfield t:id="cardNumber"  validate="required,regexp" size="20"/>]]></source>
+
+                <p>
+                    The validate parameter is used to specify validations for the field. When it is omitted,
+                    the @Validate annotation of the property is used (if present). In any case, this references
+                    two of the built-in validations: "required" and "regexp".
+                </p>
+
+                <p>
+                    The "required" validation requires no extra configuration. On the other hand, "regexp"
+                    needs to know the regular expression to enforce ... and it should also have a
+                    user presentable message.
+                </p>
+
+            </subsection>
+
+
+            <subsection name="Payment.properties (partial)">
+                <source><![CDATA[
+cardnumber-regexp-message=Credit Card numbers consist of 16 digits
+cardnumber-regexp=\\d{4}(\\-?\\d{4}){3}]]></source>
+
+                <p>
+                    Tapestry uses the page's message catalog as a source of extra validation information.
+                    The key is the component id, the name of the validation. The value is given to the validator
+                    object ... here it's the regular expression for a credit card number (four sets of four digits,
+                    optionally seperated by dashes). The "-message" entry allows the normal error message
+                    for the validator to be overridden.
+                </p>
+            </subsection>
+
+        </section>
+
+        <section name="Notes">
+            <p>
+                These same approaches apply consistently to all form control element components.
+            </p>
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.java
new file mode 100644
index 0000000..e7df453
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.java
@@ -0,0 +1,58 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.mixins.DiscardBody;
+
+import java.util.regex.Pattern;
+
+/**
+ * Outputs paragraph oriented text, typically collected via a {@link org.apache.tapestry.corelib.components.TextArea}
+ * component.  The TextArea is split into lines, and each line it output inside its own &lt;p&gt; element.
+ */
+public class TextOutput
+{
+    @Parameter(required = true)
+    private String value;
+
+    @Mixin
+    private DiscardBody discardBody;
+
+    private static final Pattern SPLIT_PATTERN = Pattern.compile("((\\r\\n)|\\r|\\n)", Pattern.MULTILINE);
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (value == null) return;
+
+        String[] lines = SPLIT_PATTERN.split(value);
+
+        for (String line : lines)
+        {
+            writer.element("p");
+
+            writer.write(line.trim());
+
+            writer.end();
+        }
+    }
+
+    void injectValue(String value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.xdoc
new file mode 100644
index 0000000..7190a81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextOutput.xdoc
@@ -0,0 +1,11 @@
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="TextArea.html">TextArea</a>
+                </li>
+            </ul>
+        </section>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
new file mode 100644
index 0000000..f8ce7f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Unless.java
@@ -0,0 +1,62 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * A close relative of the {@link org.apache.tapestry.corelib.components.If} component that inverts the meaning of its
+ * test.  This is easier than an If component with the negate parameter set to true.
+ */
+public class Unless
+{
+    /**
+     * If true, then the body of the If component is rendered. If false, the body is omitted.
+     */
+    @Parameter(required = true)
+    private boolean test;
+
+    /**
+     * An alternate {@link org.apache.tapestry.Block} to render if the test parameter is false. The default, null, means
+     * render nothing in that situation.
+     */
+    @Parameter(name = "else")
+    private Block elseBlock;
+
+    /**
+     * Returns null if the test parameter is true, which allows normal rendering (of the body). If the test parameter is
+     * false, returns the else parameter (this may also be null).
+     */
+    Object beginRender()
+    {
+        return !test ? null : elseBlock;
+    }
+
+    /**
+     * If the test parameter is true, then the body is rendered, otherwise not. The component does not have a template
+     * or do any other rendering besides its body.
+     */
+    boolean beforeRenderBody()
+    {
+        return !test;
+    }
+
+    void setup(boolean test, Block elseBlock)
+    {
+        this.test = test;
+        this.elseBlock = elseBlock;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java
new file mode 100644
index 0000000..c5d01f2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java
@@ -0,0 +1,108 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry5.json.JSONObject;
+
+
+/**
+ * A Zone is portion of the output page designed for easy dynamic updating via Ajax or other client-side effects.  A
+ * Zone renders out as a &lt;div&gt; element and may have content initially, or may only get its content as a result of
+ * client side activity.
+ * <p/>
+ * Often, Zone's are initially invisible, in which case the visible parameter may be set to false (it defaults to
+ * false).
+ * <p/>
+ * <p/>
+ * When a user clicks an {@link org.apache.tapestry.corelib.components.ActionLink} whose zone parameter is set, the
+ * corresponding client-side Tapestry.Zone object is located. It will update the content of the Zone's &lt;div&gt; and
+ * then invoke either a show method (if the div is not visible) or an update method (if the div is visible).  The show
+ * and update parameters are the <em>names</em> of functions attached to the Tapestry.ElementEffect object.
+ * <p/>
+ * Renders informal parameters, adding CSS class "t-zone" and possibly, "t-invisible".
+ */
+@SupportsInformalParameters
+public class Zone implements ClientElement
+{
+    /**
+     * Name of a function on the client-side Tapestry.ElementEffect object that is invoked to make the Zone's
+     * &lt;div&gt; visible before being updated.  If not specified, then the basic "show" method is used.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String show;
+
+    /**
+     * Name of a function on the client-side Tapestry.ElementEffect object that is invoked after the Zone's content has
+     * been updated. If not specified, then the basic "highlight" method is used, which performs a classic "yellow fade"
+     * to indicate to the user that and update has taken place.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String update;
+
+    private String clientId;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Environmental
+    private ClientBehaviorSupport clientBehaviorSupport;
+
+    /**
+     * If true (the default) then the zone will render normally.  If false, then the "t-invisible" CSS class is added,
+     * which will make the zone initially invisible.
+     */
+    @Parameter
+    private boolean visible = true;
+
+    @Inject
+    private ComponentResources resources;
+
+    void beginRender(MarkupWriter writer)
+    {
+        clientId = renderSupport.allocateClientId(resources);
+
+        Element e = writer.element("div", "id", clientId);
+
+        resources.renderInformalParameters(writer);
+
+        e.addClassName("t-zone");
+
+        if (!visible) e.addClassName("t-invisible");
+
+        // And continue on to render the body
+
+        JSONObject spec = new JSONObject();
+        spec.put("div", clientId);
+
+        clientBehaviorSupport.addZone(clientId, show, update);
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // div
+    }
+
+    public String getClientId()
+    {
+        return clientId;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beandisplay_ref.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beandisplay_ref.png
new file mode 100644
index 0000000..d9e4f91
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beandisplay_ref.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png
new file mode 100644
index 0000000..38ddfe0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png
new file mode 100644
index 0000000..ce5ce46
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png
new file mode 100644
index 0000000..5ee3635
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png
new file mode 100644
index 0000000..bae11c3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref1.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref1.png
new file mode 100644
index 0000000..74667a6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref2.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref2.png
new file mode 100644
index 0000000..8486daf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/datefield_ref2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_1.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_1.png
new file mode 100644
index 0000000..0d47fdb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_2.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_2.png
new file mode 100644
index 0000000..966ebf0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/formfragment_ref_2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref1.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref1.png
new file mode 100644
index 0000000..593ba49
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref2.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref2.png
new file mode 100644
index 0000000..20bcc5d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/grid_ref2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/palette_ref.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/palette_ref.png
new file mode 100644
index 0000000..b8a70be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/palette_ref.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/radio_ref.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/radio_ref.png
new file mode 100644
index 0000000..52d9d9f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/radio_ref.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref1.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref1.png
new file mode 100644
index 0000000..9595677
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref2.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref2.png
new file mode 100644
index 0000000..a3b946e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/select_ref2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/textfield_ref.png b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/textfield_ref.png
new file mode 100644
index 0000000..643d985
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/textfield_ref.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java
new file mode 100644
index 0000000..f414612
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/BlankOption.java
@@ -0,0 +1,38 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.data;
+
+/**
+ * Used with the {@link org.apache.tapestry.corelib.components.Select} component to control whether an initial blank
+ * option is supplied.  Determines the optionality of the undelrying property from the Select's {@linkplain
+ * org.apache.tapestry.FieldValidator#isRequired() validate parameter}
+ */
+public enum BlankOption
+{
+    /**
+     * Always include the blank option, even if the underlying property is required.
+     */
+    ALWAYS,
+
+    /**
+     * Never include the blank option, even if the underlying property is optional.
+     */
+    NEVER,
+
+    /**
+     * The default: include the blank option if the underlying property is optional.
+     */
+    AUTO;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/GridPagerPosition.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/GridPagerPosition.java
new file mode 100644
index 0000000..a523f1e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/GridPagerPosition.java
@@ -0,0 +1,64 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.data;
+
+import org.apache.tapestry.corelib.components.Grid;
+
+/**
+ * Used by the {@link Grid} component to control where the pager portion of the Grid should be displayed.
+ */
+public enum GridPagerPosition
+{
+    /**
+     * Position the pager above the Grid's table.
+     */
+    TOP(true, false),
+
+    /**
+     * Position the pager below the Grid's table (this is the default).
+     */
+    BOTTOM(false, true),
+
+    /**
+     * Show the pager above and below the Grid's table.
+     */
+    BOTH(true, true),
+
+    /**
+     * Don't show a pager (the application will need to supply its own navigation mechanism).
+     */
+    NONE(false, false);
+
+    private final boolean matchTop;
+
+    private final boolean matchBottom;
+
+    private GridPagerPosition(boolean matchTop, boolean matchBottom)
+    {
+        this.matchTop = matchTop;
+        this.matchBottom = matchBottom;
+    }
+
+    public boolean isMatchBottom()
+    {
+        return matchBottom;
+    }
+
+    public boolean isMatchTop()
+    {
+        return matchTop;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java
new file mode 100644
index 0000000..6f7953e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java
@@ -0,0 +1,28 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.data;
+
+public enum InsertPosition
+{
+    /**
+     * Insert the new content above (i.e., before) the insertion position.
+     */
+    ABOVE,
+
+    /**
+     * Insert the new context below (i.e., after) the insertion position.
+     */
+    BELOW;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportAdapter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportAdapter.java
new file mode 100644
index 0000000..c685134
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportAdapter.java
@@ -0,0 +1,68 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.internal;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * An implementation of {@link org.apache.tapestry.services.FormSupport} that delegates all behavior to another instance
+ * of FormSupport. This allows some of the behavior to be overridden easily.
+ */
+public class FormSupportAdapter implements FormSupport
+{
+    private final FormSupport delegate;
+
+    public FormSupportAdapter(FormSupport delegate)
+    {
+        this.delegate = delegate;
+    }
+
+    public String allocateControlName(String id)
+    {
+        return delegate.allocateControlName(id);
+    }
+
+    public <T> void store(T component, ComponentAction<T> action)
+    {
+        delegate.store(component, action);
+    }
+
+    public <T> void storeAndExecute(T component, ComponentAction<T> action)
+    {
+        delegate.storeAndExecute(component, action);
+    }
+
+    public void defer(Runnable command)
+    {
+        delegate.defer(command);
+    }
+
+    public void setEncodingType(String encodingType)
+    {
+        delegate.setEncodingType(encodingType);
+    }
+
+    public void addValidation(Field field, String validationName, String message, Object constraint)
+    {
+        delegate.addValidation(field, validationName, message, constraint);
+    }
+
+    public String getClientId()
+    {
+        return delegate.getClientId();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java
new file mode 100644
index 0000000..ee439a5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java
@@ -0,0 +1,163 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.internal;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.FormSupport;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+/**
+ * Provides support to components enclosed by a form when the form is rendering (allowing the components to registry
+ * form submit callback commands), and also during form submission time.
+ * <p/>
+ * TODO: Most methods should only be invokable depending on whether the form is rendering or processing a submission.
+ */
+public class FormSupportImpl implements FormSupport
+{
+    private final ClientBehaviorSupport clientBehaviorSupport;
+
+    private final boolean clientValidationEnabled;
+
+    private final IdAllocator idAllocator;
+
+    private final String clientId;
+
+    private final ObjectOutputStream actions;
+
+    private List<Runnable> commands;
+
+    private String encodingType;
+
+    /**
+     * Constructor used when processing a form submission.
+     */
+    public FormSupportImpl()
+    {
+        this(null, null, null, false, null);
+    }
+
+    /**
+     * Constructor used when rendering.
+     */
+    public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
+                           boolean clientValidationEnabled)
+    {
+        this(clientId, actions, clientBehaviorSupport, clientValidationEnabled, new IdAllocator());
+    }
+
+    /**
+     * Full constructor.
+     */
+    public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
+                           boolean clientValidationEnabled, IdAllocator idAllocator)
+    {
+        this.clientId = clientId;
+        this.actions = actions;
+        this.clientBehaviorSupport = clientBehaviorSupport;
+        this.clientValidationEnabled = clientValidationEnabled;
+        this.idAllocator = idAllocator;
+    }
+
+    public String getFormId()
+    {
+        return clientId;
+    }
+
+    public String allocateControlName(String id)
+    {
+        return idAllocator.allocateId(id);
+    }
+
+    public <T> void store(T component, ComponentAction<T> action)
+    {
+        Component castComponent = Defense.cast(component, Component.class, "component");
+        Defense.notNull(action, "action");
+
+        String completeId = castComponent.getComponentResources().getCompleteId();
+
+        try
+        {
+            // Writing the complete id is not very efficient, but the GZip filter
+            // should help out there.
+            actions.writeUTF(completeId);
+            actions.writeObject(action);
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(InternalMessages.componentActionNotSerializable(completeId, ex), ex);
+        }
+    }
+
+    public <T> void storeAndExecute(T component, ComponentAction<T> action)
+    {
+        store(component, action);
+
+        action.execute(component);
+    }
+
+    public void defer(Runnable command)
+    {
+        if (commands == null) commands = CollectionFactory.newList();
+
+        commands.add(Defense.notNull(command, "command"));
+    }
+
+    public void executeDeferred()
+    {
+        if (commands == null) return;
+
+        for (Runnable r : commands)
+            r.run();
+
+        commands.clear();
+    }
+
+    public String getClientId()
+    {
+        return clientId;
+    }
+
+    public String getEncodingType()
+    {
+        return encodingType;
+    }
+
+    public void setEncodingType(String encodingType)
+    {
+        Defense.notBlank(encodingType, "encodingType");
+
+        if (this.encodingType != null && !this.encodingType.equals(encodingType))
+            throw new IllegalStateException(InternalMessages.conflictingEncodingType(this.encodingType, encodingType));
+
+        this.encodingType = encodingType;
+    }
+
+    public void addValidation(Field field, String validationName, String message, Object constraint)
+    {
+        if (clientValidationEnabled)
+            clientBehaviorSupport.addValidation(field, validationName, message, constraint);
+    }
+
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/InternalMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/InternalMessages.java
new file mode 100644
index 0000000..977628f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/InternalMessages.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.internal;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+public final class InternalMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(InternalMessages.class);
+
+    public static String componentActionNotSerializable(String componentId, Throwable cause)
+    {
+        return MESSAGES.format("component-action-not-serializable", componentId, cause);
+    }
+
+    public static String encloseErrorsInForm()
+    {
+        return MESSAGES.get("enclose-errors-in-form");
+    }
+
+    public static String failureInstantiatingObject(Class objectType, String componentId, Throwable cause)
+    {
+        return MESSAGES.format("failure-instantitating-object", ClassFabUtils
+                .toJavaClassName(objectType), componentId, cause);
+    }
+
+    public static String conflictingEncodingType(String existing, String conflicting)
+    {
+        return MESSAGES.format("conflicting-encoding-type", existing, conflicting);
+    }
+
+    public static String toClientShouldReturnString()
+    {
+        return MESSAGES.format("to-client-should-return-string");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java
new file mode 100644
index 0000000..fa684a9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java
@@ -0,0 +1,60 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.internal;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+
+import java.io.Serializable;
+
+/**
+ * A wrapper around a component id and a {@link org.apache.tapestry.ComponentAction}.
+ *
+ * @see org.apache.tapestry.corelib.components.FormFragment
+ */
+public class WrappedComponentAction implements Serializable
+{
+    private final String componentId;
+
+    private final ComponentAction action;
+
+    public WrappedComponentAction(Component component, ComponentAction action)
+    {
+        this(component.getComponentResources().getCompleteId(), action);
+    }
+
+    /**
+     * @param componentId the component's complete id, suitable for use with {@link org.apache.tapestry.services.ComponentSource#getComponent(String)}.
+     * @param action      the action associated with the component
+     */
+    public WrappedComponentAction(String componentId, ComponentAction action)
+    {
+        this.componentId = componentId;
+        this.action = action;
+    }
+
+    /**
+     * Retrieves the component from the source and executes the action.
+     *
+     * @param source used to re-acquire the component
+     */
+    public void execute(ComponentSource source)
+    {
+        Component component = source.getComponent(componentId);
+
+        action.execute(component);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
new file mode 100644
index 0000000..4143781
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/Autocomplete.java
@@ -0,0 +1,237 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.internal.services.ResponseRenderer;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.util.TextStreamResponse;
+import org.apache.tapestry5.json.JSONObject;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A mixin for a text field that allows for autocompletion of text fields. This is based on Prototype's autocompleter
+ * control.
+ * <p/>
+ * The mixin renders an (initially invisible) progress indicator after the field (it will also be after the error icon
+ * most fields render). The progress indicator is made visible during the request to the server. The mixin then renders
+ * a &lt;div&gt; that will be filled in on the client side with dynamically obtained selections.
+ * <p/>
+ * Multiple selection on the client is enabled by binding the tokens parameter (however, the mixin doesn't help split
+ * multiple selections up on the server, that is still your code's responsibility).
+ * <p/>
+ * The container is responsible for providing an event handler for event "providecompletions".  The context will be the
+ * partial input string sent from the client.  The return value should be an array or list of completions, in
+ * presentation order.  I.e.
+ * <p/>
+ * <pre>
+ * String[] onProvideCompletionsFromMyField(String input)
+ * {
+ *   return . . .;
+ * }
+ * </pre>
+ */
+@IncludeJavaScriptLibrary("${tapestry.scriptaculous}/controls.js")
+public class Autocomplete
+{
+    static final String EVENT_NAME = "autocomplete";
+
+    private static final String PARAM_NAME = "t:input";
+
+    /**
+     * The field component to which this mixin is attached.
+     */
+    @InjectContainer
+    private Field field;
+
+    @Inject
+    private ComponentResources resources;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private TypeCoercer coercer;
+
+    @Inject
+    private MarkupWriterFactory factory;
+
+    @Inject
+    @Path("classpath:org/apache/tapestry/ajax-loader.gif")
+    private Asset loader;
+
+    /**
+     * Overwrites the default minimum characters to trigger a server round trip (the default is 1).
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private int minChars;
+
+    @Inject
+    private ResponseRenderer responseRenderer;
+
+
+    /**
+     * Overrides the default check frequency for determining whether to send a server request. The default is .4
+     * seconds.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private double frequency;
+
+    /**
+     * If given, then the autocompleter will support multiple input values, seperated by any of the individual
+     * characters in the string.
+     */
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String tokens;
+
+    /**
+     * Mixin afterRender phrase occurs after the component itself. This is where we write the &lt;div&gt; element and
+     * the JavaScript.
+     *
+     * @param writer
+     */
+    void afterRender(MarkupWriter writer)
+    {
+        String id = field.getClientId();
+
+        String menuId = id + ":menu";
+        String loaderId = id + ":loader";
+
+        // This image is made visible while the request is being processed.
+        // To be honest, I think Prototype hides it too soon, it should wait
+        // until the <div> is fully positioned and updated.
+
+        writer.element("img",
+
+                       "src", loader.toClientURL(),
+
+                       "class", CSSClassConstants.INVISIBLE,
+
+                       "id", loaderId);
+        writer.end();
+
+        writer.element("div",
+
+                       "id", menuId,
+
+                       "class", "t-autocomplete-menu");
+        writer.end();
+
+        Link link = resources.createActionLink(EVENT_NAME, false);
+
+
+        JSONObject config = new JSONObject();
+        config.put("paramName", PARAM_NAME);
+        config.put("indicator", loaderId);
+
+        if (resources.isBound("minChars")) config.put("minChars", minChars);
+
+        if (resources.isBound("frequency")) config.put("frequency", frequency);
+
+        if (resources.isBound("tokens"))
+        {
+            for (int i = 0; i < tokens.length(); i++)
+            {
+                config.accumulate("tokens", tokens.substring(i, i + 1));
+            }
+        }
+
+        // Let subclasses do more.
+        configure(config);
+
+        renderSupport.addScript("new Ajax.Autocompleter('%s', '%s', '%s', %s);", id, menuId, link.toAbsoluteURI(),
+                                config);
+    }
+
+    Object onAutocomplete()
+    {
+        String input = request.getParameter(PARAM_NAME);
+
+        final Holder<List> matchesHolder = Holder.create();
+
+        // Default it to an empty list.
+
+        matchesHolder.put(Collections.emptyList());
+
+        ComponentEventCallback callback = new ComponentEventCallback()
+        {
+            public boolean handleResult(Object result)
+            {
+                List matches = coercer.coerce(result, List.class);
+
+                matchesHolder.put(matches);
+
+                return true;
+            }
+        };
+
+        resources.triggerEvent("providecompletions", new Object[] { input }, callback);
+
+        ContentType contentType = responseRenderer.findContentType(this);
+
+        MarkupWriter writer = factory.newMarkupWriter(contentType);
+
+        generateResponseMarkup(writer, matchesHolder.get());
+
+        return new TextStreamResponse(contentType.getMimeType(), writer.toString());
+    }
+
+    /**
+     * Invoked to allow subclasses to further configure the parameters passed to the JavaScript Ajax.Autocompleter
+     * options. The values minChars, frequency and tokens my be pre-configured. Subclasses may override this method to
+     * configure additional features of the Ajax.Autocompleter.
+     * <p/>
+     * <p/>
+     * This implementation does nothing.
+     *
+     * @param config parameters object
+     */
+    protected void configure(JSONObject config)
+    {
+    }
+
+    /**
+     * Generates the markup response that will be returned to the client; this should be an &lt;ul&gt; element with
+     * nested &lt;li&gt; elements. Subclasses may override this to produce more involved markup (including images and
+     * CSS class attributes).
+     *
+     * @param writer  to write the list to
+     * @param matches list of matching objects, each should be converted to a string
+     */
+    protected void generateResponseMarkup(MarkupWriter writer, List matches)
+    {
+        writer.element("ul");
+
+        for (Object o : matches)
+        {
+            writer.element("li");
+            writer.write(o.toString());
+            writer.end();
+        }
+
+        writer.end(); // ul
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/DiscardBody.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/DiscardBody.java
new file mode 100644
index 0000000..4c19952
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/DiscardBody.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.annotation.BeforeRenderBody;
+import org.apache.tapestry.annotation.MixinAfter;
+
+/**
+ * Discards a component's body. Returns false from the {@link BeforeRenderBody} phase, which prevents the rendering of
+ * the body. Set up as a "MixinAfter" so that components can render their an alternative body if they so desire before
+ * this mixin cancels the normal body (from the container's template).
+ */
+@MixinAfter
+public class DiscardBody
+{
+    boolean beforeRenderBody()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java
new file mode 100644
index 0000000..8048e0c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.InjectContainer;
+import org.apache.tapestry.annotation.MixinAfter;
+
+/**
+ * Renders an "disabled" attribute if the containing {@link Field#isDisabled() is disabled}.
+ */
+@MixinAfter
+public class RenderDisabled
+{
+    @InjectContainer
+    private Field field;
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (field.isDisabled())
+            writer.attributes("disabled", "disabled");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java
new file mode 100644
index 0000000..190f3da
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Used to render out all informal parameters, at the end of the {@link org.apache.tapestry.annotation.BeginRender}
+ * phase.
+ * <p/>
+ * This mixin can be used with components that render a single tag inside the {@link BeginRender} phase. RenderInformals
+ * will activate during the PostBeginRender phase to write additional attributes, from the informal parameters, into the
+ * active element.
+ * <p/>
+ * If you want this behavior, but need to render more than a single tag, then implement render phase methods for the
+ * {@link BeforeRenderTemplate} and {@link AfterRenderTemplate} phases. Use those phases to write the additional
+ * elements and close them.
+ * <p/>
+ * This is often used as a base class, for cases where a component doesn't have other mixins.
+ */
+@MixinAfter
+@SupportsInformalParameters
+public class RenderInformals
+{
+    @Inject
+    private ComponentResources resources;
+
+    void beginRender(MarkupWriter writer)
+    {
+        resources.renderInformalParameters(writer);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.java
new file mode 100644
index 0000000..ca9b5eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.java
@@ -0,0 +1,69 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ClientElement;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.annotation.InjectContainer;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.services.Heartbeat;
+import org.apache.tapestry5.json.JSONArray;
+
+/**
+ * A mixin that can be applied to a {@link org.apache.tapestry.corelib.components.Checkbox} or {@link
+ * org.apache.tapestry.corelib.components.Radio} component that will link the input field and a {@link
+ * org.apache.tapestry.corelib.components.FormFragment}, making the field control the client-side visibility of the
+ * FormFragment.
+ */
+public class TriggerFragment
+{
+    @InjectContainer
+    private Field container;
+
+    /**
+     * The {@link org.apache.tapestry.corelib.components.FormFragment} instance to make dynamically visible or hidden.
+     */
+    @Parameter(required = true, defaultPrefix = BindingConstants.COMPONENT)
+    private ClientElement fragment;
+
+    @Environmental
+    private RenderSupport renderSupport;
+
+    @Environmental
+    private Heartbeat heartbeat;
+
+    void beginRender()
+    {
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                JSONArray spec = new JSONArray();
+                spec.put(container.getClientId());
+                spec.put(fragment.getClientId());
+
+                renderSupport.addInit("linkTriggerToFormFragment", spec);
+            }
+        };
+
+        // Defer generating the script to ensure that the FormFragment has rendered
+        // and generated its client id.
+
+        heartbeat.defer(r);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc
new file mode 100644
index 0000000..a9aaf69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc
@@ -0,0 +1,9 @@
+<document>
+    <body>
+        <p>
+            See the
+            <a href="../components/FormFragment.html">FormFragment</a>
+            documentation for an example.
+        </p>
+    </body>
+</document>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ExceptionReport.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ExceptionReport.java
new file mode 100644
index 0000000..c103c02
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ExceptionReport.java
@@ -0,0 +1,112 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.pages;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.annotation.ContentType;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.ExceptionReporter;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+import java.util.List;
+
+/**
+ * Responsible for reporting runtime exceptions. This page is quite verbose and is usually overridden in a production
+ * application. When {@link org.apache.tapestry.SymbolConstants#PRODUCTION_MODE} is "true", it is very abbreviated.
+ *
+ * @see org.apache.tapestry.corelib.components.ExceptionDisplay
+ */
+@ContentType("text/html")
+public class ExceptionReport implements ExceptionReporter
+{
+    private static final String PATH_SEPARATOR_PROPERTY = "path.separator";
+
+    @Property
+    private String attributeName;
+
+    @Inject
+    @Property
+    private Request request;
+
+    @Inject
+    @Symbol(SymbolConstants.PRODUCTION_MODE)
+    @Property(write = false)
+    private boolean productionMode;
+
+    @Inject
+    @Symbol(SymbolConstants.TAPESTRY_VERSION)
+    @Property(write = false)
+    private String tapestryVersion;
+
+    @Property(write = false)
+    private Throwable rootException;
+
+    @Property
+    private String propertyName;
+
+    private final String pathSeparator = System.getProperty(PATH_SEPARATOR_PROPERTY);
+
+    public void reportException(Throwable exception)
+    {
+        rootException = exception;
+    }
+
+    public boolean getHasSession()
+    {
+        return request.getSession(false) != null;
+    }
+
+    public Session getSession()
+    {
+        return request.getSession(false);
+    }
+
+    public Object getAttributeValue()
+    {
+        return getSession().getAttribute(attributeName);
+    }
+
+    /**
+     * Returns a <em>sorted</em> list of system property names.
+     */
+    public List<String> getSystemProperties()
+    {
+        return InternalUtils.sortedKeys(System.getProperties());
+    }
+
+    public String getPropertyValue()
+    {
+        return System.getProperty(propertyName);
+    }
+
+    public boolean isSimpleProperty()
+    {
+        if (propertyName.equals(PATH_SEPARATOR_PROPERTY)) return true;
+
+        return !getPropertyValue().contains(pathSeparator);
+    }
+
+    public String[] getComplexPropertyValue()
+    {
+        // Neither : nor ; is a regexp character.
+
+        return getPropertyValue().split(pathSeparator);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.java
new file mode 100644
index 0000000..b66a07e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.java
@@ -0,0 +1,71 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.pages;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.PropertyOutputContext;
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+public class PropertyDisplayBlocks
+{
+    @Environmental
+    private PropertyOutputContext context;
+
+    @Inject
+    private Locale locale;
+
+    private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
+
+    public String getConvertedEnumValue()
+    {
+        Enum value = (Enum) context.getPropertyValue();
+
+        if (value == null) return null;
+
+        return TapestryInternalUtils.getLabelForEnum(context.getMessages(), value);
+    }
+
+    public DateFormat getDateFormat()
+    {
+        return dateFormat;
+    }
+
+    public PropertyOutputContext getContext()
+    {
+        return context;
+    }
+
+    public Renderable getPasswordRenderer()
+    {
+        return new Renderable()
+        {
+            public void render(MarkupWriter writer)
+            {
+
+                Object value = context.getPropertyValue();
+
+                int length = value == null ? 0 : value.toString().length();
+
+                for (int i = 0; i < length; i++) writer.write("*");
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyEditBlocks.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyEditBlocks.java
new file mode 100644
index 0000000..45e0350
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/PropertyEditBlocks.java
@@ -0,0 +1,128 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.pages;
+
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.corelib.components.*;
+import org.apache.tapestry.services.BeanBlockContribution;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.apache.tapestry.services.PropertyEditContext;
+import org.apache.tapestry.util.EnumSelectModel;
+import org.apache.tapestry.util.EnumValueEncoder;
+
+/**
+ * A page that exists to contain blocks used to edit different types of properties. The blocks on this page are
+ * contributed into the {@link BeanBlockSource} service configuration.
+ *
+ * @see BeanBlockContribution
+ * @see BeanEditForm
+ */
+public class PropertyEditBlocks
+{
+    @Environmental
+    private PropertyEditContext context;
+
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "translate=prop:context.translator", "validate=prop:textFieldValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
+    private TextField textField;
+
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "translate=prop:context.translator", "validate=prop:numberFieldValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
+    private TextField numberField;
+
+
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "encoder=valueEncoderForProperty", "model=selectModelForProperty", "validate=prop:selectValidator", "clientId=prop:context.propertyId" })
+    private Select select;
+
+    @SuppressWarnings("unused")
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyId" })
+    private Checkbox checkboxField;
+
+    @SuppressWarnings("unused")
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "clientId=prop:context.propertyid", "validate=prop:dateFieldValidator" })
+    private DateField dateField;
+
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "translate=prop:context.translator", "validate=prop:passwordFieldValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
+    private PasswordField passwordField;
+
+    @Component(
+            parameters = { "value=context.propertyValue", "label=prop:context.label", "translate=prop:context.translator", "validate=prop:textAreaValidator", "clientId=prop:context.propertyId", "annotationProvider=context" })
+    private TextArea textArea;
+
+
+    public PropertyEditContext getContext()
+    {
+        return context;
+    }
+
+
+    public FieldValidator getTextFieldValidator()
+    {
+        return context.getValidator(textField);
+    }
+
+    public FieldValidator getNumberFieldValidator()
+    {
+        return context.getValidator(numberField);
+    }
+
+    public FieldValidator getPasswordFieldValidator()
+    {
+        return context.getValidator(passwordField);
+    }
+
+
+    public FieldValidator getTextAreaValidator()
+    {
+        return context.getValidator(textArea);
+    }
+
+
+    public FieldValidator getDateFieldValidator()
+    {
+        return context.getValidator(dateField);
+    }
+
+    public FieldValidator getSelectValidator()
+    {
+        return context.getValidator(select);
+    }
+
+    /**
+     * Provide a value encoder for an enum type.
+     */
+    @SuppressWarnings("unchecked")
+    public ValueEncoder getValueEncoderForProperty()
+    {
+        return new EnumValueEncoder(context.getPropertyType());
+    }
+
+    /**
+     * Provide a select mode for an enum type.
+     */
+    @SuppressWarnings("unchecked")
+    public SelectModel getSelectModelForProperty()
+    {
+        return new EnumSelectModel(context.getPropertyType(), context.getContainerMessages());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java
new file mode 100644
index 0000000..406616a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java
@@ -0,0 +1,72 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.services.BeanModelSource;
+
+import java.util.List;
+
+/**
+ * Page used to see the status of all services defined by the {@link Registry}.
+ * <p/>
+ * TODO: Add filters to control which services are displayed.
+ * <p/>
+ * TODO: Disable this page if in production mode (or not, as it does no harm).
+ */
+@Meta("tapestry.response-content-type=text/html")
+public class ServiceStatus
+{
+    @Inject
+    private ServiceActivityScoreboard scoreboard;
+
+    @Property
+    private List<ServiceActivity> activity;
+
+    @Property
+    private ServiceActivity row;
+
+    @Inject
+    private BeanModelSource source;
+
+    @Property
+    private final BeanModel model;
+
+    @Inject
+    private ComponentResources resources;
+
+    {
+        model = source.create(ServiceActivity.class, false, resources);
+
+        model.add("serviceInterface", null);
+
+        // There's no line number information for interfaces, so we'll reorder the
+        // propreties manually.
+
+        model.reorder("serviceId", "serviceInterface", "scope", "status");
+    }
+
+    void setupRender()
+    {
+        activity = scoreboard.getServiceActivity();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/CData.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/CData.java
new file mode 100644
index 0000000..512cc4a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/CData.java
@@ -0,0 +1,59 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import java.io.PrintWriter;
+
+/**
+ * A node that stores parsed character content (CDATA).  For XML documents (as per {@link MarkupModel#isXML()}, this
+ * will be writtens as a CDATA section. For non-XML documents, the content is filtered as it is written out.
+ */
+public class CData extends Node
+{
+    private final String content;
+
+    private final Document document;
+
+    public CData(Node container, Document document, String content)
+    {
+        super(container);
+
+        this.document = document;
+        this.content = content;
+    }
+
+
+    public void toMarkup(PrintWriter writer)
+    {
+        MarkupModel model = document.getMarkupModel();
+
+        if (model.isXML())
+        {
+            writer.print("<![CDATA[");
+            writer.print(content);
+            writer.print("]]>");
+            return;
+        }
+
+        // CDATA not supported, so write it normally, with entities escaped.  Create a working
+        // buffer that's plenty big even if a lot of characters need escaping.
+
+        StringBuilder builder = new StringBuilder(2 * content.length());
+
+        model.encode(content, builder);
+
+        writer.print(builder.toString());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Comment.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Comment.java
new file mode 100644
index 0000000..3329094
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Comment.java
@@ -0,0 +1,41 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import java.io.PrintWriter;
+
+/**
+ * A node that represents a comment within the DOM.
+ */
+public final class Comment extends Node
+{
+    private final String comment;
+
+    Comment(Node container, String comment)
+    {
+        super(container);
+
+        this.comment = comment;
+    }
+
+    @Override
+    public void toMarkup(PrintWriter writer)
+    {
+        writer.print("<!-- ");
+        writer.print(comment);
+        writer.print(" -->");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DTD.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DTD.java
new file mode 100644
index 0000000..9d8a662
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DTD.java
@@ -0,0 +1,56 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import java.io.PrintWriter;
+
+/**
+ * Representation of a document type. Note that technically, a Doctype isn't a node in an xml document; hence this
+ * doesn't extend node.
+ */
+public class DTD
+{
+    private final String name;
+
+    private final String publicId;
+
+    private final String systemId;
+
+    public DTD(String name, String publicId, String systemId)
+    {
+        this.name = name;
+        this.publicId = publicId;
+        this.systemId = systemId;
+    }
+
+    public void toMarkup(PrintWriter writer)
+    {
+        if (publicId != null)
+        {
+            if (systemId != null)
+            {
+                writer.printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">", name, publicId, systemId);
+            }
+            else
+            {
+                writer.printf("<!DOCTYPE %s PUBLIC \"%s\">", name, publicId);
+            }
+        }
+        else if (systemId != null)
+        {
+            writer.printf("<!DOCTYPE %s SYSTEM \"%s\">", name, systemId);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DefaultMarkupModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DefaultMarkupModel.java
new file mode 100644
index 0000000..568421b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DefaultMarkupModel.java
@@ -0,0 +1,92 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Set;
+
+/**
+ * Default implementation of {@link org.apache.tapestry.dom.MarkupModel} that is appropriate for traditional HTML
+ * markup. This conforms to the SGML HTML definition, including some things that are not well formed XML-style markup.
+ * Assumes that all tags are lower-case.
+ */
+public class DefaultMarkupModel implements MarkupModel
+{
+    private final Set<String> EMPTY_ELEMENTS = CollectionFactory.newSet("base", "br", "col", "frame", "hr", "img",
+                                                                        "input", "link",
+                                                                        "meta", "option", "param");
+
+    /**
+     * Passes all characters but '&lt;', '&gt;' and '&amp;' through unchanged.
+     */
+    public void encode(String content, StringBuilder buffer)
+    {
+        encode(content, false, buffer);
+    }
+
+    public void encodeQuoted(String content, StringBuilder buffer)
+    {
+        encode(content, true, buffer);
+    }
+
+    private void encode(String content, boolean encodeQuotes, StringBuilder buffer)
+    {
+        char[] array = content.toCharArray();
+
+        for (char ch : array)
+        {
+            switch (ch)
+            {
+                case '<':
+                    buffer.append("&lt;");
+                    continue;
+
+                case '>':
+                    buffer.append("&gt;");
+                    continue;
+
+                case '&':
+                    buffer.append("&amp;");
+                    continue;
+
+                case '"':
+                    if (encodeQuotes)
+                    {
+                        buffer.append("&quot;");
+                        continue;
+                    }
+
+                default:
+                    buffer.append(ch);
+            }
+        }
+    }
+
+    public EndTagStyle getEndTagStyle(String element)
+    {
+        boolean isEmpty = EMPTY_ELEMENTS.contains(element);
+
+        return isEmpty ? EndTagStyle.OMIT : EndTagStyle.REQUIRE;
+    }
+
+    /**
+     * Returns false.
+     */
+    public boolean isXML()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Document.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Document.java
new file mode 100644
index 0000000..8a09288
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Document.java
@@ -0,0 +1,163 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+import java.io.PrintWriter;
+
+/**
+ * The root node of a DOM.
+ */
+public final class Document extends Node
+{
+    private Element rootElement;
+
+    private DTD dtd;
+
+    private final MarkupModel model;
+
+    private final String encoding;
+
+    public Document(MarkupModel model)
+    {
+        this(model, null);
+    }
+
+    public Document(MarkupModel model, String encoding)
+    {
+        super(null);
+
+        this.model = model;
+        this.encoding = encoding;
+    }
+
+    Document getDocument()
+    {
+        return this;
+    }
+
+    /**
+     * Finds an element based on a path of element names.
+     *
+     * @param path slash separated series of element names
+     * @return the matching element, or null if not found
+     * @see Element#find(String)
+     */
+    public Element find(String path)
+    {
+        Defense.notBlank(path, "path");
+
+        if (rootElement == null) return null;
+
+        int slashx = path.indexOf("/");
+
+        String rootElementName = slashx < 0 ? path : path.substring(0, slashx);
+
+        if (!rootElement.getName().equals(rootElementName)) return null;
+
+        return slashx < 0 ? rootElement : rootElement.find(path.substring(slashx + 1));
+    }
+
+    /**
+     * Builds with an instance of {@link DefaultMarkupModel}.
+     */
+    public Document()
+    {
+        this(new DefaultMarkupModel());
+    }
+
+    public MarkupModel getMarkupModel()
+    {
+        return model;
+    }
+
+    /**
+     * Creates the root element for this document, replacing any previous root element.
+     */
+    public Element newRootElement(String name)
+    {
+        rootElement = new Element(this, null, name);
+
+        return rootElement;
+    }
+
+    /**
+     * Creates a new root element within a namespace.
+     *
+     * @param namespace URI of namespace containing the element
+     * @param name      name of element with namespace
+     * @return the root element
+     */
+    public Element newRootElement(String namespace, String name)
+    {
+        rootElement = new Element(this, namespace, name);
+
+        return rootElement;
+    }
+
+    @Override
+    public void toMarkup(PrintWriter writer)
+    {
+        if (rootElement == null) throw new IllegalStateException(DomMessages.noRootElement());
+
+
+        if (model.isXML())
+        {
+            writer.print("<?xml version=\"1.0\"");
+
+            if (encoding != null) writer.printf(" encoding=\"%s\"", encoding);
+
+            writer.print("?>\n");
+        }
+
+        // TODO: lead-in comments, directives.
+        if (dtd != null)
+        {
+            dtd.toMarkup(writer);
+        }
+
+        rootElement.toMarkup(writer);
+    }
+
+    @Override
+    public String toString()
+    {
+        if (rootElement == null) return "[empty Document]";
+
+        return super.toString();
+    }
+
+    public Element getRootElement()
+    {
+        return rootElement;
+    }
+
+    /**
+     * Tries to find an element in this document whose id is specified.
+     *
+     * @param id the value of the id attribute of the element being looked for
+     * @return the element if found. null if not found.
+     */
+    public Element getElementById(String id)
+    {
+        return rootElement.getElementById(id);
+    }
+
+    public void dtd(String name, String publicId, String systemId)
+    {
+        dtd = new DTD(name, publicId, systemId);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DomMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DomMessages.java
new file mode 100644
index 0000000..ce1ebdc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/DomMessages.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+final class DomMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(DomMessages.class);
+
+
+    static String noRootElement()
+    {
+        return MESSAGES.get("no-root-element");
+    }
+
+    static String namespaceURINotMappedToPrefix(String namespace)
+    {
+        return MESSAGES.format("namespace-uri-not-mapped-to-prefix", namespace);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Element.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Element.java
new file mode 100644
index 0000000..ca69c6d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Element.java
@@ -0,0 +1,532 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.io.PrintWriter;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An element that will render with a begin tag and attributes, a body, and an end tag. Also acts as a factory for
+ * enclosed Element, Text and Comment nodes.
+ * <p/>
+ * TODO: Support for CDATA nodes. Do we need Entity nodes?
+ */
+public final class Element extends Node
+{
+    class Attribute
+    {
+        private final String namespace;
+        private final String name;
+        private final String value;
+
+        public Attribute(String namespace, String name, String value)
+        {
+            this.namespace = namespace;
+            this.name = name;
+            this.value = value;
+        }
+
+        public String getValue()
+        {
+            return value;
+        }
+
+        void render(MarkupModel model, StringBuilder builder)
+        {
+            builder.append(" ");
+            builder.append(toPrefixedName(namespace, name));
+            builder.append("=\"");
+            model.encodeQuoted(value, builder);
+            builder.append('"');
+        }
+    }
+
+    private final String name;
+
+    private Map<String, Attribute> attributes;
+
+    private Element parent;
+
+    private final Document document;
+
+    private static final String CLASS_ATTRIBUTE = "class";
+
+    /**
+     * URI of the namespace which contains the element.  A quirk in XML is that the element may be in a namespace it
+     * defines itself, so resolving the namespace to a prefix must wait until render time (since the Element is created
+     * before the namespaces for it are defined).
+     */
+    private final String namespace;
+
+    private Map<String, String> namespaceToPrefix;
+
+    /**
+     * Constructor for a root element.
+     */
+    Element(Document container, String namespace, String name)
+    {
+        super(container);
+
+        document = container;
+        this.namespace = namespace;
+        this.name = name;
+    }
+
+    /**
+     * Constructor for a nested element.
+     */
+    Element(Element parent, String namespace, String name)
+    {
+        super(parent);
+
+        this.parent = parent;
+        this.namespace = namespace;
+        this.name = name;
+
+        document = parent.getDocument();
+    }
+
+    public Document getDocument()
+    {
+        return document;
+    }
+
+    /**
+     * Returns the containing element for this element. This will be null for the root element of a document.
+     */
+    public Element getParent()
+    {
+        return parent;
+    }
+
+    /**
+     * Adds an attribute to the element, but only if the attribute name does not already exist.
+     *
+     * @param name  the name of the attribute to add
+     * @param value the value for the attribute. A value of null is allowed, and no attribute will be added to the
+     *              element.
+     */
+    public void attribute(String name, String value)
+    {
+        attribute(null, name, value);
+    }
+
+    /**
+     * Adds a namespaced attribute to the element, but only if the attribute name does not already exist.
+     *
+     * @param namespace the namespace to contain the attribute, or null
+     * @param name      the name of the attribute to add
+     * @param value     the value for the attribute. A value of null is allowed, and no attribute will be added to the
+     *                  element.
+     */
+    public void attribute(String namespace, String name, String value)
+    {
+        notBlank(name, "name");
+
+        if (value == null) return;
+
+        if (attributes == null) attributes = newMap();
+
+        if (!attributes.containsKey(name)) attributes.put(name, new Attribute(namespace, name, value));
+    }
+
+
+    /**
+     * Convenience for invoking {@link #attribute(String, String)} multiple times.
+     *
+     * @param namesAndValues alternating attribute names and attribute values
+     */
+    public void attributes(String... namesAndValues)
+    {
+        int i = 0;
+        while (i < namesAndValues.length)
+        {
+            String name = namesAndValues[i++];
+            String value = namesAndValues[i++];
+
+            attribute(name, value);
+        }
+    }
+
+    /**
+     * Forces changes to a number of attributes. The new attributes <em>overwrite</em> previous values.
+     */
+    public void forceAttributes(String... namesAndValues)
+    {
+        if (attributes == null) attributes = newMap();
+
+        int i = 0;
+
+        while (i < namesAndValues.length)
+        {
+            String name = namesAndValues[i++];
+            String value = namesAndValues[i++];
+
+            if (value == null)
+            {
+                attributes.remove(name);
+                continue;
+            }
+
+            attributes.put(name, new Attribute(null, name, value));
+        }
+    }
+
+    /**
+     * Creates and returns a new Element node as a child of this node.
+     *
+     * @param name           the name of the element to create
+     * @param namesAndValues alternating attribute names and attribute values
+     */
+    public Element element(String name, String... namesAndValues)
+    {
+        notBlank(name, "name");
+
+        Element child = newChild(new Element(this, null, name));
+
+        child.attributes(namesAndValues);
+
+        return child;
+    }
+
+    /**
+     * Creates and returns a new Element within a namespace as a child of this node.
+     *
+     * @param namespace namespace to contain the element, or null
+     * @param name      element name to create within the namespace
+     * @return the newly created element
+     */
+    public Element elementNS(String namespace, String name)
+    {
+        notBlank(name, "name");
+
+        return newChild(new Element(this, namespace, name));
+    }
+
+    public Element elementAt(int index, String name, String... namesAndValues)
+    {
+        notBlank(name, "name");
+
+        Element child = new Element(this, null, name);
+        child.attributes(namesAndValues);
+
+        insertChildAt(index, child);
+
+        return child;
+    }
+
+    /**
+     * Adds the comment and returns this element for further construction.
+     */
+    public Element comment(String text)
+    {
+        newChild(new Comment(this, text));
+
+        return this;
+    }
+
+    /**
+     * Adds the raw text and returns this element for further construction.
+     */
+    public Element raw(String text)
+    {
+        newChild(new Raw(this, text));
+
+        return this;
+    }
+
+    /**
+     * Adds and returns a new text node (the text node is returned so that {@link Text#write(String)} or [@link {@link
+     * Text#writef(String, Object[])} may be invoked .
+     *
+     * @param text initial text for the node
+     * @return the new Text node
+     */
+    public Text text(String text)
+    {
+        return newChild(new Text(this, document, text));
+    }
+
+    /**
+     * Adds an returns a new CDATA node.
+     *
+     * @param content the content to be rendered by the node
+     * @return the newly created node
+     */
+    public CData cdata(String content)
+    {
+        return newChild(new CData(this, document, content));
+    }
+
+
+    private <T extends Node> T newChild(T child)
+    {
+        addChild(child);
+
+        return child;
+    }
+
+    @Override
+    public void toMarkup(PrintWriter writer)
+    {
+        StringBuilder builder = new StringBuilder();
+
+        String prefixedElementName = toPrefixedName(namespace, name);
+
+        builder.append("<").append(prefixedElementName);
+
+        MarkupModel markupModel = document.getMarkupModel();
+
+        if (attributes != null)
+        {
+            List<String> keys = InternalUtils.sortedKeys(attributes);
+
+            for (String key : keys)
+            {
+                Attribute attribute = attributes.get(key);
+
+                attribute.render(markupModel, builder);
+            }
+        }
+
+        // Next, emit namespace declarations for each namespace.
+
+        if (namespaceToPrefix != null)
+        {
+            List<String> namespaces = InternalUtils.sortedKeys(namespaceToPrefix);
+
+            for (String namespace : namespaces)
+            {
+                String prefix = namespaceToPrefix.get(namespace);
+
+                builder.append(" xmlns");
+
+                if (!prefix.equals(""))
+                {
+                    builder.append(":").append(prefix);
+                }
+
+                builder.append("=\"");
+
+                markupModel.encodeQuoted(namespace, builder);
+
+                builder.append('"');
+            }
+        }
+
+        EndTagStyle style = markupModel.getEndTagStyle(name);
+
+        boolean hasChildren = hasChildren();
+
+        String close = (!hasChildren && style == EndTagStyle.ABBREVIATE) ? "/>" : ">";
+
+        builder.append(close);
+
+        writer.print(builder.toString());
+
+        if (hasChildren) writeChildMarkup(writer);
+
+        // Dangerous -- perhaps it should be an error for a tag of type OMIT to even have children!
+        // We'll certainly be writing out unbalanced markup in that case.
+
+        if (style == EndTagStyle.OMIT) return;
+
+        if (hasChildren || style == EndTagStyle.REQUIRE) writer.printf("</%s>", prefixedElementName);
+    }
+
+    private String toPrefixedName(String namespace, String name)
+    {
+        if (namespace == null || namespace.equals("")) return name;
+
+        String prefix = toNamespacePrefix(namespace);
+
+        // The empty string indicates the default namespace which doesn't use a prefix.
+
+        if (prefix.equals("")) return name;
+
+        return prefix + ":" + name;
+    }
+
+    /**
+     * Tries to find an element under this element (including itself) whose id is specified. Performs a width-first
+     * search of the document tree.
+     *
+     * @param id the value of the id attribute of the element being looked for
+     * @return the element if found. null if not found.
+     */
+    public Element getElementById(String id)
+    {
+        Defense.notNull(id, "id");
+
+        LinkedList<Element> queue = newLinkedList();
+
+        queue.add(this);
+
+        while (!queue.isEmpty())
+        {
+            Element e = queue.removeFirst();
+
+            String elementId = e.getAttribute("id");
+
+            if (id.equals(elementId)) return e;
+
+            for (Node n : e.getChildren())
+            {
+                Element child = n.asElement();
+
+                if (child != null) queue.addLast(child);
+            }
+        }
+
+        // Exhausted the entire tree
+
+        return null;
+    }
+
+    /**
+     * Searchs for a child element with a particular name below this element. The path parameter is a slash separated
+     * series of element names.
+     *
+     * @param path
+     * @return
+     */
+    public Element find(String path)
+    {
+        notBlank(path, "path");
+
+        Element search = this;
+
+        for (String name : TapestryInternalUtils.splitPath(path))
+        {
+            search = search.findChildWithElementName(name);
+
+            if (search == null) break;
+        }
+
+        return search;
+    }
+
+    private Element findChildWithElementName(String name)
+    {
+        for (Node node : getChildren())
+        {
+            Element child = node.asElement();
+
+            if (child != null && child.getName().equals(name)) return child;
+        }
+
+        // Not found.
+
+        return null;
+    }
+
+    public String getAttribute(String attributeName)
+    {
+        Attribute attribute = InternalUtils.get(attributes, attributeName);
+
+        return attribute == null ? null : attribute.getValue();
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * All other implementations of Node return null except this one.
+     */
+    @Override
+    Element asElement()
+    {
+        return this;
+    }
+
+    /**
+     * Adds one or more CSS class names to the "class" attribute. No check for duplicates is made. Note that CSS class
+     * names are case insensitive on the client.
+     *
+     * @param className one or more CSS class names
+     * @return the element for further configuration
+     */
+    public Element addClassName(String... className)
+    {
+        String classes = getAttribute(CLASS_ATTRIBUTE);
+
+        StringBuilder builder = new StringBuilder();
+
+        if (classes != null) builder.append(classes);
+
+        for (String name : className)
+        {
+            if (builder.length() > 0) builder.append(" ");
+
+            builder.append(name);
+        }
+
+        forceAttributes(CLASS_ATTRIBUTE, builder.toString());
+
+        return this;
+    }
+
+    String toNamespacePrefix(String namespaceURI)
+    {
+        String prefix = InternalUtils.get(namespaceToPrefix, namespaceURI);
+
+        if (prefix != null) return prefix;
+
+        if (parent == null) throw new RuntimeException(DomMessages.namespaceURINotMappedToPrefix(namespaceURI));
+
+        return parent.toNamespacePrefix(namespaceURI);
+    }
+
+    /**
+     * Defines a namespace for this element, mapping a URI to a prefix.   This will affect how namespaced elements and
+     * attributes nested within the element are rendered, and will also cause <code>xmlns:</code> attributes (to define
+     * the namespace and prefix) to be rendered.
+     *
+     * @param namespace       URI of the namespace
+     * @param namespacePrefix prefix
+     * @return this element
+     */
+    public Element defineNamespace(String namespace, String namespacePrefix)
+    {
+        Defense.notNull(namespace, "namespace");
+        Defense.notNull(namespacePrefix, "namespacePrefix");
+
+        if (namespaceToPrefix == null) namespaceToPrefix = CollectionFactory.newMap();
+
+        namespaceToPrefix.put(namespace, namespacePrefix);
+
+        return this;
+    }
+
+    /**
+     * Returns the namespace for this element (which is typically a URL). The namespace may be null.
+     */
+    public String getNamespace()
+    {
+        return namespace;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/EndTagStyle.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/EndTagStyle.java
new file mode 100644
index 0000000..28f5a0a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/EndTagStyle.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+/**
+ * Part of a {@link MarkupModel}, used to define how end tags are handled when the {@link Document} in rendered out as a
+ * text stream.
+ */
+public enum EndTagStyle
+{
+
+    /**
+     * Omit the end tag. Examples for HTML include the input, br and img elements.
+     */
+    OMIT,
+    /**
+     * Require an end tag always. This is the default for most elements in HTML.
+     */
+    REQUIRE,
+    /**
+     * Require an end tag, but abbreviate it if the element has no children. This is the only value used in XML
+     * documents.
+     */
+    ABBREVIATE
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/MarkupModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/MarkupModel.java
new file mode 100644
index 0000000..37e2a03
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/MarkupModel.java
@@ -0,0 +1,57 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+/**
+ * Used by a the DOM to determine how to produce markup. Delegates details about converted entities and some formatting
+ * details.  This exists to handle the differences between traditional HTML output (which is SGML based, meaning there
+ * can be elements that are valid without a close tag) and "modern" XML, such as XHTML.  Generally speaking, for XHTML
+ * it is vital that a !DOCTYPE be included in the rendered response, or the browser will be unable to display the result
+ * properly.
+ */
+public interface MarkupModel
+{
+    /**
+     * Encodes the characters into the buffer, converting control characters (such as '&lt;') into corresponding
+     * entities (such as &amp;lt;).
+     *
+     * @param content to be filtered
+     * @param buffer  to receive the filtered content
+     */
+    void encode(String content, StringBuilder buffer);
+
+    /**
+     * Encodes the characters into the buffer for use in a quoted value (that is, an attribute value), converting
+     * control characters (such as '&lt;') into corresponding entities (such as &amp;lt;). In addition, double quotes
+     * must be quoted or otherwise escaped.
+     *
+     * @param content to be filtered
+     * @param buffer  to receive the filtered content
+     */
+    void encodeQuoted(String content, StringBuilder buffer);
+
+    /**
+     * For a given element, determines how the end tag for the element should be rendered.
+     */
+    EndTagStyle getEndTagStyle(String element);
+
+    /**
+     * Returns true if the document markup is XML, which is used to determine the need for an XML declaration at the
+     * start of the document, and whether CDATA sections are supported.
+     *
+     * @return true for XML output, false for HTML (SGML) output
+     */
+    boolean isXML();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java
new file mode 100644
index 0000000..929ca6f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Node.java
@@ -0,0 +1,117 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.internal.util.PrintOutCollector;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A node within the DOM.
+ */
+public abstract class Node
+{
+    private Node container;
+
+    private List<Node> children;
+
+    /**
+     * Creates a new node, setting its container to the provided value. Container may also be null, but that is only
+     * used for Document nodes (the topmost node of a DOM).
+     *
+     * @param container
+     */
+    protected Node(Node container)
+    {
+        this.container = container;
+    }
+
+    public Node getContainer()
+    {
+        return container;
+    }
+
+    /**
+     * Returns the node as an {@link Element}, if it is an element. Returns null otherwise.
+     */
+    Element asElement()
+    {
+        return null;
+    }
+
+    void addChild(Node child)
+    {
+        if (children == null) children = newList();
+
+        children.add(child);
+    }
+
+    void insertChildAt(int index, Node child)
+    {
+        if (children == null) children = newList();
+
+        children.add(index, child);
+    }
+
+    boolean hasChildren()
+    {
+        return children != null && !children.isEmpty();
+    }
+
+    void writeChildMarkup(PrintWriter writer)
+    {
+        if (children == null) return;
+
+        for (Node child : children)
+            child.toMarkup(writer);
+    }
+
+    /**
+     * @return the concatenation of the String representations {@link #toString()} of its children.
+     */
+    public final String getChildMarkup()
+    {
+        PrintOutCollector collector = new PrintOutCollector();
+
+        writeChildMarkup(collector.getPrintWriter());
+
+        return collector.getPrintOut();
+    }
+
+    /**
+     * Invokes {@link #toMarkup(PrintWriter)}, collecting output in a string, which is returned.
+     */
+    @Override
+    public String toString()
+    {
+        PrintOutCollector collector = new PrintOutCollector();
+        toMarkup(collector.getPrintWriter());
+        return collector.getPrintOut();
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<Node> getChildren()
+    {
+        return children == null ? Collections.EMPTY_LIST : children;
+    }
+
+    /**
+     * Writes the markup for this node to the writer.
+     */
+    public abstract void toMarkup(PrintWriter writer);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Raw.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Raw.java
new file mode 100644
index 0000000..42e141f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Raw.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import java.io.PrintWriter;
+
+/**
+ * A specialized node in the document tree that contains raw markup to be printed to the client exactly as-is.
+ */
+public final class Raw extends Node
+{
+    private final String text;
+
+    Raw(Node container, String text)
+    {
+        super(container);
+
+        this.text = text;
+    }
+
+    /**
+     * Prints the text exactly as is, no translations, filtering, etc.
+     */
+    @Override
+    public void toMarkup(PrintWriter writer)
+    {
+        writer.print(text);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Text.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Text.java
new file mode 100644
index 0000000..125d79a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/Text.java
@@ -0,0 +1,58 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.dom;

+

+import java.io.PrintWriter;

+

+/**

+ * A type of node that contains text.

+ */

+public final class Text extends Node

+{

+    private final StringBuilder buffer;

+

+    private final Document document;

+

+    Text(Node container, Document document, String text)

+    {

+        super(container);

+

+        this.document = document;

+

+        buffer = new StringBuilder(text.length());

+

+        write(text);

+    }

+

+    /**

+     * Writes additional text into the node, appending it to any existing text.

+     */

+    public void write(String text)

+    {

+        document.getMarkupModel().encode(text, buffer);

+    }

+

+    public void writef(String format, Object... args)

+    {

+        write(String.format(format, args));

+    }

+

+    @Override

+    public void toMarkup(PrintWriter writer)

+    {

+        writer.print(buffer.toString());

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/XMLMarkupModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/XMLMarkupModel.java
new file mode 100644
index 0000000..3981cf7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/dom/XMLMarkupModel.java
@@ -0,0 +1,40 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+/**
+ * Markup model used when generating any form of XML markup.
+ */
+public final class XMLMarkupModel extends DefaultMarkupModel
+{
+
+    /**
+     * Always returns ABBREVIATE.
+     */
+    @Override
+    public EndTagStyle getEndTagStyle(String element)
+    {
+        return EndTagStyle.ABBREVIATE;
+    }
+
+    /**
+     * Returns true.
+     */
+    @Override
+    public boolean isXML()
+    {
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/ColumnSort.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/ColumnSort.java
new file mode 100644
index 0000000..0dbab86
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/ColumnSort.java
@@ -0,0 +1,22 @@
+package org.apache.tapestry.grid;
+
+/**
+ * Identifies how a column within a {@link org.apache.tapestry.grid.GridSortModel} is sorted.
+ */
+public enum ColumnSort
+{
+    /**
+     * A sort column and sorted in ascending order.
+     */
+    ASCENDING,
+
+    /**
+     * A sort column, and sorted in descending order.
+     */
+    DESCENDING,
+
+    /**
+     * Not a sort column.
+     */
+    UNSORTED
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java
new file mode 100644
index 0000000..e76c17d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridConstants.java
@@ -0,0 +1,43 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+public class GridConstants
+{
+    /**
+     * CSS class for the first column or the first row. May be applied to a &lt;th&gt; (in the &lt;thead&gt;) or a
+     * &lt;tr&gt; (in the &lt;tbody&gt;).
+     */
+    public static final String FIRST_CLASS = "t-first";
+
+    /**
+     * CSS class for the last column or the last row. May be applied to a &lt;th&gt; (in the &lt;thead&gt;) or a
+     * &lt;tr&gt; (in the &lt;tbody&gt;).
+     */
+    public static final String LAST_CLASS = "t-last";
+
+    /**
+     * Marks the column that is currently sorted for sort ascending.  May be applied to a &lt;th&gt; (in the
+     * &lt;thead&gt; or a &lt;td&gt; in the &lt;tbody&gt;).
+     */
+    public static final String SORT_ASCENDING_CLASS = "t-sort-column-ascending";
+
+    /**
+     * Marks the column that is currently sorted for sort descending.  May be applied to a &lt;th&gt; (in the
+     * &lt;thead&gt; or a &lt;td&gt; in the &lt;tbody&gt;).
+     */
+
+    public static final String SORT_DESCENDING_CLASS = "t-sort-column-descending";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridDataSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridDataSource.java
new file mode 100644
index 0000000..f2fa03d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridDataSource.java
@@ -0,0 +1,53 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+import java.util.List;
+
+/**
+ * Defines how a {@link org.apache.tapestry.corelib.components.Grid} component (and its sub-components) gain access to
+ * the row data that is displayed on the page. In many cases, this is just a wrapper around a simple List, but the
+ * abstractions exist to support access to a large data set that is accessible in sections.
+ */
+public interface GridDataSource
+{
+    /**
+     * Returns the number of rows available in the data source.
+     */
+    int getAvailableRows();
+
+    /**
+     * Invoked to allow the source to prepare to present values. This gives the source a chance to pre-fetch data (when
+     * appropriate) and informs the source of the desired sort order.  Sorting comes first, then extraction by range.
+     *
+     * @param startIndex      the starting index to be retrieved
+     * @param endIndex        the ending index to be retrieved
+     * @param sortConstraints identify how data is to be sorted
+     */
+    void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints);
+
+    /**
+     * Returns the row value at the provided index. This method will be invoked in sequential order.
+     */
+    Object getRowValue(int index);
+
+    /**
+     * Returns the type of value in the rows, or null if not known. This value is used to create a default {@link
+     * org.apache.tapestry.beaneditor.BeanModel} when no such model is explicitly provided.
+     *
+     * @return the row type, or null
+     */
+    Class getRowType();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridModel.java
new file mode 100644
index 0000000..20509a5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridModel.java
@@ -0,0 +1,42 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+import org.apache.tapestry.beaneditor.BeanModel;
+
+/**
+ * A provider of model data to the sub-components of the {@link org.apache.tapestry.corelib.components.Grid} component.
+ * The primary implementor of this component is the Grid component itself. This is effectively a way to package three
+ * values as a single parameter to components such as {@link org.apache.tapestry.corelib.components.GridColumns} and
+ * {@link org.apache.tapestry.corelib.components.GridRows}.
+ */
+public interface GridModel
+{
+    /**
+     * Returns the data model, which defines the columns (in terms of properties of the row type), and provides access
+     * to actual values for a given row instance.
+     */
+    BeanModel getDataModel();
+
+    /**
+     * Returns the source for the data to be presented in the Grid.
+     */
+    GridDataSource getDataSource();
+
+    /**
+     * Returns the object used to track sorting behavior of the Grid.
+     */
+    GridSortModel getSortModel();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridSortModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridSortModel.java
new file mode 100644
index 0000000..7b5c1b4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/GridSortModel.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+import java.util.List;
+
+/**
+ * Models the sorting applied to the a {@link org.apache.tapestry.grid.GridDataSource}.
+ */
+public interface GridSortModel
+{
+    /**
+     * Identifies how (or if) a column is sorted.
+     *
+     * @param columnId
+     * @return the sort for the indicated column or {@link org.apache.tapestry.grid.ColumnSort#UNSORTED} if the column
+     *         is not used for sorting
+     */
+    ColumnSort getColumnSort(String columnId);
+
+    /**
+     * Updates the column sort.  The receiver determines how to handle the sort request.
+     *
+     * @param columnId property id of column to sort on
+     */
+    void updateSort(String columnId);
+
+    /**
+     * Returns a list of sort constraints, identifying which columns are sorted, and how.  May return an empty list (but
+     * won't return null).
+     *
+     * @see org.apache.tapestry.grid.GridDataSource#prepare(int, int, java.util.List)
+     */
+    List<SortConstraint> getSortContraints();
+
+    void clear();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/SortConstraint.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/SortConstraint.java
new file mode 100644
index 0000000..6afa0b3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/grid/SortConstraint.java
@@ -0,0 +1,63 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.grid;
+
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+/**
+ * Identifies how a single column (identified as a {@link org.apache.tapestry.beaneditor.PropertyModel}) is sorted.
+ */
+public class SortConstraint
+{
+    private final PropertyModel propertyModel;
+
+    private final ColumnSort columnSort;
+
+    public SortConstraint(PropertyModel propertyModel, ColumnSort columnSort)
+    {
+        Defense.notNull(propertyModel, "propertyModel");
+        Defense.notNull(columnSort, "columnSort");
+
+        this.propertyModel = propertyModel;
+        this.columnSort = columnSort;
+    }
+
+    public PropertyModel getPropertyModel()
+    {
+        return propertyModel;
+    }
+
+    public ColumnSort getColumnSort()
+    {
+        return columnSort;
+    }
+
+    // equals() is useful for testing
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o) return true;
+
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SortConstraint that = (SortConstraint) o;
+
+        if (columnSort != that.columnSort) return false;
+
+        return propertyModel.equals(that.propertyModel);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultNullFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultNullFieldStrategy.java
new file mode 100644
index 0000000..00058b5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultNullFieldStrategy.java
@@ -0,0 +1,39 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.NullFieldStrategy;
+
+/**
+ * Default strategy, which is to do nothing: null values stay null.
+ */
+public class DefaultNullFieldStrategy implements NullFieldStrategy
+{
+    /**
+     * Returns null.
+     */
+    public Object replaceToClient()
+    {
+        return null;
+    }
+
+    /**
+     * Returns the empty string.
+     */
+    public String replaceFromClient()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultValidationDecorator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultValidationDecorator.java
new file mode 100644
index 0000000..c4fefa8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/DefaultValidationDecorator.java
@@ -0,0 +1,95 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.Environment;
+
+/**
+ * Default implementation that writes an attribute into fields or labels that are in error.
+ */
+public final class DefaultValidationDecorator extends BaseValidationDecorator
+{
+    private final Environment environment;
+
+    private final Asset iconAsset;
+
+    private final Messages validationMessages;
+
+    private final MarkupWriter markupWriter;
+
+    /**
+     * @param environment        used to locate objects and services during the render
+     * @param validationMessages obtained from {@link org.apache.tapestry.services.ValidationMessagesSource}, used to
+     *                           obtain the label for the icon
+     * @param iconAsset          asset for an icon that will be displayed after each field (marked with the
+     * @param markupWriter
+     */
+    public DefaultValidationDecorator(Environment environment, Messages validationMessages, Asset iconAsset,
+                                      MarkupWriter markupWriter)
+    {
+        this.environment = environment;
+        this.validationMessages = validationMessages;
+        this.iconAsset = iconAsset;
+        this.markupWriter = markupWriter;
+    }
+
+    @Override
+    public void insideField(Field field)
+    {
+        if (inError(field)) addErrorClassToCurrentElement();
+    }
+
+    @Override
+    public void insideLabel(Field field, Element element)
+    {
+        if (field == null) return;
+
+        if (inError(field)) element.addClassName(CSSClassConstants.ERROR);
+    }
+
+    @Override
+    public void afterField(Field field)
+    {
+        String iconId = field.getClientId() + ":icon";
+
+        String cssClass = inError(field) ? "t-error-icon" : "t-error-icon t-invisible";
+
+        markupWriter.element("img",
+
+                             "src", iconAsset.toClientURL(),
+
+                             "alt", validationMessages.get("icon-label"),
+
+                             "class", cssClass,
+
+                             "id", iconId);
+        markupWriter.end();
+    }
+
+    private boolean inError(Field field)
+    {
+        ValidationTracker tracker = environment.peekRequired(ValidationTracker.class);
+
+        return tracker.inError(field);
+    }
+
+    private void addErrorClassToCurrentElement()
+    {
+        markupWriter.getElement().addClassName(CSSClassConstants.ERROR);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java
new file mode 100644
index 0000000..924a50a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/EmptyEventContext.java
@@ -0,0 +1,39 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.EventContext;
+
+/**
+ * Placeholder used when no context is available.
+ */
+public class EmptyEventContext implements EventContext
+{
+    /**
+     * Always returns zero.
+     */
+    public int getCount()
+    {
+        return 0;
+    }
+
+    /**
+     * This should never be called because the count is always zero.
+     */
+    public <T> T get(Class<T> desiredType, int index)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
new file mode 100644
index 0000000..7d0250f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
@@ -0,0 +1,96 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.services.PersistentFieldManager;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.RenderQueue;
+
+/**
+ * An extension of {@link org.apache.tapestry.ComponentResources} that represents additional methods that are private to
+ * the framework and not exposed in any public APIs.
+ */
+public interface InternalComponentResources extends ComponentResources, InternalComponentResourcesCommon
+{
+    /**
+     * Get the current persisted value of the field.
+     *
+     * @param fieldName the name of the field to access
+     * @return the value stored for the field, or null if no value is currently stored
+     */
+    Object getFieldChange(String fieldName);
+
+    /**
+     * Checks to see if there is a value stored for the indicated field.
+     */
+    boolean hasFieldChange(String fieldName);
+
+    /**
+     * Posts a change to a persistent field. If the component is still loading, then this change is ignored. Otherwise,
+     * it is propagated, via the {@link Page#persistFieldChange(org.apache.tapestry.ComponentResources, String, Object)
+     * page} to the {@link PersistentFieldManager}.
+     */
+    void persistFieldChange(String fieldName, Object newValue);
+
+    /**
+     * Reads the value of a parameter, via the parameter's {@link org.apache.tapestry.Binding}.
+     *
+     * @param <T>
+     * @param parameterName the name of the parameter to read
+     * @param expectedType  the expected type of parameter
+     * @return the value for the parameter, or null if the parameter is not bound.
+     */
+    <T> T readParameter(String parameterName, Class<T> expectedType);
+
+    /**
+     * Used by generated component code to read a parameter value.
+     *
+     * @param parameterName   the name of the parameter to read
+     * @param desiredTypeName the class name of the desired value (classes will be resolved in the component class
+     *                        loader)
+     * @return the value coerced to the correct type
+     */
+    Object readParameter(String parameterName, String desiredTypeName);
+
+    /**
+     * Updates a parameter. It is an error to update a parameter which is not bound. The parameter {@link
+     * org.apache.tapestry.Binding binding} may also not support updates.
+     *
+     * @param <T>
+     * @param parameterName  of parameter to update
+     * @param parameterValue new value (which may be null)
+     */
+    <T> void writeParameter(String parameterName, T parameterValue);
+
+    /**
+     * Returns true if the named parameter's {@link org.apache.tapestry.Binding} is invariant, false if otherwise, or if
+     * the parameter is not bound. Invariant bindings are cached more aggressively than variant bindings.
+     *
+     * @param parameterName the name of parameter to check for invariance
+     * @return true if the binding is an invariant, false if the binding has no fixed value
+     */
+    boolean isInvariant(String parameterName);
+
+    /**
+     * Allows the resources to cleanup any render-time only data.
+     */
+    void postRenderCleanup();
+
+    /**
+     * Invoked to make the receiver queue itself to be rendered.
+     */
+    void queueRender(RenderQueue queue);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java
new file mode 100644
index 0000000..ec9ba6d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java
@@ -0,0 +1,58 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.runtime.Component;
+
+import java.util.Map;
+
+/**
+ * Operations shared by {@link InternalComponentResources} and {@link ComponentPageElement}. Typically, these means
+ * methods of InternalComponentResources that are delegated to the component page element.
+ */
+public interface InternalComponentResourcesCommon
+{
+    /**
+     * Returns true if the component has finished loading. Initially, this value will be false.
+     *
+     * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()
+     */
+    boolean isLoaded();
+
+    /**
+     * Used during construction of the page to identify the binding for a particular parameter.
+     * <p/>
+     */
+    void bindParameter(String parameterName, Binding binding);
+
+    /**
+     * Returns the mixin instance for the fully qualfied mixin class name.
+     *
+     * @param mixinClassName fully qualified class name
+     * @return IllegalArgumentException if no such mixin is associated with the core component
+     */
+    Component getMixinByClassName(String mixinClassName);
+
+    /**
+     * Constructs a map linking informal parameters to the corresponding bindings.
+     *
+     * @return map, possible empty
+     */
+    Map<String, Binding> getInformalParameterBindings();
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
new file mode 100644
index 0000000..40ea9c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
@@ -0,0 +1,97 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.services.Alias;
+
+public final class InternalConstants
+{
+    /**
+     * Init parameter used to identify the package from which application classes are loaded. Such classes are in the
+     * pages, components and mixins sub-packages.
+     */
+    public static final String TAPESTRY_APP_PACKAGE_PARAM = "tapestry.app-package";
+
+    /**
+     * Turns off loading of default modules (as driven by JAR file Manifest entries).
+     */
+    public static final String DISABLE_DEFAULT_MODULES_PARAM = "tapestry.disable-default-modules";
+
+    /**
+     * The application mode, generally "servlet", used to select the correct contributions to the {@link Alias}
+     * service.
+     */
+    public static final String TAPESTRY_ALIAS_MODE_SYMBOL = "tapestry.alias-mode";
+
+    /**
+     * The name of the application (i.e., the name of the application filter). Used, for example, to select additional
+     * resources related to the application.
+     */
+    public static final String TAPESTRY_APP_NAME_SYMBOL = "tapestry.app-name";
+
+    /**
+     * The extension used for Tapestry component template files, <em>T</em>apestry <em>M</em>arkup <em>L</em>anguage.
+     * Template files are well-formed XML files.
+     */
+    public static final String TEMPLATE_EXTENSION = "tml";
+
+    /**
+     * The name of the query parameter that stores the page activation context inside an action request.
+     */
+    public static final String PAGE_CONTEXT_NAME = "t:ac";
+
+    /**
+     * Name of event triggered by Grid sub-components when an in-place Grid is updated.
+     */
+    public static final String GRID_INPLACE_UPDATE = "inplaceupdate";
+
+    /**
+     * The name of a query parameter that stores the containing page (used in action links when the page containing the
+     * component is not the same as the page that was rendering). The active page (the page which initiated the render)
+     * is encoded into the URL, and the containing page is tacked on as this query parameter.
+     */
+    public static final String CONTAINER_PAGE_NAME = "t:cp";
+
+    public static final String OBJECT_RENDER_DIV_SECTION = "t-env-data-section";
+
+    public static final String MIXINS_SUBPACKAGE = "mixins";
+
+    public static final String COMPONENTS_SUBPACKAGE = "components";
+
+    public static final String PAGES_SUBPACKAGE = "pages";
+
+    public static final String BASE_SUBPACKAGE = "base";
+
+    /**
+     * Used in some Ajax scenarios to set the content type for the response early, when the Page instance (the authority
+     * on content types) is known. The value is of type {@link org.apache.tapestry.ContentType}.
+     */
+    public static final String CONTENT_TYPE_ATTRIBUTE_NAME = "content-type";
+
+    public static final String CHARSET_CONTENT_TYPE_PARAMETER = "charset";
+
+    /**
+     * Request attribute that stores a {@link org.apache.tapestry.internal.structure.Page} instance that will be
+     * rendered as the {@linkplain org.apache.tapestry.SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS immediate
+     * mode response}.
+     */
+    public static final String IMMEDIATE_RESPONSE_PAGE_ATTRIBUTE = "tapestry.immediate-response-page";
+
+    /**
+     * Required MIME type for JSON responses. If this MIME type is not used, the client-side Prototype code will not
+     * recognize the response as JSON, and the Ajax.Response.responseJSON property will be null.
+     */
+    public static final String JSON_MIME_TYPE = "application/json";
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java
new file mode 100644
index 0000000..95def3a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalMessages.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+final class InternalMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(InternalMessages.class);
+
+    static String badKeyValue(String input)
+    {
+        return MESSAGES.format("bad-key-value", input);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/KeyValue.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/KeyValue.java
new file mode 100644
index 0000000..e2c3976
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/KeyValue.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+/**
+ * A key/value pair.
+ */
+public class KeyValue
+{
+    private final String key;
+
+    private final String value;
+
+    public KeyValue(final String key, final String value)
+    {
+        this.key = key;
+        this.value = value;
+    }
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionGroupModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionGroupModelImpl.java
new file mode 100644
index 0000000..0c5edc7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionGroupModelImpl.java
@@ -0,0 +1,75 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.OptionGroupModel;
+import org.apache.tapestry.OptionModel;
+
+import java.util.List;
+import java.util.Map;
+
+public final class OptionGroupModelImpl implements OptionGroupModel
+{
+    private final String label;
+
+    private final boolean disabled;
+
+    private final List<OptionModel> options;
+
+    private final Map<String, String> attributes;
+
+    public OptionGroupModelImpl(String label, boolean disabled, List<OptionModel> options,
+                                String... attributeKeysAndValues)
+    {
+        this(label, disabled, options, attributeKeysAndValues.length == 0 ? null : TapestryInternalUtils
+                .mapFromKeysAndValues(attributeKeysAndValues));
+    }
+
+    public OptionGroupModelImpl(String label, boolean disabled, List<OptionModel> options,
+                                Map<String, String> attributes)
+    {
+        this.label = label;
+        this.disabled = disabled;
+        this.options = options;
+        this.attributes = attributes;
+    }
+
+    public Map<String, String> getAttributes()
+    {
+        return attributes;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public List<OptionModel> getOptions()
+    {
+        return options;
+    }
+
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("OptionGroupModel[%s]", label);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionModelImpl.java
new file mode 100644
index 0000000..a9ee082
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/OptionModelImpl.java
@@ -0,0 +1,54 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.AbstractOptionModel;
+
+public class OptionModelImpl extends AbstractOptionModel
+{
+    private final String label;
+
+    private final Object value;
+
+    /**
+     * Constructor for when the value and the label are the same.
+     */
+    public OptionModelImpl(String value)
+    {
+        this(value, value);
+    }
+
+    public OptionModelImpl(String label, Object value)
+    {
+        this.label = label;
+        this.value = value;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public Object getValue()
+    {
+        return value;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("OptionModel[%s %s]", label, value);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SelectModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SelectModelImpl.java
new file mode 100644
index 0000000..87b827c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SelectModelImpl.java
@@ -0,0 +1,57 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.OptionGroupModel;
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.util.AbstractSelectModel;
+
+import java.util.Arrays;
+import java.util.List;
+
+public final class SelectModelImpl extends AbstractSelectModel
+{
+    private final List<OptionGroupModel> optionGroups;
+
+    private final List<OptionModel> optionModels;
+
+    public SelectModelImpl(final List<OptionGroupModel> optionGroups,
+                           final List<OptionModel> optionModels)
+    {
+        this.optionGroups = optionGroups;
+        this.optionModels = optionModels;
+    }
+
+    public SelectModelImpl(OptionModel... optionModels)
+    {
+        this(null, Arrays.asList(optionModels));
+    }
+
+    public SelectModelImpl(OptionGroupModel... groupModels)
+    {
+        this(Arrays.asList(groupModels), null);
+    }
+
+    public List<OptionGroupModel> getOptionGroups()
+    {
+        return optionGroups;
+    }
+
+    public List<OptionModel> getOptions()
+    {
+        return optionModels;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ServletContextSymbolProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ServletContextSymbolProvider.java
new file mode 100644
index 0000000..2a36c3b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ServletContextSymbolProvider.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+
+import javax.servlet.ServletContext;
+import java.util.Map;
+
+/**
+ * A wrapper around {@link ServletContext} that makes init-parameters accessible as symbols.
+ */
+public class ServletContextSymbolProvider implements SymbolProvider
+{
+    private final Map<String, String> properties = CollectionFactory.newCaseInsensitiveMap();
+
+    public ServletContextSymbolProvider(ServletContext context)
+    {
+        for (String name : InternalUtils.toList(context.getInitParameterNames()))
+        {
+            properties.put(name, context.getInitParameter(name));
+        }
+    }
+
+    public String valueForSymbol(String symbolName)
+    {
+        return properties.get(symbolName);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SingleKeySymbolProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SingleKeySymbolProvider.java
new file mode 100644
index 0000000..27b6e58
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SingleKeySymbolProvider.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.services.SymbolProvider;
+
+/**
+ * Implementation of {@link SymbolProvider} that only supports a single key/value pair.
+ */
+public class SingleKeySymbolProvider implements SymbolProvider
+{
+    private final String symbolName;
+
+    private final String value;
+
+    public SingleKeySymbolProvider(final String symbolName, final String value)
+    {
+        this.symbolName = symbolName;
+        this.value = value;
+    }
+
+    public String valueForSymbol(String symbolName)
+    {
+        if (this.symbolName.equalsIgnoreCase(symbolName)) return value;
+
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticModuleDef.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticModuleDef.java
new file mode 100644
index 0000000..bde98ff
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticModuleDef.java
@@ -0,0 +1,85 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * A synthetic module definition, used to mix in some additional "pre-built" service configuration contributions.
+ */
+public class SyntheticModuleDef implements ModuleDef
+{
+    private final Set<ContributionDef> contributionDefs;
+
+    public SyntheticModuleDef(ContributionDef... contributionDefs)
+    {
+        this.contributionDefs = CollectionFactory.newSet(contributionDefs);
+    }
+
+    /**
+     * Returns null.
+     */
+    public Class getBuilderClass()
+    {
+        return null;
+    }
+
+    /**
+     * Returns the configured set.
+     */
+    public Set<ContributionDef> getContributionDefs()
+    {
+        return contributionDefs;
+    }
+
+    /**
+     * Returns an empty set.
+     */
+    public Set<DecoratorDef> getDecoratorDefs()
+    {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns "SyntheticModule".
+     */
+    public String getLoggerName()
+    {
+        return "SyntheticModule";
+    }
+
+    /**
+     * Returns null.
+     */
+    public ServiceDef getServiceDef(String serviceId)
+    {
+        return null;
+    }
+
+    /**
+     * Returns an empty set.
+     */
+    public Set<String> getServiceIds()
+    {
+        return Collections.emptySet();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticSymbolSourceContributionDef.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticSymbolSourceContributionDef.java
new file mode 100644
index 0000000..97bbce2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/SyntheticSymbolSourceContributionDef.java
@@ -0,0 +1,65 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+
+/**
+ * Makes a contribution to the SymbolSource service configuration.
+ */
+public class SyntheticSymbolSourceContributionDef implements ContributionDef
+{
+    private final String contributionName;
+
+    private final SymbolProvider provider;
+
+    private final String[] constraints;
+
+    public SyntheticSymbolSourceContributionDef(String contributionName, SymbolProvider provider,
+                                                String... constraints)
+    {
+        this.contributionName = contributionName;
+        this.provider = provider;
+        this.constraints = constraints;
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           Configuration configuration)
+    {
+    }
+
+    @SuppressWarnings("unchecked")
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           OrderedConfiguration configuration)
+    {
+        configuration.add(contributionName, provider, constraints);
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           MappedConfiguration configuration)
+    {
+    }
+
+    /**
+     * Returns "SymbolSource".
+     */
+    public String getServiceId()
+    {
+        return "SymbolSource";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryAppInitializer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryAppInitializer.java
new file mode 100644
index 0000000..51e8d1d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryAppInitializer.java
@@ -0,0 +1,164 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.IOCUtilities;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.RegistryBuilder;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.services.Alias;
+import org.apache.tapestry.services.TapestryModule;
+
+/**
+ * This class is used to build the {@link Registry}. The Registry contains {@link org.apache.tapestry.ioc.services.TapestryIOCModule}
+ * and {@link TapestryModule}, any modules identified by {@link #addModules(Class[])} )}, plus the application module.
+ * <p/>
+ * The application module is optional.
+ * <p/>
+ * The application module is identified as <em>package</em>.services.<em>appName</em>Module, where <em>package</em> and
+ * the <em>appName</em> are specified by the caller.
+ */
+public class TapestryAppInitializer
+{
+    private final SymbolProvider appProvider;
+
+    private final String appName;
+
+    private final String aliasMode;
+
+    private final long startTime;
+
+    private final RegistryBuilder builder = new RegistryBuilder();
+
+    private long registryCreatedTime;
+
+    public TapestryAppInitializer(String appPackage, String appName, String aliasMode)
+    {
+        this(new SingleKeySymbolProvider(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM, appPackage), appName, aliasMode);
+    }
+
+    /**
+     * @param appProvider provides symbols for the application (normally, from the ServletContext init parameters)
+     * @param appName     the name of the application (i.e., the name of the application servlet)
+     * @param aliasMode   the mode, used by the {@link Alias} service, normally "servlet"
+     */
+    public TapestryAppInitializer(SymbolProvider appProvider, String appName, String aliasMode)
+    {
+        this.appProvider = appProvider;
+
+        String appPackage = appProvider.valueForSymbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM);
+
+
+        this.appName = appName;
+        this.aliasMode = aliasMode;
+
+        startTime = System.currentTimeMillis();
+
+
+        if (!Boolean.parseBoolean(appProvider.valueForSymbol(InternalConstants.DISABLE_DEFAULT_MODULES_PARAM)))
+        {
+            IOCUtilities.addDefaultModules(builder);
+        }
+
+        // This gets added automatically.
+
+        addModules(TapestryModule.class);
+
+        String className = appPackage + ".services." + InternalUtils.capitalize(this.appName) + "Module";
+
+        try
+        {
+            // This class is possibly loaded by a parent class loader of the application class
+            // loader. The context class loader should have the approprite view to the module class,
+            // if any.
+
+            Class moduleClass = Thread.currentThread().getContextClassLoader().loadClass(className);
+
+            builder.add(moduleClass);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            // That's OK, not all applications will have a module class, even though any
+            // non-trivial application will.
+        }
+
+        // Add a synthetic module that contributes symbol sources.
+
+        addSyntheticSymbolSourceModule();
+    }
+
+    /**
+     * Adds additional modules.
+     *
+     * @param moduleDefs
+     */
+    public void addModules(ModuleDef... moduleDefs)
+    {
+        for (ModuleDef def : moduleDefs)
+            builder.add(def);
+    }
+
+    public void addModules(Class... moduleBuilderClasses)
+    {
+        builder.add(moduleBuilderClasses);
+    }
+
+    private void addSyntheticSymbolSourceModule()
+    {
+        ContributionDef symbolSourceContribution = new SyntheticSymbolSourceContributionDef("ServletContext",
+                                                                                            appProvider,
+                                                                                            "before:ApplicationDefaults");
+
+        ContributionDef aliasModeContribution = new SyntheticSymbolSourceContributionDef("AliasMode",
+                                                                                         new SingleKeySymbolProvider(
+                                                                                                 InternalConstants.TAPESTRY_ALIAS_MODE_SYMBOL,
+                                                                                                 aliasMode),
+                                                                                         "before:ServletContext");
+
+        ContributionDef appNameContribution = new SyntheticSymbolSourceContributionDef("AppName",
+                                                                                       new SingleKeySymbolProvider(
+                                                                                               InternalConstants.TAPESTRY_APP_NAME_SYMBOL,
+                                                                                               appName),
+                                                                                       "before:ServletContext");
+
+        builder.add(new SyntheticModuleDef(symbolSourceContribution, aliasModeContribution, appNameContribution));
+    }
+
+    public Registry getRegistry()
+    {
+        registryCreatedTime = System.currentTimeMillis();
+
+        return builder.build();
+    }
+
+    /**
+     * @return the system time (in ms) when the registry has been created successfully.
+     */
+    public long getRegistryCreatedTime()
+    {
+        return registryCreatedTime;
+    }
+
+    /**
+     * @return the time when the initialization was started.
+     */
+    public long getStartTime()
+    {
+        return startTime;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
new file mode 100644
index 0000000..5ae9e16
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
@@ -0,0 +1,581 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.net.URLCodec;
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.Orderer;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.slf4j.Logger;
+
+import java.lang.reflect.Method;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Shared utility methods used by various implementation classes.
+ */
+public class TapestryInternalUtils
+{
+    private static final Pattern NON_WORD_PATTERN = Pattern.compile("[^\\w]");
+
+    private static final URLCodec CODEC = new URLCodec()
+    {
+
+        private BitSet contextSafe = (BitSet) WWW_FORM_URL.clone();
+
+        {
+            // Servlet container does not decode '+' in path to ' ',
+            // so we encode ' ' to %20, not to '+'.
+            contextSafe.clear(' ');
+        }
+
+        @Override
+        public byte[] encode(byte[] bytes)
+        {
+            return encodeUrl(contextSafe, bytes);
+        }
+    };
+
+    private TapestryInternalUtils()
+    {
+        // Prevent instantiation.
+    }
+
+    /**
+     * Capitalizes the string, and inserts a space before each upper case character (or sequence of upper case
+     * characters). Thus "userId" becomes "User Id", etc. Also, converts underscore into space (and capitalizes the
+     * following word), thus "user_id" also becomes "User Id".
+     */
+    public static String toUserPresentable(String id)
+    {
+        StringBuilder builder = new StringBuilder(id.length() * 2);
+
+        char[] chars = id.toCharArray();
+        boolean postSpace = true;
+        boolean upcaseNext = true;
+
+        for (char ch : chars)
+        {
+            if (upcaseNext)
+            {
+                builder.append(Character.toUpperCase(ch));
+                upcaseNext = false;
+
+                continue;
+            }
+
+            if (ch == '_')
+            {
+                builder.append(' ');
+                upcaseNext = true;
+                continue;
+            }
+
+            boolean upperCase = Character.isUpperCase(ch);
+
+            if (upperCase && !postSpace) builder.append(' ');
+
+            builder.append(ch);
+
+            postSpace = upperCase;
+        }
+
+        return builder.toString();
+    }
+
+    public static Map<String, String> mapFromKeysAndValues(String... keysAndValues)
+    {
+        Map<String, String> result = CollectionFactory.newMap();
+
+        int i = 0;
+        while (i < keysAndValues.length)
+        {
+            String key = keysAndValues[i++];
+            String value = keysAndValues[i++];
+
+            result.put(key, value);
+        }
+
+        return result;
+    }
+
+    /**
+     * Converts a string to an {@link OptionModel}. The string is of the form "value=label". If the equals sign is
+     * omitted, then the same value is used for both value and label.
+     *
+     * @param input
+     * @return
+     */
+    public static OptionModel toOptionModel(String input)
+    {
+        Defense.notNull(input, "input");
+
+        int equalsx = input.indexOf('=');
+
+        if (equalsx < 0) return new OptionModelImpl(input);
+
+        String value = input.substring(0, equalsx);
+        String label = input.substring(equalsx + 1);
+
+        return new OptionModelImpl(label, value);
+    }
+
+    /**
+     * Parses a string input into a series of value=label pairs compatible with {@link #toOptionModel(String)}. Splits
+     * on commas. Ignores whitespace around commas.
+     *
+     * @param input comma seperated list of terms
+     * @return list of option models
+     */
+    public static List<OptionModel> toOptionModels(String input)
+    {
+        Defense.notNull(input, "input");
+
+        List<OptionModel> result = newList();
+
+        for (String term : input.split(","))
+            result.add(toOptionModel(term.trim()));
+
+        return result;
+    }
+
+    /**
+     * Wraps the result of {@link #toOptionModels(String)} as a {@link SelectModel} (with no option groups).
+     *
+     * @param input
+     * @return
+     */
+    public static SelectModel toSelectModel(String input)
+    {
+        List<OptionModel> options = toOptionModels(input);
+
+        return new SelectModelImpl(null, options);
+    }
+
+    /**
+     * Converts a map entry to an {@link OptionModel}.
+     *
+     * @param input
+     * @return
+     */
+    public static OptionModel toOptionModel(Map.Entry input)
+    {
+        notNull(input, "input");
+
+        String label = input.getValue() != null ? String.valueOf(input.getValue()) : "";
+
+        return new OptionModelImpl(label, input.getKey());
+    }
+
+    /**
+     * Processes a map input into a series of map entries compatible with {@link #toOptionModel(Map.Entry)}.
+     *
+     * @param input map of elements
+     * @return list of option models
+     */
+    public static <K, V> List<OptionModel> toOptionModels(Map<K, V> input)
+    {
+        Defense.notNull(input, "input");
+
+        List<OptionModel> result = newList();
+
+        for (Map.Entry entry : input.entrySet())
+            result.add(toOptionModel(entry));
+
+        return result;
+    }
+
+    /**
+     * Wraps the result of {@link #toOptionModels(Map)} as a {@link SelectModel} (with no option groups).
+     *
+     * @param input
+     * @return
+     */
+    public static <K, V> SelectModel toSelectModel(Map<K, V> input)
+    {
+        List<OptionModel> options = toOptionModels(input);
+
+        return new SelectModelImpl(null, options);
+    }
+
+    /**
+     * Converts an object to an {@link OptionModel}.
+     *
+     * @param input
+     * @return
+     */
+    public static OptionModel toOptionModel(Object input)
+    {
+        String label = (input != null ? String.valueOf(input) : "");
+
+        return new OptionModelImpl(label, input);
+    }
+
+    /**
+     * Processes a list input into a series of objects compatible with {@link #toOptionModel(Object)}.
+     *
+     * @param input list of elements
+     * @return list of option models
+     */
+    public static <E> List<OptionModel> toOptionModels(List<E> input)
+    {
+        Defense.notNull(input, "input");
+
+        List<OptionModel> result = newList();
+
+        for (E element : input)
+            result.add(toOptionModel(element));
+
+        return result;
+    }
+
+    /**
+     * Wraps the result of {@link #toOptionModels(List)} as a {@link SelectModel} (with no option groups).
+     *
+     * @param input
+     * @return
+     */
+    public static <E> SelectModel toSelectModel(List<E> input)
+    {
+        List<OptionModel> options = toOptionModels(input);
+
+        return new SelectModelImpl(null, options);
+    }
+
+    /**
+     * Parses a key/value pair where the key and the value are seperated by an equals sign. The key and value are
+     * trimmed of leading and trailing whitespace, and returned as a {@link KeyValue}.
+     *
+     * @param input
+     * @return
+     */
+    public static KeyValue parseKeyValue(String input)
+    {
+        int pos = input.indexOf('=');
+
+        if (pos < 1) throw new IllegalArgumentException(InternalMessages.badKeyValue(input));
+
+        String key = input.substring(0, pos);
+        String value = input.substring(pos + 1);
+
+        return new KeyValue(key.trim(), value.trim());
+    }
+
+
+    /**
+     * Used to convert a property expression into a key that can be used to locate various resources (Blocks, messages,
+     * etc.). Strips out any punctuation characters, leaving just words characters (letters, number and the
+     * underscore).
+     *
+     * @param expression a property expression
+     * @return the expression with punctuation removed
+     */
+    public static String extractIdFromPropertyExpression(String expression)
+    {
+        return replace(expression, NON_WORD_PATTERN, "");
+    }
+
+    /**
+     * Looks for a label within the messages based on the id. If found, it is used, otherwise the name is converted to a
+     * user presentable form.
+     */
+    public static String defaultLabel(String id, Messages messages, String propertyExpression)
+    {
+        String key = id + "-label";
+
+        if (messages.contains(key)) return messages.get(key);
+
+        return toUserPresentable(extractIdFromPropertyExpression(lastTerm(propertyExpression)));
+    }
+
+    /**
+     * Strips a dotted sequence (such as a property expression, or a qualified class name) down to the last term of that
+     * expression, by locating the last period ('.') in the string.
+     */
+    public static String lastTerm(String input)
+    {
+        int dotx = input.lastIndexOf('.');
+
+        return input.substring(dotx + 1);
+    }
+
+    /**
+     * Converts an list of strings into a space-separated string combining them all, suitable for use as an HTML class
+     * attribute value.
+     *
+     * @param classes classes to combine
+     * @return the joined classes, or null if classes is empty
+     */
+    public static String toClassAttributeValue(List<String> classes)
+    {
+        if (classes.isEmpty()) return null;
+
+        return InternalUtils.join(classes, " ");
+    }
+
+    private static class PropertyOrder implements Comparable<PropertyOrder>
+    {
+        final String propertyName;
+
+        final int classDepth;
+
+        final int sortKey;
+
+        public PropertyOrder(final String propertyName, int classDepth, int sortKey)
+        {
+            this.propertyName = propertyName;
+            this.classDepth = classDepth;
+            this.sortKey = sortKey;
+        }
+
+        public int compareTo(PropertyOrder o)
+        {
+            int result = classDepth - o.classDepth;
+
+            if (result == 0) result = sortKey - o.sortKey;
+
+            if (result == 0) result = propertyName.compareTo(o.propertyName);
+
+            return result;
+        }
+    }
+
+    /**
+     * Sorts the property names into presentation order. Filters out any properties that have an explicit {@link
+     * OrderBefore}, leaving the remainder. Estimates each propertie's position based on the relative position of the
+     * property's getter. The code assumes that all methods are readable (have a getter method).
+     *
+     * @param classAdapter  defines the bean that contains the properties
+     * @param classFactory  used to access method line number information
+     * @param propertyNames the initial set of property names
+     * @return propertyNames filtered and sorted
+     */
+    public static List<String> orderProperties(Logger logger, ClassPropertyAdapter classAdapter,
+                                               ClassFactory classFactory, List<String> propertyNames)
+    {
+
+        // Property name to a list of constraints.
+        Map<String, List<String>> constraints = CollectionFactory.newMap();
+
+        List<PropertyOrder> properties = newList();
+
+        for (String name : propertyNames)
+        {
+
+            PropertyAdapter pa = classAdapter.getPropertyAdapter(name);
+            List<String> propertyConstraints = CollectionFactory.newList();
+
+            OrderBefore beforeAnnotation = pa.getAnnotation(OrderBefore.class);
+
+            if (beforeAnnotation != null) propertyConstraints.add("before:" + beforeAnnotation.value());
+
+            OrderAfter afterAnnotation = pa.getAnnotation(OrderAfter.class);
+
+            if (afterAnnotation != null) propertyConstraints.add("after:" + afterAnnotation.value());
+
+            if (!propertyConstraints.isEmpty()) constraints.put(name, propertyConstraints);
+
+            Method readMethod = pa.getReadMethod();
+
+            Location location = classFactory.getMethodLocation(readMethod);
+
+            properties.add(new PropertyOrder(name, computeDepth(readMethod), location.getLine()));
+        }
+
+        Collections.sort(properties);
+
+        Orderer<String> orderer = new Orderer<String>(logger);
+        String prev = null;
+
+        for (PropertyOrder po : properties)
+        {
+            String name = po.propertyName;
+
+            List<String> propertyConstraints = constraints.get(name);
+
+            if (propertyConstraints != null)
+            {
+
+                String[] asArray = propertyConstraints.toArray(new String[propertyConstraints
+                        .size()]);
+
+                orderer.add(name, name, asArray);
+
+                prev = name;
+
+                continue;
+            }
+
+            if (prev == null) orderer.add(name, name);
+            else orderer.add(name, name, "after:" + prev);
+
+            prev = name;
+        }
+
+        return orderer.getOrdered();
+
+    }
+
+    private static int computeDepth(Method method)
+    {
+        int depth = 0;
+        Class c = method.getDeclaringClass();
+
+        // When the method originates in an interface, the parent may be null, not Object.
+
+        while (c != null && c != Object.class)
+        {
+            depth++;
+            c = c.getSuperclass();
+        }
+
+        return depth;
+    }
+
+    /**
+     * Converts an enum to a label string, allowing for overrides from a message catalog.
+     * <p/>
+     * <ul> <li>As key <em>prefix</em>.<em>name</em> if present.  Ex: "ElementType.LOCAL_VARIABLE" <li>As key
+     * <em>name</em> if present, i.e., "LOCAL_VARIABLE". <li>As a user-presentable version of the name, i.e., "Local
+     * Variable". </ul>
+     *
+     * @param messages the messages to search for the label
+     * @param prefix
+     * @param value    to get a label for
+     * @return the label
+     */
+    public static String getLabelForEnum(Messages messages, String prefix, Enum value)
+    {
+        String name = value.name();
+
+        String key = prefix + "." + name;
+
+        if (messages.contains(key)) return messages.get(key);
+
+        if (messages.contains(name)) return messages.get(name);
+
+        return toUserPresentable(name.toLowerCase());
+    }
+
+    public static String getLabelForEnum(Messages messages, Enum value)
+    {
+        String prefix = lastTerm(value.getClass().getName());
+
+        return getLabelForEnum(messages, prefix, value);
+    }
+
+    /**
+     * Encodes a string for inclusion in a URL.  Slashes and percents are converted to "%25" and "%2F" respectively,
+     * then the entire string is  URL encoded.
+     *
+     * @param input string to include, may not be blank
+     * @return encoded input
+     */
+    public static String encodeContext(String input)
+    {
+        Defense.notBlank(input, "input");
+
+        try
+        {
+            return CODEC.encode(escapePercentAndSlash(input));
+        }
+        catch (EncoderException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private static final String PERCENT = "%";
+    private static final Pattern PERCENT_PATTERN = Pattern.compile(PERCENT);
+    private static final String ENCODED_PERCENT = "%25";
+    private static final Pattern ENCODED_PERCENT_PATTERN = Pattern.compile(ENCODED_PERCENT);
+
+    private static final String SLASH = "/";
+    private static final Pattern SLASH_PATTERN = Pattern.compile(SLASH);
+    private static final String ENCODED_SLASH = "%2F";
+    private static final Pattern ENCODED_SLASH_PATTERN = Pattern.compile(ENCODED_SLASH, Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Encodes percent and slash characters in the string for later decoding via {@link
+     * #unescapePercentAndSlash(String)}.
+     *
+     * @param input string to encode
+     * @return modified string
+     */
+    public static String escapePercentAndSlash(String input)
+    {
+        return replace(replace(input, PERCENT_PATTERN, ENCODED_PERCENT), SLASH_PATTERN, ENCODED_SLASH);
+    }
+
+    /**
+     * Used to decode certain escaped characters that are replaced when using {@link #encodeContext(String)}}.
+     *
+     * @param input a previously encoded string
+     * @return the string with slash and percent characters restored
+     */
+    public static String unescapePercentAndSlash(String input)
+    {
+        return replace(replace(input, ENCODED_SLASH_PATTERN, SLASH), ENCODED_PERCENT_PATTERN, PERCENT);
+    }
+
+    private static String replace(String input, Pattern pattern, String replacement)
+    {
+        return pattern.matcher(input).replaceAll(replacement);
+    }
+
+    /**
+     * Determines if the two values are equal. They are equal if they are the exact same value (including if they are
+     * both null). Otherwise standard equals() comparison is used.
+     *
+     * @param <T>
+     * @param left  value to compare, possibly null
+     * @param right value to compare, possibly null
+     * @return true if same value, both null, or equal
+     */
+    public static <T> boolean isEqual(T left, T right)
+    {
+        if (left == right) return true;
+
+        if (left == null) return right == null;
+
+        return left.equals(right);
+    }
+
+
+    /**
+     * Splits a path at each slash.
+     */
+    public static String[] splitPath(String path)
+    {
+        return SLASH_PATTERN.split(path);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java
new file mode 100644
index 0000000..cddcece
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/URLEventContext.java
@@ -0,0 +1,45 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.services.ContextValueEncoder;
+
+/**
+ * Implementation based on values extracted from the URL (an event context, or a page activation context) that uses a
+ * {@link org.apache.tapestry.services.ContextValueEncoder} to convert from string values to the desired values.
+ */
+public class URLEventContext implements EventContext
+{
+    private final ContextValueEncoder valueEncoder;
+
+    private final String[] values;
+
+    public URLEventContext(ContextValueEncoder valueEncoder, String[] values)
+    {
+        this.valueEncoder = valueEncoder;
+        this.values = values;
+    }
+
+    public int getCount()
+    {
+        return values.length;
+    }
+
+    public <T> T get(Class<T> desiredType, int index)
+    {
+        return valueEncoder.toValue(desiredType, values[index]);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ZeroNullFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ZeroNullFieldStrategy.java
new file mode 100644
index 0000000..4bcee39
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/ZeroNullFieldStrategy.java
@@ -0,0 +1,39 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.NullFieldStrategy;
+
+/**
+ * Treats nulls to or from the client as if they were 0's.
+ */
+public class ZeroNullFieldStrategy implements NullFieldStrategy
+{
+    /**
+     * Returns the value 0.
+     */
+    public Object replaceToClient()
+    {
+        return 0L;
+    }
+
+    /**
+     * Returns "0".
+     */
+    public String replaceFromClient()
+    {
+        return "0";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanEditorMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanEditorMessages.java
new file mode 100644
index 0000000..d35b460
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanEditorMessages.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+import java.util.Collection;
+
+class BeanEditorMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(BeanEditorMessages.class);
+
+    static String duplicatePropertyName(Class beanType, String propertyName)
+    {
+        return MESSAGES.format("duplicate-property-name", beanType.getName(), propertyName);
+    }
+
+    static String unknownProperty(Class beanType, String propertyName,
+                                  Collection<String> propertyNames)
+    {
+        return MESSAGES.format("unknown-property", beanType.getName(), propertyName, InternalUtils
+                .joinSorted(propertyNames));
+    }
+
+    static String unknownPropertyId(Class beanType, String propertyId, Collection<String> propertyIds)
+    {
+        return MESSAGES.format("unknown-property-id", beanType.getName(), propertyId,
+                               InternalUtils.joinSorted(propertyIds));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java
new file mode 100644
index 0000000..c68509b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelImpl.java
@@ -0,0 +1,280 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.beaneditor.RelativePosition;
+import org.apache.tapestry.internal.services.CoercingPropertyConduitWrapper;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.PropertyConduitSource;
+
+import java.util.List;
+import java.util.Map;
+
+public class BeanModelImpl<T> implements BeanModel<T>
+{
+    private final Class<T> beanType;
+
+    private final PropertyConduitSource propertyConduitSource;
+
+    private final TypeCoercer typeCoercer;
+
+    private final Messages messages;
+
+    private final ObjectLocator locator;
+
+    private final Map<String, PropertyModel> properties = CollectionFactory.newCaseInsensitiveMap();
+
+    // The list of property names, in desired order (generally not alphabetical order).
+
+    private final List<String> propertyNames = CollectionFactory.newList();
+
+    public BeanModelImpl(
+            Class<T> beanType, PropertyConduitSource
+            propertyConduitSource,
+            TypeCoercer typeCoercer, Messages
+            messages, ObjectLocator locator)
+
+    {
+        this.beanType = beanType;
+        this.propertyConduitSource = propertyConduitSource;
+        this.typeCoercer = typeCoercer;
+        this.messages = messages;
+        this.locator = locator;
+    }
+
+    public Class<T> getBeanType()
+    {
+        return beanType;
+    }
+
+    public T newInstance()
+    {
+        return locator.autobuild(beanType);
+    }
+
+    public PropertyModel add(String propertyName)
+    {
+        PropertyConduit conduit = createConduit(propertyName);
+
+        return add(propertyName, conduit);
+    }
+
+    private void validateNewPropertyName(String propertyName)
+    {
+        Defense.notBlank(propertyName, "propertyName");
+
+        if (properties.containsKey(propertyName))
+            throw new RuntimeException(BeanEditorMessages.duplicatePropertyName(
+                    beanType,
+                    propertyName));
+    }
+
+    public PropertyModel add(RelativePosition position, String existingPropertyName,
+                             String propertyName, PropertyConduit conduit)
+    {
+        Defense.notNull(position, "position");
+
+        validateNewPropertyName(propertyName);
+
+        // Locate the existing one.
+
+        PropertyModel existing = get(existingPropertyName);
+
+        // Use the case normalized property name.
+
+        int pos = propertyNames.indexOf(existing.getPropertyName());
+
+        PropertyModel newModel = new PropertyModelImpl(this, propertyName, conduit, messages);
+
+        properties.put(propertyName, newModel);
+
+        int offset = position == RelativePosition.AFTER ? 1 : 0;
+
+        propertyNames.add(pos + offset, propertyName);
+
+        return newModel;
+    }
+
+    public PropertyModel add(RelativePosition position, String existingPropertyName,
+                             String propertyName)
+    {
+        PropertyConduit conduit = createConduit(propertyName);
+
+        return add(position, existingPropertyName, propertyName, conduit);
+    }
+
+    public PropertyModel add(String propertyName, PropertyConduit conduit)
+    {
+        validateNewPropertyName(propertyName);
+
+        PropertyModel propertyModel = new PropertyModelImpl(this, propertyName, conduit, messages);
+
+        properties.put(propertyName, propertyModel);
+
+        // Remember the order in which the properties were added.
+
+        propertyNames.add(propertyName);
+
+        return propertyModel;
+    }
+
+    private CoercingPropertyConduitWrapper createConduit(String propertyName)
+    {
+        return new CoercingPropertyConduitWrapper(propertyConduitSource.create(beanType,
+                                                                               propertyName), typeCoercer);
+    }
+
+    public PropertyModel get(String propertyName)
+    {
+        PropertyModel propertyModel = properties.get(propertyName);
+
+        if (propertyModel == null)
+            throw new RuntimeException(BeanEditorMessages.unknownProperty(beanType,
+                                                                          propertyName,
+                                                                          properties.keySet()));
+
+        return propertyModel;
+    }
+
+    public PropertyModel getById(String propertyId)
+    {
+        for (PropertyModel model : properties.values())
+        {
+            if (model.getId().equalsIgnoreCase(propertyId)) return model;
+        }
+
+        // Not found, so we throw an exception. A bit of work to set
+        // up the exception however.
+
+        List<String> ids = CollectionFactory.newList();
+
+        for (PropertyModel model : properties.values())
+        {
+            ids.add(model.getId());
+        }
+
+        throw new RuntimeException(BeanEditorMessages.unknownPropertyId(beanType,
+                                                                        propertyId, ids));
+
+    }
+
+    public List<String> getPropertyNames()
+    {
+        return CollectionFactory.newList(propertyNames);
+    }
+
+    public BeanModel exclude(String... propertyNames)
+    {
+        for (String propertyName : propertyNames)
+        {
+            PropertyModel model = properties.get(propertyName);
+
+            if (model == null) continue;
+
+            // De-referencing from the model is needed because the name provided may not be a
+            // case-exact match, so we get the normalized or canonical name from the model because
+            // that's the one in propertyNames.
+
+            this.propertyNames.remove(model.getPropertyName());
+
+            properties.remove(propertyName);
+        }
+
+        return this;
+    }
+
+    public BeanModel reorder(String... propertyNames)
+    {
+        List<String> remainingPropertyNames = CollectionFactory.newList(this.propertyNames);
+        List<String> reorderedPropertyNames = CollectionFactory.newList();
+
+        for (String name : propertyNames)
+        {
+            PropertyModel model = get(name);
+
+            // Get the canonical form (which may differ from name in terms of case)
+            String canonical = model.getPropertyName();
+
+            reorderedPropertyNames.add(canonical);
+
+            remainingPropertyNames.remove(canonical);
+        }
+
+        this.propertyNames.clear();
+        this.propertyNames.addAll(reorderedPropertyNames);
+
+        // Any unspecified names are ordered to the end. Don't want them? Remove them instead.
+        this.propertyNames.addAll(remainingPropertyNames);
+
+        return this;
+    }
+
+    public BeanModel include(String... propertyNames)
+    {
+        List<String> reorderedPropertyNames = CollectionFactory.newList();
+        Map<String, PropertyModel> reduced = CollectionFactory.newCaseInsensitiveMap();
+
+
+        for (String name : propertyNames)
+        {
+
+            PropertyModel model = get(name);
+
+            String canonical = model.getPropertyName();
+
+            reorderedPropertyNames.add(canonical);
+            reduced.put(canonical, model);
+
+        }
+
+        this.propertyNames.clear();
+        this.propertyNames.addAll(reorderedPropertyNames);
+
+        properties.clear();
+        properties.putAll(reduced);
+
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder("BeanModel[");
+        builder.append(ClassFabUtils.toJavaClassName(beanType));
+
+        builder.append(" properties:");
+        String sep = "";
+
+        for (String name : propertyNames)
+        {
+            builder.append(sep);
+            builder.append(name);
+
+            sep = ", ";
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java
new file mode 100644
index 0000000..78d792f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/BeanModelUtils.java
@@ -0,0 +1,103 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.beaneditor.BeanModel;
+
+/**
+ * Utilities used in a few places to modify an existing {@link BeanModel}.
+ */
+public final class BeanModelUtils
+{
+
+    /**
+     * Performs standard set of modifications to a {@link org.apache.tapestry.beaneditor.BeanModel}. First new
+     * properties may be added, then properties removed, then properties reordered.
+     *
+     * @param model                to modifiy
+     * @param addPropertyNames     comma seperated list of property names to add, or null
+     * @param includePropertyNames comma seperated list of property names to include
+     * @param excludePropertyNames comma seperated list of property names to exclude, or null
+     * @param reorderPropertyNames comma seperated list of property names to reorder, or null
+     */
+    public static void modify(BeanModel model, String addPropertyNames, String includePropertyNames,
+                              String excludePropertyNames,
+                              String reorderPropertyNames)
+    {
+        if (addPropertyNames != null) add(model, addPropertyNames);
+
+        if (includePropertyNames != null) include(model, includePropertyNames);
+
+        if (excludePropertyNames != null) exclude(model, excludePropertyNames);
+
+        if (reorderPropertyNames != null) reorder(model, reorderPropertyNames);
+    }
+
+    /**
+     * Adds empty properties to the bean model.  New properties are added with a <em>null</em> {@link
+     * org.apache.tapestry.PropertyConduit}.
+     *
+     * @param model         to be modified
+     * @param propertyNames comma-separated list of property names
+     */
+    public static void add(BeanModel model, String propertyNames)
+    {
+        for (String name : split(propertyNames))
+        {
+            model.add(name, null);
+        }
+    }
+
+    /**
+     * Removes properties from the bean model.
+     *
+     * @param model
+     * @param propertyNames comma-separated list of property names
+     * @see BeanModel#exclude(String...)
+     */
+    public static void exclude(BeanModel model, String propertyNames)
+    {
+        model.exclude(split(propertyNames));
+    }
+
+    /**
+     * Selects a subset of the properties to keep, and reorders them.
+     */
+    public static void include(BeanModel model, String propertyNames)
+    {
+        model.include(split(propertyNames));
+    }
+
+    /**
+     * Reorders properties within the bean model.
+     *
+     * @param model
+     * @param propertyNames comma-separated list of property names
+     * @see BeanModel#reorder(String...)
+     */
+    public static void reorder(BeanModel model, String propertyNames)
+    {
+        model.reorder(split(propertyNames));
+    }
+
+    static String[] split(String propertyNames)
+    {
+        String trimmed = propertyNames.trim();
+
+        if (trimmed.length() == 0) return new String[0];
+
+        return trimmed.split("\\s*,\\s*");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PrimitiveFieldConstraintGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PrimitiveFieldConstraintGenerator.java
new file mode 100644
index 0000000..1a89aab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PrimitiveFieldConstraintGenerator.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Adds a "required" constraint for any property of whose type is a primitive (not a wrapper or reference) type.
+ */
+public class PrimitiveFieldConstraintGenerator implements ValidationConstraintGenerator
+{
+    private final List<String> REQUIRED = Arrays.asList("required");
+
+    public List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider)
+    {
+        return propertyType.isPrimitive() ? REQUIRED : null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java
new file mode 100644
index 0000000..c8c255b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/PropertyModelImpl.java
@@ -0,0 +1,128 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+import java.lang.annotation.Annotation;
+
+public class PropertyModelImpl implements PropertyModel
+{
+    private final BeanModel model;
+
+    private final String name;
+
+    private final PropertyConduit conduit;
+
+    private final String id;
+
+    private String label;
+
+    private String dataType;
+
+    private boolean sortable;
+
+    public PropertyModelImpl(BeanModel model, String name, PropertyConduit conduit, Messages messages)
+    {
+        this.model = model;
+        this.name = name;
+        this.conduit = conduit;
+
+        id = TapestryInternalUtils.extractIdFromPropertyExpression(name);
+
+        label = TapestryInternalUtils.defaultLabel(id, messages, name);
+
+        // Primitive types need to be converted to wrapper types before checking to see
+        // if they are sortable.
+
+        Class wrapperType = ClassFabUtils.getWrapperType(getPropertyType());
+
+        sortable = Comparable.class.isAssignableFrom(wrapperType);
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public Class getPropertyType()
+    {
+        return conduit == null ? Object.class : conduit.getPropertyType();
+    }
+
+    public PropertyConduit getConduit()
+    {
+        return conduit;
+    }
+
+    public PropertyModel label(String label)
+    {
+        Defense.notBlank(label, "label");
+
+        this.label = label;
+
+        return this;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public String getPropertyName()
+    {
+        return name;
+    }
+
+    public BeanModel model()
+    {
+        return model;
+    }
+
+    public PropertyModel dataType(String dataType)
+    {
+        this.dataType = dataType;
+
+        return this;
+    }
+
+    public String getDataType()
+    {
+        return dataType;
+    }
+
+    public boolean isSortable()
+    {
+        return sortable;
+    }
+
+    public PropertyModel sortable(boolean sortable)
+    {
+        this.sortable = sortable;
+
+        return this;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return conduit == null ? null : conduit.getAnnotation(annotationClass);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGenerator.java
new file mode 100644
index 0000000..55faf19
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGenerator.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Checks for the {@link Validate} annotation, and extracts its value to form the result.
+ */
+public class ValidateAnnotationConstraintGenerator implements ValidationConstraintGenerator
+{
+
+    public List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider)
+    {
+        Validate annotation = annotationProvider.getAnnotation(Validate.class);
+
+        if (annotation == null)
+            return null;
+
+        return Arrays.asList(annotation.value().split(","));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AbstractBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AbstractBinding.java
new file mode 100644
index 0000000..321ccd6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AbstractBinding.java
@@ -0,0 +1,75 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Abstract base class for bindings. Assumes that the binding is read only and invariant. Subclasses must provide an
+ * implementation of {@link Binding#get()}.
+ */
+public abstract class AbstractBinding extends BaseLocatable implements Binding
+{
+    public AbstractBinding()
+    {
+        this(null);
+    }
+
+    protected AbstractBinding(Location location)
+    {
+        super(location);
+    }
+
+    /**
+     * @throws TapestryException always
+     */
+    public void set(Object value)
+    {
+        throw new TapestryException(BindingsMessages.bindingIsReadOnly(this), this, null);
+    }
+
+    /**
+     * Returns true. Subclasses that do not supply a fixed, read-only value should override this method to return
+     * false.
+     */
+    public boolean isInvariant()
+    {
+        return true;
+    }
+
+    /**
+     * Returns the actual class, by invoking {@link Binding#get()}. Subclasses may override this method to work more
+     * efficiently (say, when the binding type is known statically).
+     */
+    public Class getBindingType()
+    {
+        return get().getClass();
+    }
+
+    /**
+     * Always returns null. Bindings that provide access to a method or field will override this method to return the
+     * appropriate annotation.
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AssetBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AssetBindingFactory.java
new file mode 100644
index 0000000..05d8356
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/AssetBindingFactory.java
@@ -0,0 +1,97 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.BindingFactory;
+
+/**
+ * Binding factory where the expression is a reference to an asset.
+ *
+ * @see AssetSource
+ */
+public class AssetBindingFactory implements BindingFactory
+{
+    private final AssetSource source;
+
+    private final boolean forceAbsoluteURIs;
+
+    public class AssetBinding extends AbstractBinding
+    {
+        private final String description;
+
+        private final Asset asset;
+
+        protected AssetBinding(String description, Asset asset, Location location)
+        {
+            super(location);
+
+            this.description = description;
+            this.asset = asset;
+        }
+
+        public Object get()
+        {
+            return asset;
+        }
+
+        /**
+         * Asset bindings are invariant only if full URIs are being used.  This is complicated ... basically, if the
+         * Asset is invariant, then any value coerced from the Asset is also invariant (such as a String version of an
+         * Asset's path).  Thus, the invariant String gets cached inside component parameter fields.  However, when the
+         * path is dynamic (i.e., because of {@link org.apache.tapestry.internal.services.RequestPathOptimizer}), we
+         * need to ensure that the Assets aren't cached.
+         *
+         * @return true if full URIs are enabled, false otherwise
+         */
+        @Override
+        public boolean isInvariant()
+        {
+            return forceAbsoluteURIs;
+        }
+
+        @Override
+        public String toString()
+        {
+            return String.format("AssetBinding[%s: %s]", description, asset);
+        }
+    }
+
+    public AssetBindingFactory(AssetSource source,
+
+                               @Symbol(SymbolConstants.FORCE_ABSOLUTE_URIS)
+                               boolean forceAbsoluteURIs)
+    {
+        this.source = source;
+        this.forceAbsoluteURIs = forceAbsoluteURIs;
+    }
+
+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                              String expression, Location location)
+    {
+        Resource baseResource = container.getBaseResource();
+
+        Asset asset = source.getAsset(baseResource, expression, container.getLocale());
+
+        return new AssetBinding(description, asset, location);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BindingsMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BindingsMessages.java
new file mode 100644
index 0000000..d1bae76
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BindingsMessages.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+final class BindingsMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(BindingsMessages.class);
+
+    private BindingsMessages()
+    {
+    }
+
+    static String bindingIsReadOnly(Binding binding)
+    {
+        return MESSAGES.format("binding-is-read-only", binding);
+    }
+
+    static String validateBindingForFieldsOnly(ComponentResources component)
+    {
+        return MESSAGES.format("validate-binding-for-fields-only", component.getCompleteId());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBinding.java
new file mode 100644
index 0000000..bd7d853
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBinding.java
@@ -0,0 +1,47 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+public class BlockBinding extends AbstractBinding
+{
+    private final String description;
+
+    private final ComponentResources component;
+
+    private final String blockId;
+
+    public BlockBinding(String description, ComponentResources component, String blockId, Location location)
+    {
+        super(location);
+
+        this.description = description;
+        this.component = component;
+        this.blockId = blockId;
+    }
+
+    public Object get()
+    {
+        return component.getBlock(blockId);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("BlockBinding[%s: %s]", description, blockId);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBindingFactory.java
new file mode 100644
index 0000000..49c8e7c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/BlockBindingFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+
+/**
+ * Accesses a named block from the container. The block must exist.
+ */
+public class BlockBindingFactory implements BindingFactory
+{
+    public Binding newBinding(String description, ComponentResources container,
+                              ComponentResources component, String expression, Location location)
+    {
+        return new BlockBinding(description, container, expression, location);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBinding.java
new file mode 100644
index 0000000..15de64f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBinding.java
@@ -0,0 +1,48 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+public class ComponentBinding extends AbstractBinding
+{
+    private final String description;
+
+    private final ComponentResources resources;
+
+    private final String componentId;
+
+    public ComponentBinding(String description, ComponentResources resources, String componentId,
+                            Location location)
+    {
+        super(location);
+
+        this.description = description;
+        this.resources = resources;
+        this.componentId = componentId;
+    }
+
+    public Object get()
+    {
+        return resources.getEmbeddedComponent(componentId);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("ComponentResources[%s %s]", description, componentId);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBindingFactory.java
new file mode 100644
index 0000000..d3093ba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ComponentBindingFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+
+/**
+ * The "component:" binding prefix, which allows access to a child component via its id.
+ */
+public class ComponentBindingFactory implements BindingFactory
+{
+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                              String expression, Location location)
+    {
+        return new ComponentBinding(description, container, expression, location);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBinding.java
new file mode 100644
index 0000000..ce1bcc4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBinding.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Binding type for literal, immutable values. Literal bindings are {@linkplain org.apache.tapestry.Binding#isInvariant()
+ * invariant}; any value provided by a LiteralBinding, even if {@linkplain org.apache.tapestry.ioc.services.TypeCoercer#coerce(Object,
+ * Class) coerced}, will be cached aggresively by Tapestry cmponent.
+ * <p/>
+ * <p>LiteralBindings are often used for literal string values supplied in-line in the component template, but is used
+ * for many other things as well, any kind of fixed, read-only value.
+ */
+public class LiteralBinding extends AbstractBinding
+{
+    private final String description;
+
+    private final Object value;
+
+    public LiteralBinding(String description, Object value, Location location)
+    {
+        super(location);
+        this.description = description;
+        this.value = value;
+    }
+
+    public Object get()
+    {
+        return value;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("LiteralBinding[%s: %s]", description, value);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBindingFactory.java
new file mode 100644
index 0000000..e0d5b7f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/LiteralBindingFactory.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;

+

+import org.apache.tapestry.Binding;

+import org.apache.tapestry.ComponentResources;

+import org.apache.tapestry.ioc.Location;

+import org.apache.tapestry.services.BindingFactory;

+

+/**

+ * Binding factory that treats the expression as a literal string. The simplest form of binding.

+ *

+ * @see org.apache.tapestry.internal.bindings.LiteralBinding

+ */

+public class LiteralBindingFactory implements BindingFactory

+{

+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,

+                              String expression, Location location)

+    {

+        return new LiteralBinding(description, expression, location);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/MessageBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/MessageBindingFactory.java
new file mode 100644
index 0000000..7ffc2910
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/MessageBindingFactory.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+
+/**
+ * Implementation of the message: binding prefix -- we simply get the message key and store it inside at {@link
+ * LiteralBinding}.
+ */
+public class MessageBindingFactory implements BindingFactory
+{
+
+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                              String expression, Location location)
+    {
+        String messageValue = container.getMessages().get(expression);
+
+        return new LiteralBinding(description, messageValue, location);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/NullFieldStrategyBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/NullFieldStrategyBindingFactory.java
new file mode 100644
index 0000000..2e8fcd1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/NullFieldStrategyBindingFactory.java
@@ -0,0 +1,44 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.NullFieldStrategy;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.NullFieldStrategySource;
+
+/**
+ * Treats the expression as the name of a {@link org.apache.tapestry.NullFieldStrategy}, accessed via the {@link
+ * org.apache.tapestry.services.NullFieldStrategySource} service.
+ */
+public class NullFieldStrategyBindingFactory implements BindingFactory
+{
+    private NullFieldStrategySource strategySource;
+
+    public NullFieldStrategyBindingFactory(NullFieldStrategySource strategySource)
+    {
+        this.strategySource = strategySource;
+    }
+
+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                              String expression, Location location)
+    {
+        NullFieldStrategy strategy = strategySource.get(expression);
+
+        return new LiteralBinding(description, strategy, location);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBinding.java
new file mode 100644
index 0000000..f61b8db
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBinding.java
@@ -0,0 +1,101 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Base class for bindings created by the {@link org.apache.tapestry.internal.bindings.PropBindingFactory}. A subclass
+ * of this is created at runtime.
+ */
+public class PropBinding extends AbstractBinding
+{
+    private final Object root;
+
+    private final PropertyConduit conduit;
+
+    private final String toString;
+
+    public PropBinding(final Object root, final PropertyConduit conduit, final String toString,
+                       final Location location)
+    {
+        super(location);
+
+        this.root = root;
+        this.conduit = conduit;
+        this.toString = toString;
+    }
+
+    /**
+     * The default implementation of get() will throw a TapestryException (binding is write only). The fabricated
+     * subclass <em>may</em> override this method (as well as set()).
+     */
+    public Object get()
+    {
+        try
+        {
+            return conduit.get(root);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), getLocation(), ex);
+        }
+    }
+
+    @Override
+    public void set(Object value)
+    {
+        try
+        {
+            conduit.set(root, value);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), getLocation(), ex);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return toString;
+    }
+
+    /**
+     * Returns false; these properties are always dynamic.
+     */
+    @Override
+    public boolean isInvariant()
+    {
+        return false;
+    }
+
+    @Override
+    public Class getBindingType()
+    {
+        return conduit.getPropertyType();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return conduit.getAnnotation(annotationClass);
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java
new file mode 100644
index 0000000..f7bb01b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/PropBindingFactory.java
@@ -0,0 +1,60 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.PropertyConduitSource;
+
+/**
+ * Binding factory for reading and updating JavaBean properties.
+ * <p/>
+ * Expression are evaluated via a {@link PropertyConduit}, which is generated by {@link PropertyConduitSource} (which
+ * therefore defines the expression language).
+ */
+public class PropBindingFactory implements BindingFactory
+{
+    private final PropertyConduitSource source;
+
+    public PropBindingFactory(PropertyConduitSource propertyConduitSource)
+    {
+        source = propertyConduitSource;
+    }
+
+    public Binding newBinding(String description, ComponentResources container,
+                              ComponentResources component, String expression, Location location)
+    {
+        Object target = container.getComponent();
+        Class targetClass = target.getClass();
+
+        try
+        {
+            PropertyConduit conduit = source.create(targetClass, expression);
+
+            String toString = String.format("PropBinding[%s %s(%s)]", description, container
+                    .getCompleteId(), expression);
+
+            return new PropBinding(target, conduit, toString, location);
+        }
+        catch (Throwable ex)
+        {
+            throw new TapestryException(ex.getMessage(), location, ex);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBinding.java
new file mode 100644
index 0000000..be12d79
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBinding.java
@@ -0,0 +1,70 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+public class RenderVariableBinding extends AbstractBinding
+{
+    private final String description;
+    private final ComponentResources resources;
+    private final String name;
+
+    public RenderVariableBinding(String description, ComponentResources resources, String name, Location location)
+    {
+        super(location);
+
+        this.description = description;
+        this.resources = resources;
+        this.name = name;
+    }
+
+    @Override
+    public void set(Object value)
+    {
+        resources.storeRenderVariable(name, value);
+    }
+
+    /**
+     * Returns false, render variables are always variable.
+     */
+    @Override
+    public boolean isInvariant()
+    {
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("RenderVariable[%s %s]", description, name);
+    }
+
+
+    public Object get()
+    {
+        return resources.getRenderVariable(name);
+    }
+
+    /**
+     * Always returns Object since we don't (statically) know the type of object.
+     */
+    @Override
+    public Class getBindingType()
+    {
+        return Object.class;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBindingFactory.java
new file mode 100644
index 0000000..f5b465c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/RenderVariableBindingFactory.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+
+public class RenderVariableBindingFactory implements BindingFactory
+{
+    public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                              String expression, Location location)
+    {
+        return new RenderVariableBinding(description, container, expression, location);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/TranslateBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/TranslateBindingFactory.java
new file mode 100644
index 0000000..a93c3f8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/TranslateBindingFactory.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.TranslatorSource;
+
+/**
+ * Interprets the binding expression as the name of a {@link Translator} provided by the {@link TranslatorSource}.
+ */
+public class TranslateBindingFactory implements BindingFactory
+{
+    private final TranslatorSource source;
+
+    public TranslateBindingFactory(TranslatorSource source)
+    {
+        this.source = source;
+    }
+
+    public Binding newBinding(String description, ComponentResources container,
+                              ComponentResources component, String expression, Location location)
+    {
+        Translator translator = source.get(expression);
+
+        return new LiteralBinding(description, translator, location);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ValidateBindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ValidateBindingFactory.java
new file mode 100644
index 0000000..1b01ad9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/bindings/ValidateBindingFactory.java
@@ -0,0 +1,60 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.FieldValidatorSource;
+
+/**
+ * Factory for bindings that provide a {@link FieldValidator} based on a validator specification. This binding factory
+ * is only useable with components that implement the {@link Field} interface.
+ */
+public class ValidateBindingFactory implements BindingFactory
+{
+    private final FieldValidatorSource fieldValidatorSource;
+
+    public ValidateBindingFactory(FieldValidatorSource fieldValidatorSource)
+    {
+        this.fieldValidatorSource = fieldValidatorSource;
+    }
+
+    public Binding newBinding(String description, ComponentResources container,
+                              ComponentResources component, String expression, Location location)
+    {
+        Object fieldAsObject = component.getComponent();
+
+        if (!Field.class.isInstance(fieldAsObject))
+            throw new TapestryException(BindingsMessages.validateBindingForFieldsOnly(component),
+                                        location, null);
+
+        Field field = (Field) fieldAsObject;
+
+        // The expression is a validator specification, such as "required,minLength=5".
+        // ValidatorBindingFactory is the odd man out becasuse it needs the binding component (the
+        // component whose parameter is to be bound) rather than the containing component, the way
+        // most factories work.
+
+        FieldValidator validator = fieldValidatorSource.createValidators(field, expression);
+
+        return new LiteralBinding(description, validator, location);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHub.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHub.java
new file mode 100644
index 0000000..489fcfa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHub.java
@@ -0,0 +1,28 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.event;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+
+/**
+ * An object which manages a list of {@link org.apache.tapestry.internal.events.InvalidationListener}s.
+ * <p/>
+ * TODO: This interface need to move to the public side (as it is extended by other public interfaces), or we need to
+ * come up with an alternate mechanism for propogating invalidation data.
+ */
+public interface InvalidationEventHub
+{
+    void addInvalidationListener(InvalidationListener listener);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java
new file mode 100644
index 0000000..303cc45
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/event/InvalidationEventHubImpl.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.event;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newThreadSafeList;
+
+import java.util.List;
+
+/**
+ * Base implementation class for classes (especially services) that need to manage a list of {@link
+ * org.apache.tapestry.internal.events.InvalidationListener}s.
+ */
+public class InvalidationEventHubImpl implements InvalidationEventHub
+{
+    private final List<InvalidationListener> listeners = newThreadSafeList();
+
+    /**
+     * Notifies all {@link InvalidationListener listener}s.
+     */
+    protected final void fireInvalidationEvent()
+    {
+        for (InvalidationListener listener : listeners)
+        {
+            listener.objectWasInvalidated();
+        }
+    }
+
+    public final void addInvalidationListener(InvalidationListener listener)
+    {
+        listeners.add(listener);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/InvalidationListener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/InvalidationListener.java
new file mode 100644
index 0000000..6dfaa97
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/InvalidationListener.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.events;

+

+/**

+ * Interface for objects that may cache information that can be invalidated. Invalidation occurs when external files,

+ * from which in-memory data is cached, is determined to have changed.

+ */

+public interface InvalidationListener

+{

+    /**

+     * Invoked to indicate that some object is invalid. The receiver should clear its cache.

+     */

+    void objectWasInvalidated();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/UpdateListener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/UpdateListener.java
new file mode 100644
index 0000000..2c68659
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/events/UpdateListener.java
@@ -0,0 +1,26 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.events;
+
+/**
+ * Interface for objects which can periodically check for updates.
+ */
+public interface UpdateListener
+{
+    /**
+     * Invoked to force the receiver to check for updates to whatever underlying resources it makes use of.
+     */
+    void checkForUpdates();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/CollectionGridDataSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/CollectionGridDataSource.java
new file mode 100644
index 0000000..6bb6822
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/CollectionGridDataSource.java
@@ -0,0 +1,114 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.grid;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.grid.ColumnSort;
+import org.apache.tapestry.grid.GridDataSource;
+import org.apache.tapestry.grid.SortConstraint;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class CollectionGridDataSource implements GridDataSource
+{
+    private final List list;
+
+    @SuppressWarnings("unchecked")
+    public CollectionGridDataSource(final Collection collection)
+    {
+        Defense.notNull(collection, "collection");
+
+        // Copy the collection so that we can sort it without disturbing the original
+
+        list = CollectionFactory.newList(collection);
+    }
+
+    public int getAvailableRows()
+    {
+        return list.size();
+    }
+
+    public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints)
+    {
+        for (SortConstraint constraint : sortConstraints)
+        {
+            final ColumnSort sort = constraint.getColumnSort();
+
+            if (sort == ColumnSort.UNSORTED) continue;
+
+            final PropertyConduit conduit = constraint.getPropertyModel().getConduit();
+
+            final Comparator valueComparator = new Comparator<Comparable>()
+            {
+                public int compare(Comparable o1, Comparable o2)
+                {
+                    // Simplify comparison, and handle case where both are nulls.
+
+                    if (o1 == o2) return 0;
+
+                    if (o2 == null) return 1;
+
+                    if (o1 == null) return -1;
+
+                    return o1.compareTo(o2);
+                }
+            };
+
+            final Comparator rowComparator = new Comparator()
+            {
+                public int compare(Object row1, Object row2)
+                {
+                    Comparable value1 = (Comparable) conduit.get(row1);
+                    Comparable value2 = (Comparable) conduit.get(row2);
+
+                    return valueComparator.compare(value1, value2);
+                }
+            };
+
+            final Comparator reverseComparator = new Comparator()
+            {
+                public int compare(Object o1, Object o2)
+                {
+                    int modifier = sort == ColumnSort.ASCENDING ? 1 : -1;
+
+                    return modifier * rowComparator.compare(o1, o2);
+                }
+            };
+
+            // We can freely sort this list because its just a copy.
+
+            Collections.sort(list, reverseComparator);
+        }
+    }
+
+    /**
+     * Returns the type of the first element in the list, or null if the list is empty.
+     */
+    public Class getRowType()
+    {
+        return list.isEmpty() ? null : list.get(0).getClass();
+    }
+
+    public Object getRowValue(int index)
+    {
+        return list.get(index);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/NullDataSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/NullDataSource.java
new file mode 100644
index 0000000..486f8d4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/grid/NullDataSource.java
@@ -0,0 +1,47 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.grid;
+
+import org.apache.tapestry.grid.GridDataSource;
+import org.apache.tapestry.grid.SortConstraint;
+
+import java.util.List;
+
+/**
+ * An implementation of {@link org.apache.tapestry.grid.GridDataSource} used when the value null is provided as the
+ * source.
+ */
+public class NullDataSource implements GridDataSource
+{
+    public int getAvailableRows()
+    {
+        return 0;
+    }
+
+    public Class getRowType()
+    {
+        return null;
+    }
+
+    public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints)
+    {
+    }
+
+    public Object getRowValue(int index)
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ModelMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ModelMessages.java
new file mode 100644
index 0000000..030f06c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ModelMessages.java
@@ -0,0 +1,52 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.model;

+

+import org.apache.tapestry.ioc.Messages;

+import org.apache.tapestry.ioc.internal.util.MessagesImpl;

+

+class ModelMessages

+{

+    private final static Messages MESSAGES = MessagesImpl.forClass(ModelMessages.class);

+

+    private ModelMessages()

+    {

+    }

+

+    static String duplicateParameter(String parameterName, String componentName)

+    {

+        return MESSAGES.format("duplicate-parameter", parameterName, componentName);

+    }

+

+    static String duplicateParameterValue(String parameterName, String componentId, String componentClassName)

+    {

+        return MESSAGES.format("duplicate-parameter-value", parameterName, componentId, componentClassName);

+    }

+

+    static String duplicateComponentId(String id, String componentClassName)

+    {

+        return MESSAGES.format("duplicate-component-id", id, componentClassName);

+    }

+

+    static String missingPersistentField(String fieldName)

+    {

+        return MESSAGES.format("missing-persistent-field", fieldName);

+    }

+

+    static String duplicateMixin(String simpleName, String componentId)

+    {

+        return MESSAGES.format("duplicate-mixin", simpleName, componentId);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java
new file mode 100644
index 0000000..14740d8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java
@@ -0,0 +1,285 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.model;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.*;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Internal implementation of {@link org.apache.tapestry.model.MutableComponentModel}.
+ */
+public final class MutableComponentModelImpl implements MutableComponentModel
+{
+    private final ComponentModel parentModel;
+
+    private final Resource baseResource;
+
+    private final String componentClassName;
+
+    private final IdAllocator persistentFieldNameAllocator = new IdAllocator();
+
+    private final Logger logger;
+
+    private Map<String, ParameterModel> parameters;
+
+    private Map<String, EmbeddedComponentModel> embeddedComponents;
+
+    /**
+     * Maps from field name to strategy.
+     */
+    private Map<String, String> persistentFields;
+
+    private List<String> mixinClassNames;
+
+    private boolean informalParametersSupported;
+
+    private boolean mixinAfter;
+
+    private Map<String, String> metaData;
+
+    public MutableComponentModelImpl(String componentClassName, Logger logger, Resource baseResource,
+                                     ComponentModel parentModel)
+    {
+        this.componentClassName = componentClassName;
+        this.logger = logger;
+        this.baseResource = baseResource;
+        this.parentModel = parentModel;
+
+        // Pre-allocate names from the parent, to avoid name collisions.
+
+        if (this.parentModel != null)
+        {
+            for (String name : this.parentModel.getPersistentFieldNames())
+            {
+                persistentFieldNameAllocator.allocateId(name);
+            }
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("ComponentModel[%s]", componentClassName);
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public Resource getBaseResource()
+    {
+        return baseResource;
+    }
+
+    public String getComponentClassName()
+    {
+        return componentClassName;
+    }
+
+    public void addParameter(String name, boolean required, String defaultBindingPrefix)
+    {
+        Defense.notBlank(name, "name");
+        Defense.notBlank(defaultBindingPrefix, "defaultBindingPrefix");
+
+        // TODO: Check for conflict with base model
+
+        if (parameters == null) parameters = CollectionFactory.newCaseInsensitiveMap();
+        else
+        {
+            if (parameters.containsKey(name))
+                throw new IllegalArgumentException(ModelMessages.duplicateParameter(name, componentClassName));
+        }
+
+        parameters.put(name, new ParameterModelImpl(name, required, defaultBindingPrefix));
+    }
+
+    public ParameterModel getParameterModel(String parameterName)
+    {
+        ParameterModel result = InternalUtils.get(parameters, parameterName.toLowerCase());
+
+        if (result == null && parentModel != null) result = parentModel.getParameterModel(parameterName);
+
+        return result;
+    }
+
+    public List<String> getParameterNames()
+    {
+        List<String> names = CollectionFactory.newList();
+
+        if (parameters != null) names.addAll(parameters.keySet());
+
+        if (parentModel != null) names.addAll(parentModel.getParameterNames());
+
+        Collections.sort(names);
+
+        return names;
+    }
+
+    public List<String> getDeclaredParameterNames()
+    {
+        return InternalUtils.sortedKeys(parameters);
+    }
+
+    public MutableEmbeddedComponentModel addEmbeddedComponent(String id, String type, String componentClassName,
+                                                              boolean inheritInformalParameters, Location location)
+    {
+        // TODO: Parent compent model? Or would we simply override the parent?
+
+        if (embeddedComponents == null) embeddedComponents = CollectionFactory.newCaseInsensitiveMap();
+        else if (embeddedComponents.containsKey(id))
+            throw new IllegalArgumentException(ModelMessages.duplicateComponentId(id, this.componentClassName));
+
+        MutableEmbeddedComponentModel embedded = new MutableEmbeddedComponentModelImpl(id, type, componentClassName,
+                                                                                       this.componentClassName,
+                                                                                       inheritInformalParameters,
+                                                                                       location);
+
+        embeddedComponents.put(id, embedded);
+
+        return embedded; // So that parameters can be filled in
+    }
+
+    public List<String> getEmbeddedComponentIds()
+    {
+        List<String> result = CollectionFactory.newList();
+
+        if (embeddedComponents != null) result.addAll(embeddedComponents.keySet());
+
+        if (parentModel != null) result.addAll(parentModel.getEmbeddedComponentIds());
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public EmbeddedComponentModel getEmbeddedComponentModel(String componentId)
+    {
+        EmbeddedComponentModel result = InternalUtils.get(embeddedComponents, componentId);
+
+        if (result == null && parentModel != null) result = parentModel.getEmbeddedComponentModel(componentId);
+
+        return result;
+    }
+
+    public String getFieldPersistenceStrategy(String fieldName)
+    {
+        String result = InternalUtils.get(persistentFields, fieldName);
+
+        if (result == null && parentModel != null) result = parentModel.getFieldPersistenceStrategy(fieldName);
+
+        if (result == null) throw new IllegalArgumentException(ModelMessages.missingPersistentField(fieldName));
+
+        return result;
+    }
+
+    public List<String> getPersistentFieldNames()
+    {
+        return persistentFieldNameAllocator.getAllocatedIds();
+    }
+
+    public String setFieldPersistenceStrategy(String fieldName, String strategy)
+    {
+        String logicalFieldName = persistentFieldNameAllocator.allocateId(fieldName);
+
+        if (persistentFields == null) persistentFields = CollectionFactory.newMap();
+
+        persistentFields.put(logicalFieldName, strategy);
+
+        return logicalFieldName;
+    }
+
+    public boolean isRootClass()
+    {
+        return parentModel == null;
+    }
+
+    public void addMixinClassName(String mixinClassName)
+    {
+        if (mixinClassNames == null) mixinClassNames = CollectionFactory.newList();
+
+        mixinClassNames.add(mixinClassName);
+    }
+
+    public List<String> getMixinClassNames()
+    {
+        List<String> result = CollectionFactory.newList();
+
+        if (mixinClassNames != null) result.addAll(mixinClassNames);
+
+        if (parentModel != null) result.addAll(parentModel.getMixinClassNames());
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public void enableSupportsInformalParameters()
+    {
+        informalParametersSupported = true;
+    }
+
+    public boolean getSupportsInformalParameters()
+    {
+        return informalParametersSupported;
+    }
+
+    public ComponentModel getParentModel()
+    {
+        return parentModel;
+    }
+
+    public boolean isMixinAfter()
+    {
+        return mixinAfter;
+    }
+
+    public void setMixinAfter(boolean mixinAfter)
+    {
+        this.mixinAfter = mixinAfter;
+    }
+
+    public void setMeta(String key, String value)
+    {
+        Defense.notBlank(key, "key");
+        Defense.notBlank(value, "value");
+
+        if (metaData == null) metaData = CollectionFactory.newCaseInsensitiveMap();
+
+        // TODO: Error if duplicate?
+
+        metaData.put(key, value);
+    }
+
+    public String getMeta(String key)
+    {
+        String result = InternalUtils.get(metaData, key);
+
+        if (result == null && parentModel != null) result = parentModel.getMeta(key);
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableEmbeddedComponentModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableEmbeddedComponentModelImpl.java
new file mode 100644
index 0000000..d9e6bb4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/MutableEmbeddedComponentModelImpl.java
@@ -0,0 +1,125 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.model;
+
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.MutableEmbeddedComponentModel;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class MutableEmbeddedComponentModelImpl extends BaseLocatable implements MutableEmbeddedComponentModel
+{
+    private final String id;
+
+    private final String componentType;
+
+    private final String componentClassName;
+
+    private final String declaredClass;
+
+    private final boolean inheritInformalParameters;
+
+    private Map<String, String> parameters;
+
+    /**
+     * List of mixin class names.
+     */
+    private List<String> mixinClassNames;
+
+    public MutableEmbeddedComponentModelImpl(String id, String componentType, String componentClassName,
+                                             String declaredClass, boolean inheritInformalParameters, Location location)
+    {
+        super(location);
+
+        this.id = id;
+        this.componentType = componentType;
+        this.componentClassName = componentClassName;
+        this.inheritInformalParameters = inheritInformalParameters;
+        this.declaredClass = declaredClass;
+    }
+
+    public String getComponentClassName()
+    {
+        return componentClassName;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("EmbeddedComponentModel[id=%s type=%s class=%s inheritInformals=%s]", id, componentType,
+                             componentClassName, inheritInformalParameters);
+    }
+
+    public void addParameter(String name, String value)
+    {
+        if (parameters == null) parameters = CollectionFactory.newMap();
+        else if (parameters.containsKey(name))
+            throw new IllegalArgumentException(ModelMessages.duplicateParameterValue(name, id, declaredClass));
+
+        parameters.put(name, value);
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public String getComponentType()
+    {
+        return componentType;
+    }
+
+    public List<String> getParameterNames()
+    {
+        return InternalUtils.sortedKeys(parameters);
+    }
+
+    public String getParameterValue(String parameterName)
+    {
+        return InternalUtils.get(parameters, parameterName);
+    }
+
+    public List<String> getMixinClassNames()
+    {
+        if (mixinClassNames == null) return Collections.emptyList();
+
+        return Collections.unmodifiableList(mixinClassNames);
+    }
+
+    public void addMixin(String mixinClassName)
+    {
+        if (mixinClassNames == null)
+        {
+            mixinClassNames = CollectionFactory.newList();
+        }
+        else
+        {
+            if (mixinClassNames.contains(mixinClassName)) throw new IllegalArgumentException(ModelMessages
+                    .duplicateMixin(mixinClassName, id));
+        }
+
+        mixinClassNames.add(mixinClassName);
+    }
+
+    public boolean getInheritInformalParameters()
+    {
+        return inheritInformalParameters;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ParameterModelImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ParameterModelImpl.java
new file mode 100644
index 0000000..af5c329
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/model/ParameterModelImpl.java
@@ -0,0 +1,48 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.model;
+
+import org.apache.tapestry.model.ParameterModel;
+
+public class ParameterModelImpl implements ParameterModel
+{
+    private final String name;
+
+    private final boolean required;
+
+    private final String defaultBindingPrefix;
+
+    public ParameterModelImpl(String name, boolean required, String defaultBindingPrefix)
+    {
+        this.name = name;
+        this.required = required;
+        this.defaultBindingPrefix = defaultBindingPrefix;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public boolean isRequired()
+    {
+        return required;
+    }
+
+    public String getDefaultBindingPrefix()
+    {
+        return defaultBindingPrefix;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java
new file mode 100644
index 0000000..b9eb0e0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/AttributeToken.java
@@ -0,0 +1,74 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * Stores an attribute/value pair (as part of an XML element).

+ */

+public class AttributeToken extends TemplateToken

+{

+    private final String namespaceURI;

+

+    private final String name;

+

+    private final String value;

+

+    public AttributeToken(String namespaceURI, String name, String value, Location location)

+    {

+        super(TokenType.ATTRIBUTE, location);

+

+        this.namespaceURI = namespaceURI;

+        this.name = name;

+        this.value = value;

+    }

+

+    /**

+     * Returns local name for the attribute.

+     */

+    public String getName()

+    {

+        return name;

+    }

+

+    /**

+     * Returns the value for the attribute.

+     */

+    public String getValue()

+    {

+        return value;

+    }

+

+    /**

+     * Returns the namespace URI containing the attribute, or the empty string for the default namespace.

+     */

+    public String getNamespaceURI()

+    {

+        return namespaceURI;

+    }

+

+    @Override

+    public String toString()

+    {

+        StringBuilder builder = new StringBuilder("Attribute[");

+

+        if (namespaceURI.length() > 0) builder.append(namespaceURI).append(" ");

+

+        builder.append(name).append("=").append(value).append("]");

+

+        return builder.toString();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BlockToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BlockToken.java
new file mode 100644
index 0000000..751f675
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BlockToken.java
@@ -0,0 +1,50 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * A block, used to enclose a chunk of template (including components) and control when or if the content is rendered.
+ */
+public class BlockToken extends TemplateToken
+{
+    private final String id;
+
+    /**
+     * @param id       the id of the block, or null for an anonymous block
+     * @param location of the block element
+     */
+    public BlockToken(String id, Location location)
+    {
+        super(TokenType.BLOCK, location);
+
+        this.id = id;
+    }
+
+    /**
+     * Returns the block's template-unique id, or null if the block element did not specify an id.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("Block[%s]", id == null ? "" : id);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BodyToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BodyToken.java
new file mode 100644
index 0000000..1552819
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/BodyToken.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * Placeholder for a component's body (within the component's template).

+ */

+public class BodyToken extends TemplateToken

+{

+    public BodyToken(Location location)

+    {

+        super(TokenType.BODY, location);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java
new file mode 100644
index 0000000..449c3dd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CDATAToken.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * Literal text that was enclosed within a !CDATA in the input template (so we should do the same during output).

+ */

+public class CDATAToken extends TemplateToken

+{

+    private final String content;

+

+    public CDATAToken(String content, Location location)

+    {

+        super(TokenType.CDATA, location);

+

+        this.content = content;

+    }

+

+    public String getContent()

+    {

+        return content;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("CDATA[%s]", content);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java
new file mode 100644
index 0000000..f6a2107
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/CommentToken.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * A node representing a comment embedded in the source input.

+ */

+public class CommentToken extends TemplateToken

+{

+    private final String comment;

+

+    public CommentToken(String comment, Location location)

+    {

+        super(TokenType.COMMENT, location);

+

+        this.comment = comment;

+    }

+

+    public String getComment()

+    {

+        return comment;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Comment[%s]", comment);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java
new file mode 100644
index 0000000..7ca6df5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplate.java
@@ -0,0 +1,47 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Resource;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A parsed component template, containing all the tokens parsed from the template.
+ */
+public interface ComponentTemplate
+{
+    /**
+     * Returns true if no template could be found for the component.
+     */
+    boolean isMissing();
+
+    /**
+     * Returns the resource that was parsed to form the template.
+     */
+    Resource getResource();
+
+    /**
+     * Returns a list of tokens that were parsed from the template. The caller should not modify this list.
+     */
+    List<TemplateToken> getTokens();
+
+    /**
+     * Returns a set of strings corresponding to {@link org.apache.tapestry.internal.parser.StartComponentToken}s within
+     * the template that have a non-blank id attribute.
+     */
+    Set<String> getComponentIds();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java
new file mode 100644
index 0000000..fcfb2a3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ComponentTemplateImpl.java
@@ -0,0 +1,68 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Resource;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+
+import java.util.List;
+import java.util.Set;
+
+public class ComponentTemplateImpl implements ComponentTemplate
+{
+    private final Resource resource;
+
+    private final List<TemplateToken> tokens;
+
+    private final Set<String> componentIds;
+
+    /**
+     * @param resource     the resource from which the template was parsed
+     * @param tokens       the tokens of the template, a copy of this list will be made
+     * @param componentIds ids of components defined in the template
+     */
+    public ComponentTemplateImpl(Resource resource, List<TemplateToken> tokens,
+                                 Set<String> componentIds)
+    {
+        this.resource = resource;
+        this.tokens = newList(tokens);
+        this.componentIds = newSet(componentIds);
+    }
+
+    public Resource getResource()
+    {
+        return resource;
+    }
+
+    public List<TemplateToken> getTokens()
+    {
+        return tokens;
+    }
+
+    public Set<String> getComponentIds()
+    {
+        return componentIds;
+    }
+
+    /**
+     * Returns false.
+     */
+    public boolean isMissing()
+    {
+        return false;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DTDToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DTDToken.java
new file mode 100644
index 0000000..6be0f40
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DTDToken.java
@@ -0,0 +1,70 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Represents the presence of a Document Type declaration within a template. The Document type declaration will be
+ * output to the client. In the event that multiple declarations are encountered (a page and one or more nested
+ * components all declare a document type), the first document type declared will be used.
+ */
+public class DTDToken extends TemplateToken
+{
+    private final String name;
+
+    private final String publicId;
+
+    private final String systemId;
+
+    public DTDToken(String name, String publicId, String systemId, Location location)
+    {
+        super(TokenType.DTD, location);
+
+        this.name = name;
+        this.publicId = publicId;
+        this.systemId = systemId;
+    }
+
+    /**
+     * Returns the doctype name (the name of the document root element)
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Returns the public identifier of the DTD
+     */
+    public String getPublicId()
+    {
+        return publicId;
+    }
+
+    /**
+     * Returns the system identifier of the DTD
+     */
+    public String getSystemId()
+    {
+        return systemId;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("DTD[name=%s; publicId=%s; systemId=%s]", name, publicId, systemId);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DefineNamespacePrefixToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DefineNamespacePrefixToken.java
new file mode 100644
index 0000000..6940eec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/DefineNamespacePrefixToken.java
@@ -0,0 +1,55 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * A token from a template that defines a namespace prefix. This will always follow a {@link
+ * org.apache.tapestry.internal.parser.StartComponentToken} or {@link org.apache.tapestry.internal.parser.StartElementToken}
+ * (and come before {@link org.apache.tapestry.internal.parser.AttributeToken}) and applies to the component or
+ * element.
+ *
+ * @see org.apache.tapestry.dom.Element#defineNamespace(String, String)
+ */
+public class DefineNamespacePrefixToken extends TemplateToken
+{
+    private final String namespaceURI;
+    private final String namespacePrefix;
+
+    public DefineNamespacePrefixToken(String namespaceURI, String namespacePrefix, Location location)
+    {
+        super(TokenType.DEFINE_NAMESPACE_PREFIX, location);
+
+        this.namespacePrefix = namespacePrefix;
+        this.namespaceURI = namespaceURI;
+    }
+
+    public String getNamespacePrefix()
+    {
+        return namespacePrefix;
+    }
+
+    public String getNamespaceURI()
+    {
+        return namespaceURI;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("DefineNamespacePrefix[%s=%s]", namespacePrefix, namespaceURI);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java
new file mode 100644
index 0000000..d77e386
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/EndElementToken.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;
+

+/**

+ * Ends a previously started element (including components, parameters, blocks, etc.).

+ */

+public class EndElementToken extends TemplateToken

+{

+    public EndElementToken(Location location)

+    {

+        super(TokenType.END_ELEMENT, location);

+    }

+

+    @Override

+    public String toString()

+    {

+        return "End";

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ExpansionToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ExpansionToken.java
new file mode 100644
index 0000000..e20f6db
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ExpansionToken.java
@@ -0,0 +1,45 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * A token containing an expression expansion from the template. Expression expansions look like Ant variables, i.e.,

+ * "${xyz}", where xyz is a binding expression. It may have a prefix or not ("prop:" will be the default prefix if not

+ * specified).

+ */

+public class ExpansionToken extends TemplateToken

+{

+    private final String expression;

+

+    public ExpansionToken(String expression, Location location)

+    {

+        super(TokenType.EXPANSION, location);

+

+        this.expression = expression;

+    }

+

+    public String getExpression()

+    {

+        return expression;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Expression[%s]", expression);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ParameterToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ParameterToken.java
new file mode 100644
index 0000000..6046200
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/ParameterToken.java
@@ -0,0 +1,47 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * A parameter block to be passed to a component as a parameter.
+ */
+public class ParameterToken extends TemplateToken
+{
+    private final String name;
+
+    /**
+     * @param name     the name of the parameter to be bound
+     * @param location location of the element
+     */
+    public ParameterToken(String name, Location location)
+    {
+        super(TokenType.PARAMETER, location);
+
+        this.name = name;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("Parameter[%s]", name);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java
new file mode 100644
index 0000000..d26098e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartComponentToken.java
@@ -0,0 +1,122 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * The start element of a component within the template. Will be followed by a series of {@link
+ * org.apache.tapestry.internal.parser.AttributeToken}s for any attributes (outside of id and type), and eventually will
+ * be balanced by an {@link org.apache.tapestry.internal.parser.EndElementToken}.
+ */
+public class StartComponentToken extends TemplateToken
+{
+    private final String elementName;
+
+    private final String id;
+
+    private final String componentType;
+
+    private final String mixins;
+
+    /**
+     * @param elementName the name of the element from which this component was parsed, or null if the element was the
+     *                    t:comp placeholder
+     * @param id          the id of the component (may be null for anonymous components)
+     * @param type        the type of component (may be null if the component type is specified outside the template)
+     * @param mixins      a comma-separated list of mixins (possibly null)
+     * @param location    the location within the template at which the element was parsed
+     */
+    public StartComponentToken(String elementName, String id, String type, String mixins,
+                               Location location)
+    {
+        super(TokenType.START_COMPONENT, location);
+
+        // TODO: id or type may be null, but not both!
+
+        this.elementName = elementName;
+        this.id = id;
+        componentType = type;
+        this.mixins = mixins;
+    }
+
+    /**
+     * Returns the element for this component. When using the &lt;t:comp&gt; placeholder, this value will be null. When
+     * using "invisible instrumentation", where t:id or t:type attributes are added to existing elements, this is the
+     * local name of the element so attached.
+     *
+     * @return the element name or null
+     */
+    public String getElementName()
+    {
+        return elementName;
+    }
+
+    /**
+     * Returns a non-blank id if one was provided in the template. If the id attribute was missing (or the value was
+     * blank), returns null.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    /**
+     * Returns a non-blank component type if one was provided in the template. If the type attribute was missing (or the
+     * value was blank), returns null.
+     */
+    public String getComponentType()
+    {
+        return componentType;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder();
+
+        add(builder, "element", elementName);
+        add(builder, "id", id);
+        add(builder, "type", componentType);
+        add(builder, "mixins", mixins);
+
+        builder.insert(0, "StartComponentToken[");
+        builder.append("]");
+
+        return builder.toString();
+    }
+
+    private void add(StringBuilder builder, String label, String value)
+    {
+        if (value == null)
+            return;
+
+        if (builder.length() > 0)
+            builder.append(" ");
+
+        builder.append(label);
+        builder.append("=");
+        builder.append(value);
+    }
+
+    /**
+     * Returns the list of mixins for this component instance, or null for no mixins.
+     */
+    public String getMixins()
+    {
+        return mixins;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java
new file mode 100644
index 0000000..33303d5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/StartElementToken.java
@@ -0,0 +1,67 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * The start of an ordinary element within the template (as opposed to {@link org.apache.tapestry.internal.parser.StartComponentToken},

+ * which represents an active Tapestry token. A start element token may be immediately followed by {@link

+ * org.apache.tapestry.internal.parser.AttributeToken}s that represents the attributes associated with the element. A

+ * start element token will always be balanced by a {@link org.apache.tapestry.internal.parser.EndElementToken} (though

+ * there will likely be some amount of intermediate tokens).

+ */

+public class StartElementToken extends TemplateToken

+{

+    private final String namespaceURI;

+

+    private final String name;

+

+    public StartElementToken(String namespaceURI, String name, Location location)

+    {

+        super(TokenType.START_ELEMENT, location);

+

+        this.namespaceURI = namespaceURI;

+        this.name = name;

+    }

+

+    /**

+     * Returns local name for the element.

+     */

+    public String getName()

+    {

+        return name;

+    }

+

+    /**

+     * @return the namespace URI for the element, or the empty string for the default namespace

+     */

+    public String getNamespaceURI()

+    {

+        return namespaceURI;

+    }

+

+    @Override

+    public String toString()

+    {

+        StringBuilder builder = new StringBuilder("Start[");

+

+        if (namespaceURI.length() > 0) builder.append(namespaceURI).append(" ");

+

+        builder.append(name).append("]");

+

+        return builder.toString();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java
new file mode 100644
index 0000000..49b1d65
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TemplateToken.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.BaseLocatable;

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * Base class for tokens parsed out of a template. The set of classes rooted here are effectively object encapsulations

+ * of the events generated by a SAX parser.

+ */

+public abstract class TemplateToken extends BaseLocatable

+{

+    private final TokenType tokenType;

+

+    protected TemplateToken(TokenType tokenType, Location location)

+    {

+        super(location);

+        this.tokenType = tokenType;

+    }

+

+    public TokenType getTokenType()

+    {

+        return tokenType;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TextToken.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TextToken.java
new file mode 100644
index 0000000..f7bd01c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TextToken.java
@@ -0,0 +1,46 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.parser;

+

+import org.apache.tapestry.ioc.Location;

+

+/**

+ *

+ */

+public class TextToken extends TemplateToken

+{

+    private final String text;

+

+    public TextToken(String text, Location location)

+    {

+        super(TokenType.TEXT, location);

+

+        this.text = text;

+    }

+

+    /**

+     * Returns the text extracted from that part of the template.

+     */

+    public String getText()

+    {

+        return text;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Text[%s]", text);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TokenType.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TokenType.java
new file mode 100644
index 0000000..b440381
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/TokenType.java
@@ -0,0 +1,26 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.parser;
+
+/**
+ * Defines the different types of {@link org.apache.tapestry.internal.parser.TemplateToken}s. Each value maps to a
+ * particular subclass of TemplateToken.
+ */
+public enum TokenType
+{
+
+    ATTRIBUTE, CDATA, COMMENT, END_ELEMENT, START_COMPONENT, START_ELEMENT, TEXT, BODY, EXPANSION, PARAMETER, BLOCK, DTD,
+    DEFINE_NAMESPACE_PREFIX
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/package.html b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/package.html
new file mode 100644
index 0000000..3a4fe96
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/parser/package.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+Classes related to parsing of Tapestry component templates.
+</body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ComponentResourcesRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ComponentResourcesRenderer.java
new file mode 100644
index 0000000..ec5b160
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ComponentResourcesRenderer.java
@@ -0,0 +1,50 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+/**
+ * Renders {@link ComponentResources} instance, showing the complete id and the class name and the location (if a
+ * location is available, it won't be for pages).
+ */
+public class ComponentResourcesRenderer implements ObjectRenderer<ComponentResources>
+{
+    private final ObjectRenderer masterRenderer;
+
+    public ComponentResourcesRenderer(@Primary ObjectRenderer masterRenderer)
+    {
+        this.masterRenderer = masterRenderer;
+    }
+
+    public void render(ComponentResources object, MarkupWriter writer)
+    {
+        writer.writef("%s (class %s)", object.getCompleteId(), object.getComponentModel().getComponentClassName());
+
+        Location location = object.getLocation();
+
+        if (location != null)
+        {
+            writer.element("br");
+            writer.end();
+
+            masterRenderer.render(location, writer);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/EventContextRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/EventContextRenderer.java
new file mode 100644
index 0000000..22b2dc4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/EventContextRenderer.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+/**
+ * Renders out the values stored inside a {@link EventContext}.
+ */
+public class EventContextRenderer implements ObjectRenderer<EventContext>
+{
+    private final ObjectRenderer masterRenderer;
+
+    public EventContextRenderer(@Primary ObjectRenderer masterRenderer)
+    {
+        this.masterRenderer = masterRenderer;
+    }
+
+
+    public void render(EventContext object, MarkupWriter writer)
+    {
+        int count = object.getCount();
+
+        if (count == 0) return;
+
+        writer.element("ul", "class", "t-data-list");
+
+        for (int i = 0; i < count; i++)
+        {
+            writer.element("li");
+
+            masterRenderer.render(object.get(Object.class, i), writer);
+
+            writer.end();
+        }
+
+        writer.end();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ListRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ListRenderer.java
new file mode 100644
index 0000000..61c7d80
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ListRenderer.java
@@ -0,0 +1,58 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+import java.util.List;
+
+/**
+ * Renders a List, but rendering an unordered list.
+ */
+public class ListRenderer implements ObjectRenderer<List>
+{
+    private final ObjectRenderer masterRenderer;
+
+    public ListRenderer(@Primary ObjectRenderer masterRenderer)
+    {
+        this.masterRenderer = masterRenderer;
+    }
+
+    public void render(List list, MarkupWriter writer)
+    {
+        if (list.isEmpty())
+        {
+            writer.element("em");
+            writer.write("empty list");
+            writer.end();
+            return;
+        }
+
+        writer.element("ul", "class", "t-data-list");
+
+        for (Object element : list)
+        {
+            writer.element("li");
+
+            masterRenderer.render(element, writer);
+
+            writer.end();
+        }
+
+        writer.end();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/LocationRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/LocationRenderer.java
new file mode 100644
index 0000000..77fb8e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/LocationRenderer.java
@@ -0,0 +1,122 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.Element;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.ObjectRenderer;
+
+import java.io.*;
+import java.util.Set;
+
+/**
+ * Responsible for rendering a {@link Location}. It is designed to only perform the full output (which includes a
+ * snippet of the source file) once per render. This requires the use of the "perthread" scope (since the service
+ * tracks, internally, which locations have already been rendered, to avoid repetition).
+ */
+@Scope(PERTHREAD_SCOPE)
+public class LocationRenderer implements ObjectRenderer<Location>
+{
+    private static final int RANGE = 5;
+
+    private final Set<Location> rendered = CollectionFactory.newSet();
+
+    public void render(Location location, MarkupWriter writer)
+    {
+        writer.write(location.toString());
+
+        /** If the full details were already rendered this request, then skip the rest. */
+        if (rendered.contains(location)) return;
+
+        rendered.add(location);
+
+        Resource r = location.getResource();
+        int line = location.getLine();
+
+        // No line number? then nothing more to render.
+
+        if (line <= 0) return;
+
+        if (!r.exists()) return;
+
+
+        int start = line - RANGE;
+        int end = line + RANGE;
+
+        writer.element("table", "class", "t-location-outer");
+
+        LineNumberReader reader = null;
+
+        try
+        {
+            InputStream is = r.openStream();
+            InputStreamReader isr = new InputStreamReader(is);
+            reader = new LineNumberReader(new BufferedReader(isr));
+
+            while (true)
+            {
+                String input = reader.readLine();
+
+                if (input == null) break;
+
+                int current = reader.getLineNumber();
+
+                if (current < start) continue;
+
+                if (current > end) break;
+
+                writer.element("tr");
+
+                writer.element("td", "class", "t-location-line");
+
+                if (line == current) writer.getElement().addClassName("t-location-current");
+
+                writer.write(Integer.toString(current));
+                writer.end();
+
+                Element td = writer.element("td", "class", "t-location-content");
+
+                if (line == current) td.addClassName("t-location-current");
+
+                if (start == current) td.addClassName("t-location-content-first");
+
+                writer.write(input);
+                writer.end();
+
+                writer.end(); // tr
+            }
+
+            reader.close();
+            reader = null;
+        }
+        catch (IOException ex)
+        {
+            writer.write(ex.toString());
+        }
+        finally
+        {
+            InternalUtils.close(reader);
+        }
+
+        writer.end(); // div
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ObjectArrayRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ObjectArrayRenderer.java
new file mode 100644
index 0000000..a59cab6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/ObjectArrayRenderer.java
@@ -0,0 +1,50 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.services.ObjectRenderer;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Renders an Object[] array as an unordered list.
+ */
+public class ObjectArrayRenderer implements ObjectRenderer<Object[]>
+{
+    private final ObjectRenderer masterRenderer;
+
+    public ObjectArrayRenderer(@Primary ObjectRenderer masterRenderer)
+    {
+        this.masterRenderer = masterRenderer;
+    }
+
+    public void render(Object[] array, MarkupWriter writer)
+    {
+        if (array.length == 0)
+        {
+            writer.element("em");
+            writer.write("empty array");
+            writer.end();
+            return;
+        }
+
+        List list = Arrays.asList(array);
+
+        masterRenderer.render(list, writer);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/RequestRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/RequestRenderer.java
new file mode 100644
index 0000000..f15434c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/renderers/RequestRenderer.java
@@ -0,0 +1,146 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.renderers;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.services.ObjectRenderer;
+import org.apache.tapestry.services.Request;
+
+import java.util.List;
+
+public class RequestRenderer implements ObjectRenderer<Request>
+{
+    public void render(Request request, MarkupWriter writer)
+    {
+        writer.element("dl");
+
+        dt(writer, "Context Path");
+
+        writer.element("dd");
+
+        String contextPath = request.getContextPath();
+
+        if (contextPath.equals(""))
+        {
+            writer.element("em");
+            writer.write("none (deployed as root)");
+            writer.end();
+        }
+        else
+        {
+            writer.write(contextPath);
+        }
+        writer.end(); // dd
+
+        dt(writer, "Request Path");
+        dd(writer, request.getPath());
+
+        dt(writer, "Locale");
+        dd(writer, request.getLocale().toString());
+
+        dt(writer, "Secure");
+        dd(writer, Boolean.toString(request.isSecure()));
+
+        dt(writer, "Server Name");
+        dd(writer, request.getServerName());
+
+        writer.end();
+
+        parameters(request, writer);
+        headers(request, writer);
+    }
+
+    private void parameters(Request request, MarkupWriter writer)
+    {
+        List<String> parameterNames = request.getParameterNames();
+
+        if (parameterNames.isEmpty())
+            return;
+
+        section(writer, "Query Parameters");
+
+        writer.element("dl");
+
+        for (String name : parameterNames)
+        {
+            String[] values = request.getParameters(name);
+
+            dt(writer, name);
+
+            writer.element("dd");
+
+            if (values.length > 1)
+            {
+                writer.element("ul");
+
+                for (String value : values)
+                {
+                    writer.element("li");
+                    writer.write(value);
+                    writer.end();
+                }
+
+                writer.end(); // ul
+            }
+            else
+            {
+                writer.write(values[0]);
+            }
+
+            writer.end(); // dd
+        }
+
+        writer.end(); // dl
+    }
+
+    private void dt(MarkupWriter writer, String name)
+    {
+        writer.element("dt");
+        writer.write(name);
+        writer.end();
+    }
+
+    private void dd(MarkupWriter writer, String name)
+    {
+        writer.element("dd");
+        writer.write(name);
+        writer.end();
+    }
+
+    private void section(MarkupWriter writer, String name)
+    {
+        writer.element("div", "class", InternalConstants.OBJECT_RENDER_DIV_SECTION);
+        writer.write(name);
+        writer.end();
+    }
+
+    private void headers(Request request, MarkupWriter writer)
+    {
+        section(writer, "Headers");
+
+        writer.element("dl");
+
+        for (String name : request.getHeaderNames())
+        {
+            dt(writer, name);
+            dd(writer, request.getHeader(name));
+        }
+
+        writer.end(); // dl
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractComponentMethodInvocation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractComponentMethodInvocation.java
new file mode 100644
index 0000000..bd7ac7f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractComponentMethodInvocation.java
@@ -0,0 +1,144 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.services.ComponentMethodAdvice;
+import org.apache.tapestry.services.ComponentMethodInvocation;
+
+public abstract class AbstractComponentMethodInvocation implements ComponentMethodInvocation
+{
+    private final MethodInvocationInfo info;
+
+    private final ComponentResources resources;
+
+    private int adviceIndex = 0;
+
+    private Throwable thrown;
+
+    private Object result;
+
+    public AbstractComponentMethodInvocation(MethodInvocationInfo info, ComponentResources resources)
+    {
+        this.info = info;
+        this.resources = resources;
+    }
+
+    public ComponentResources getComponentResources()
+    {
+        return resources;
+    }
+
+    public String getMethodName()
+    {
+        return info.getMethodName();
+    }
+
+    public Class getResultType()
+    {
+        return info.getResultType();
+    }
+
+    public int getParameterCount()
+    {
+        return info.getParameterCount();
+    }
+
+    public Class getParameterType(int index)
+    {
+        return info.getParameterType(index);
+    }
+
+    /**
+     * This first call is to the first advice.  When we run out of advice, we re-invoke.
+     */
+    public void proceed()
+    {
+        if (adviceIndex >= info.getAdviceCount())
+        {
+            invokeAdvisedMethod();
+            return;
+        }
+
+        ComponentMethodAdvice advice = info.getAdvice(adviceIndex++);
+
+        // When this advice invokes proceed(), we can advance to the next advice,
+        // and then ultimately to the advised method.
+
+        advice.advise(this);
+    }
+
+    /**
+     * Implemented to reinvoke the method on the advised method of the component.
+     */
+    protected abstract void invokeAdvisedMethod();
+
+    public boolean isFail()
+    {
+        return thrown != null;
+    }
+
+    public <T extends Throwable> T getThrown(Class<T> throwableClass)
+    {
+        if (throwableClass.isInstance(thrown))
+            return throwableClass.cast(thrown);
+
+        return null;
+    }
+
+    public void overrideThrown(Exception thrown)
+    {
+        for (Class type : info.getExceptionTypes())
+        {
+            if (type.isInstance(thrown))
+            {
+                this.thrown = thrown;
+                return;
+            }
+        }
+
+        throw new IllegalArgumentException(
+                String.format("Exception class %s is not a declared exception type for method %s().",
+                              thrown.getClass(),
+                              info.getMethodName()));
+    }
+
+    public Object getResult()
+    {
+        return result;
+    }
+
+    public void overrideResult(Object newResult)
+    {
+        if (newResult != null)
+        {
+            Class expectedType = info.getEffectiveResultType();
+
+            if (!expectedType.isInstance(newResult))
+            {
+                throw new IllegalArgumentException(
+                        String.format("Invalid result value (%s) does not match return type %s for method %s.",
+                                      newResult,
+                                      expectedType.getName(),
+                                      info.getMethodName()));
+            }
+        }
+
+        result = newResult;
+        thrown = null;
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractInstantiator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractInstantiator.java
new file mode 100644
index 0000000..f46475d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractInstantiator.java
@@ -0,0 +1,44 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.model.ComponentModel;
+
+/**
+ * Abstract base class for instantiators; for each component, a new subclass is created at runtime.
+ */
+public abstract class AbstractInstantiator implements Instantiator
+{
+    private final ComponentModel model;
+
+    private final String description;
+
+    public AbstractInstantiator(ComponentModel model, String description)
+    {
+        this.model = model;
+        this.description = description;
+    }
+
+    @Override
+    public String toString()
+    {
+        return description;
+    }
+
+    public ComponentModel getModel()
+    {
+        return model;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java
new file mode 100644
index 0000000..5c3e47a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AbstractSessionPersistentFieldStrategy.java
@@ -0,0 +1,130 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Base class for strategies that store their values as keys in the session. Implements a uniform format for the keys,
+ * based on a prefix to identify the particular strategy.
+ */
+public abstract class AbstractSessionPersistentFieldStrategy implements PersistentFieldStrategy
+{
+    private final String prefix;
+
+    private final Request request;
+
+    protected AbstractSessionPersistentFieldStrategy(String prefix, Request request)
+    {
+        this.prefix = prefix;
+        this.request = request;
+    }
+
+    public final Collection<PersistentFieldChange> gatherFieldChanges(String pageName)
+    {
+        Session session = request.getSession(false);
+
+        if (session == null) return Collections.emptyList();
+
+        List<PersistentFieldChange> result = newList();
+
+        String fullPrefix = prefix + pageName + ":";
+
+        for (String name : session.getAttributeNames(fullPrefix))
+        {
+            PersistentFieldChange change = buildChange(name, session.getAttribute(name));
+
+            result.add(change);
+
+            didReadChange(session, name);
+        }
+
+        return result;
+    }
+
+    public void discardChanges(String pageName)
+    {
+        Session session = request.getSession(false);
+
+        if (session == null) return;
+
+        String fullPrefix = prefix + pageName + ":";
+
+        for (String name : session.getAttributeNames(fullPrefix))
+        {
+            session.setAttribute(name, null);
+        }
+    }
+
+    /**
+     * Called after each key is read by {@link #gatherFieldChanges(String)}. This implementation does nothing,
+     * subclasses may override.
+     *
+     * @param session       the session from which a value was just read
+     * @param attributeName the name of the attribute used to read a value
+     */
+    protected void didReadChange(Session session, String attributeName)
+    {
+    }
+
+    private PersistentFieldChange buildChange(String name, Object attribute)
+    {
+        // TODO: Regexp is probably too expensive for what we need here. Maybe an IOC InternalUtils
+        // method for this purpose?
+
+        String[] chunks = name.split(":");
+
+        // Will be empty string for the root component
+        String componentId = chunks[2];
+        String fieldName = chunks[3];
+
+        return new PersistentFieldChangeImpl(componentId, fieldName, attribute);
+    }
+
+    public final void postChange(String pageName, String componentId, String fieldName,
+                                 Object newValue)
+    {
+        notBlank(pageName, "pageName");
+        notBlank(fieldName, "fieldName");
+
+        StringBuilder builder = new StringBuilder(prefix);
+        builder.append(pageName);
+        builder.append(':');
+
+        if (componentId != null) builder.append(componentId);
+
+        builder.append(':');
+        builder.append(fieldName);
+
+        Session session = request.getSession(newValue != null);
+
+        // TAPESTRY-2308: The session will be false when newValue is null and the session
+        // does not already exist.
+
+        if (session != null)
+        {
+            session.setAttribute(builder.toString(), newValue);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionLinkTarget.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionLinkTarget.java
new file mode 100644
index 0000000..3bb3387
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionLinkTarget.java
@@ -0,0 +1,82 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+/**
+ * It represents an invocation target for an action link.
+ */
+public class ActionLinkTarget implements InvocationTarget
+{
+    private final String eventType;
+
+    private final String pageName;
+
+    private final String componentNestedId;
+
+    public ActionLinkTarget(String eventType, String pageName, String componentNestedId)
+    {
+        this.eventType = eventType;
+        this.pageName = pageName;
+        this.componentNestedId = componentNestedId;
+
+    }
+
+    public String getPath()
+    {
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(pageName.toLowerCase());
+
+        boolean hasComponentId = InternalUtils.isNonBlank(componentNestedId);
+
+        if (hasComponentId)
+        {
+
+            builder.append(".");
+            // Already lower case by design.
+            builder.append(componentNestedId);
+        }
+
+        // If no nested component id, then must append the action; the ':' and the action become the
+        // delimiter between the page name and the event context.
+
+        if (!hasComponentId || !eventType.equals(EventConstants.ACTION))
+        {
+            builder.append(":");
+            builder.append(eventType);
+        }
+
+        return builder.toString();
+    }
+
+    public String getEventType()
+    {
+        return eventType;
+    }
+
+    public String getComponentNestedId()
+    {
+        return componentNestedId;
+    }
+
+    public String getPageName()
+    {
+        return pageName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGenerator.java
new file mode 100644
index 0000000..9ffe5b5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGenerator.java
@@ -0,0 +1,27 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+import java.io.IOException;
+
+/**
+ * Used to produce the normal response to an action request: a redirect to a particular page.
+ */
+public interface ActionRenderResponseGenerator
+{
+    void generateResponse(Page page) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGeneratorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGeneratorImpl.java
new file mode 100644
index 0000000..b2c5a66
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ActionRenderResponseGeneratorImpl.java
@@ -0,0 +1,45 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+
+/**
+ * Simply uses the {@link org.apache.tapestry.internal.services.LinkFactory} to generate a link which is then
+ * {@linkplain org.apache.tapestry.services.Response#sendRedirect(org.apache.tapestry.Link)} sent as a redirect}.
+ */
+public class ActionRenderResponseGeneratorImpl implements ActionRenderResponseGenerator
+{
+    private final LinkFactory linkFactory;
+
+    private final Response response;
+
+    public ActionRenderResponseGeneratorImpl(LinkFactory linkFactory, Response response)
+    {
+        this.linkFactory = linkFactory;
+        this.response = response;
+    }
+
+    public void generateResponse(Page page) throws IOException
+    {
+        Link link = linkFactory.createPageLink(page, false);
+
+        response.sendRedirect(link);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java
new file mode 100644
index 0000000..141b7df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentEventRequestHandler.java
@@ -0,0 +1,111 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.*;
+import org.apache.tapestry5.json.JSONObject;
+
+import java.io.IOException;
+
+/**
+ * Similar to {@link ComponentEventRequestHandlerImpl}, but built around the Ajax request cycle, where the action
+ * request sends back an immediate JSON response containing the new content.
+ */
+public class AjaxComponentEventRequestHandler implements ComponentEventRequestHandler
+{
+    private final RequestPageCache cache;
+
+    private final Request request;
+
+    private final PageRenderQueue queue;
+
+    private final ComponentEventResultProcessor resultProcessor;
+
+    private final PageContentTypeAnalyzer pageContentTypeAnalyzer;
+
+    private final Environment environment;
+
+    private final AjaxPartialResponseRenderer partialRenderer;
+
+    public AjaxComponentEventRequestHandler(RequestPageCache cache, Request request, PageRenderQueue queue,
+                                            @Ajax ComponentEventResultProcessor resultProcessor,
+                                            PageContentTypeAnalyzer pageContentTypeAnalyzer, Environment environment,
+                                            AjaxPartialResponseRenderer partialRenderer)
+    {
+        this.cache = cache;
+        this.queue = queue;
+        this.resultProcessor = resultProcessor;
+        this.pageContentTypeAnalyzer = pageContentTypeAnalyzer;
+        this.request = request;
+        this.environment = environment;
+        this.partialRenderer = partialRenderer;
+    }
+
+    public void handle(ComponentEventRequestParameters parameters) throws IOException
+    {
+        Page activePage = cache.get(parameters.getActivePageName());
+
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(resultProcessor);
+
+
+        activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
+                                                        parameters.getPageActivationContext(), callback);
+
+
+        if (callback.isAborted()) return;
+
+        // If we end up doing a partial render, the page render queue service needs to know the
+        // page that will be rendered (for logging purposes, if nothing else).
+
+        queue.setRenderingPage(activePage);
+
+        ContentType contentType = pageContentTypeAnalyzer.findContentType(activePage);
+
+        request.setAttribute(InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME, contentType);
+
+        Page containerPage = cache.get(parameters.getContainingPageName());
+
+        ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
+
+        // In many cases, the triggered element is a Form that needs to be able to
+        // pass its event handler return values to the correct result processor.
+
+        environment.push(ComponentEventResultProcessor.class, resultProcessor);
+
+        element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
+
+        environment.pop(ComponentEventResultProcessor.class);
+
+        if (queue.isPartialRenderInitialized())
+        {
+            partialRenderer.renderPartialPageMarkup();
+            return;
+        }
+
+        if (callback.isAborted()) return;
+
+        // Send an empty JSON reply if no value was returned from the component event handler method.
+
+        JSONObject reply = new JSONObject();
+
+        resultProcessor.processResultValue(reply);
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
new file mode 100644
index 0000000..e1ba236
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessor.java
@@ -0,0 +1,57 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * Performs a partial page render based on a root component.
+ */
+public class AjaxComponentInstanceEventResultProcessor implements ComponentEventResultProcessor<Component>
+{
+    private final RequestPageCache cache;
+
+    private final PageRenderQueue pageRenderQueue;
+
+    public AjaxComponentInstanceEventResultProcessor(RequestPageCache cache, PageRenderQueue pageRenderQueue)
+    {
+        this.cache = cache;
+        this.pageRenderQueue = pageRenderQueue;
+    }
+
+    public void processResultValue(Component value) throws IOException
+    {
+        ComponentResources resources = value.getComponentResources();
+
+        String pageName = resources.getPageName();
+
+        Page page = cache.get(pageName);
+
+        String nestedId = resources.getNestedId();
+
+        // The user may return a complete page instance, which isn't really a partial render, I guess.
+        // Depends on the structure of the page returned.
+
+        RenderCommand command = nestedId == null ? page.getRootElement() : page.getComponentElementByNestedId(nestedId);
+
+        pageRenderQueue.initializeForPartialPageRender(command);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
new file mode 100644
index 0000000..512085d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxFilter.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+/**
+ * A filter that intercepts Ajax-oriented requests, thos that originate on the client-side using XmlHttpRequest. In
+ * these cases, the action processing occurs normally, but the response is quite different.
+ */
+public class AjaxFilter implements ComponentEventRequestFilter
+{
+    private final Request request;
+
+    private final ComponentEventRequestHandler ajaxHandler;
+
+    public AjaxFilter(Request request, @Ajax ComponentEventRequestHandler ajaxHandler)
+    {
+        this.request = request;
+        this.ajaxHandler = ajaxHandler;
+    }
+
+    public void handle(ComponentEventRequestParameters parameters, ComponentEventRequestHandler handler)
+            throws IOException
+    {
+        ComponentEventRequestHandler next = request.isXHR() ? ajaxHandler : handler;
+
+        next.handle(parameters);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRenderer.java
new file mode 100644
index 0000000..3a19ec6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRenderer.java
@@ -0,0 +1,35 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.io.IOException;
+
+/**
+ * Used to render portions of a page as part of an {@linkplain AjaxComponentEventRequestHandler Ajax request}.    This
+ * encapsulates rendering of the partial response and then the construction of a {@linkplain
+ * org.apache.tapestry5.json.JSONObject JSON reply}. Works with the pipeline defined by the {@link
+ * org.apache.tapestry.services.PartialMarkupRenderer} service.
+ *
+ * @see org.apache.tapestry.internal.services.PageRenderQueue
+ */
+public interface AjaxPartialResponseRenderer
+{
+    /**
+     * Used to render a partial response as part of an Ajax action request. A call to {@link
+     * org.apache.tapestry.internal.services.PageRenderQueue#initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)}
+     * should precede this call.
+     */
+    void renderPartialPageMarkup() throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRendererImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRendererImpl.java
new file mode 100644
index 0000000..51ae903
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxPartialResponseRendererImpl.java
@@ -0,0 +1,75 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.PartialMarkupRenderer;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry5.json.JSONObject;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class AjaxPartialResponseRendererImpl implements AjaxPartialResponseRenderer
+{
+    private final MarkupWriterFactory factory;
+
+    private final Request request;
+
+    private final Response response;
+
+    private final PartialMarkupRenderer partialMarkupRenderer;
+
+    public AjaxPartialResponseRendererImpl(MarkupWriterFactory factory, Request request,
+                                           Response response, PartialMarkupRenderer partialMarkupRenderer)
+    {
+        this.factory = factory;
+        this.request = request;
+        this.response = response;
+        this.partialMarkupRenderer = partialMarkupRenderer;
+    }
+
+    public void renderPartialPageMarkup() throws IOException
+    {
+        // This is a complex area as we are trying to keep public and private services properly
+        // seperated, and trying to keep stateless and stateful (i.e., perthread scope) services
+        // seperated. So we inform the stateful queue service what it needs to do here ...
+
+        ContentType pageContentType = (ContentType) request.getAttribute(
+                InternalConstants.CONTENT_TYPE_ATTRIBUTE_NAME);
+        String charset = pageContentType.getParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER);
+
+        ContentType contentType = new ContentType(InternalConstants.JSON_MIME_TYPE);
+        contentType.setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, charset);
+
+        MarkupWriter writer = factory.newMarkupWriter(pageContentType);
+
+        JSONObject reply = new JSONObject();
+
+        // ... and here, the pipeline eventually reaches the PRQ to let it render the root render command.
+
+        partialMarkupRenderer.renderMarkup(writer, reply);
+
+        PrintWriter pw = response.getPrintWriter(contentType.toString());
+
+        pw.print(reply);
+
+        pw.flush();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasImpl.java
new file mode 100644
index 0000000..0f184a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasImpl.java
@@ -0,0 +1,79 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.Alias;
+import org.apache.tapestry.services.AliasManager;
+
+import java.util.Map;
+
+public class AliasImpl implements Alias, ObjectProvider
+{
+    // Derived from the managers when first needed
+
+    private final Map<Class, Object> properties = CollectionFactory.newMap();
+
+    private final String mode;
+
+    private boolean initialized = false;
+
+    private AliasManager masterManager;
+
+    private AliasManager overridesManager;
+
+    public AliasImpl(AliasManager masterManager, String mode, AliasManager overridesManager)
+    {
+        this.masterManager = masterManager;
+        this.mode = mode;
+        this.overridesManager = overridesManager;
+    }
+
+    public ObjectProvider getObjectProvider()
+    {
+        return this;
+    }
+
+    private synchronized void initialize()
+    {
+        if (initialized) return;
+
+        properties.putAll(masterManager.getAliasesForMode(mode));
+        properties.putAll(overridesManager.getAliasesForMode(mode));
+
+        masterManager = null;
+        overridesManager = null;
+
+        initialized = true;
+    }
+
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
+                         ObjectLocator locator)
+    {
+        initialize();
+
+        Object object = properties.get(objectType);
+
+        // Let another provider handle this (probably the default object provider)
+        if (object == null) return null;
+
+        // A ClassCastException should never occur.
+
+        return objectType.cast(object);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasManagerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasManagerImpl.java
new file mode 100644
index 0000000..a562f69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AliasManagerImpl.java
@@ -0,0 +1,76 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.AliasContribution;
+import org.apache.tapestry.services.AliasManager;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class AliasManagerImpl implements AliasManager
+{
+    private final Logger logger;
+
+    private final Collection<AliasContribution> contributions;
+
+    public AliasManagerImpl(Logger logger, Collection<AliasContribution> contributions)
+    {
+        this.logger = logger;
+        this.contributions = contributions;
+    }
+
+    public Map<Class, Object> getAliasesForMode(String mode)
+    {
+        Map<Class, Object> general = buildMapForMode("");
+        Map<Class, Object> specific = buildMapForMode(mode);
+
+        // Anything in specific overrides anything in general
+
+        general.putAll(specific);
+
+        return general;
+    }
+
+    private Map<Class, Object> buildMapForMode(String mode)
+    {
+        Map<Class, Object> result = CollectionFactory.newMap();
+
+        for (AliasContribution ic : contributions)
+        {
+            if (!ic.getMode().equalsIgnoreCase(mode)) continue;
+
+            Class contributionType = ic.getContributionType();
+
+            Object existing = result.get(contributionType);
+
+            if (existing != null)
+            {
+                logger.error(ServicesMessages.duplicateContribution(
+                        ic.getObject(),
+                        contributionType,
+                        existing));
+                continue;
+            }
+
+            result.put(contributionType, ic.getObject());
+        }
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzer.java
new file mode 100644
index 0000000..d229d76
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzer.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.beaneditor.DataType;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.services.DataTypeAnalyzer;
+
+/**
+ * Checks for the {@link DataType} annotation, returning its value if present.
+ */
+public class AnnotationDataTypeAnalyzer implements DataTypeAnalyzer
+{
+    public String identifyDataType(PropertyAdapter adapter)
+    {
+        DataType annotation = adapter.getAnnotation(DataType.class);
+
+        return annotation == null ? null : annotation.value();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationGlobalsImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationGlobalsImpl.java
new file mode 100644
index 0000000..5c709e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationGlobalsImpl.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Context;
+import org.apache.tapestry5.services.ApplicationGlobals;
+
+import javax.servlet.ServletContext;
+
+public class ApplicationGlobalsImpl implements ApplicationGlobals
+{
+    private ServletContext servletContext;
+
+    private Context context;
+
+    public void storeServletContext(ServletContext context)
+    {
+        servletContext = context;
+    }
+
+    public ServletContext getServletContext()
+    {
+        return servletContext;
+    }
+
+    public Context getContext()
+    {
+        return context;
+    }
+
+    public void storeContext(Context context)
+    {
+        this.context = context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStateManagerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStateManagerImpl.java
new file mode 100644
index 0000000..40b0479
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStateManagerImpl.java
@@ -0,0 +1,146 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.ObjectLocator;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import org.apache.tapestry.services.*;
+
+import java.util.Map;
+
+public class ApplicationStateManagerImpl implements ApplicationStateManager
+{
+    static final String DEFAULT_STRATEGY = "session";
+
+    static class ApplicationStateAdapter<T>
+    {
+        private final Class<T> asoClass;
+
+        private final ApplicationStatePersistenceStrategy strategy;
+
+        private final ApplicationStateCreator<T> creator;
+
+        ApplicationStateAdapter(Class<T> asoClass, ApplicationStatePersistenceStrategy strategy,
+                                ApplicationStateCreator<T> creator)
+        {
+            this.asoClass = asoClass;
+            this.strategy = strategy;
+            this.creator = creator;
+        }
+
+        T getOrCreate()
+        {
+            return strategy.get(asoClass, creator);
+        }
+
+        void set(T aso)
+        {
+            strategy.set(asoClass, aso);
+        }
+
+        boolean exists()
+        {
+            return strategy.exists(asoClass);
+        }
+    }
+
+    /**
+     * The map will be extended periodically as new ASOs, not in the configuration, are encountered. Thut is is thread
+     * safe.
+     */
+    private final Map<Class, ApplicationStateAdapter> classToAdapter = newConcurrentMap();
+
+    private final ApplicationStatePersistenceStrategySource source;
+
+    private final ObjectLocator locator;
+
+    @SuppressWarnings("unchecked")
+    public ApplicationStateManagerImpl(Map<Class, ApplicationStateContribution> configuration,
+                                       ApplicationStatePersistenceStrategySource source, ObjectLocator locator)
+    {
+        this.source = source;
+        this.locator = locator;
+
+        for (Class asoClass : configuration.keySet())
+        {
+            ApplicationStateContribution contribution = configuration.get(asoClass);
+
+            ApplicationStateAdapter adapter = newAdapter(asoClass, contribution.getStrategy(),
+                                                         contribution.getCreator());
+
+            classToAdapter.put(asoClass, adapter);
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> ApplicationStateAdapter<T> newAdapter(final Class<T> asoClass, String strategyName,
+                                                      ApplicationStateCreator<T> creator)
+    {
+        if (creator == null)
+        {
+            creator = new ApplicationStateCreator<T>()
+            {
+                public T create()
+                {
+                    return locator.autobuild(asoClass);
+                }
+            };
+        }
+
+        ApplicationStatePersistenceStrategy strategy = source.get(strategyName);
+
+        return new ApplicationStateAdapter(asoClass, strategy, creator);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> ApplicationStateAdapter<T> getAdapter(Class<T> asoClass)
+    {
+        ApplicationStateAdapter<T> result = classToAdapter.get(asoClass);
+
+        // Not found is completely OK, we'll define it on the fly.
+
+        if (result == null)
+        {
+            result = newAdapter(asoClass, DEFAULT_STRATEGY, null);
+            classToAdapter.put(asoClass, result);
+        }
+
+        return result;
+    }
+
+    public <T> T get(Class<T> asoClass)
+    {
+        return getAdapter(asoClass).getOrCreate();
+    }
+
+    public <T> T getIfExists(Class<T> asoClass)
+    {
+        ApplicationStateAdapter<T> adapter = getAdapter(asoClass);
+
+        return adapter.exists() ? adapter.getOrCreate() : null;
+    }
+
+    public <T> void set(Class<T> asoClass, T aso)
+    {
+        getAdapter(asoClass).set(aso);
+    }
+
+    public <T> boolean exists(Class<T> asoClass)
+    {
+        return getAdapter(asoClass).exists();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImpl.java
new file mode 100644
index 0000000..93411ea
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImpl.java
@@ -0,0 +1,43 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategy;
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategySource;
+
+import java.util.Map;
+
+public class ApplicationStatePersistenceStrategySourceImpl implements
+        ApplicationStatePersistenceStrategySource
+{
+    private final Map<String, ApplicationStatePersistenceStrategy> configuration;
+
+    public ApplicationStatePersistenceStrategySourceImpl(Map<String, ApplicationStatePersistenceStrategy> configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public ApplicationStatePersistenceStrategy get(String name)
+    {
+        ApplicationStatePersistenceStrategy result = configuration.get(name);
+
+        if (result == null)
+            throw new RuntimeException(ServicesMessages.missingApplicationStatePersistenceStrategy(
+                    name,
+                    configuration.keySet()));
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetDispatcher.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetDispatcher.java
new file mode 100644
index 0000000..851447e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetDispatcher.java
@@ -0,0 +1,159 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+import org.apache.tapestry.services.Dispatcher;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Recognizes requests where the path begins with "/asset/" and delivers the content therein as a bytestream. Also
+ * handles requests that are simply polling for a change to the file.
+ *
+ * @see ResourceStreamer
+ * @see ClasspathAssetAliasManager
+ * @see ResourceCache
+ */
+public class AssetDispatcher implements Dispatcher
+{
+    private final ResourceStreamer streamer;
+
+    private final ClasspathAssetAliasManager aliasManager;
+
+    private final ResourceCache resourceCache;
+
+    static final String IF_MODIFIED_SINCE_HEADER = "If-Modified-Since";
+
+    public AssetDispatcher(ResourceStreamer streamer, ClasspathAssetAliasManager aliasManager,
+                           ResourceCache resourceCache)
+    {
+        this.streamer = streamer;
+        this.aliasManager = aliasManager;
+        this.resourceCache = resourceCache;
+    }
+
+    public boolean dispatch(Request request, Response response) throws IOException
+    {
+        String path = request.getPath();
+
+        // Remember that the request path does not include the context path, so we can simply start
+        // looking for the asset path prefix right off the bat.
+
+        if (!path.startsWith(RequestConstants.ASSET_PATH_PREFIX)) return false;
+
+        // ClassLoaders like their paths to start with a leading slash.
+
+        String resourcePath = aliasManager.toResourcePath(path);
+
+        Resource resource = findResourceAndValidateDigest(response, resourcePath);
+
+        if (resource == null) return true;
+
+        if (!resource.exists())
+        {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND, ServicesMessages
+                    .assetDoesNotExist(resource));
+            return true;
+        }
+
+        long ifModifiedSince = 0;
+
+        try
+        {
+            ifModifiedSince = request.getDateHeader(IF_MODIFIED_SINCE_HEADER);
+        }
+        catch (IllegalArgumentException ex)
+        {
+            // Simulate the header being missing if it is poorly formatted.
+
+            ifModifiedSince = -1;
+        }
+
+        if (ifModifiedSince > 0)
+        {
+            long modified = resourceCache.getTimeModified(resource);
+
+            if (ifModifiedSince >= modified)
+            {
+                response.sendError(HttpServletResponse.SC_NOT_MODIFIED, "");
+                return true;
+            }
+        }
+
+        streamer.streamResource(resource);
+
+        return true;
+    }
+
+    /**
+     * @param response     used to send errors back to the client
+     * @param resourcePath the path to the requested resource, from the request
+     * @return the resource for the path, with the digest stripped out of the URL, or null if the digest is invalid (and
+     *         an error has been sent back to the client)
+     * @throws IOException
+     */
+    private Resource findResourceAndValidateDigest(Response response, String resourcePath) throws IOException
+    {
+        Resource resource = new ClasspathResource(resourcePath);
+
+        if (!resourceCache.requiresDigest(resource)) return resource;
+
+        String file = resource.getFile();
+
+        // Somehow this code got real ugly, but it's all about preventing NPEs when a resource
+        // that should have a digest doesn't.
+
+        boolean valid = false;
+        Resource result = resource;
+
+        int lastdotx = file.lastIndexOf('.');
+
+        if (lastdotx > 0)
+        {
+            int prevdotx = file.lastIndexOf('.', lastdotx - 1);
+
+            if (prevdotx > 0)
+            {
+
+                String requestDigest = file.substring(prevdotx + 1, lastdotx);
+
+                // Strip the digest out of the file name.
+
+                String realFile = file.substring(0, prevdotx) + file.substring(lastdotx);
+
+                result = resource.forFile(realFile);
+
+                String actualDigest = resourceCache.getDigest(result);
+
+                valid = requestDigest.equals(actualDigest);
+            }
+        }
+
+        if (!valid)
+        {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN, ServicesMessages
+                    .wrongAssetDigest(result));
+            result = null;
+        }
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
new file mode 100644
index 0000000..dadd70a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetInjectionProvider.java
@@ -0,0 +1,70 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+
+import static java.lang.String.format;
+
+/**
+ * Performs injection of assets, based on the presence of the {@link Path} annotation. This is more useful than the
+ * general {@link AssetObjectProvider}, becase relative assets are supported.
+ */
+public class AssetInjectionProvider implements InjectionProvider
+{
+    private final SymbolSource symbolSource;
+
+    private final AssetSource assetSource;
+
+    public AssetInjectionProvider(SymbolSource symbolSource, AssetSource assetSource)
+    {
+        this.symbolSource = symbolSource;
+        this.assetSource = assetSource;
+    }
+
+    public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                                    ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        Path path = transformation.getFieldAnnotation(fieldName, Path.class);
+
+        if (path == null) return false;
+
+        String expanded = symbolSource.expandSymbols(path.value());
+
+        String sourceFieldName = transformation.addInjectedField(AssetSource.class, "assetSource", assetSource);
+
+        String baseResourceFieldName = transformation.addInjectedField(Resource.class, "baseResource",
+                                                                       componentModel.getBaseResource());
+
+        String resourcesFieldName = transformation.getResourcesFieldName();
+
+        String statement = format("%s = (%s) %s.getAsset(%s, \"%s\", %s.getLocale());", fieldName, fieldType.getName(),
+                                  sourceFieldName, baseResourceFieldName, expanded, resourcesFieldName);
+
+        transformation.extendConstructor(statement);
+
+        transformation.makeReadOnly(fieldName);
+
+        return true;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetObjectProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetObjectProvider.java
new file mode 100644
index 0000000..ea2ab0f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetObjectProvider.java
@@ -0,0 +1,70 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.Core;
+
+/**
+ * Exposes assets (in the current locale). The Inject annotation must be supplemented by a {@link Path} annotation, to
+ * identify what asset to be injected.
+ */
+public class AssetObjectProvider implements ObjectProvider
+{
+    private final AssetSource source;
+
+    private final TypeCoercer typeCoercer;
+
+    private final SymbolSource symbolSource;
+
+    public AssetObjectProvider(@Core AssetSource source,
+
+                               @Builtin TypeCoercer typeCoercer,
+
+                               @Builtin SymbolSource symbolSource)
+    {
+        this.source = source;
+        this.typeCoercer = typeCoercer;
+        this.symbolSource = symbolSource;
+    }
+
+    /**
+     * Provides the asset. If the expression does not identify an asset domain, with a prefix, it is assumed to be a
+     * path on the classpath, relative to the root of the classpath.
+     *
+     * @param objectType the type of object (which must be Object or Asset)
+     * @param locator    not used
+     */
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+    {
+        Path path = annotationProvider.getAnnotation(Path.class);
+
+        if (path == null) return null;
+
+        String expanded = symbolSource.expandSymbols(path.value());
+
+        Asset asset = source.getAsset(null, expanded, null);
+
+        return typeCoercer.coerce(asset, objectType);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetSourceImpl.java
new file mode 100644
index 0000000..92a3cfd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AssetSourceImpl.java
@@ -0,0 +1,133 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.AssetSource;
+
+import java.util.Locale;
+import java.util.Map;
+
+public class AssetSourceImpl implements AssetSource
+{
+    private static final String CLASSPATH = "classpath";
+
+    private final StrategyRegistry<AssetFactory> registry;
+
+    private final ThreadLocale threadLocale;
+
+    private final Map<String, Resource> prefixToRootResource = CollectionFactory.newMap();
+
+    private final Map<Resource, Asset> cache = CollectionFactory.newConcurrentMap();
+
+    public AssetSourceImpl(ThreadLocale threadLocale,
+
+                           Map<String, AssetFactory> configuration)
+    {
+        this.threadLocale = threadLocale;
+
+        Map<Class, AssetFactory> byResourceClass = CollectionFactory.newMap();
+
+        for (Map.Entry<String, AssetFactory> e : configuration.entrySet())
+        {
+            String prefix = e.getKey();
+            AssetFactory factory = e.getValue();
+
+            Resource rootResource = factory.getRootResource();
+
+            byResourceClass.put(rootResource.getClass(), factory);
+
+            prefixToRootResource.put(prefix, rootResource);
+        }
+
+        registry = StrategyRegistry.newInstance(AssetFactory.class, byResourceClass);
+    }
+
+    public Asset getClasspathAsset(String path)
+    {
+        return getClasspathAsset(path, null);
+    }
+
+    public Asset getClasspathAsset(String path, Locale locale)
+    {
+        return getAsset(null, path, locale);
+    }
+
+    public Asset getAsset(Resource baseResource, String path, Locale locale)
+    {
+        Defense.notBlank(path, "path");
+
+        if (baseResource == null) baseResource = prefixToRootResource.get(CLASSPATH);
+
+        if (locale == null) locale = threadLocale.getLocale();
+
+        int colonx = path.indexOf(':');
+
+        if (colonx < 0) return findRelativeAsset(baseResource, path, locale);
+
+        String prefix = path.substring(0, colonx);
+
+        Resource rootResource = prefixToRootResource.get(prefix);
+
+        if (rootResource == null)
+            throw new IllegalArgumentException(ServicesMessages.unknownAssetPrefix(path));
+
+        return findRelativeAsset(rootResource, path.substring(colonx + 1), locale);
+    }
+
+    private Asset findRelativeAsset(Resource baseResource, String path, Locale locale)
+    {
+        Resource unlocalized = baseResource.forFile(path);
+        Resource localized = unlocalized.forLocale(locale);
+
+        if (localized == null)
+            throw new RuntimeException(ServicesMessages.assetDoesNotExist(unlocalized));
+
+        return getAssetForResource(localized);
+    }
+
+    private Asset getAssetForResource(Resource resource)
+    {
+        Asset result = cache.get(resource);
+
+        if (result == null)
+        {
+            result = createAssetFromResource(resource);
+            cache.put(resource, result);
+        }
+
+        return result;
+    }
+
+    private Asset createAssetFromResource(Resource resource)
+    {
+        // The class of the resource is derived from the class of the base resource.
+        // So we can then use the class of the resource as a key to locate the correct asset
+        // factory.
+
+        Class resourceClass = resource.getClass();
+
+        AssetFactory factory = registry.get(resourceClass);
+
+        return factory.createAsset(resource);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AttributeExpansionBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AttributeExpansionBinding.java
new file mode 100644
index 0000000..de79b24
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AttributeExpansionBinding.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.internal.bindings.AbstractBinding;
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Wraps a {@link StringProvider} as a read-only {@link Binding}.
+ */
+public class AttributeExpansionBinding extends AbstractBinding
+{
+    private final StringProvider provider;
+
+    public AttributeExpansionBinding(StringProvider provider, Location location)
+    {
+        super(location);
+
+        this.provider = provider;
+    }
+
+    public Object get()
+    {
+        return provider.provideString();
+    }
+
+    /**
+     * Returns false. Expansions reference properties that may change arbitrarily.
+     */
+    @Override
+    public boolean isInvariant()
+    {
+        return false;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
new file mode 100644
index 0000000..3b504f5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BasePropertyConduit.java
@@ -0,0 +1,61 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Base class for {@link org.apache.tapestry.PropertyConduit} instances created by the {@link
+ * org.apache.tapestry.services.PropertyConduitSource}.
+ */
+public abstract class BasePropertyConduit implements PropertyConduit
+{
+    private final Class propertyType;
+
+    private final AnnotationProvider annotationProvider;
+
+    private final String description;
+
+    public BasePropertyConduit(Class propertyType, AnnotationProvider annotationProvider, String description)
+    {
+        Defense.notNull(propertyType, "propertyType");
+        Defense.notNull(annotationProvider, "annotationProvider");
+        Defense.notBlank(description, "description");
+
+        this.propertyType = propertyType;
+        this.annotationProvider = annotationProvider;
+        this.description = description;
+    }
+
+    @Override
+    public String toString()
+    {
+        return description;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return annotationProvider.getAnnotation(annotationClass);
+    }
+
+    public Class getPropertyType()
+    {
+        return propertyType;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BaseURLSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BaseURLSourceImpl.java
new file mode 100644
index 0000000..3dbf8d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BaseURLSourceImpl.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.BaseURLSource;
+import org.apache.tapestry.services.Request;
+
+public class BaseURLSourceImpl implements BaseURLSource
+{
+    private final Request request;
+
+    public BaseURLSourceImpl(Request request)
+    {
+        this.request = request;
+    }
+
+    public String getBaseURL(boolean secure)
+    {
+        return String.format("%s://%s", secure ? "https" : "http", request.getServerName());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockOverrideSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockOverrideSourceImpl.java
new file mode 100644
index 0000000..b8a4e11
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockOverrideSourceImpl.java
@@ -0,0 +1,71 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.BeanBlockContribution;
+import org.apache.tapestry.services.BeanBlockOverrideSource;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class BeanBlockOverrideSourceImpl implements BeanBlockOverrideSource
+{
+    private final RequestPageCache pageCache;
+
+    private final Map<String, BeanBlockContribution> display = CollectionFactory.newCaseInsensitiveMap();
+
+    private final Map<String, BeanBlockContribution> edit = CollectionFactory.newCaseInsensitiveMap();
+
+    public BeanBlockOverrideSourceImpl(RequestPageCache pageCache,
+                                       Collection<BeanBlockContribution> configuration)
+    {
+        this.pageCache = pageCache;
+
+        for (BeanBlockContribution contribution : configuration)
+        {
+            Map<String, BeanBlockContribution> map = contribution.isEdit() ? edit : display;
+
+            map.put(contribution.getDataType(), contribution);
+        }
+    }
+
+    public boolean hasDisplayBlock(String datatype)
+    {
+        return display.containsKey(datatype);
+    }
+
+    public Block getDisplayBlock(String datatype)
+    {
+        return toBlock(display.get(datatype));
+    }
+
+    private Block toBlock(BeanBlockContribution contribution)
+    {
+        if (contribution == null) return null;
+
+        Page page = pageCache.get(contribution.getPageName());
+
+        return page.getRootElement().getBlock(contribution.getBlockId());
+    }
+
+    public Block getEditBlock(String datatype)
+    {
+        return toBlock(edit.get(datatype));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockSourceImpl.java
new file mode 100644
index 0000000..b7761ce
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanBlockSourceImpl.java
@@ -0,0 +1,69 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.services.BeanBlockContribution;
+import org.apache.tapestry.services.BeanBlockOverrideSource;
+import org.apache.tapestry.services.BeanBlockSource;
+
+import java.util.Collection;
+
+public class BeanBlockSourceImpl implements BeanBlockSource
+{
+    // This is checked before masterSource
+    private final BeanBlockOverrideSource overrideSource;
+
+    private final BeanBlockOverrideSource masterSource;
+
+    public BeanBlockSourceImpl(RequestPageCache pageCache,
+                               BeanBlockOverrideSource overrideSource, Collection<BeanBlockContribution> configuration)
+    {
+        this.overrideSource = overrideSource;
+        masterSource = new BeanBlockOverrideSourceImpl(pageCache, configuration);
+    }
+
+    public boolean hasDisplayBlock(String datatype)
+    {
+        return overrideSource.hasDisplayBlock(datatype) || masterSource.hasDisplayBlock(datatype);
+    }
+
+    public Block getDisplayBlock(String datatype)
+    {
+        Block result = overrideSource.getDisplayBlock(datatype);
+
+        if (result == null)
+            result = masterSource.getDisplayBlock(datatype);
+
+        if (result == null)
+            throw new RuntimeException(ServicesMessages.noDisplayForDataType(datatype));
+
+        return result;
+    }
+
+    public Block getEditBlock(String datatype)
+    {
+        Block result = overrideSource.getEditBlock(datatype);
+
+        if (result == null)
+            result = masterSource.getEditBlock(datatype);
+
+        if (result == null)
+            throw new RuntimeException(ServicesMessages.noEditForDataType(datatype));
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java
new file mode 100644
index 0000000..0c805ff
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BeanModelSourceImpl.java
@@ -0,0 +1,132 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.NonVisual;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.beaneditor.BeanModelImpl;
+import org.apache.tapestry.ioc.LoggerSource;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Primary;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.services.ComponentLayer;
+import org.apache.tapestry.services.DataTypeAnalyzer;
+import org.apache.tapestry.services.PropertyConduitSource;
+
+import java.util.List;
+import java.util.Map;
+
+public class BeanModelSourceImpl implements BeanModelSource
+{
+    private final LoggerSource loggerSource;
+
+    private final TypeCoercer typeCoercer;
+
+    private final PropertyAccess propertyAccess;
+
+    private final PropertyConduitSource propertyConduitSource;
+
+    private final ClassFactory classFactory;
+
+    private final DataTypeAnalyzer dataTypeAnalyzer;
+
+    private final ObjectLocator locator;
+
+    public BeanModelSourceImpl(LoggerSource loggerSource, TypeCoercer typeCoercer, PropertyAccess propertyAccess,
+                               PropertyConduitSource propertyConduitSource, @ComponentLayer ClassFactory classFactory,
+                               @Primary DataTypeAnalyzer dataTypeAnalyzer, ObjectLocator locator)
+    {
+        this.loggerSource = loggerSource;
+        this.typeCoercer = typeCoercer;
+        this.propertyAccess = propertyAccess;
+        this.propertyConduitSource = propertyConduitSource;
+        this.classFactory = classFactory;
+        this.dataTypeAnalyzer = dataTypeAnalyzer;
+        this.locator = locator;
+    }
+
+    public <T> BeanModel<T> create(Class<T> beanClass, boolean filterReadOnlyProperties, ComponentResources resources)
+    {
+        Defense.notNull(beanClass, "beanClass");
+        Defense.notNull(resources, "resources");
+
+        Messages messages = resources.getMessages();
+
+        ClassPropertyAdapter adapter = propertyAccess.getAdapter(beanClass);
+
+        final BeanModel<T> model = new BeanModelImpl<T>(beanClass, propertyConduitSource, typeCoercer, messages,
+                                                        locator);
+
+        List<String> propertyNames = CollectionFactory.newList();
+
+        Map<String, Runnable> worksheet = CollectionFactory.newMap();
+
+        for (final String propertyName : adapter.getPropertyNames())
+        {
+            PropertyAdapter pa = adapter.getPropertyAdapter(propertyName);
+
+            if (!pa.isRead()) continue;
+
+            if (pa.getAnnotation(NonVisual.class) != null) continue;
+
+            if (filterReadOnlyProperties && !pa.isUpdate()) continue;
+
+            final String dataType = dataTypeAnalyzer.identifyDataType(pa);
+
+            // If an unregistered type, then ignore the property.
+
+            if (dataType == null) continue;
+
+            propertyNames.add(propertyName);
+
+            // We need to defer execution of this; we want to add them in proper order, not
+            // alphabetical order.
+
+            Runnable worker = new Runnable()
+            {
+                public void run()
+                {
+                    model.add(propertyName).dataType(dataType);
+                }
+            };
+
+            worksheet.put(propertyName, worker);
+        }
+
+        // Determine the correct order to add the properties.
+
+        List<String> orderedNames = TapestryInternalUtils.orderProperties(loggerSource
+                .getLogger(beanClass), adapter, classFactory, propertyNames);
+
+        for (String propertyName : orderedNames)
+        {
+            Runnable r = worksheet.get(propertyName);
+
+            // This actually adds the property to the model, but we're doing it
+            // in orderedNames order, not propertyNames order (which is alphabetical).
+            // The default ordering comes from method ordering within the class.
+
+            r.run();
+        }
+
+        return model;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BindingSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BindingSourceImpl.java
new file mode 100644
index 0000000..0df8db5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BindingSourceImpl.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.BindingSource;
+
+import java.util.Map;
+
+public class BindingSourceImpl implements BindingSource
+{
+    private final Map<String, BindingFactory> factories;
+
+    public BindingSourceImpl(Map<String, BindingFactory> factories)
+    {
+        this.factories = factories;
+    }
+
+    public Binding newBinding(String description, ComponentResources container,
+                              String defaultPrefix, String expression)
+    {
+        return newBinding(description, container, container, defaultPrefix, expression, null);
+    }
+
+    public Binding newBinding(String description, ComponentResources container,
+                              ComponentResources component, String defaultPrefix, String expression, Location location)
+    {
+        Defense.notBlank(description, "description");
+        Defense.notNull(container, "container");
+        Defense.notNull(component, "component");
+        Defense.notBlank(defaultPrefix, "defaultPrefix");
+
+        if (InternalUtils.isBlank(expression))
+            throw new TapestryException(ServicesMessages.emptyBinding(description), location, null);
+
+        // Location might be null
+
+        String subexpression = expression;
+        int colonx = expression.indexOf(':');
+
+        BindingFactory factory = null;
+
+        if (colonx > 0)
+        {
+            String prefix = expression.substring(0, colonx);
+
+            factory = factories.get(prefix);
+            if (factory != null)
+                subexpression = expression.substring(colonx + 1);
+        }
+
+        if (factory == null)
+            factory = factories.get(defaultPrefix);
+
+        // And if that's null, what then? We assume that the default prefix is a valid prefix,
+        // or we'll get an NPE below and report it like any other error.
+
+        try
+        {
+            return factory.newBinding(description, container, component, subexpression, location);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ServicesMessages.bindingSourceFailure(expression, ex),
+                                        location, ex);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java
new file mode 100644
index 0000000..30d39c5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/BlockInjectionProvider.java
@@ -0,0 +1,69 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Id;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Identifies fields of type {@link Block} that have the {@link Inject} annotation and converts them into read-only
+ * fields containing the injected Block from the template. The annotation's value is the id of the block to inject; if
+ * omitted, the block id is deduced from the field id.
+ * <p/>
+ * Must be scheduled before {@link DefaultInjectionProvider} because it uses the same annotation, Inject, with a
+ * different interpretation.
+ */
+public class BlockInjectionProvider implements InjectionProvider
+{
+
+    public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                                    ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        if (!fieldType.equals(Block.class)) return false;
+
+        String resourcesFieldName = transformation.getResourcesFieldName();
+
+        Id annotation = transformation.getFieldAnnotation(fieldName, Id.class);
+
+        String blockId = getBlockId(fieldName, annotation);
+
+        transformation.makeReadOnly(fieldName);
+
+        String body = String.format(
+                "%s = %s.getBlock(\"%s\");",
+                fieldName,
+                resourcesFieldName,
+                blockId);
+
+        transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
+
+        return true; // claim the field
+    }
+
+    private String getBlockId(String fieldName, Id annotation)
+    {
+        if (annotation != null) return annotation.value();
+
+        return InternalUtils.stripMemberPrefix(fieldName);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CheckForUpdatesFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CheckForUpdatesFilter.java
new file mode 100644
index 0000000..2492d82
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CheckForUpdatesFilter.java
@@ -0,0 +1,113 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.ioc.internal.util.ConcurrentBarrier;
+import org.apache.tapestry.ioc.internal.util.Invokable;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.RequestFilter;
+import org.apache.tapestry.services.RequestHandler;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a barrier that periodically asks the {@link org.apache.tapestry.internal.services.UpdateListenerHub} to
+ * check for updates to files. The UpdateListenerHub is invoked from a write method, meaning that when it is called, all
+ * other threads will be blocked.
+ */
+public class CheckForUpdatesFilter implements RequestFilter
+{
+    private final long checkInterval;
+
+    private final long updateTimeout;
+
+    private final UpdateListenerHub updateListenerHub;
+
+    private final ConcurrentBarrier barrier = new ConcurrentBarrier();
+
+    private final Runnable checker = new Runnable()
+    {
+        public void run()
+        {
+            // On a race condition, multiple threads may hit this method briefly. If we've
+            // already done a check, don't run it again.
+
+            if (System.currentTimeMillis() - lastCheck >= checkInterval)
+            {
+
+                // Fire the update event which will force a number of checks and then
+                // corresponding invalidation events.
+
+                updateListenerHub.fireUpdateEvent();
+
+                lastCheck = System.currentTimeMillis();
+            }
+        }
+    };
+
+    private long lastCheck = 0;
+
+    /**
+     * @param updateListenerHub invoked, at intervals, to spur the process of detecting changes
+     * @param checkInterval     interval, in milliseconds, between checks
+     * @param updateTimeout     time, in  milliseconds, to wait to obtain update lock.
+     */
+    public CheckForUpdatesFilter(UpdateListenerHub updateListenerHub, long checkInterval, long updateTimeout)
+    {
+        this.updateListenerHub = updateListenerHub;
+        this.checkInterval = checkInterval;
+        this.updateTimeout = updateTimeout;
+    }
+
+    public boolean service(final Request request, final Response response, final RequestHandler handler)
+            throws IOException
+    {
+        final Holder<IOException> exceptionHolder = new Holder<IOException>();
+
+        Invokable<Boolean> invokable = new Invokable<Boolean>()
+        {
+            public Boolean invoke()
+            {
+                if (System.currentTimeMillis() - lastCheck >= checkInterval)
+                    barrier.tryWithWrite(checker, updateTimeout, TimeUnit.MILLISECONDS);
+
+                // And, now, back to code within the read lock.
+
+                try
+                {
+                    return handler.service(request, response);
+                }
+                catch (IOException ex)
+                {
+                    exceptionHolder.put(ex);
+                    return false;
+                }
+            }
+        };
+
+        // Obtain a read lock while handling the request. This will not impair parallel operations, except when a file check
+        // is needed (the exclusive write lock will block threads attempting to get a read lock).
+
+        boolean result = barrier.withRead(invokable);
+
+        if (exceptionHolder.hasValue()) throw exceptionHolder.get();
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
new file mode 100644
index 0000000..3e84255
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClassResultProcessor.java
@@ -0,0 +1,53 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.internal.structure.Page;

+import org.apache.tapestry.services.ComponentClassResolver;

+import org.apache.tapestry.services.ComponentEventResultProcessor;

+

+import java.io.IOException;

+

+/**

+ * Used when a component event handler returns a class value. The value is interpreted as the page class. A link to the

+ * page will be sent.

+ */

+public class ClassResultProcessor implements ComponentEventResultProcessor<Class>

+{

+    private final ComponentClassResolver resolver;

+

+    private final RequestPageCache requestPageCache;

+

+    private final ActionRenderResponseGenerator generator;

+

+    public ClassResultProcessor(ComponentClassResolver resolver, RequestPageCache requestPageCache,

+                                ActionRenderResponseGenerator generator)

+    {

+        this.resolver = resolver;

+        this.requestPageCache = requestPageCache;

+        this.generator = generator;

+    }

+

+    public void processResultValue(Class value) throws IOException

+    {

+        String className = value.getName();

+        String pageName = resolver.resolvePageClassNameToPageName(className);

+

+        Page page = requestPageCache.get(pageName);

+

+        generator.generateResponse(page);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImpl.java
new file mode 100644
index 0000000..35e26b6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImpl.java
@@ -0,0 +1,137 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+import org.apache.tapestry.services.Request;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+public class ClasspathAssetAliasManagerImpl implements ClasspathAssetAliasManager
+{
+    private final Request request;
+
+    private final RequestPathOptimizer optimizer;
+
+    /**
+     * Map from alias to path.
+     */
+    private final Map<String, String> aliasToPathPrefix = CollectionFactory.newMap();
+
+    /**
+     * Map from path to alias.
+     */
+    private final Map<String, String> pathPrefixToAlias = CollectionFactory.newMap();
+
+    private final List<String> sortedAliases;
+
+    private final List<String> sortedPathPrefixes;
+
+    /**
+     * Configuration is a map of aliases (short names) to complete names. Keys and values should end with a slash, but
+     * one will be provided as necessary, so don't both.
+     */
+    public ClasspathAssetAliasManagerImpl(Request request,
+
+                                          RequestPathOptimizer optimizer,
+
+                                          Map<String, String> configuration)
+    {
+        this.request = request;
+        this.optimizer = optimizer;
+
+        for (Map.Entry<String, String> e : configuration.entrySet())
+        {
+            String alias = withSlash(e.getKey());
+            String path = withSlash(e.getValue());
+
+            aliasToPathPrefix.put(alias, path);
+            pathPrefixToAlias.put(path, alias);
+
+        }
+
+        Comparator<String> sortDescendingByLength = new Comparator<String>()
+        {
+            public int compare(String o1, String o2)
+            {
+                return o2.length() - o1.length();
+            }
+        };
+
+        sortedAliases = CollectionFactory.newList(aliasToPathPrefix.keySet());
+        Collections.sort(sortedAliases, sortDescendingByLength);
+
+        sortedPathPrefixes = CollectionFactory.newList(aliasToPathPrefix.values());
+        Collections.sort(sortedPathPrefixes, sortDescendingByLength);
+    }
+
+    private String withSlash(String input)
+    {
+        if (input.endsWith("/")) return input;
+
+        return input + "/";
+    }
+
+    public String toClientURL(String resourcePath)
+    {
+        String path = toCompleteClientURI(resourcePath);
+
+        return optimizer.optimizePath(path);
+    }
+
+    private String toCompleteClientURI(String resourcePath)
+    {
+        StringBuilder builder = new StringBuilder(request.getContextPath());
+        builder.append(RequestConstants.ASSET_PATH_PREFIX);
+
+        for (String pathPrefix : sortedPathPrefixes)
+        {
+            if (resourcePath.startsWith(pathPrefix))
+            {
+                String alias = pathPrefixToAlias.get(pathPrefix);
+                builder.append(alias);
+                builder.append(resourcePath.substring(pathPrefix.length()));
+
+                return builder.toString();
+            }
+        }
+
+        // No alias available as a prefix (kind of unlikely, but whatever).
+
+        builder.append(resourcePath);
+
+        return builder.toString();
+    }
+
+    public String toResourcePath(String clientURL)
+    {
+        String basePath = clientURL.substring(RequestConstants.ASSET_PATH_PREFIX.length());
+
+        for (String alias : sortedAliases)
+        {
+            if (basePath.startsWith(alias))
+            {
+                return aliasToPathPrefix.get(alias) + basePath.substring(alias.length());
+            }
+        }
+
+        return basePath;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetFactory.java
new file mode 100644
index 0000000..fc10bf5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClasspathAssetFactory.java
@@ -0,0 +1,113 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+
+import java.util.Map;
+
+/**
+ * Generates Assets for files on the classpath. Caches generated client URLs internally, and clears that cache when
+ * notified to do so by the {@link ResourceCache}.
+ *
+ * @see AssetDispatcher
+ */
+public class ClasspathAssetFactory implements AssetFactory, InvalidationListener
+{
+    private final ResourceCache cache;
+
+    private final ClasspathAssetAliasManager aliasManager;
+
+    private final Map<Resource, String> resourceToClientURL = newConcurrentMap();
+
+    public ClasspathAssetFactory(final ResourceCache cache, final ClasspathAssetAliasManager aliasManager)
+    {
+        this.cache = cache;
+        this.aliasManager = aliasManager;
+    }
+
+    public void objectWasInvalidated()
+    {
+        resourceToClientURL.clear();
+    }
+
+    private String clientURL(Resource resource)
+    {
+        String clientURL = resourceToClientURL.get(resource);
+
+        if (clientURL == null)
+        {
+            clientURL = buildClientURL(resource);
+            resourceToClientURL.put(resource, clientURL);
+        }
+
+        // The path generated is partially request-dependent and therefore can't be cached, it will even
+        // vary from request to the next.
+
+        return aliasManager.toClientURL(clientURL);
+    }
+
+    private String buildClientURL(Resource resource)
+    {
+        boolean requiresDigest = cache.requiresDigest(resource);
+
+        String path = resource.getPath();
+
+        if (requiresDigest)
+        {
+            // Resources with extensions go from foo/bar/baz.txt --> foo/bar/baz.CHECKSUM.txt
+
+            int lastdotx = path.lastIndexOf('.');
+
+            path = path.substring(0, lastdotx + 1) + cache.getDigest(resource) + path.substring(lastdotx);
+        }
+
+        return path;
+    }
+
+    public Asset createAsset(final Resource resource)
+    {
+        return new Asset()
+        {
+            public Resource getResource()
+            {
+                return resource;
+            }
+
+            public String toClientURL()
+            {
+                return clientURL(resource);
+            }
+
+            @Override
+            public String toString()
+            {
+                return toClientURL();
+            }
+        };
+    }
+
+    public Resource getRootResource()
+    {
+        return new ClasspathResource("");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java
new file mode 100644
index 0000000..53f4ad0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java
@@ -0,0 +1,82 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.corelib.data.InsertPosition;
+
+/**
+ * Collects details about zone usage for efficient initialization of the client side objects.  This has grown to include
+ * the client-side behavior associated with {@link org.apache.tapestry.corelib.components.FormFragment}s.
+ *
+ * @see org.apache.tapestry.corelib.components.Zone
+ */
+public interface ClientBehaviorSupport
+{
+    /**
+     * Adds a new client-side Tapestry.Zone object. Zones are linked to a an element (typically, a &lt;div&gt;).  A Zone
+     * may have handlers used to initially show it, or to highlight it when its content changes. Such handlers are
+     * referenced by name, as functions of the Tapestry.ElementEffect object.
+     *
+     * @param clientId           client-side id of the element that will be updated by the zone
+     * @param showFunctionName   name of the function used to initially show the zone (if not visible), or null for
+     *                           default
+     * @param updateFunctionName name of function used to highlight the function after an update, or null for default
+     */
+    void addZone(String clientId, String showFunctionName, String updateFunctionName);
+
+    /**
+     * Sets the client-side onclick handler for an &lt;a&gt; element to perform an Ajax update of a zone.
+     *
+     * @param linkId    id of the link to Ajax enable
+     * @param elementId id of an element that has been previously registered as a Zone
+     */
+    void linkZone(String linkId, String elementId);
+
+    /**
+     * Adds a new client-side Tapestry.FormFragment object.  FormFragment's are used to make parts of a client-side form
+     * visible or invisible, which involves interactions with both the server-side and client-side validation.
+     *
+     * @param clientId         client-side id of the element that will be made visible or invisible
+     * @param showFunctionName name of function (of the Tapestry.ElementEffect object) used to make the SubForm visible,
+     *                         or null for the default
+     * @param hideFunctionName name of the function used to make the SubForm invisible, or null for the default
+     */
+    void addFormFragment(String clientId, String showFunctionName, String hideFunctionName);
+
+    /**
+     * Adds a new client-side Tapestry.FormInjector object.  FormInjectors are used to extend an existing Form with new
+     * content.
+     *
+     * @param clientId         client-side id of the element that identifiess where the new content will be placed
+     * @param link             action request link used to trigger the server-side object, to render the new content
+     * @param insertPosition   where the new content should go (above or below the element)
+     * @param showFunctionName name of function (of the Tapestry.ElementEffect object) used to make the new element
+     *                         visible, or null for the default
+     */
+    void addFormInjector(String clientId, Link link, InsertPosition insertPosition, String showFunctionName);
+
+    /**
+     * Collects field validation information.
+     *
+     * @param field          for which validation is being generated
+     * @param validationName name of validation method (see Tapestry.Validation in tapestry.js)
+     * @param message        the error message to display if the field is invalid
+     * @param constraint     additional constraint value, or null for validations that don't require a constraint
+     */
+    void addValidation(Field field, String validationName, String message, Object constraint);
+}
+
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java
new file mode 100644
index 0000000..8802f59
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java
@@ -0,0 +1,144 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.corelib.data.InsertPosition;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+
+public class ClientBehaviorSupportImpl implements ClientBehaviorSupport
+{
+    private final RenderSupport renderSupport;
+
+    private final JSONObject validations = new JSONObject();
+
+    public ClientBehaviorSupportImpl(RenderSupport renderSupport)
+    {
+        this.renderSupport = renderSupport;
+    }
+
+    public void addZone(String clientId, String showFunctionName, String updateFunctionName)
+    {
+        JSONObject spec = new JSONObject();
+
+        addFunction(spec, "show", showFunctionName);
+        addFunction(spec, "update", updateFunctionName);
+
+        addElementInit("zone", clientId, spec);
+    }
+
+    private void addElementInit(String functionName, String clientId, JSONObject spec)
+    {
+        Defense.notBlank(clientId, "clientId");
+
+        if (spec.length() == 0)
+        {
+            renderSupport.addInit(functionName, clientId);
+            return;
+        }
+
+        spec.put("element", clientId);
+
+        renderSupport.addInit(functionName, spec);
+    }
+
+
+    private void addFunction(JSONObject spec, String key, String showFunctionName)
+    {
+        if (showFunctionName != null) spec.put(key, showFunctionName.toLowerCase());
+    }
+
+    public void linkZone(String linkId, String elementId)
+    {
+        JSONArray spec = new JSONArray();
+        spec.put(linkId);
+        spec.put(elementId);
+
+        renderSupport.addInit("linkZone", spec);
+    }
+
+    public void addFormFragment(String clientId, String showFunctionName, String hideFunctionName)
+    {
+        JSONObject spec = new JSONObject();
+
+        addFunction(spec, "show", showFunctionName);
+        addFunction(spec, "hide", hideFunctionName);
+
+        addElementInit("formFragment", clientId, spec);
+    }
+
+    public void addFormInjector(String clientId, Link link, InsertPosition insertPosition, String showFunctionName)
+    {
+        JSONObject spec = new JSONObject();
+        spec.put("element", clientId);
+
+        spec.put("url", link.toAbsoluteURI());
+
+        if (insertPosition == InsertPosition.BELOW)
+            spec.put("below", true);
+
+        addFunction(spec, "show", showFunctionName);
+
+        // Always has at least two properties.
+
+        renderSupport.addInit("formInjector", spec);
+    }
+
+
+    public void addValidation(Field field, String validationName, String message, Object constraint)
+    {
+        String fieldId = field.getClientId();
+
+        JSONArray specs;
+
+        if (validations.has(fieldId)) specs = validations.getJSONArray(fieldId);
+        else
+        {
+            specs = new JSONArray();
+            validations.put(fieldId, specs);
+        }
+
+        JSONArray thisSpec = new JSONArray();
+
+        thisSpec.put(validationName);
+        thisSpec.put(message);
+
+        if (constraint != null) thisSpec.put(constraint);
+
+        specs.put(thisSpec);
+    }
+
+    /**
+     * Invoked at the end of rendering to commit (to the {@link org.apache.tapestry.RenderSupport}) any accumulated
+     * validations.
+     */
+    public void commit()
+    {
+        for (String field : validations.keys())
+        {
+            JSONArray specs = validations.getJSONArray(field);
+
+            JSONArray parameters = new JSONArray();
+            parameters.put(field);
+            parameters.put(specs);
+
+            renderSupport.addInit("validate", parameters);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorage.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorage.java
new file mode 100644
index 0000000..3804909
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorage.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+
+/**
+ * Describes an object that can store {@link PersistentFieldChange}s, and manage a query parameter stored into a {@link
+ * Link} to maining this data across requests.
+ */
+public interface ClientPersistentFieldStorage extends PersistentFieldStrategy
+{
+    /**
+     * Updates a link, adding a query parameter to it (if necessary) to store
+     *
+     * @param link
+     */
+    void updateLink(Link link);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java
new file mode 100644
index 0000000..4b98ebf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImpl.java
@@ -0,0 +1,286 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.util.Base64ObjectInputStream;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.Request;
+
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Manages client-persistent values on behalf of a {@link ClientPersistentFieldStorageImpl}. Some effort is made to
+ * ensure that we don't uncessarily convert between objects and Base64 (the encoding used to record the value on the
+ * client).
+ */
+@Scope(PERTHREAD_SCOPE)
+public class ClientPersistentFieldStorageImpl implements ClientPersistentFieldStorage
+{
+    static final String PARAMETER_NAME = "t:state:client";
+
+    private static class Key implements Serializable
+    {
+        private static final long serialVersionUID = -2741540370081645945L;
+
+        private final String pageName;
+
+        private final String componentId;
+
+        private final String fieldName;
+
+        Key(String pageName, String componentId, String fieldName)
+        {
+            this.pageName = pageName;
+            this.componentId = componentId;
+            this.fieldName = fieldName;
+        }
+
+        public boolean matches(String pageName)
+        {
+            return this.pageName.equals(pageName);
+        }
+
+        public PersistentFieldChange toChange(Object value)
+        {
+            return new PersistentFieldChangeImpl(componentId == null ? "" : componentId,
+                                                 fieldName, value);
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int PRIME = 31;
+
+            int result = 1;
+
+            result = PRIME * result + ((componentId == null) ? 0 : componentId.hashCode());
+
+            // fieldName and pageName are never null
+
+            result = PRIME * result + fieldName.hashCode();
+            result = PRIME * result + pageName.hashCode();
+
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (getClass() != obj.getClass()) return false;
+            final Key other = (Key) obj;
+
+            // fieldName and pageName are never null
+
+            if (!fieldName.equals(other.fieldName)) return false;
+            if (!pageName.equals(other.pageName)) return false;
+
+            if (componentId == null)
+            {
+                if (other.componentId != null) return false;
+            }
+            else if (!componentId.equals(other.componentId)) return false;
+
+            return true;
+        }
+    }
+
+    private final Map<Key, Object> persistedValues = newMap();
+
+    private String clientData;
+
+    private boolean mapUptoDate = false;
+
+    public ClientPersistentFieldStorageImpl(Request request)
+    {
+        String value = request.getParameter(PARAMETER_NAME);
+
+        // MIME can encode to a '+' character; the browser converts that to a space; we convert it
+        // back.
+
+        clientData = value == null ? null : value.replace(' ', '+');
+    }
+
+    public void updateLink(Link link)
+    {
+        refreshClientData();
+
+        if (clientData != null) link.addParameter(PARAMETER_NAME, clientData);
+    }
+
+    public Collection<PersistentFieldChange> gatherFieldChanges(String pageName)
+    {
+        refreshMap();
+
+        if (persistedValues.isEmpty()) return Collections.emptyList();
+
+        Collection<PersistentFieldChange> result = CollectionFactory.newList();
+
+        for (Map.Entry<Key, Object> e : persistedValues.entrySet())
+        {
+            Key key = e.getKey();
+
+            if (key.matches(pageName)) result.add(key.toChange(e.getValue()));
+        }
+
+        return result;
+    }
+
+    public void discardChanges(String pageName)
+    {
+        refreshMap();
+
+        Collection<Key> removedKeys = CollectionFactory.newList();
+
+        for (Key key : persistedValues.keySet())
+        {
+            if (key.pageName.equals(pageName)) removedKeys.add(key);
+        }
+
+        for (Key key : removedKeys)
+        {
+            persistedValues.remove(key);
+            clientData = null;
+        }
+    }
+
+    public void postChange(String pageName, String componentId, String fieldName, Object newValue)
+    {
+        refreshMap();
+
+        Key key = new Key(pageName, componentId, fieldName);
+
+        if (newValue == null)
+            persistedValues.remove(key);
+        else
+        {
+            if (!Serializable.class.isInstance(newValue))
+                throw new IllegalArgumentException(ServicesMessages
+                        .clientStateMustBeSerializable(newValue));
+
+            persistedValues.put(key, newValue);
+        }
+
+        clientData = null;
+    }
+
+    /**
+     * Refreshes the _persistedValues map if it is not up to date.
+     */
+    @SuppressWarnings("unchecked")
+    private void refreshMap()
+    {
+        if (mapUptoDate) return;
+
+        // Parse the client data to form the map.
+
+        restoreMapFromClientData();
+
+        mapUptoDate = true;
+    }
+
+    /**
+     * Restores the _persistedValues map from the client data provided in the incoming Request.
+     */
+    private void restoreMapFromClientData()
+    {
+        persistedValues.clear();
+
+        if (clientData == null) return;
+
+        ObjectInputStream in = null;
+
+        try
+        {
+            in = new Base64ObjectInputStream(clientData);
+
+            int count = in.readInt();
+
+            for (int i = 0; i < count; i++)
+            {
+                Key key = (Key) in.readObject();
+                Object value = in.readObject();
+
+                persistedValues.put(key, value);
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServicesMessages.corruptClientState(), ex);
+        }
+        finally
+        {
+            InternalUtils.close(in);
+        }
+    }
+
+    private void refreshClientData()
+    {
+        // Client data will be null after a change to the map, or if there was no client data in the
+        // request. In any other case where the client data is non-null, it is by definition
+        // up-to date (since it is reset to null any time there's a change to the map).
+
+        if (clientData != null) return;
+
+        // Very typical: we're refreshing the client data but haven't created the map yet, and there
+        // was no value in the request. Leave it as null.
+
+        if (!mapUptoDate) return;
+
+        // Null is also appropriate when the persisted values are empty.
+
+        if (persistedValues.isEmpty()) return;
+
+        // Otherwise, time to update clientData from persistedValues
+
+        Base64ObjectOutputStream os = null;
+
+        try
+        {
+            os = new Base64ObjectOutputStream();
+
+            os.writeInt(persistedValues.size());
+
+            for (Map.Entry<Key, Object> e : persistedValues.entrySet())
+            {
+                os.writeObject(e.getKey());
+                os.writeObject(e.getValue());
+            }
+
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
+        finally
+        {
+            InternalUtils.close(os);
+        }
+
+        clientData = os.toBase64();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java
new file mode 100644
index 0000000..30f4bd1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientPersistentFieldStrategy.java
@@ -0,0 +1,61 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+
+import java.util.Collection;
+
+/**
+ * Implements simple client-persistent properties. Most of the logic is delegated to an instance of {@link
+ * ClientPersistentFieldStorage}. This division of layer allows this service to be a true singleton, and a listener to
+ * the {@link LinkFactory}, and allow per-request state to be isolated inside the other service.
+ */
+public class ClientPersistentFieldStrategy implements PersistentFieldStrategy, LinkFactoryListener
+{
+    private final ClientPersistentFieldStorage storage;
+
+    public ClientPersistentFieldStrategy(ClientPersistentFieldStorage storage)
+    {
+        this.storage = storage;
+    }
+
+    public Collection<PersistentFieldChange> gatherFieldChanges(String pageName)
+    {
+        return storage.gatherFieldChanges(pageName);
+    }
+
+    public void postChange(String pageName, String componentId, String fieldName, Object newValue)
+    {
+        storage.postChange(pageName, componentId, fieldName, newValue);
+    }
+
+    public void createdActionLink(Link link)
+    {
+        storage.updateLink(link);
+    }
+
+    public void createdPageLink(Link link)
+    {
+        storage.updateLink(link);
+    }
+
+    public void discardChanges(String pageName)
+    {
+        storage.discardChanges(pageName);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CoercingPropertyConduitWrapper.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CoercingPropertyConduitWrapper.java
new file mode 100644
index 0000000..01cb81e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CoercingPropertyConduitWrapper.java
@@ -0,0 +1,57 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+
+import java.lang.annotation.Annotation;
+
+public class CoercingPropertyConduitWrapper implements PropertyConduit
+{
+    private final PropertyConduit conduit;
+
+    private final TypeCoercer coercer;
+
+    public CoercingPropertyConduitWrapper(final PropertyConduit conduit, final TypeCoercer coercer)
+    {
+        this.conduit = conduit;
+        this.coercer = coercer;
+    }
+
+    public Object get(Object instance)
+    {
+        return conduit.get(instance);
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return conduit.getAnnotation(annotationClass);
+    }
+
+    public Class getPropertyType()
+    {
+        return conduit.getPropertyType();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void set(Object instance, Object value)
+    {
+        Object coerced = coercer.coerce(value, getPropertyType());
+
+        conduit.set(instance, coerced);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java
new file mode 100644
index 0000000..b1dc315
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CommonResourcesInjectionProvider.java
@@ -0,0 +1,63 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+import org.slf4j.Logger;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Allows for a number of anonymous injections based on the type of field that is to be injected.
+ */
+public class CommonResourcesInjectionProvider implements InjectionProvider
+{
+    private static final Map<Class, String> configuration = CollectionFactory.newMap();
+
+    {
+        configuration.put(Messages.class, "getMessages");
+        configuration.put(Locale.class, "getLocale");
+        configuration.put(Logger.class, "getLogger");
+        configuration.put(String.class, "getCompleteId");
+    }
+
+    public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                                    ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        String implementationMethodName = configuration.get(fieldType);
+
+        if (implementationMethodName == null) return false;
+
+        String resourcesField = transformation.getResourcesFieldName();
+
+        String body = String.format(
+                "%s = %s.%s();",
+                fieldName,
+                resourcesField,
+                implementationMethodName);
+
+        transformation.makeReadOnly(fieldName);
+
+        transformation.extendConstructor(body);
+
+        return true;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCache.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCache.java
new file mode 100644
index 0000000..0668164
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCache.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * A cache for converting between class names and component (or other) classes.  For component classes, ensures that the
+ * class is the transformed class.
+ */
+public interface ComponentClassCache
+{
+    /**
+     * Gets the Class instance for the given fully-qualified class name.
+     *
+     * @param className fully qualified class name, or a primitive type name, or an array name (in source format)
+     * @return the class instance
+     */
+    Class forName(String className);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCacheImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCacheImpl.java
new file mode 100644
index 0000000..5d519ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassCacheImpl.java
@@ -0,0 +1,78 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.util.Map;
+
+public class ComponentClassCacheImpl implements ComponentClassCache, InvalidationListener
+{
+    private final Map<String, Class> cache = CollectionFactory.newConcurrentMap();
+
+    private final ClassFactory classFactory;
+
+    public ComponentClassCacheImpl(ClassFactory classFactory)
+    {
+        this.classFactory = classFactory;
+    }
+
+    public void objectWasInvalidated()
+    {
+        cache.clear();
+    }
+
+
+    public Class forName(final String className)
+    {
+        Class result = cache.get(className);
+
+        if (result == null)
+        {
+            result = lookupClassForType(className);
+
+
+            cache.put(className, result);
+        }
+
+        return result;
+    }
+
+    private Class lookupClassForType(String className)
+    {
+        if (className.equals("void")) return void.class;
+
+        if (ClassFabUtils.isPrimitiveType(className))
+            return ClassFabUtils.getPrimitiveType(className);
+
+        // This step is necessary to handle primitives arrays.
+
+        String jvmName = ClassFabUtils.toJVMBinaryName(className);
+
+        ClassLoader componentLoader = classFactory.getClassLoader();
+
+        try
+        {
+            return Class.forName(jvmName, true, componentLoader);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
new file mode 100644
index 0000000..8c74632
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
@@ -0,0 +1,545 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.ConcurrentBarrier;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.Invokable;
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.LibraryMapping;
+import org.slf4j.Logger;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+public class ComponentClassResolverImpl implements ComponentClassResolver, InvalidationListener
+{
+    private static final String CORE_LIBRARY_PREFIX = "core/";
+
+    private final Logger logger;
+
+    private final ComponentInstantiatorSource componentInstantiatorSource;
+
+    private final ClassNameLocator classNameLocator;
+
+    private final String appRootPackage;
+
+    // Map from folder name to a list of root package names.
+    // The key does not begin or end with a slash.
+
+    private final Map<String, List<String>> mappings = CollectionFactory.newCaseInsensitiveMap();
+
+    // Flag indicating that the maps have been cleared following an invalidation
+    // and need to be rebuilt. The flag and the four maps below are not synchronized
+    // because they are only modified inside a synchronized block. That should be strong enough ...
+    // and changes made will become "visible" at the end of the synchronized block. Because of the
+    // structure of Tapestry, there should not be any reader threads while the write thread
+    // is operating.
+
+    private boolean needsRebuild = true;
+
+    /**
+     * Logical page name to class name.
+     */
+    private final Map<String, String> pageToClassName = CollectionFactory.newCaseInsensitiveMap();
+
+    /**
+     * Component type to class name.
+     */
+    private final Map<String, String> componentToClassName = CollectionFactory.newCaseInsensitiveMap();
+
+    /**
+     * Mixing type to class name.
+     */
+    private final Map<String, String> mixinToClassName = CollectionFactory.newCaseInsensitiveMap();
+
+    /**
+     * Page class name to logical name (needed to build URLs). This one is case sensitive, since class names do always
+     * have a particular case.
+     */
+    private final Map<String, String> pageClassNameToLogicalName = CollectionFactory.newMap();
+
+
+    /**
+     * Used to convert an logical page name to the canonical form of the page name; this ensures that uniform case for
+     * page names is used.
+     */
+    private final Map<String, String> pageNameToCanonicalPageName = CollectionFactory.newCaseInsensitiveMap();
+
+    private final ConcurrentBarrier barrier = new ConcurrentBarrier();
+
+    private static final Pattern SPLIT_PACKAGE_PATTERN = Pattern.compile("\\.");
+
+    private static final Pattern SPLIT_FOLDER_PATTERN = Pattern.compile("/");
+
+    private static final int LOGICAL_NAME_BUFFER_SIZE = 40;
+
+    public ComponentClassResolverImpl(Logger logger,
+
+                                      ComponentInstantiatorSource componentInstantiatorSource,
+
+                                      ClassNameLocator classNameLocator,
+
+                                      @Inject @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
+                                      String appRootPackage,
+
+                                      Collection<LibraryMapping> mappings)
+    {
+        this.logger = logger;
+        this.componentInstantiatorSource = componentInstantiatorSource;
+        this.classNameLocator = classNameLocator;
+
+        this.appRootPackage = appRootPackage;
+
+        addPackagesToInstantiatorSource(this.appRootPackage);
+
+        for (LibraryMapping mapping : mappings)
+        {
+            String prefix = mapping.getPathPrefix();
+
+            while (prefix.startsWith("/"))
+            {
+                prefix = prefix.substring(1);
+            }
+
+            while (prefix.endsWith("/"))
+            {
+                prefix = prefix.substring(0, prefix.length() - 1);
+            }
+
+            String rootPackage = mapping.getRootPackage();
+
+            List<String> packages = this.mappings.get(prefix);
+
+            if (packages == null)
+            {
+                packages = CollectionFactory.newList();
+                this.mappings.put(prefix, packages);
+            }
+
+            packages.add(rootPackage);
+
+            // These packages, which will contain classes subject to class transformation,
+            // must be registered with the component instantiator (which is responsible
+            // for transformation).
+
+            addPackagesToInstantiatorSource(rootPackage);
+        }
+
+    }
+
+    private void addPackagesToInstantiatorSource(String rootPackage)
+    {
+        componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.PAGES_SUBPACKAGE);
+        componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.COMPONENTS_SUBPACKAGE);
+        componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.MIXINS_SUBPACKAGE);
+        componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.BASE_SUBPACKAGE);
+    }
+
+    /**
+     * When the class loader is invalidated, clear any cached page names or component types.
+     */
+    public synchronized void objectWasInvalidated()
+    {
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                needsRebuild = true;
+            }
+        });
+
+    }
+
+    /**
+     * Invoked from within a withRead() block, checks to see if a rebuild is needed, and then performs the rebuild
+     * within a withWrite() block.
+     */
+    private void rebuild()
+    {
+        if (!needsRebuild) return;
+
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                performRebuild();
+            }
+        });
+    }
+
+    private void performRebuild()
+    {
+
+        Map<String, String> savedPages = CollectionFactory.newMap(pageToClassName);
+        Map<String, String> savedComponents = CollectionFactory.newMap(componentToClassName);
+        Map<String, String> savedMixins = CollectionFactory.newMap(mixinToClassName);
+
+        pageToClassName.clear();
+        componentToClassName.clear();
+        mixinToClassName.clear();
+        pageClassNameToLogicalName.clear();
+        pageNameToCanonicalPageName.clear();
+
+        rebuild("", appRootPackage);
+
+        for (String prefix : mappings.keySet())
+        {
+            List<String> packages = mappings.get(prefix);
+
+            String folder = prefix + "/";
+
+            for (String packageName : packages)
+                rebuild(folder, packageName);
+        }
+
+
+        showChanges("pages", savedPages, pageToClassName);
+        showChanges("components", savedComponents, componentToClassName);
+        showChanges("mixins", savedMixins, mixinToClassName);
+
+        needsRebuild = false;
+    }
+
+    private void showChanges(String title, Map<String, String> savedMap, Map<String, String> newMap)
+    {
+        if (savedMap.equals(newMap)) return;
+
+        Map<String, String> core = CollectionFactory.newMap();
+        Map<String, String> nonCore = CollectionFactory.newMap();
+
+        int maxLength = 0;
+
+        // Pass # 1: Get all the stuff in the core library
+
+        for (String name : newMap.keySet())
+        {
+            if (name.startsWith(CORE_LIBRARY_PREFIX))
+            {
+                // Strip off the "core/" prefix.
+
+                String key = name.substring(CORE_LIBRARY_PREFIX.length());
+
+                maxLength = Math.max(maxLength, key.length());
+
+                core.put(key, newMap.get(name));
+            }
+            else
+            {
+                maxLength = Math.max(maxLength, name.length());
+
+                nonCore.put(name, newMap.get(name));
+            }
+        }
+
+        // Merge the non-core mappings into the core mappings. Where there are conflicts on name, it
+        // means the application overrode a core page/component/mixin and that's ok ... the
+        // merged core map will reflect the application's mapping.
+
+        core.putAll(nonCore);
+
+        StringBuilder builder = new StringBuilder(2000);
+        Formatter f = new Formatter(builder);
+
+        f.format("Available %s:\n", title);
+
+        String formatString = "%" + maxLength + "s: %s\n";
+
+        List<String> sorted = InternalUtils.sortedKeys(core);
+
+        for (String name : sorted)
+        {
+            String className = core.get(name);
+
+            if (name.equals("")) name = "(blank)";
+
+            f.format(formatString, name, className);
+        }
+
+        logger.info(builder.toString());
+
+    }
+
+    private void rebuild(String pathPrefix, String rootPackage)
+    {
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.PAGES_SUBPACKAGE, pageToClassName);
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.COMPONENTS_SUBPACKAGE, componentToClassName);
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.MIXINS_SUBPACKAGE, mixinToClassName);
+    }
+
+    private void fillNameToClassNameMap(String pathPrefix, String rootPackage, String subPackage,
+                                        Map<String, String> logicalNameToClassName)
+    {
+        String searchPackage = rootPackage + "." + subPackage;
+        boolean isPage = subPackage.equals(InternalConstants.PAGES_SUBPACKAGE);
+
+        Collection<String> classNames = classNameLocator.locateClassNames(searchPackage);
+
+        int startPos = searchPackage.length() + 1;
+
+        for (String name : classNames)
+        {
+            String logicalName = toLogicalName(name, pathPrefix, startPos, true);
+            String unstrippedName = toLogicalName(name, pathPrefix, startPos, false);
+
+            if (isPage)
+            {
+                int lastSlashx = logicalName.lastIndexOf("/");
+
+                String lastTerm = lastSlashx < 0 ? logicalName : logicalName.substring(lastSlashx + 1);
+
+                if (lastTerm.equalsIgnoreCase("index"))
+                {
+                    String reducedName = lastSlashx < 0 ? "" : logicalName.substring(0, lastSlashx);
+
+                    // Make the super-stripped name another alias to the class.
+
+                    logicalNameToClassName.put(reducedName, name);
+                    pageNameToCanonicalPageName.put(reducedName, logicalName);
+                }
+
+                pageClassNameToLogicalName.put(name, logicalName);
+                pageNameToCanonicalPageName.put(logicalName, logicalName);
+                pageNameToCanonicalPageName.put(unstrippedName, logicalName);
+            }
+
+            logicalNameToClassName.put(logicalName, name);
+            logicalNameToClassName.put(unstrippedName, name);
+        }
+    }
+
+
+    /**
+     * Converts a fully qualified class name to a logical name
+     *
+     * @param className  fully qualified class name
+     * @param pathPrefix prefix to be placed on the logical name (to identify the library from in which the class
+     *                   lives)
+     * @param startPos   start position within the class name to extract the logical name (i.e., after the final '.' in
+     *                   "rootpackage.pages.").
+     * @param stripTerms
+     * @return a short logical name in folder format ('.' replaced with '/')
+     */
+    private String toLogicalName(String className, String pathPrefix, int startPos, boolean stripTerms)
+    {
+        List<String> terms = CollectionFactory.newList();
+
+        addAll(terms, SPLIT_FOLDER_PATTERN, pathPrefix);
+
+        addAll(terms, SPLIT_PACKAGE_PATTERN, className.substring(startPos));
+
+        StringBuilder builder = new StringBuilder(LOGICAL_NAME_BUFFER_SIZE);
+        String sep = "";
+
+        String logicalName = terms.remove(terms.size() - 1);
+
+        String unstripped = logicalName;
+
+        for (String term : terms)
+        {
+            builder.append(sep);
+            builder.append(term);
+
+            sep = "/";
+
+            if (stripTerms) logicalName = stripTerm(term, logicalName);
+        }
+
+        if (logicalName.equals("")) logicalName = unstripped;
+
+        builder.append(sep);
+        builder.append(logicalName);
+
+        return builder.toString();
+    }
+
+    private void addAll(List<String> terms, Pattern splitter, String input)
+    {
+        for (String term : splitter.split(input))
+        {
+            if (term.equals("")) continue;
+
+            terms.add(term);
+        }
+    }
+
+    private String stripTerm(String term, String logicalName)
+    {
+        if (isCaselessPrefix(term, logicalName))
+        {
+            logicalName = logicalName.substring(term.length());
+        }
+
+        if (isCaselessSuffix(term, logicalName))
+        {
+            logicalName = logicalName.substring(0, logicalName.length() - term.length());
+        }
+
+        return logicalName;
+    }
+
+    private boolean isCaselessPrefix(String prefix, String string)
+    {
+        return string.regionMatches(true, 0, prefix, 0, prefix.length());
+    }
+
+    private boolean isCaselessSuffix(String suffix, String string)
+    {
+        return string.regionMatches(true, string.length() - suffix.length(), suffix, 0, suffix
+                .length());
+    }
+
+    public String resolvePageNameToClassName(final String pageName)
+    {
+        return barrier.withRead(new Invokable<String>()
+        {
+            public String invoke()
+            {
+                String result = locate(pageName, pageToClassName);
+
+                if (result == null) throw new IllegalArgumentException(
+                        ServicesMessages.couldNotResolvePageName(pageName, presentableNames(pageToClassName)));
+
+                return result;
+            }
+        });
+
+    }
+
+    public boolean isPageName(final String pageName)
+    {
+        return barrier.withRead(new Invokable<Boolean>()
+        {
+            public Boolean invoke()
+            {
+                return locate(pageName, pageToClassName) != null;
+            }
+        });
+    }
+
+    public String resolveComponentTypeToClassName(final String componentType)
+    {
+        return barrier.withRead(new Invokable<String>()
+        {
+            public String invoke()
+            {
+                String result = locate(componentType, componentToClassName);
+
+                if (result == null) throw new IllegalArgumentException(ServicesMessages
+                        .couldNotResolveComponentType(componentType, presentableNames(componentToClassName)));
+
+                return result;
+            }
+        });
+    }
+
+    Collection<String> presentableNames(Map<String, ?> map)
+    {
+        Set<String> result = CollectionFactory.newSet();
+
+        for (String name : map.keySet())
+        {
+
+            if (name.startsWith(CORE_LIBRARY_PREFIX))
+            {
+                result.add(name.substring(CORE_LIBRARY_PREFIX.length()));
+                continue;
+            }
+
+            result.add(name);
+        }
+
+        return result;
+    }
+
+    public String resolveMixinTypeToClassName(final String mixinType)
+    {
+        return barrier.withRead(new Invokable<String>()
+        {
+            public String invoke()
+            {
+                String result = locate(mixinType, mixinToClassName);
+
+                if (result == null) throw new IllegalArgumentException(
+                        ServicesMessages.couldNotResolveMixinType(mixinType, presentableNames(mixinToClassName)));
+
+                return result;
+            }
+        });
+    }
+
+    /**
+     * Locates a class name within the provided map, given its logical name. If not found naturally, a search inside the
+     * "core" library is included.
+     *
+     * @param logicalName            name to search for
+     * @param logicalNameToClassName mapping from logical name to class name
+     * @return the located class name or null
+     */
+    private String locate(String logicalName, Map<String, String> logicalNameToClassName)
+    {
+        rebuild();
+
+        String result = logicalNameToClassName.get(logicalName);
+
+        // If not found, see if it exists under the core package. In this way,
+        // anything in core is "inherited" (but overridable) by the application.
+
+        if (result == null) result = logicalNameToClassName.get(CORE_LIBRARY_PREFIX + logicalName);
+
+        return result;
+    }
+
+    public String resolvePageClassNameToPageName(final String pageClassName)
+    {
+        return barrier.withRead(new Invokable<String>()
+        {
+            public String invoke()
+            {
+                rebuild();
+
+                String result = pageClassNameToLogicalName.get(pageClassName);
+
+                if (result == null) throw new IllegalArgumentException(ServicesMessages
+                        .pageNameUnresolved(pageClassName));
+
+                return result;
+            }
+        });
+    }
+
+    public String canonicalizePageName(final String pageName)
+    {
+        return barrier.withRead(new Invokable<String>()
+        {
+            public String invoke()
+            {
+                String result = locate(pageName, pageNameToCanonicalPageName);
+
+                if (result == null) throw new IllegalArgumentException(ServicesMessages
+                        .couldNotCanonicalizePageName(pageName, presentableNames(pageNameToCanonicalPageName)));
+
+                return result;
+            }
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformer.java
new file mode 100644
index 0000000..832e707
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformer.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import javassist.CtClass;

+

+/**

+ * Encapsulates all the work performed by the {@link org.apache.tapestry.internal.services.ComponentInstantiatorSource}

+ * when it loads and transforms a class.

+ */

+public interface ComponentClassTransformer

+{

+    /**

+     * Performs a transformation on the class, accessing the class from the class pool.

+     *

+     * @param ctClass     compile time class to be transformed

+     * @param classLoader class loader used to resolve references to other classes (both transformed and not)

+     */

+    void transformComponentClass(CtClass ctClass, ClassLoader classLoader);

+

+    /**

+     * Creates a new instantiator instance.

+     *

+     * @param componentClassName fully qualified name of component class to instantiate

+     */

+    Instantiator createInstantiator(String componentClassName);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
new file mode 100644
index 0000000..b23aa40
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
@@ -0,0 +1,205 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.NotFoundException;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.model.MutableComponentModelImpl;
+import org.apache.tapestry.ioc.LoggerSource;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.ComponentLayer;
+import org.slf4j.Logger;
+
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+/**
+ * Implementation of {@link org.apache.tapestry.internal.services.ComponentClassTransformer}.
+ */
+public class ComponentClassTransformerImpl implements ComponentClassTransformer, InvalidationListener
+{
+    /**
+     * Map from class name to class transformation.
+     */
+    private final Map<String, InternalClassTransformation> nameToClassTransformation = CollectionFactory.newConcurrentMap();
+
+    private final Map<String, ComponentModel> nameToComponentModel = CollectionFactory.newConcurrentMap();
+
+    private final ComponentClassTransformWorker workerChain;
+
+    private final LoggerSource loggerSource;
+
+    private final ClassFactory classFactory;
+
+    private final CtClassSource classSource;
+
+    private final ComponentClassCache componentClassCache;
+
+    private final String[] SUBPACKAGES = { "." + InternalConstants.PAGES_SUBPACKAGE + ".",
+            "." + InternalConstants.COMPONENTS_SUBPACKAGE + ".",
+            "." + InternalConstants.MIXINS_SUBPACKAGE + ".",
+            "." + InternalConstants.BASE_SUBPACKAGE + "." };
+
+    /**
+     * @param workerChain         the ordered list of class transform works as a chain of command instance
+     * @param classSource
+     * @param componentClassCache
+     */
+    public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain,
+                                         LoggerSource loggerSource,
+                                         @ComponentLayer ClassFactory classFactory,
+                                         @ComponentLayer CtClassSource classSource,
+                                         ComponentClassCache componentClassCache)
+    {
+        this.workerChain = workerChain;
+        this.loggerSource = loggerSource;
+        this.classFactory = classFactory;
+        this.componentClassCache = componentClassCache;
+        this.classSource = classSource;
+    }
+
+    /**
+     * Clears the cache of {@link InternalClassTransformation} instances whenever the class loader is invalidated.
+     */
+    public void objectWasInvalidated()
+    {
+        nameToClassTransformation.clear();
+        nameToComponentModel.clear();
+    }
+
+    public void transformComponentClass(CtClass ctClass, ClassLoader classLoader)
+    {
+        String parentClassname;
+
+        // Component classes must be public
+
+        if (!Modifier.isPublic(ctClass.getModifiers())) return;
+
+        try
+        {
+            // And have a public constructor.
+
+            CtConstructor ctor = ctClass.getConstructor("()V");
+
+            if (!Modifier.isPublic(ctor.getModifiers())) return;
+        }
+        catch (NotFoundException ex)
+        {
+            return;
+        }
+
+        // Force the creation of the parent class.
+
+        try
+        {
+            parentClassname = ctClass.getSuperclass().getName();
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        String classname = ctClass.getName();
+
+        Logger logger = loggerSource.getLogger(classname);
+
+        // If the parent class is in a controlled package, it will already have been loaded and
+        // transformed (that is driven by the ComponentInstantiatorSource).
+
+        InternalClassTransformation parentTransformation = nameToClassTransformation
+                .get(parentClassname);
+
+        if (parentTransformation == null && !parentClassname.equals(Object.class.getName()))
+        {
+            String suggestedPackageName = buildSuggestedPackageName(classname);
+
+            throw new RuntimeException(
+                    ServicesMessages.baseClassInWrongPackage(parentClassname, classname, suggestedPackageName));
+        }
+
+        // TODO: Check that the name is not already in the map. But I think that can't happen,
+        // because the classloader itself is synchronized.
+
+        Resource baseResource = new ClasspathResource(classname.replace(".", "/") + ".class");
+
+        ComponentModel parentModel = nameToComponentModel.get(parentClassname);
+
+        MutableComponentModel model = new MutableComponentModelImpl(classname, logger, baseResource, parentModel);
+
+        InternalClassTransformation transformation =
+                parentTransformation == null
+                ? new InternalClassTransformationImpl(classFactory, ctClass, componentClassCache, model, classSource)
+                : parentTransformation.createChildTransformation(ctClass, model);
+
+        try
+        {
+            workerChain.transform(transformation, model);
+
+            transformation.finish();
+        }
+        catch (Throwable ex)
+        {
+            throw new TransformationException(transformation, ex);
+        }
+
+        if (logger.isDebugEnabled()) logger.debug("Finished class transformation: " + transformation);
+
+        nameToClassTransformation.put(classname, transformation);
+        nameToComponentModel.put(classname, model);
+    }
+
+    public Instantiator createInstantiator(String componentClassName)
+    {
+        InternalClassTransformation ct = nameToClassTransformation.get(componentClassName);
+
+        if (ct == null) throw new RuntimeException(ServicesMessages.classNotTransformed(componentClassName));
+
+        try
+        {
+            return ct.createInstantiator();
+        }
+        catch (Throwable ex)
+        {
+            throw new TransformationException(ct, ex);
+        }
+    }
+
+    private String buildSuggestedPackageName(String className)
+    {
+        for (String subpackage : SUBPACKAGES)
+        {
+            int pos = className.indexOf(subpackage);
+
+            // Keep the leading '.' in the subpackage name and tack on "base".
+
+            if (pos > 0) return className.substring(0, pos + 1) + InternalConstants.BASE_SUBPACKAGE;
+        }
+
+        // Is this even reachable?  className should always be in a controlled package and so
+        // some subpackage above should have matched.
+
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImpl.java
new file mode 100644
index 0000000..3ca58eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImpl.java
@@ -0,0 +1,110 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Messages;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.TranslatorSource;
+import org.apache.tapestry.services.ValueEncoderSource;
+
+public class ComponentDefaultProviderImpl implements ComponentDefaultProvider
+{
+    private final PropertyAccess propertyAccess;
+
+    private final BindingSource bindingSource;
+
+    private final ValueEncoderSource valueEncoderSource;
+
+    private final TranslatorSource translatorSource;
+
+    public ComponentDefaultProviderImpl(PropertyAccess propertyAccess, BindingSource bindingSource,
+                                        ValueEncoderSource valueEncoderSource, TranslatorSource translatorSource)
+    {
+        this.propertyAccess = propertyAccess;
+        this.bindingSource = bindingSource;
+        this.valueEncoderSource = valueEncoderSource;
+        this.translatorSource = translatorSource;
+    }
+
+    public String defaultLabel(ComponentResources resources)
+    {
+        notNull(resources, "resources");
+
+        String componentId = resources.getId();
+        String key = componentId + "-label";
+
+        Messages containerMessages = resources.getContainerResources().getMessages();
+
+        if (containerMessages.contains(key)) return containerMessages.get(key);
+
+        return TapestryInternalUtils.toUserPresentable(componentId);
+    }
+
+    public Binding defaultBinding(String parameterName, ComponentResources resources)
+    {
+        notBlank(parameterName, "parameterName");
+        notNull(resources, "resources");
+
+        String componentId = resources.getId();
+
+        Component container = resources.getContainer();
+
+        // Only provide a default binding if the container actually contains the property.
+        // This sets up an error condition for when the parameter is not bound, and
+        // the binding can't be deduced.
+
+        if (propertyAccess.getAdapter(container).getPropertyAdapter(componentId) == null)
+            return null;
+
+        ComponentResources containerResources = resources.getContainerResources();
+
+        return bindingSource.newBinding(
+                "default " + parameterName,
+                containerResources,
+                BindingConstants.PROP,
+                componentId);
+    }
+
+    public ValueEncoder defaultValueEncoder(String parameterName, ComponentResources resources)
+    {
+        notBlank(parameterName, "parameterName");
+        notNull(resources, "resources");
+
+        Class parameterType = resources.getBoundType(parameterName);
+
+        if (parameterType == null) return null;
+
+        return valueEncoderSource.getValueEncoder(parameterType);
+    }
+
+    public Translator defaultTranslator(String parameterName, ComponentResources resources)
+    {
+        notBlank(parameterName, "parameterName");
+        notNull(resources, "resources");
+
+        Class type = resources.getBoundType(parameterName);
+
+        if (type == null) return null;
+
+        return translatorSource.findByType(type);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
new file mode 100644
index 0000000..38a6d29
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
@@ -0,0 +1,155 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.EmptyEventContext;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.URLEventContext;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Processes component action events sent as requests from the client. Action events include an event type, identify a
+ * page and a component, and may provide additional context strings.
+ * <p/>
+ * Forms: <ul> <li>/context/pagename:eventname -- event on the page, no action context</li>
+ * <li>/context/pagename:eventname/foo/bar -- event on the page with action context "foo", "bar"</li>
+ * <li>/context/pagename.foo.bar -- event on component foo.bar within the page, default event, no action context</li>
+ * <li>/context/pagename.foo.bar/baz.gnu -- event on component foo.bar within the page, default event, with action
+ * context "baz", "gnu"</li> <li>/context/pagename.bar.baz:eventname/foo/gnu -- event on component bar.baz within the
+ * page with action context "foo" , "gnu"</li> </ul>
+ * <p/>
+ * The page name portion may itself consist of a series of folder names, i.e., "admin/user/create".  The context portion
+ * isn't the concern of this code, since {@link org.apache.tapestry.services.Request#getPath()} will already have
+ * stripped that off.  We can act as if the context is always "/" (the path always starts with a slash).
+ *
+ * @see LinkFactory#createActionLink(org.apache.tapestry.internal.structure.Page, String, String,boolean, Object...)
+ */
+public class ComponentEventDispatcher implements Dispatcher
+{
+    private final ComponentClassResolver componentClassResolver;
+
+    private final ComponentEventRequestHandler componentEventRequestHandler;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    private final RequestEncodingInitializer requestEncodingInitializer;
+
+    private final EventContext emptyContext = new EmptyEventContext();
+
+    public ComponentEventDispatcher(@Traditional ComponentEventRequestHandler componentEventRequestHandler,
+                                    ComponentClassResolver componentClassResolver,
+                                    ContextValueEncoder contextValueEncoder,
+                                    RequestEncodingInitializer requestEncodingInitializer)
+    {
+        this.componentEventRequestHandler = componentEventRequestHandler;
+        this.componentClassResolver = componentClassResolver;
+        this.contextValueEncoder = contextValueEncoder;
+        this.requestEncodingInitializer = requestEncodingInitializer;
+    }
+
+    // A beast that recognizes all the elements of a path in a single go.
+    // We skip the leading slash, then take the next few terms (until a dot or a colon)
+    // as the page name.  Then there's a sequence that sees a dot
+    // and recognizes the nested component id (which may be missing), which ends
+    // at the colon, or at the slash (or the end of the string).  The colon identifies
+    // the event name (the event name is also optional).  A valid path will always have
+    // a nested component id or an event name (or both) ... when both are missing, then the
+    // path is most likely a page render request.  After the optional event name,
+    // the next piece is the action context, which is the remainder of the path.
+
+    private final Pattern PATH_PATTERN = Pattern.compile(
+
+            "^/" +      // The leading slash is recognized but skipped
+                    "(((\\w+)/)*(\\w+))" + // A series of folder names leading up to the page name, forming the logical page name
+                    "(\\.(\\w+(\\.\\w+)*))?" + // The first dot separates the page name from the nested component id
+                    "(\\:(\\w+))?" + // A colon, then the event type
+                    "(/(.*))?", //  A slash, then the action context
+                                Pattern.COMMENTS);
+
+    // Constants for the match groups in the above pattern.
+    private static final int LOGICAL_PAGE_NAME = 1;
+    private static final int NESTED_ID = 6;
+    private static final int EVENT_NAME = 9;
+    private static final int CONTEXT = 11;
+
+    public boolean dispatch(Request request, Response response) throws IOException
+    {
+        Matcher matcher = PATH_PATTERN.matcher(request.getPath());
+
+        if (!matcher.matches()) return false;
+
+        String activePageName = matcher.group(LOGICAL_PAGE_NAME);
+
+        String nestedComponentId = matcher.group(NESTED_ID);
+
+        String eventType = matcher.group(EVENT_NAME);
+
+        if (nestedComponentId == null && eventType == null) return false;
+
+        if (!componentClassResolver.isPageName(activePageName)) return false;
+
+        EventContext eventContext = decodeContext(matcher.group(CONTEXT));
+
+        // Initialize the request encoding BEFORE accessing any query parameters
+        // (TAPESTRY-1605)
+
+        requestEncodingInitializer.initializeRequestEncoding(activePageName);
+
+        EventContext activationContext = decodeContext(request.getParameter(InternalConstants.PAGE_CONTEXT_NAME));
+
+        // The event type is often omitted, and defaults to "action".
+
+        if (eventType == null) eventType = EventConstants.ACTION;
+
+        if (nestedComponentId == null) nestedComponentId = "";
+
+        String containingPageName = request.getParameter(InternalConstants.CONTAINER_PAGE_NAME);
+
+        if (containingPageName == null) containingPageName = activePageName;
+
+        ComponentEventRequestParameters parameters = new ComponentEventRequestParameters(activePageName,
+                                                                                         containingPageName,
+                                                                                         nestedComponentId, eventType,
+                                                                                         activationContext,
+                                                                                         eventContext);
+
+        componentEventRequestHandler.handle(parameters);
+
+        return true;
+    }
+
+
+    private EventContext decodeContext(String input)
+    {
+        if (input == null) return emptyContext;
+
+        String[] values = TapestryInternalUtils.splitPath(input);
+
+        for (int i = 0; i < values.length; i++)
+        {
+            values[i] = TapestryInternalUtils.unescapePercentAndSlash(values[i]);
+        }
+
+        return new URLEventContext(contextValueEncoder, values);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
new file mode 100644
index 0000000..193332d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventImpl.java
@@ -0,0 +1,93 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.structure.PageResources;
+import org.apache.tapestry.runtime.ComponentEvent;
+
+public class ComponentEventImpl extends EventImpl implements ComponentEvent
+{
+    private final String eventType;
+
+    private final String originatingComponentId;
+
+    private final EventContext context;
+
+    private final PageResources pageResources;
+
+    /**
+     * @param eventType              non blank string used to identify the type of event that was triggered
+     * @param originatingComponentId the id of the component that triggered the event (this will likely need to change
+     *                               somewhat)
+     * @param context                provides access to parameter values
+     * @param handler                invoked when a non-null return value is obtained from an event handler method
+     * @param pageResources          provides access to common resources and services
+     */
+    public ComponentEventImpl(String eventType, String originatingComponentId, EventContext context,
+                              ComponentEventCallback handler, PageResources pageResources)
+    {
+        super(handler);
+
+        this.eventType = eventType;
+        this.originatingComponentId = originatingComponentId;
+        this.pageResources = pageResources;
+        this.context = context;
+    }
+
+    public boolean matches(String eventType, String componentId, int parameterCount)
+    {
+        return this.eventType.equalsIgnoreCase(
+                eventType) && context.getCount() >= parameterCount && (originatingComponentId.equalsIgnoreCase(
+                componentId) || componentId.equals(""));
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object coerceContext(int index, String desiredTypeName)
+    {
+        if (index >= context.getCount()) throw new IllegalArgumentException(ServicesMessages
+                .contextIndexOutOfRange(getMethodDescription()));
+        try
+        {
+            Class desiredType = pageResources.toClass(desiredTypeName);
+
+            return context.get(desiredType, index);
+
+        }
+        catch (Exception ex)
+        {
+            throw new IllegalArgumentException(
+                    ServicesMessages.exceptionInMethodParameter(getMethodDescription(), index, ex), ex);
+        }
+    }
+
+    public Object[] getContext()
+    {
+        int count = context.getCount();
+
+        Object[] result = new Object[count];
+
+        for (int i = 0; i < count; i++)
+            result[i] = context.get(Object.class, i);
+
+        return result;
+    }
+
+    public EventContext getEventContext()
+    {
+        return context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java
new file mode 100644
index 0000000..4c3b406
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentEventRequestHandlerImpl.java
@@ -0,0 +1,75 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+public class ComponentEventRequestHandlerImpl implements ComponentEventRequestHandler
+{
+    private final ComponentEventResultProcessor resultProcessor;
+
+    private final RequestPageCache cache;
+
+    private final Response response;
+
+    private final ActionRenderResponseGenerator generator;
+
+    private final Environment environment;
+
+    public ComponentEventRequestHandlerImpl(@Traditional ComponentEventResultProcessor resultProcessor,
+                                            RequestPageCache cache, Response response,
+                                            ActionRenderResponseGenerator generator, Environment environment)
+    {
+        this.resultProcessor = resultProcessor;
+        this.cache = cache;
+        this.response = response;
+        this.generator = generator;
+        this.environment = environment;
+    }
+
+    public void handle(ComponentEventRequestParameters parameters) throws IOException
+    {
+        Page activePage = cache.get(parameters.getActivePageName());
+
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(resultProcessor);
+
+        // If activating the page returns a "navigational result", then don't trigger the action
+        // on the component.
+
+        activePage.getRootElement().triggerContextEvent(EventConstants.ACTIVATE,
+                                                        parameters.getPageActivationContext(), callback);
+
+        if (callback.isAborted()) return;
+
+        Page containerPage = cache.get(parameters.getContainingPageName());
+
+        ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
+
+        environment.push(ComponentEventResultProcessor.class, resultProcessor);
+
+        element.triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
+
+        environment.pop(ComponentEventResultProcessor.class);
+
+        if (callback.isAborted()) return;
+
+        if (!response.isCommitted()) generator.generateResponse(activePage);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java
new file mode 100644
index 0000000..4bcfd8c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessor.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+
+public class ComponentInstanceResultProcessor implements ComponentEventResultProcessor<Component>
+{
+    private final RequestPageCache requestPageCache;
+
+    private final Logger logger;
+
+    private final ActionRenderResponseGenerator generator;
+
+    public ComponentInstanceResultProcessor(Logger logger, RequestPageCache requestPageCache,
+                                            ActionRenderResponseGenerator generator)
+    {
+        this.requestPageCache = requestPageCache;
+        this.logger = logger;
+        this.generator = generator;
+    }
+
+    public void processResultValue(Component value) throws IOException
+    {
+        ComponentResources resources = value.getComponentResources();
+
+        if (resources.getContainer() != null)
+            logger.warn(ServicesMessages.componentInstanceIsNotAPage(value));
+
+        // We have all these layers and layers between us and the page instance, but its easy to
+        // extract the page class name and quickly re-resolve that to the page instance.
+
+        Page page = requestPageCache.get(resources.getPageName());
+
+        generator.generateResponse(page);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java
new file mode 100644
index 0000000..c1814a1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java
@@ -0,0 +1,72 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+/**
+ * Creates {@link org.apache.tapestry.internal.services.Instantiator}s for components, based on component class name.
+ * This will involve transforming the component's class before it is loaded.
+ * <p/>
+ * In addition, a source acts as an event hub for {@link org.apache.tapestry.internal.events.InvalidationListener}s, so
+ * that any information derived from loaded classes can be discarded and rebuilt when classes change.
+ * <p/>
+ * The strategy used is that when <em>any</em> class (in a controlled package) changes, the entire class loader is
+ * discarded, along with any instances derived from those classes. A new class loader is created, and then invalidation
+ * events are fired to listeners.
+ */
+public interface ComponentInstantiatorSource extends InvalidationEventHub
+{
+
+    /**
+     * Given the name of a component class, provides an instantiator for that component. Instantiators are cached, so
+     * repeated calls to this method with the same class name will return the same instance; however, callers should
+     * also be aware that the instantiators may lose validity after an invalidation (caused by changes to external Java
+     * class files).
+     *
+     * @param classname FQCN to find (and perhaps transform and load)
+     * @return an object which can instantiate an instance of the component
+     */
+    Instantiator findInstantiator(String classname);
+
+    /**
+     * Adds a controlled package. Only classes within controlled packages are subject to transformation.
+     *
+     * @param packageName the package name to add (must not be blank)
+     */
+    void addPackage(String packageName);
+
+    /**
+     * Checks to see if a fully qualfied class name exists.
+     *
+     * @param className name of class to check
+     * @return true if the class exists (there's a ".class" file), false otherwise
+     */
+    boolean exists(String className);
+
+    /**
+     * Returns a class factory that can be used to generate additional classes around enhanced classes, or create
+     * subclasses of enhanced classes.
+     */
+    ClassFactory getClassFactory();
+
+    /**
+     * Returns a class source used when creating new classes dynamically.
+     */
+    CtClassSource getClassSource();
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
new file mode 100644
index 0000000..8d21155
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
@@ -0,0 +1,314 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.*;
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryClassPool;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.internal.services.CtClassSourceImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A wrapper around a Javassist class loader that allows certain classes to be modified as they are loaded.
+ */
+public final class ComponentInstantiatorSourceImpl extends InvalidationEventHubImpl implements Translator, ComponentInstantiatorSource, UpdateListener
+{
+    /**
+     * Add -Djavassist-write-dir=target/transformed-classes to the command line to force output of transformed classes
+     * to disk (for hardcore debugging).
+     */
+    private static final String JAVASSIST_WRITE_DIR = System.getProperty("javassist-write-dir");
+
+    private final Set<String> controlledPackageNames = CollectionFactory.newSet();
+
+    private final URLChangeTracker changeTracker = new URLChangeTracker();
+
+    private final ClassLoader parent;
+
+    private final InternalRequestGlobals internalRequestGlobals;
+
+    private Loader loader;
+
+    private final ComponentClassTransformer transformer;
+
+    private final Logger logger;
+
+    private ClassFactory classFactory;
+
+    /**
+     * Map from class name to Instantiator.
+     */
+    private final Map<String, Instantiator> classNameToInstantiator = CollectionFactory.newMap();
+
+    private CtClassSource classSource;
+
+    private class PackageAwareLoader extends Loader
+    {
+        public PackageAwareLoader(ClassLoader parent, ClassPool classPool)
+        {
+            super(parent, classPool);
+        }
+
+        @Override
+        protected Class findClass(String className) throws ClassNotFoundException
+        {
+            if (inControlledPackage(className)) return super.findClass(className);
+
+            // Returning null forces delegation to the parent class loader.
+
+            return null;
+        }
+
+    }
+
+    public ComponentInstantiatorSourceImpl(Logger logger, ClassLoader parent, ComponentClassTransformer transformer,
+                                           InternalRequestGlobals internalRequestGlobals)
+    {
+        this.parent = parent;
+        this.transformer = transformer;
+        this.logger = logger;
+        this.internalRequestGlobals = internalRequestGlobals;
+
+        initializeService();
+    }
+
+    public synchronized void checkForUpdates()
+    {
+        if (!changeTracker.containsChanges()) return;
+
+        changeTracker.clear();
+        classNameToInstantiator.clear();
+
+        // Release the existing class pool, loader and so forth.
+        // Create a new one.
+
+        initializeService();
+
+        // Tell everyone that the world has changed and they should discard
+        // their cache.
+
+        fireInvalidationEvent();
+    }
+
+    /**
+     * Invoked at object creation, or when there are updates to class files (i.e., invalidation), to create a new set of
+     * Javassist class pools and loaders.
+     */
+    private void initializeService()
+    {
+        ClassFactoryClassPool classPool = new ClassFactoryClassPool(parent);
+
+        loader = new PackageAwareLoader(parent, classPool);
+
+        ClassPath path = new LoaderClassPath(loader);
+
+        classPool.appendClassPath(path);
+
+        classSource = new CtClassSourceImpl(classPool, loader);
+
+        try
+        {
+            loader.addTranslator(classPool, this);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        classFactory = new ClassFactoryImpl(loader, classPool, classSource, logger);
+    }
+
+    // This is called from well within a synchronized block.
+    public void onLoad(ClassPool pool, String classname) throws NotFoundException, CannotCompileException
+    {
+        logger.debug("BEGIN onLoad " + classname);
+
+        // This is our chance to make changes to the CtClass before it is loaded into memory.
+
+        String diag = "FAIL";
+
+        // If we are loading a class, it is because it is in a controlled package. There may be
+        // errors in the class that keep it from loading. By adding it to the change tracker
+        // early, we ensure that when the class is fixed, the change is picked up. Originally,
+        // this code was at the end of the method, and classes that contained errors would not be
+        // reloaded even after the code was fixed.
+
+        addClassFileToChangeTracker(classname);
+
+        try
+        {
+            CtClass ctClass = pool.get(classname);
+
+            // Force the creation of the super-class before the target class.
+
+            forceSuperclassTransform(ctClass);
+
+            // Do the transformations here
+
+            transformer.transformComponentClass(ctClass, loader);
+
+            writeClassToFileSystemForHardCoreDebuggingPurposesOnly(ctClass);
+
+            diag = "END";
+        }
+        catch (RuntimeException classLoaderException)
+        {
+            internalRequestGlobals.storeClassLoaderException(classLoaderException);
+
+            throw classLoaderException;
+        }
+        finally
+        {
+            logger.debug(String.format("%5s onLoad %s", diag, classname));
+        }
+    }
+
+    private void writeClassToFileSystemForHardCoreDebuggingPurposesOnly(CtClass ctClass)
+    {
+        if (JAVASSIST_WRITE_DIR == null) return;
+
+        try
+        {
+            boolean p = ctClass.stopPruning(true);
+            ctClass.writeFile(JAVASSIST_WRITE_DIR);
+            ctClass.defrost();
+            ctClass.stopPruning(p);
+
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private void addClassFileToChangeTracker(String classname)
+    {
+        String path = classname.replace('.', '/') + ".class";
+
+        URL url = loader.getResource(path);
+
+        changeTracker.add(url);
+    }
+
+    private void forceSuperclassTransform(CtClass ctClass) throws NotFoundException
+    {
+        CtClass superClass = ctClass.getSuperclass();
+
+        findClass(superClass.getName());
+    }
+
+    /**
+     * Does nothing.
+     */
+    public void start(ClassPool pool) throws NotFoundException, CannotCompileException
+    {
+    }
+
+    public synchronized Instantiator findInstantiator(String className)
+    {
+        Instantiator result = classNameToInstantiator.get(className);
+
+        if (result == null)
+        {
+            // Force the creation of the class (and the transformation of the class).
+
+            findClass(className);
+
+            result = transformer.createInstantiator(className);
+
+            classNameToInstantiator.put(className, result);
+        }
+
+        return result;
+    }
+
+    private Class findClass(String classname)
+    {
+        try
+        {
+            return loader.loadClass(classname);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Returns true if the package for the class name is in a package that is controlled by the enhancer. Controlled
+     * packages are identified by {@link #addPackage(String)}.
+     */
+
+    boolean inControlledPackage(String classname)
+    {
+        String packageName = stripTail(classname);
+
+        while (packageName != null)
+        {
+            if (controlledPackageNames.contains(packageName)) return true;
+
+            packageName = stripTail(packageName);
+        }
+
+        return false;
+    }
+
+    private String stripTail(String input)
+    {
+        int lastdot = input.lastIndexOf('.');
+
+        if (lastdot < 0) return null;
+
+        return input.substring(0, lastdot);
+    }
+
+    // synchronized may be overkill, but that's ok.
+    public synchronized void addPackage(String packageName)
+    {
+        Defense.notBlank(packageName, "packageName");
+
+        // TODO: Should we check that packages are not nested?
+
+        controlledPackageNames.add(packageName);
+    }
+
+    public boolean exists(String className)
+    {
+        String path = className.replace(".", "/") + ".class";
+
+        return parent.getResource(path) != null;
+    }
+
+    public ClassFactory getClassFactory()
+    {
+        return classFactory;
+    }
+
+    public CtClassSource getClassSource()
+    {
+        return classSource;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocation.java
new file mode 100644
index 0000000..deb121f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocation.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.util.List;
+
+public interface ComponentInvocation
+{
+    /**
+     * @return A path taking the format <em>target-path</em>/e1/e2?&q1=v1&q2=v2. where the <em>target-path</em> is the
+     *         path provided by the invocation target; e1 and e2 are elements of the context; q1 and q2 are the
+     *         parameters.
+     */
+    String buildURI(boolean isForm);
+
+    String[] getContext();
+
+    String[] getActivationContext();
+
+    void addParameter(String parameterName, String value);
+
+    List<String> getParameterNames();
+
+    String getParameterValue(String name);
+
+    InvocationTarget getTarget();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationImpl.java
new file mode 100644
index 0000000..847c5c4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationImpl.java
@@ -0,0 +1,143 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.test.PageTester;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents an invocation for a page or a component in the current application. This information is extracted from
+ * incoming URLs for a running application (or created by the {@link PageTester}. Each invocation may provide a context
+ * (Object[]) and parameters to the invocation target.
+ */
+public class ComponentInvocationImpl implements ComponentInvocation
+{
+    private final String[] context;
+
+    private final InvocationTarget target;
+
+    private final String[] activationContext;
+
+    private Map<String, String> parameters;
+
+    /**
+     * @param target            identifies the target of the event: a component with a page
+     * @param context           context information supplied by the component to be provided back when the event on the
+     *                          component is triggered, or contains the activation context when the invocation is for a
+     *                          page render request
+     * @param activationContext page activation context for the page containing the component, supplied via a passivate
+     *                          event to the page's root component (used when an action component invocation is for a
+     *                          page with an activation context)
+     */
+    public ComponentInvocationImpl(InvocationTarget target, String[] context, String[] activationContext)
+    {
+        this.target = target;
+        this.context = context;
+        this.activationContext = activationContext;
+    }
+
+
+    public String buildURI(boolean isForm)
+    {
+        String path = getPath();
+        if (isForm || parameters == null) return path;
+
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(path);
+
+        String sep = "?";
+
+        for (String name : getParameterNames())
+        {
+            String value = parameters.get(name);
+
+            builder.append(sep);
+
+            // We assume that the name is URL safe and that the value will already have been URL
+            // encoded if it is not known to be URL safe.
+
+            builder.append(name);
+            builder.append("=");
+            builder.append(value);
+
+            sep = "&";
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * @return Just like the return value of {@link #buildURI(boolean)} except that parameters are not included.
+     */
+    private String getPath()
+    {
+        StringBuilder builder = new StringBuilder();
+        builder.append(target.getPath());
+
+        for (String id : context)
+        {
+            if (builder.length() > 0) builder.append("/");
+
+            builder.append(TapestryInternalUtils.encodeContext(id));
+        }
+
+        return builder.toString();
+    }
+
+    public String[] getContext()
+    {
+        return context;
+    }
+
+    public String[] getActivationContext()
+    {
+        return activationContext;
+    }
+
+    public void addParameter(String parameterName, String value)
+    {
+        notBlank(parameterName, "parameterName");
+        notBlank(value, "value");
+
+        if (parameters == null) parameters = newMap();
+
+        if (parameters.containsKey(parameterName)) throw new IllegalArgumentException(
+                ServicesMessages.parameterNameMustBeUnique(parameterName, parameters.get(parameterName)));
+
+        parameters.put(parameterName, value);
+    }
+
+    public List<String> getParameterNames()
+    {
+        return InternalUtils.sortedKeys(parameters);
+    }
+
+    public String getParameterValue(String name)
+    {
+        return InternalUtils.get(parameters, name);
+    }
+
+    public InvocationTarget getTarget()
+    {
+        return target;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationMap.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationMap.java
new file mode 100644
index 0000000..4458646
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentInvocationMap.java
@@ -0,0 +1,61 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.test.PageTester;
+
+/**
+ * Used by the {@link PageTester} to map {@link Element}s (pulled from the rendered {@link Document}) into {@link
+ * ComponentInvocation}s, that can be used to to trigger further (simulated) requests. In this way, a unit test can have
+ * the {@link PageTester#clickLink(Element) click a link} or {@link PageTester#submitForm(Element, java.util.Map) submit
+ * a form}.
+ * <p/>
+ * The information needed is generated in slightly disparate places, so the {@link LinkFactory} tells the map about
+ * Links and ComponentInvocations, and the {@link MarkupWriter} will link Elements to Link instance.
+ */
+public interface ComponentInvocationMap
+{
+    /**
+     * Stores a connection between a particular link and an invocation of a component.
+     */
+    void store(Link link, ComponentInvocation invocation);
+
+    /**
+     * Stores a connection between an element and the link associated with that element.
+     */
+    void store(Element element, Link link);
+
+    /**
+     * Returns the invocation associated with a link.
+     *
+     * @param link previously create link
+     * @return associcated component invocation, or null
+     */
+    ComponentInvocation get(Link link);
+
+    /**
+     * Returns the invocation associated with a rendered element.
+     *
+     * @param element extracted from the rendered {@link Document}
+     * @return the corresponding invocation
+     */
+    ComponentInvocation get(Element element);
+
+    void clear();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImpl.java
new file mode 100644
index 0000000..84f0227
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImpl.java
@@ -0,0 +1,119 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+
+import java.util.Locale;
+
+public class ComponentMessagesSourceImpl implements ComponentMessagesSource, UpdateListener
+{
+    private final MessagesSource messagesSource;
+
+    private final Resource rootResource;
+
+    private final String appCatalog;
+
+    private static class ComponentModelBundle implements MessagesBundle
+    {
+        private final ComponentModel model;
+
+        private final MessagesBundle rootBundle;
+
+        public ComponentModelBundle(ComponentModel model, MessagesBundle rootBundle)
+        {
+            this.model = model;
+            this.rootBundle = rootBundle;
+        }
+
+        public Resource getBaseResource()
+        {
+            return model.getBaseResource();
+        }
+
+        public Object getId()
+        {
+            return model.getComponentClassName();
+        }
+
+        public MessagesBundle getParent()
+        {
+            ComponentModel parentModel = model.getParentModel();
+
+            if (parentModel == null) return rootBundle;
+
+            return new ComponentModelBundle(parentModel, rootBundle);
+        }
+    }
+
+    public ComponentMessagesSourceImpl(Resource rootResource, String appCatalog)
+    {
+        this(rootResource, appCatalog, new URLChangeTracker());
+    }
+
+    ComponentMessagesSourceImpl(Resource rootResource, String appCatalog, URLChangeTracker tracker)
+    {
+        this.rootResource = rootResource;
+        this.appCatalog = appCatalog;
+
+        messagesSource = new MessagesSourceImpl(tracker);
+    }
+
+    public void checkForUpdates()
+    {
+        messagesSource.checkForUpdates();
+    }
+
+    public Messages getMessages(ComponentModel componentModel, Locale locale)
+    {
+        final Resource appCatalogResource = rootResource.forFile(appCatalog);
+
+        // If the application catalog exists, set it up as the root, otherwise use null.
+
+        MessagesBundle appCatalogBundle = !appCatalogResource.exists() ? null
+                                          : new MessagesBundle()
+        {
+            public Resource getBaseResource()
+            {
+                return appCatalogResource;
+            }
+
+            public Object getId()
+            {
+                return appCatalog;
+            }
+
+            public MessagesBundle getParent()
+            {
+                return null;
+            }
+        };
+
+        MessagesBundle bundle = new ComponentModelBundle(componentModel, appCatalogBundle);
+
+        return messagesSource.getMessages(bundle, locale);
+    }
+
+    public void addInvalidationListener(InvalidationListener listener)
+    {
+        messagesSource.addInvalidationListener(listener);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
new file mode 100644
index 0000000..b8c420e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
@@ -0,0 +1,46 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+
+import static java.lang.String.format;
+
+/**
+ * Allows for the injection of the component's {@link org.apache.tapestry.ComponentResources}.
+ */
+public class ComponentResourcesInjectionProvider implements InjectionProvider
+{
+    public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                                    ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        if (fieldType.equals(ComponentResources.class))
+        {
+            String body = format("%s = %s;", fieldName, transformation.getResourcesFieldName());
+
+            transformation.extendConstructor(body);
+
+            transformation.makeReadOnly(fieldName);
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java
new file mode 100644
index 0000000..b659564
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesOperation.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+
+/**
+ * A kind of callback that can easily be injected into a transformed class to perform complex work.
+ * <p/>
+ * These callbacks are often injected into a transformed component class via {@link
+ * org.apache.tapestry.services.ClassTransformation#addInjectedField(Class, String, Object)}. Bear in mind that such
+ * callbacks must be <em>threadsafe</em>, since every instance of such a class will share a single instance of the
+ * operation.
+ */
+public interface ComponentResourcesOperation
+{
+    /**
+     * Perform some operation that requires the components' resources.
+     */
+    void perform(ComponentResources resources);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java
new file mode 100644
index 0000000..89b80a0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentResultProcessorWrapper.java
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * A wrapper around {@link ComponentEventResultProcessor} that encapsulates capturing the exception.
+ */
+public class ComponentResultProcessorWrapper implements ComponentEventCallback
+{
+    private boolean aborted;
+
+    private IOException exception;
+
+    private final ComponentEventResultProcessor processor;
+
+    public ComponentResultProcessorWrapper(ComponentEventResultProcessor processor)
+    {
+        this.processor = processor;
+    }
+
+    public boolean handleResult(Object result)
+    {
+        try
+        {
+            processor.processResultValue(result);
+        }
+        catch (IOException ex)
+        {
+            exception = ex;
+        }
+
+        aborted = true;
+
+        return true;
+    }
+
+    /**
+     * Returns true if {@link org.apache.tapestry.ComponentEventCallback#handleResult(Object)} was invoked, false
+     * otherwise.
+     *
+     * @return true if the event was aborted
+     * @throws IOException if {@link ComponentEventResultProcessor#processResultValue(Object)} threw an IOException
+     */
+    public boolean isAborted() throws IOException
+    {
+        if (exception != null) throw exception;
+
+        return aborted;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
new file mode 100644
index 0000000..37d2ff6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentSourceImpl.java
@@ -0,0 +1,75 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+
+public class ComponentSourceImpl implements ComponentSource
+{
+    private final RequestPageCache pageCache;
+
+    public ComponentSourceImpl(RequestPageCache pageCache)
+    {
+        this.pageCache = pageCache;
+    }
+
+    public Component getComponent(String completeId)
+    {
+        int colonx = completeId.indexOf(':');
+
+        if (colonx < 0)
+        {
+            Page page = pageCache.get(completeId);
+
+            return page.getRootComponent();
+        }
+
+        String pageName = completeId.substring(0, colonx);
+
+        Page page = pageCache.get(pageName);
+        String nestedId = completeId.substring(colonx + 1);
+        String mixinId = null;
+
+        int dollarx = nestedId.indexOf("$");
+
+        if (dollarx > 0)
+        {
+            mixinId = nestedId.substring(dollarx + 1);
+            nestedId = nestedId.substring(0, dollarx);
+        }
+
+
+        ComponentPageElement element = page.getComponentElementByNestedId(nestedId);
+
+        if (mixinId == null)
+            return element.getComponent();
+
+        ComponentResources resources = element.getMixinResources(mixinId);
+
+        return resources.getComponent();
+    }
+
+    public Component getPage(String pageName)
+    {
+        Page page = pageCache.get(pageName);
+
+        return page.getRootComponent();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSource.java
new file mode 100644
index 0000000..9ad2955
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSource.java
@@ -0,0 +1,47 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.model.ComponentModel;
+
+import java.util.Locale;
+
+/**
+ * Provides access to cached {@link org.apache.tapestry.internal.parser.ComponentTemplate}s. The source acts as a
+ * invalidation event hub, and will broadcast invalidation events when any loaded template resource changes. The
+ * listener for these invalidation events is the page source, which stores cached page instances.
+ * <p/>
+ * Any search for a template will end with success (a non-null template), but the template returned may be the {@link
+ * ComponentTemplate#isMissing() missing template}.
+ * <p/>
+ * TODO: A more sophisticated, finer grained dependency manager.
+ */
+public interface ComponentTemplateSource extends InvalidationEventHub
+{
+    /**
+     * Provides access to a template. The template will be parsed as necessary. If no template for the exact component
+     * is found, then the template for the component's parent is returned. In this way, it is possible for a component
+     * to extend the behavior of its super-class without duplicating the super-class component's template.
+     * <p/>
+     * In some cases, the empty template will be returned.
+     *
+     * @param componentModel model for the component whose template is to be accessed
+     * @param locale         the locale to find the template within
+     * @return the cached template instance
+     */
+    ComponentTemplate getTemplate(ComponentModel componentModel, Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImpl.java
new file mode 100644
index 0000000..f2b5eef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImpl.java
@@ -0,0 +1,197 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.TemplateToken;
+import org.apache.tapestry.internal.util.MultiKey;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.model.ComponentModel;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Service implementation that manages a cache of parsed component templates.
+ */
+public final class ComponentTemplateSourceImpl extends InvalidationEventHubImpl implements ComponentTemplateSource, UpdateListener
+{
+
+    private final TemplateParser parser;
+
+    private final PageTemplateLocator locator;
+
+    private final URLChangeTracker tracker;
+
+    /**
+     * Caches from a key (combining component name and locale) to a resource. Often, many different keys will point to
+     * the same resource (i.e., "foo:en_US", "foo:en_UK", and "foo:en" may all be parsed from the same "foo.tml"
+     * resource). The resource may end up being null, meaning the template does not exist in any locale.
+     */
+    private final Map<MultiKey, Resource> templateResources = CollectionFactory.newConcurrentMap();
+
+    /**
+     * Cache of parsed templates, keyed on resource.
+     */
+    private final Map<Resource, ComponentTemplate> templates = CollectionFactory.newConcurrentMap();
+
+    private final ComponentTemplate missingTemplate = new ComponentTemplate()
+    {
+        public Set<String> getComponentIds()
+        {
+            return null;
+        }
+
+        public Resource getResource()
+        {
+            return null;
+        }
+
+        public List<TemplateToken> getTokens()
+        {
+            return null;
+        }
+
+        public boolean isMissing()
+        {
+            return true;
+        }
+    };
+
+    public ComponentTemplateSourceImpl(TemplateParser parser, PageTemplateLocator locator)
+    {
+        this(parser, locator, new URLChangeTracker());
+    }
+
+    ComponentTemplateSourceImpl(TemplateParser parser, PageTemplateLocator locator, URLChangeTracker tracker)
+    {
+        this.parser = parser;
+        this.locator = locator;
+        this.tracker = tracker;
+    }
+
+    /**
+     * Resolves the component name to a {@link Resource} and finds the localization of that resource (the combination of
+     * component name and locale is resolved to a resource). The localized resource is used as the key to a cache of
+     * {@link ComponentTemplate}s.
+     * <p/>
+     * If a template doesn't exist, then the missing ComponentTemplate is returned.
+     */
+    public ComponentTemplate getTemplate(ComponentModel componentModel, Locale locale)
+    {
+        String componentName = componentModel.getComponentClassName();
+
+        MultiKey key = new MultiKey(componentName, locale);
+
+        // First cache is key to resource.
+
+        Resource resource = templateResources.get(key);
+
+        if (resource == null)
+        {
+            resource = locateTemplateResource(componentModel, locale);
+            templateResources.put(key, resource);
+        }
+
+        // If we haven't yet parsed the template into the cache, do so now.
+
+        ComponentTemplate result = templates.get(resource);
+
+        if (result == null)
+        {
+            result = parseTemplate(resource);
+            templates.put(resource, result);
+        }
+
+        return result;
+    }
+
+    private ComponentTemplate parseTemplate(Resource r)
+    {
+        // In a race condition, we may parse the same template more than once. This will likely add
+        // the resource to the tracker multiple times. Not likely this will cause a big issue.
+
+        if (!r.exists()) return missingTemplate;
+
+        tracker.add(r.toURL());
+
+        return parser.parseTemplate(r);
+    }
+
+    private Resource locateTemplateResource(ComponentModel initialModel, Locale locale)
+    {
+        ComponentModel model = initialModel;
+        while (model != null)
+        {
+
+            Resource baseResource = baseResourceForModel(model);
+            Resource localized = baseResource.forLocale(locale);
+
+            // In a race condition, we may hit this method a couple of times, and overwrite previous
+            // results with identical new results.
+
+            // If found a properly localized version of the base resource for the model,
+            // then we've found a match (even if we had to ascend a couple of levels
+            // to reach it).
+
+            if (localized != null) return localized;
+
+            // Not on the classpath, the the locator see if its a) a page and b) a resource inside
+            // the context
+
+            localized = locator.findPageTemplateResource(model, locale);
+
+            if (localized != null) return localized;
+
+            // Otherwise, this component doesn't have its own template ... lets work up to its
+            // base class and check there.
+
+            model = model.getParentModel();
+        }
+
+        // This will be a Resource whose URL is null, which will be picked up later and force the
+        // return of the empty template.
+
+        return baseResourceForModel(initialModel);
+    }
+
+    private Resource baseResourceForModel(ComponentModel model)
+    {
+        return model.getBaseResource().withExtension(InternalConstants.TEMPLATE_EXTENSION);
+    }
+
+    /**
+     * Checks to see if any parsed resource has changed. If so, then all internal caches are cleared, and an
+     * invalidation event is fired. This is brute force ... a more targeted dependency management strategy may come
+     * later.
+     */
+    public void checkForUpdates()
+    {
+        if (tracker.containsChanges())
+        {
+            tracker.clear();
+            templateResources.clear();
+            templates.clear();
+            fireInvalidationEvent();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CompositeFieldValidator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CompositeFieldValidator.java
new file mode 100644
index 0000000..0eccfe4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CompositeFieldValidator.java
@@ -0,0 +1,58 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+
+import java.util.List;
+
+/**
+ * Aggregates together a number of field validator instances as a single unit.
+ */
+public final class CompositeFieldValidator implements FieldValidator
+{
+    private final FieldValidator[] validators;
+
+    public CompositeFieldValidator(List<FieldValidator> validators)
+    {
+        this.validators = validators.toArray(new FieldValidator[validators.size()]);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void validate(Object value) throws ValidationException
+    {
+        for (FieldValidator fv : validators)
+            fv.validate(value);
+    }
+
+    public void render(MarkupWriter writer)
+    {
+        for (FieldValidator fv : validators)
+            fv.render(writer);
+    }
+
+    public boolean isRequired()
+    {
+        for (FieldValidator fv : validators)
+        {
+            if (fv.isRequired()) return true;
+        }
+
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextAssetFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextAssetFactory.java
new file mode 100644
index 0000000..0d638ae
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextAssetFactory.java
@@ -0,0 +1,79 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.Context;
+import org.apache.tapestry.services.Request;
+
+/**
+ * Implementation of {@link AssetFactory} for assets that are part of the web application context.
+ *
+ * @see ContextResource
+ */
+public class ContextAssetFactory implements AssetFactory
+{
+    private final Request request;
+
+    private final Context context;
+
+    private final RequestPathOptimizer optimizer;
+
+    public ContextAssetFactory(Request request, Context context, RequestPathOptimizer optimizer)
+    {
+        this.request = request;
+        this.context = context;
+        this.optimizer = optimizer;
+    }
+
+    public Asset createAsset(final Resource resource)
+    {
+        final String contextPath = request.getContextPath() + "/" + resource.getPath();
+
+        return new Asset()
+        {
+            public Resource getResource()
+            {
+                return resource;
+            }
+
+            public String toClientURL()
+            {
+                return optimizer.optimizePath(contextPath);
+            }
+
+            /**
+             * Returns the client URL, which is essiential to allow informal parameters of type
+             * Asset to generate a proper value.
+             */
+            @Override
+            public String toString()
+            {
+                return toClientURL();
+            }
+        };
+    }
+
+    /**
+     * Returns the root {@link ContextResource}.
+     */
+    public Resource getRootResource()
+    {
+        return new ContextResource(context, "/");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java
new file mode 100644
index 0000000..40a1634
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextImpl.java
@@ -0,0 +1,101 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.util.Stack;
+import org.apache.tapestry.services.Context;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class ContextImpl implements Context
+{
+    private final ServletContext servletContext;
+
+    public ContextImpl(ServletContext servletContext)
+    {
+        this.servletContext = servletContext;
+    }
+
+    public URL getResource(String path)
+    {
+        try
+        {
+            return servletContext.getResource(path);
+        }
+        catch (MalformedURLException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public File getRealFile(String path)
+    {
+        String realPath = servletContext.getRealPath(path);
+
+        return realPath == null ? null : new File(realPath);
+    }
+
+    public String getInitParameter(String name)
+    {
+        return servletContext.getInitParameter(name);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<String> getResourcePaths(String path)
+    {
+        List<String> result = CollectionFactory.newList();
+        Stack<String> queue = CollectionFactory.newStack();
+
+        queue.push(path);
+
+        while (!queue.isEmpty())
+        {
+            String current = queue.pop();
+
+            Set<String> matches = servletContext.getResourcePaths(current);
+
+            // Tomcat 5.5.20 inside JBoss 4.0.2 has been observed to do this!
+            // Perhaps other servers do as well.
+
+            if (matches == null) continue;
+
+            for (String match : matches)
+            {
+                // Folders are queued up for further expansion.
+
+                if (match.endsWith("/")) queue.push(match);
+                else result.add(match);
+            }
+
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public Object getAttribute(String name)
+    {
+        return servletContext.getAttribute(name);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextResource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextResource.java
new file mode 100644
index 0000000..b4cde64
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextResource.java
@@ -0,0 +1,105 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.AbstractResource;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.services.Context;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * A resource stored with in the web application context.
+ */
+public class ContextResource extends AbstractResource
+{
+    private static final int PRIME = 37;
+
+    private final Context context;
+
+    public ContextResource(Context context, String path)
+    {
+        super(path);
+
+        notNull(context, "context");
+
+        this.context = context;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("context:%s", getPath());
+    }
+
+    @Override
+    protected Resource newResource(String path)
+    {
+        return new ContextResource(context, path);
+    }
+
+    public URL toURL()
+    {
+        // This is so easy to screw up; ClassLoader.getResource() doesn't want a leading slash,
+        // and HttpServletContext.getResource() does. This is what I mean when I say that
+        // a framework is an accumulation of the combined experience of many users and developers.
+
+        String contextPath = "/" + getPath();
+
+        // Always prefer the actual file to the URL.  This is critical for templates to
+        // reload inside Tomcat.
+
+        File file = context.getRealFile(contextPath);
+
+        if (file != null && file.exists())
+        {
+            try
+            {
+                return file.toURL();
+            }
+            catch (MalformedURLException ex)
+            {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        // But, when packaged inside a WAR or JAR, the File will not be available, so use whatever
+        // URL we get ... but reloading won't work.
+
+        return context.getResource(contextPath);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return PRIME * context.hashCode() + getPath().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+
+        final ContextResource other = (ContextResource) obj;
+
+        return context == other.context && getPath().equals(other.getPath());
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java
new file mode 100644
index 0000000..f3c19e4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ContextValueEncoderImpl.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.ValueEncoderSource;
+
+public class ContextValueEncoderImpl implements ContextValueEncoder
+{
+    private final ValueEncoderSource valueEncoderSource;
+
+    public ContextValueEncoderImpl(ValueEncoderSource valueEncoderSource)
+    {
+        this.valueEncoderSource = valueEncoderSource;
+    }
+
+    public String toClient(Object value)
+    {
+        Defense.notNull(value, "value");
+
+        ValueEncoder encoder = valueEncoderSource.getValueEncoder(value.getClass());
+
+        return encoder.toClient(value);
+    }
+
+
+    public <T> T toValue(Class<T> requiredType, String clientValue)
+    {
+        Defense.notNull(requiredType, "requiredType");
+
+        ValueEncoder<T> encoder = valueEncoderSource.getValueEncoder(requiredType);
+
+        return encoder.toValue(clientValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSink.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSink.java
new file mode 100644
index 0000000..bc6d5d4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSink.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javax.servlet.http.Cookie;
+
+/**
+ * You can write cookies to it.
+ */
+public interface CookieSink
+{
+
+    /**
+     * Adds a cookie to the sink
+     */
+    void addCookie(Cookie cookie);
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSource.java
new file mode 100644
index 0000000..158db1f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookieSource.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+
+import javax.servlet.http.Cookie;
+

+/**

+ * Provides the cookies from the browser.

+ */

+public interface CookieSource

+{

+    /**

+     * Returns the cookies from the browser.

+     */

+    Cookie[] getCookies();

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookiesImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookiesImpl.java
new file mode 100644
index 0000000..e28a0bb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/CookiesImpl.java
@@ -0,0 +1,132 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.util.TimeInterval;
+import org.apache.tapestry.services.Cookies;
+import org.apache.tapestry.services.Request;
+
+import javax.servlet.http.Cookie;
+
+/**
+ * Implementation of the {@link org.apache.tapestry.services.Cookies} service interface.
+ */
+public class CookiesImpl implements Cookies
+{
+    private final Request request;
+
+    private final CookieSource cookieSource;
+
+    private final CookieSink cookieSink;
+
+    private final int defaultMaxAge;
+
+    /**
+     * @param request
+     * @param cookieSource
+     * @param cookieSink
+     * @param defaultMaxAge default cookie expiration time in milliseconds
+     */
+    public CookiesImpl(Request request,
+
+                       CookieSource cookieSource,
+
+                       CookieSink cookieSink,
+
+                       @Symbol("tapestry.default-cookie-max-age") @IntermediateType(TimeInterval.class)
+                       long defaultMaxAge)
+    {
+        this.request = request;
+        this.cookieSource = cookieSource;
+        this.cookieSink = cookieSink;
+        this.defaultMaxAge = (int) (defaultMaxAge / 1000l);
+    }
+
+    public String readCookieValue(String name)
+    {
+        Cookie[] cookies = cookieSource.getCookies();
+
+        if (cookies == null) return null;
+
+        for (Cookie cooky : cookies)
+        {
+            if (cooky.getName().equals(name)) return cooky.getValue();
+        }
+
+        return null;
+    }
+
+    public void writeCookieValue(String name, String value)
+    {
+        writeCookieValue(name, value, defaultMaxAge);
+    }
+
+    public void writeCookieValue(String name, String value, int maxAge)
+    {
+        Cookie cookie = new Cookie(name, value);
+        cookie.setPath(request.getContextPath() + "/");
+        cookie.setMaxAge(maxAge);
+
+        cookieSink.addCookie(cookie);
+    }
+
+    public void writeCookieValue(String name, String value, String path)
+    {
+        Cookie cookie = new Cookie(name, value);
+        cookie.setPath(path);
+
+        cookieSink.addCookie(cookie);
+    }
+
+    public void writeDomainCookieValue(String name, String value, String domain)
+    {
+        Cookie cookie = new Cookie(name, value);
+        cookie.setPath(request.getContextPath() + "/");
+        cookie.setDomain(domain);
+
+        cookieSink.addCookie(cookie);
+    }
+
+    public void writeDomainCookieValue(String name, String value, String domain, int maxAge)
+    {
+        Cookie cookie = new Cookie(name, value);
+        cookie.setPath(request.getContextPath() + "/");
+        cookie.setDomain(domain);
+        cookie.setMaxAge(maxAge);
+
+        cookieSink.addCookie(cookie);
+    }
+
+    public void writeCookieValue(String name, String value, String path, String domain)
+    {
+        Cookie cookie = new Cookie(name, value);
+        cookie.setPath(path);
+        cookie.setDomain(domain);
+
+        cookieSink.addCookie(cookie);
+    }
+
+    public void removeCookieValue(String name)
+    {
+        Cookie cookie = new Cookie(name, null);
+        cookie.setPath(request.getContextPath() + "/");
+        cookie.setMaxAge(0);
+
+        cookieSink.addCookie(cookie);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultDataTypeAnalyzer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultDataTypeAnalyzer.java
new file mode 100644
index 0000000..e074ac1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultDataTypeAnalyzer.java
@@ -0,0 +1,62 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.DataTypeAnalyzer;
+
+import java.util.Map;
+
+/**
+ * The default data type analyzer, which is based entirely on the type of the property (and not on annotations or naming
+ * conventions). This is based on a configuration of property type class to string provided as an IoC service
+ * configuration.
+ */
+public class DefaultDataTypeAnalyzer implements DataTypeAnalyzer, InvalidationListener
+{
+    private final StrategyRegistry<String> registry;
+
+    public DefaultDataTypeAnalyzer(Map<Class, String> configuration)
+    {
+        registry = StrategyRegistry.newInstance(String.class, configuration);
+    }
+
+    /**
+     * Clears the registry on an invalidation event (this is because the registry caches results, and the keys are
+     * classes that may be component classes from the invalidated component class loader).
+     */
+    public void objectWasInvalidated()
+    {
+        registry.clearCache();
+    }
+
+    public String identifyDataType(PropertyAdapter adapter)
+    {
+        Class propertyType = adapter.getType();
+
+        String dataType = registry.get(propertyType);
+
+        // To avoid "no strategy" exceptions, we expect a contribution of Object.class to the empty
+        // string. We convert that back to a null.
+
+        if (dataType.equals(""))
+            return null;
+
+        return dataType;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java
new file mode 100644
index 0000000..786236e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java
@@ -0,0 +1,72 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.services.MasterObjectProvider;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Worker for the {@link org.apache.tapestry.ioc.annotation.Inject} annotation that delegates out to the master {@link
+ * org.apache.tapestry.ioc.services.MasterObjectProvider} to access the value. This worker must be scheduled after
+ * certain other workers, such as {@link BlockInjectionProvider} (which is keyed off a combination of type and the
+ * Inject annotation).
+ *
+ * @see org.apache.tapestry.ioc.services.MasterObjectProvider
+ */
+public class DefaultInjectionProvider implements InjectionProvider
+{
+    private final MasterObjectProvider masterObjectProvider;
+
+    private final ObjectLocator locator;
+
+    public DefaultInjectionProvider(MasterObjectProvider masterObjectProvider, ObjectLocator locator)
+    {
+        this.masterObjectProvider = masterObjectProvider;
+        this.locator = locator;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean provideInjection(final String fieldName, Class fieldType, ObjectLocator locator,
+                                    final ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        AnnotationProvider annotationProvider = new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return transformation.getFieldAnnotation(fieldName, annotationClass);
+            }
+        };
+
+        Object inject = masterObjectProvider.provide(fieldType, annotationProvider, this.locator, false);
+
+        // Null means that no ObjectProvider could provide the value. We have set up the chain of
+        // command so that InjectResources can give it a try next. Later, we'll try to match against
+        // a service.
+
+        if (inject != null)
+        {
+            transformation.injectField(fieldName, inject);
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java
new file mode 100644
index 0000000..ba0c07c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DefaultRequestExceptionHandler.java
@@ -0,0 +1,57 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ExceptionReporter;
+import org.apache.tapestry.services.RequestExceptionHandler;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+
+/**
+ * Default implementation of {@link RequestExceptionHandler} that displays the standard ExceptionReport page. The page
+ * must implement the {@link ExceptionReporter} interface.
+ */
+public class DefaultRequestExceptionHandler implements RequestExceptionHandler
+{
+    private final RequestPageCache pageCache;
+
+    private final PageResponseRenderer renderer;
+
+    private final Logger logger;
+
+    public DefaultRequestExceptionHandler(RequestPageCache pageCache, PageResponseRenderer renderer, Logger logger)
+    {
+        this.pageCache = pageCache;
+        this.renderer = renderer;
+        this.logger = logger;
+    }
+
+    public void handleRequestException(Throwable exception) throws IOException
+    {
+        logger.error(ServicesMessages.requestException(exception), exception);
+
+        Page page = pageCache.get("ExceptionReport");
+
+        ExceptionReporter rootComponent = (ExceptionReporter) page.getRootComponent();
+
+        // Let the page set up for the new exception.
+
+        rootComponent.reportException(exception);
+
+        renderer.renderPageResponse(page);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinker.java
new file mode 100644
index 0000000..ec65c02
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinker.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Responsible for injecting script and style links into the &lt;head&gt; and &lt;body&gt; element of the rendered HTML
+ * document.
+ */
+public interface DocumentLinker
+{
+    /**
+     * Adds a link to load a script. Scripts will be loaded only once.  The &lt;script&gt; elements will be added at the
+     * bottom of the &lt;body&gt; element.
+     */
+    void addScriptLink(String scriptURL);
+
+    /**
+     * Adds a link to load a CSS stylesheet. Stylesheets are loaded only once.
+     *
+     * @param styleURL URL of stylesheet to load
+     * @param media    media value (or null to omit the media attribute)
+     */
+    void addStylesheetLink(String styleURL, String media);
+
+    /**
+     * Adds JavaScript code. The code is collected into a single block that is injected just before the close body tag
+     * of the page.
+     *
+     * @param script statement to add to the block (a newline will be appended as well)
+     */
+    void addScript(String script);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinkerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinkerImpl.java
new file mode 100644
index 0000000..65b58f4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/DocumentLinkerImpl.java
@@ -0,0 +1,156 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.util.List;
+import java.util.Set;
+
+public class DocumentLinkerImpl implements DocumentLinker
+{
+    private final List<String> scripts = CollectionFactory.newList();
+
+    private final StringBuilder scriptBlock = new StringBuilder();
+
+    private final Set<String> stylesheets = CollectionFactory.newSet();
+
+    private final List<IncludedStylesheet> includedStylesheets = CollectionFactory.newList();
+
+    private final boolean developmentMode;
+
+    public DocumentLinkerImpl(boolean productionMode)
+    {
+        developmentMode = !productionMode;
+    }
+
+    private class IncludedStylesheet
+    {
+        private final String url;
+
+        private final String media;
+
+        IncludedStylesheet(String url, String media)
+        {
+            this.url = url;
+            this.media = media;
+        }
+
+        void add(Element head, int index)
+        {
+            head.elementAt(index, "link",
+
+                           "href", url,
+
+                           "rel", "stylesheet",
+
+                           "type", "text/css",
+
+                           "media", media);
+        }
+    }
+
+    public void addStylesheetLink(String styleURL, String media)
+    {
+        if (stylesheets.contains(styleURL)) return;
+
+        includedStylesheets.add(new IncludedStylesheet(styleURL, media));
+
+        stylesheets.add(styleURL);
+    }
+
+    public void addScriptLink(String scriptURL)
+    {
+        if (scripts.contains(scriptURL)) return;
+
+        scripts.add(scriptURL);
+    }
+
+    public void addScript(String script)
+    {
+        if (InternalUtils.isBlank(script)) return;
+
+        scriptBlock.append(script);
+        scriptBlock.append("\n");
+    }
+
+    /**
+     * Updates the supplied Document, locating the html/body element and adding script links (to the top) and a script
+     * block (to the end).
+     *
+     * @param document to be updated
+     */
+    public void updateDocument(Document document)
+    {
+        Element root = document.getRootElement();
+
+        // This can happen due to a catastrophic rendering error, such as a missing page template.
+        if (root == null) return;
+
+        // This only applies when the document is an HTML document. This may need to change in the
+        // future, perhaps configurable, to allow for html and xhtml and perhaps others. Does SVG
+        // use stylesheets?
+
+        if (!root.getName().equals("html")) return;
+
+        int stylesheets = includedStylesheets.size();
+
+        if (stylesheets > 0)
+        {
+            Element head = root.find("head");
+
+            if (head == null) head = root.elementAt(0, "head");
+
+            for (int i = 0; i < stylesheets; i++)
+                includedStylesheets.get(i).add(head, i);
+        }
+
+        Element body = root.find("body");
+
+        if (body == null) return;
+
+        // TAPESTRY-2364
+
+
+        for (String scriptURL : scripts)
+        {
+            body.element("script", "src", scriptURL, "type", "text/javascript");
+        }
+
+        boolean blockNeeded = (developmentMode && !scripts.isEmpty()) || scriptBlock.length() > 0;
+
+        if (blockNeeded)
+        {
+            Element e = body.element("script", "type", "text/javascript");
+            e.raw("\n<!--\n");
+
+            if (developmentMode)
+                e.text("Tapestry.DEBUG_ENABLED = true;\n");
+
+            e.text("Tapestry.onDOMLoaded(function() {\n");
+
+            e.text(scriptBlock.toString());
+
+            e.text("});\n");
+
+            e.raw("// -->\n");
+        }
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnumValueEncoderFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnumValueEncoderFactory.java
new file mode 100644
index 0000000..59e7181
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnumValueEncoderFactory.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.services.ValueEncoderFactory;
+import org.apache.tapestry.util.EnumValueEncoder;
+
+/**
+ * Factory that provides a configured instance of {@link EnumValueEncoder}.
+ *
+ * @param <E>
+ */
+public class EnumValueEncoderFactory<E extends Enum<E>> implements ValueEncoderFactory<E>
+{
+    public ValueEncoder<E> create(Class<E> type)
+    {
+        return new EnumValueEncoder<E>(type);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentImpl.java
new file mode 100644
index 0000000..bee1732
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentImpl.java
@@ -0,0 +1,101 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
+import org.apache.tapestry.services.Environment;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A non-threadsafe implementation (expects to use the "perthread" service lifecyle).
+ */
+@Scope(PERTHREAD_SCOPE)
+public class EnvironmentImpl implements Environment
+{
+    // My generics mojo breaks down when we talk about the key and the value being related
+    // types.
+
+    private final Map<Class, LinkedList> stacks = CollectionFactory.newMap();
+
+    @SuppressWarnings("unchecked")
+    private <T> LinkedList<T> stackFor(Class<T> type)
+    {
+        LinkedList<T> result = stacks.get(type);
+
+        if (result == null)
+        {
+            result = newLinkedList();
+            stacks.put(type, result);
+        }
+
+        return result;
+    }
+
+    public <T> T peek(Class<T> type)
+    {
+        LinkedList<T> stack = stackFor(type);
+
+        return stack.isEmpty() ? null : stack.getFirst();
+    }
+
+    public <T> T peekRequired(Class<T> type)
+    {
+        T result = peek(type);
+
+        if (result == null)
+        {
+            List<Class> types = CollectionFactory.newList();
+            for (Map.Entry<Class, LinkedList> e : stacks.entrySet())
+            {
+                LinkedList list = e.getValue();
+
+                if (list != null && !list.isEmpty()) types.add(e.getKey());
+            }
+
+            throw new RuntimeException(ServicesMessages.missingFromEnvironment(type, types));
+        }
+
+        return result;
+    }
+
+    public <T> T pop(Class<T> type)
+    {
+        LinkedList<T> stack = stackFor(type);
+
+        return stack.removeFirst();
+    }
+
+    public <T> T push(Class<T> type, T instance)
+    {
+        LinkedList<T> stack = stackFor(type);
+
+        T result = stack.isEmpty() ? null : stack.getFirst();
+
+        stack.addFirst(instance);
+
+        return result;
+    }
+
+    public void clear()
+    {
+        stacks.clear();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImpl.java
new file mode 100644
index 0000000..10784b9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImpl.java
@@ -0,0 +1,83 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.EnvironmentalShadowBuilder;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+public class EnvironmentalShadowBuilderImpl implements EnvironmentalShadowBuilder
+{
+    private final ClassFactory classFactory;
+
+    private final Environment environment;
+
+    /**
+     * Construct using the default builtin factory, not the component layer version.
+     */
+    public EnvironmentalShadowBuilderImpl(@Builtin ClassFactory classFactory,
+
+                                          Environment environment)
+    {
+        this.classFactory = classFactory;
+        this.environment = environment;
+    }
+
+    public <T> T build(Class<T> serviceType)
+    {
+        // TODO: Check that serviceType is an interface?
+
+        Class proxyClass = buildProxyClass(serviceType);
+
+        try
+        {
+            Constructor cons = proxyClass.getConstructors()[0];
+
+            Object raw = cons.newInstance(environment, serviceType);
+
+            return serviceType.cast(raw);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private Class buildProxyClass(Class serviceType)
+    {
+        ClassFab classFab = classFactory.newClass(serviceType);
+
+        classFab.addField("environment", Environment.class);
+        classFab.addField("_serviceType", Class.class);
+
+        classFab.addConstructor(new Class[] { Environment.class, Class.class }, null,
+                                "{ environment = $1; _serviceType = $2; }");
+
+        classFab.addMethod(Modifier.PRIVATE, new MethodSignature(serviceType, "_delegate", null, null),
+                           "return ($r) environment.peekRequired(_serviceType); ");
+
+        classFab.proxyMethodsToDelegate(serviceType, "_delegate()",
+                                        String.format("<EnvironmentalProxy for %s>", serviceType.getName()));
+
+        return classFab.createClass();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
new file mode 100644
index 0000000..50f1931
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
@@ -0,0 +1,65 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.runtime.Event;
+
+public class EventImpl implements Event
+{
+    private boolean aborted;
+
+    private String methodDescription;
+
+    private final ComponentEventCallback handler;
+
+    public EventImpl(ComponentEventCallback handler)
+    {
+        this.handler = notNull(handler, "handler");
+    }
+
+    public boolean isAborted()
+    {
+        return aborted;
+    }
+
+    public void setMethodDescription(String methodDescription)
+    {
+        this.methodDescription = methodDescription;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean storeResult(Object result)
+    {
+        // Given that this method is *only* invoked from code
+        // that is generated at runtime and proven to be correct,
+        // this should never, ever happen. But what the hell,
+        // let's check anyway.
+
+        if (aborted) throw new IllegalStateException(ServicesMessages
+                .componentEventIsAborted(methodDescription));
+
+
+        if (result != null) aborted |= handler.handleResult(result);
+
+        return aborted;
+    }
+
+    protected String getMethodDescription()
+    {
+        return methodDescription;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java
new file mode 100644
index 0000000..e6deda8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidationSupportImpl.java
@@ -0,0 +1,173 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.corelib.internal.InternalMessages;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.util.ExceptionUtils;
+import org.apache.tapestry.services.ValidationMessagesSource;
+
+public class FieldValidationSupportImpl implements FieldValidationSupport
+{
+    static final String PARSE_CLIENT_EVENT = "parseClient";
+    static final String TO_CLIENT_EVENT = "toClient";
+    static final String VALIDATE_EVENT = "validate";
+
+    private final ValidationMessagesSource messagesSource;
+
+    private final TypeCoercer typeCoercer;
+
+    public FieldValidationSupportImpl(ValidationMessagesSource messagesSource, TypeCoercer typeCoercer)
+    {
+        this.messagesSource = messagesSource;
+        this.typeCoercer = typeCoercer;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public String toClient(Object value, ComponentResources componentResources, Translator translator,
+                           NullFieldStrategy nullFieldStrategy)
+    {
+        Defense.notNull(componentResources, "componentResources");
+        Defense.notNull(translator, "translator");
+        Defense.notNull(nullFieldStrategy, "nullFieldStrategy");
+
+        final Holder<String> resultHolder = Holder.create();
+
+        ComponentEventCallback callback = new ComponentEventCallback()
+        {
+            public boolean handleResult(Object result)
+            {
+                // What's nice is that the ComponentEventException will automatically identify
+                // the method description.
+
+                if (!(result instanceof String))
+                    throw new RuntimeException(InternalMessages.toClientShouldReturnString());
+
+                resultHolder.put((String) result);
+
+                return true;
+            }
+        };
+
+        componentResources.triggerEvent(TO_CLIENT_EVENT, new Object[] { value }, callback);
+
+        if (resultHolder.hasValue()) return resultHolder.get();
+
+        Object effectiveValue = value;
+
+        if (effectiveValue == null)
+        {
+            effectiveValue = nullFieldStrategy.replaceToClient();
+
+            // Don't try to coerce or translate null.
+
+            if (effectiveValue == null) return null;
+        }
+
+        // And now, whether its a value from a bound property, or from the null field strategy,
+        // get it into the right format for the translator and let it translate.
+
+        Object coerced = typeCoercer.coerce(effectiveValue, translator.getType());
+
+        return translator.toClient(coerced);
+
+    }
+
+    public Object parseClient(String clientValue, ComponentResources componentResources, Translator translator,
+                              NullFieldStrategy nullFieldStrategy)
+            throws ValidationException
+    {
+        Defense.notNull(componentResources, "componentResources");
+        Defense.notNull(translator, "translator");
+        Defense.notNull(nullFieldStrategy, "nullFieldStrategy");
+
+        String effectiveValue = clientValue;
+
+        if (InternalUtils.isBlank(effectiveValue))
+        {
+            effectiveValue = nullFieldStrategy.replaceFromClient();
+
+            if (effectiveValue == null) return null;
+        }
+
+        final Holder<Object> resultHolder = Holder.create();
+
+        ComponentEventCallback callback = new ComponentEventCallback()
+        {
+            public boolean handleResult(Object result)
+            {
+                resultHolder.put(result);
+                return true;
+            }
+        };
+
+        try
+        {
+            componentResources.triggerEvent(PARSE_CLIENT_EVENT, new Object[] { effectiveValue }, callback);
+        }
+        catch (RuntimeException ex)
+        {
+            rethrowValidationException(ex);
+        }
+
+        if (resultHolder.hasValue()) return resultHolder.get();
+
+        // Otherwise, let the normal translator do the job.
+
+        Messages messages = messagesSource.getValidationMessages(componentResources.getLocale());
+
+        return translator.parseClient(effectiveValue, messages);
+    }
+
+    /**
+     * Checks for a {@link org.apache.tapestry.ValidationException} inside the outer exception and throws that,
+     * otherwise rethrows the runtime exception.
+     *
+     * @param outerException initially caught exception
+     * @throws ValidationException if found
+     */
+    private void rethrowValidationException(RuntimeException outerException) throws ValidationException
+    {
+        ValidationException ve = ExceptionUtils.findCause(outerException, ValidationException.class);
+
+        if (ve != null) throw ve;
+
+        throw outerException;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public void validate(Object value, ComponentResources componentResources, FieldValidator validator)
+            throws ValidationException
+    {
+        Defense.notNull(componentResources, "componentResources");
+        Defense.notNull(validator, "validator");
+
+        validator.validate(value);
+
+        try
+        {
+            componentResources.triggerEvent(VALIDATE_EVENT, new Object[] { value }, null);
+        }
+        catch (RuntimeException ex)
+        {
+            rethrowValidationException(ex);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImpl.java
new file mode 100644
index 0000000..0444cc6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImpl.java
@@ -0,0 +1,71 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Messages;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.services.FieldValidatorDefaultSource;
+import org.apache.tapestry.services.FieldValidatorSource;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+
+import java.util.List;
+import java.util.Locale;
+
+public class FieldValidatorDefaultSourceImpl implements FieldValidatorDefaultSource
+{
+    private final ValidationConstraintGenerator validationConstraintGenerator;
+
+    private final FieldValidatorSource fieldValidatorSource;
+
+    public FieldValidatorDefaultSourceImpl(
+            ValidationConstraintGenerator validationConstraintGenerator,
+            FieldValidatorSource fieldValidatorSource)
+    {
+        this.validationConstraintGenerator = validationConstraintGenerator;
+        this.fieldValidatorSource = fieldValidatorSource;
+    }
+
+    public FieldValidator createDefaultValidator(Field field, String overrideId,
+                                                 Messages overrideMessages, Locale locale, Class propertyType,
+                                                 AnnotationProvider propertyAnnotations)
+    {
+        List<FieldValidator> validators = newList();
+
+        for (String constraint : validationConstraintGenerator.buildConstraints(
+                propertyType,
+                propertyAnnotations))
+        {
+            int equalsx = constraint.indexOf('=');
+
+            String validatorType = equalsx > 0 ? constraint.substring(0, equalsx) : constraint;
+            String constraintValue = equalsx > 0 ? constraint.substring(equalsx + 1) : null;
+
+            FieldValidator validator = fieldValidatorSource.createValidator(
+                    field,
+                    validatorType,
+                    constraintValue,
+                    overrideId,
+                    overrideMessages,
+                    locale);
+
+            validators.add(validator);
+        }
+
+        return validators.size() == 1 ? validators.get(0) : new CompositeFieldValidator(validators);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
new file mode 100644
index 0000000..dced4ce
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorImpl.java
@@ -0,0 +1,69 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+public class FieldValidatorImpl implements FieldValidator
+{
+    private final Field field;
+
+    private final Object constraintValue;
+
+    private final MessageFormatter messageFormatter;
+
+    private final Validator validator;
+
+    private final FormSupport formSupport;
+
+    public FieldValidatorImpl(Field field, Object constraintValue, MessageFormatter messageFormatter,
+                              Validator validator, FormSupport formSupport)
+    {
+        this.field = field;
+        this.constraintValue = constraintValue;
+        this.messageFormatter = messageFormatter;
+        this.validator = validator;
+        this.formSupport = formSupport;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void validate(Object value) throws ValidationException
+    {
+        if (!validator.isRequired() && isBlank(value)) return;
+
+        if (value != null && !validator.getValueType().isInstance(value)) return;
+
+        validator.validate(field, constraintValue, messageFormatter, value);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void render(MarkupWriter writer)
+    {
+        validator.render(field, constraintValue, messageFormatter, writer, formSupport);
+    }
+
+    public boolean isRequired()
+    {
+        return validator.isRequired();
+    }
+
+    private boolean isBlank(Object value)
+    {
+        return value == null || value.equals("");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
new file mode 100644
index 0000000..4806070
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FieldValidatorSourceImpl.java
@@ -0,0 +1,330 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.Defense.cast;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.FieldValidatorSource;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.ValidationMessagesSource;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+public class FieldValidatorSourceImpl implements FieldValidatorSource
+{
+    private final ValidationMessagesSource messagesSource;
+
+    private final Map<String, Validator> validators;
+
+    private final TypeCoercer typeCoercer;
+
+    private final FormSupport formSupport;
+
+    public FieldValidatorSourceImpl(ValidationMessagesSource messagesSource, TypeCoercer typeCoercer,
+                                    FormSupport formSupport, Map<String, Validator> validators)
+    {
+        this.messagesSource = messagesSource;
+        this.typeCoercer = typeCoercer;
+        this.formSupport = formSupport;
+        this.validators = validators;
+    }
+
+    public FieldValidator createValidator(Field field, String validatorType, String constraintValue)
+    {
+        Component component = cast(field, Component.class, "field");
+        notBlank(validatorType, "validatorType");
+
+        ComponentResources componentResources = component.getComponentResources();
+        String overrideId = componentResources.getId();
+        Locale locale = componentResources.getLocale();
+
+        // So, if you use a TextField on your EditUser page, we want to search the messages
+        // of the EditUser page (the container), not the TextField (which will always be the same).
+
+        Messages overrideMessages = componentResources.getContainerMessages();
+
+        return createValidator(field, validatorType, constraintValue, overrideId, overrideMessages, locale);
+    }
+
+    public FieldValidator createValidator(Field field, String validatorType, String constraintValue, String overrideId,
+                                          Messages overrideMessages, Locale locale)
+    {
+        notBlank(validatorType, "validatorType");
+
+        Validator validator = validators.get(validatorType);
+
+        if (validator == null) throw new IllegalArgumentException(
+                ServicesMessages.unknownValidatorType(validatorType, InternalUtils.sortedKeys(validators)));
+
+        // I just have this thing about always treating parameters as finals, so
+        // we introduce a second variable to treat a mutable.
+
+        String finalConstraintValue = constraintValue;
+
+        // If no constraint was provided, check to see if it is available via a localized message
+        // key. This is really handy for complex validations such as patterns.
+
+        if (finalConstraintValue == null && validator.getConstraintType() != null)
+        {
+            String key = overrideId + "-" + validatorType;
+
+            if (overrideMessages.contains(key)) finalConstraintValue = overrideMessages.get(key);
+            else throw new IllegalArgumentException(
+                    ServicesMessages.missingValidatorConstraint(validatorType, validator.getConstraintType()));
+        }
+
+        Object coercedConstraintValue = coerceConstraintValue(finalConstraintValue, validator
+                .getConstraintType());
+
+        MessageFormatter formatter = findMessageFormatter(overrideId, overrideMessages, locale, validatorType,
+                                                          validator);
+
+        return new FieldValidatorImpl(field, coercedConstraintValue, formatter, validator, formSupport);
+    }
+
+    private MessageFormatter findMessageFormatter(String overrideId, Messages overrideMessages, Locale locale,
+                                                  String validatorType, Validator validator)
+    {
+
+        String overrideKey = overrideId + "-" + validatorType + "-message";
+
+        if (overrideMessages.contains(overrideKey)) return overrideMessages.getFormatter(overrideKey);
+
+        Messages messages = messagesSource.getValidationMessages(locale);
+
+        String key = validator.getMessageKey();
+
+        return messages.getFormatter(key);
+    }
+
+    public FieldValidator createValidators(Field field, String specification)
+    {
+        List<ValidatorSpecification> specs = parse(specification);
+
+        List<FieldValidator> fieldValidators = newList();
+
+        for (ValidatorSpecification spec : specs)
+        {
+            fieldValidators.add(createValidator(field, spec.getValidatorType(), spec
+                    .getConstraintValue()));
+        }
+
+        if (fieldValidators.size() == 1) return fieldValidators.get(0);
+
+        return new CompositeFieldValidator(fieldValidators);
+    }
+
+    @SuppressWarnings("unchecked")
+    private Object coerceConstraintValue(String constraintValue, Class constraintType)
+    {
+        if (constraintType == null) return null;
+
+        return typeCoercer.coerce(constraintValue, constraintType);
+    }
+
+    /**
+     * A code defining what the parser is looking for.
+     */
+    enum State
+    {
+
+        /**
+         * The start of a validator type.
+         */
+        TYPE_START,
+        /**
+         * The end of a validator type.
+         */
+        TYPE_END,
+        /**
+         * Equals sign after a validator type, or a comma.
+         */
+        EQUALS_OR_COMMA,
+        /**
+         * The start of a constraint value.
+         */
+        VALUE_START,
+        /**
+         * The end of the constraint value.
+         */
+        VALUE_END,
+        /**
+         * The comma after a constraint value.
+         */
+        COMMA
+    }
+
+    static List<ValidatorSpecification> parse(String specification)
+    {
+        List<ValidatorSpecification> result = newList();
+
+        char[] input = specification.toCharArray();
+
+        int cursor = 0;
+        int start = -1;
+
+        String type = null;
+        boolean skipWhitespace = true;
+        State state = State.TYPE_START;
+
+        while (cursor < input.length)
+        {
+            char ch = input[cursor];
+
+            if (skipWhitespace && Character.isWhitespace(ch))
+            {
+                cursor++;
+                continue;
+            }
+
+            skipWhitespace = false;
+
+            switch (state)
+            {
+
+                case TYPE_START:
+
+                    if (Character.isLetter(ch))
+                    {
+                        start = cursor;
+                        state = State.TYPE_END;
+                        break;
+                    }
+
+                    parseError(cursor, specification);
+
+                case TYPE_END:
+
+                    if (Character.isLetter(ch))
+                    {
+                        break;
+                    }
+
+                    type = specification.substring(start, cursor);
+
+                    skipWhitespace = true;
+                    state = State.EQUALS_OR_COMMA;
+                    continue;
+
+                case EQUALS_OR_COMMA:
+
+                    if (ch == '=')
+                    {
+                        skipWhitespace = true;
+                        state = State.VALUE_START;
+                        break;
+                    }
+
+                    if (ch == ',')
+                    {
+                        result.add(new ValidatorSpecification(type));
+                        type = null;
+                        state = State.COMMA;
+                        continue;
+                    }
+
+                    parseError(cursor, specification);
+
+                case VALUE_START:
+
+                    start = cursor;
+                    state = State.VALUE_END;
+                    break;
+
+                case VALUE_END:
+
+                    // The value ends when we hit whitespace or a comma
+
+                    if (Character.isWhitespace(ch) || ch == ',')
+                    {
+                        String value = specification.substring(start, cursor);
+
+                        result.add(new ValidatorSpecification(type, value));
+                        type = null;
+
+                        skipWhitespace = true;
+                        state = State.COMMA;
+                        continue;
+                    }
+
+                    break;
+
+                case COMMA:
+
+                    if (ch == ',')
+                    {
+                        skipWhitespace = true;
+                        state = State.TYPE_START;
+                        break;
+
+                    }
+
+                    parseError(cursor, specification);
+            } // case
+
+            cursor++;
+        } // while
+
+        // cursor is now one character past end of string.
+        // Cleanup whatever state we were in the middle of.
+
+        switch (state)
+        {
+            case TYPE_END:
+
+                type = specification.substring(start);
+
+            case EQUALS_OR_COMMA:
+
+                result.add(new ValidatorSpecification(type));
+                break;
+
+                // Case when the specification ends with an equals sign.
+
+            case VALUE_START:
+                result.add(new ValidatorSpecification(type, ""));
+                break;
+
+            case VALUE_END:
+
+                result.add(new ValidatorSpecification(type, specification.substring(start)));
+                break;
+
+                // For better or worse, ending the string with a comma is valid.
+
+            default:
+
+        }
+
+        return result;
+    }
+
+    private static void parseError(int cursor, String specification)
+    {
+        throw new RuntimeException(ServicesMessages.validatorSpecificationParseError(cursor, specification));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategy.java
new file mode 100644
index 0000000..e84407e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategy.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+/**
+ * The "flash" strategy stores data inside the {@link Session session}, just like {@link
+ * SessionPersistentFieldStrategy}, but also removes the values from the session on first use. In this way, a short-term
+ * value (such as an error message) will "survive" from an action request to a render request and then disappear.
+ */
+public class FlashPersistentFieldStrategy extends AbstractSessionPersistentFieldStrategy
+{
+    /**
+     * Prefix used to identify keys stored in the session.
+     */
+    static final String PREFIX = "flash:";
+
+    public FlashPersistentFieldStrategy(Request request)
+    {
+        super(PREFIX, request);
+    }
+
+    @Override
+    protected void didReadChange(Session session, String attributeName)
+    {
+        // For flash persistence, after reading a value, get rid of it.
+        session.setAttribute(attributeName, null);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/GenericValueEncoderFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/GenericValueEncoderFactory.java
new file mode 100644
index 0000000..c91e1a9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/GenericValueEncoderFactory.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.services.ValueEncoderFactory;
+
+/**
+ * An implementation of {@link ValueEncoderFactory} that returns a pre-wired instance of {@link ValueEncoder}. This is
+ * odd for a factory, because it doesn't actually create the returned instance, just stores it until the encoder is
+ * needed.
+ *
+ * @param <V>
+ */
+public class GenericValueEncoderFactory<V> implements ValueEncoderFactory<V>
+{
+    private final ValueEncoder<V> encoder;
+
+    public GenericValueEncoderFactory(ValueEncoder<V> encoder)
+    {
+        this.encoder = encoder;
+    }
+
+    public ValueEncoder<V> create(Class<V> type)
+    {
+        return encoder;
+    }
+
+    public static <V> GenericValueEncoderFactory<V> create(ValueEncoder<V> encoder)
+    {
+        return new GenericValueEncoderFactory<V>(encoder);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/HeartbeatImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/HeartbeatImpl.java
new file mode 100644
index 0000000..ffd615f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/HeartbeatImpl.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newStack;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.util.Stack;
+import org.apache.tapestry.services.Heartbeat;
+
+import java.util.List;
+
+public class HeartbeatImpl implements Heartbeat
+{
+    private final Stack<List<Runnable>> stack = newStack();
+
+    public void begin()
+    {
+        List<Runnable> beat = CollectionFactory.newList();
+
+        stack.push(beat);
+    }
+
+    public void defer(Runnable command)
+    {
+        Defense.notNull(command, "command");
+
+        stack.peek().add(command);
+
+    }
+
+    public void end()
+    {
+        List<Runnable> beat = stack.pop();
+
+        for (Runnable r : beat)
+            r.run();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IgnoredPathsFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IgnoredPathsFilter.java
new file mode 100644
index 0000000..c4c46df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/IgnoredPathsFilter.java
@@ -0,0 +1,64 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.HttpServletRequestFilter;
+import org.apache.tapestry.services.HttpServletRequestHandler;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.regex.Pattern;
+
+public class IgnoredPathsFilter implements HttpServletRequestFilter
+{
+    private final Pattern[] ignoredPatterns;
+
+    public IgnoredPathsFilter(Collection<String> configuration)
+    {
+        ignoredPatterns = new Pattern[configuration.size()];
+
+        int i = 0;
+
+        for (String regexp : configuration)
+        {
+            Pattern p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
+
+            ignoredPatterns[i++] = p;
+        }
+    }
+
+    public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler)
+            throws IOException
+    {
+        // The servlet path should be "/", and path info is everything after that.
+
+        String path = request.getServletPath();
+        String pathInfo = request.getPathInfo();
+
+        if (pathInfo != null) path += pathInfo;
+
+
+        for (Pattern p : ignoredPatterns)
+        {
+            if (p.matcher(path).matches()) return false;
+        }
+
+        // Not a match, so let it go.
+
+        return handler.service(request, response);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java
new file mode 100644
index 0000000..8fe96ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseFilter.java
@@ -0,0 +1,66 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+public class ImmediateActionRenderResponseFilter implements ComponentEventRequestFilter
+{
+    private final Request request;
+
+    private final Response response;
+
+    private final PageResponseRenderer renderer;
+
+    public ImmediateActionRenderResponseFilter(Request request, PageResponseRenderer renderer, Response response)
+    {
+        this.request = request;
+        this.renderer = renderer;
+        this.response = response;
+    }
+
+    public void handle(ComponentEventRequestParameters parameters, ComponentEventRequestHandler handler)
+            throws IOException
+    {
+        handler.handle(parameters);
+
+        // If markup or a redirect has already been generated, then we're good.
+
+        if (response.isCommitted()) return;
+
+        // Otherwise, we should be operating in immediate mode.  Figure out which page
+        // was selected to render.
+
+        Page page = (Page) request.getAttribute(InternalConstants.IMMEDIATE_RESPONSE_PAGE_ATTRIBUTE);
+
+        if (page != null)
+        {
+            // We don't have a context to provide but this still nags me as not the right thing to do.
+
+            page.getRootElement().triggerEvent(EventConstants.ACTIVATE, new Object[0], null);
+
+            renderer.renderPageResponse(page);
+            return;
+        }
+
+        throw new IllegalStateException(
+                "Sanity check - neither a stream response nor a redirect response was generated for this action request.");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseGenerator.java
new file mode 100644
index 0000000..9996376
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ImmediateActionRenderResponseGenerator.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.Request;
+
+import java.io.IOException;
+
+/**
+ * Alternative implementation, used when {@link org.apache.tapestry.SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS}
+ * is set to true.
+ */
+public class ImmediateActionRenderResponseGenerator implements ActionRenderResponseGenerator
+{
+    private final Request request;
+
+    public ImmediateActionRenderResponseGenerator(Request request)
+    {
+        this.request = request;
+    }
+
+    public void generateResponse(Page page) throws IOException
+    {
+        Defense.notNull(page, "page");
+
+        // This can happen when the ComponentEventRequestHandlerImpl notices that the response
+        // is not yet committed, and sets up to render a default response for the page containing
+        // the component.
+        if (request.getAttribute(InternalConstants.IMMEDIATE_RESPONSE_PAGE_ATTRIBUTE) != null) return;
+
+        // We are somewhere in the middle of processing an action request, possibly something
+        // complicated like a form submission.  Tapestry components are not re-entrant, so we
+        // can't render the request right now, instead we record that we need to render
+        // a response as an attribute, and let a filter on the ComponentEventRequestHandler service
+        // do the work.
+
+        request.setAttribute(InternalConstants.IMMEDIATE_RESPONSE_PAGE_ATTRIBUTE, page);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java
new file mode 100644
index 0000000..bd03ac1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java
@@ -0,0 +1,108 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Wraps another binding, adjusting the description of the binding and the location of the binding (as reported in any
+ * thrown exceptions).
+ */
+public class InheritedBinding extends BaseLocatable implements Binding
+{
+    private final String toString;
+
+    private final Binding binding;
+
+    public InheritedBinding(String toString, Binding binding, Location location)
+    {
+        super(location);
+
+        this.toString = toString;
+        this.binding = binding;
+    }
+
+    @Override
+    public String toString()
+    {
+        return toString;
+    }
+
+    public Object get()
+    {
+        try
+        {
+            return binding.get();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public Class getBindingType()
+    {
+        try
+        {
+            return binding.getBindingType();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public boolean isInvariant()
+    {
+        try
+        {
+            return binding.isInvariant();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public void set(Object value)
+    {
+        try
+        {
+            binding.set(value);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        try
+        {
+            return binding.getAnnotation(annotationClass);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/Instantiator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/Instantiator.java
new file mode 100644
index 0000000..9443d71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/Instantiator.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.internal.InternalComponentResources;

+import org.apache.tapestry.model.ComponentModel;

+import org.apache.tapestry.runtime.Component;

+

+/**

+ * An object that can instantiate a component. This is used with transformed classes, in which the normal no-arguments

+ * constructor has been replaced with a constructor with arguments; the instantiator will retain the necessary arguments

+ * and pass them to the enhanced class' constructor.

+ */

+public interface Instantiator

+{

+    /**

+     * Instantiates and returns a new instance of the desired class. Component classes are always modified so that they

+     * implement {@link Component} (and often, other interfaces as well).

+     */

+    Component newInstance(InternalComponentResources resources);

+

+    /**

+     * Returns the model that defines the behavior of the component.

+     */

+    ComponentModel getModel();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformation.java
new file mode 100644
index 0000000..2e97ad7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformation.java
@@ -0,0 +1,78 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.CtClass;
+import org.apache.tapestry.internal.util.MultiKey;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.util.List;
+
+/**
+ * Extends {@link org.apache.tapestry.services.ClassTransformation} with additional methods that may only be used
+ * internally by Tapestry.
+ */
+public interface InternalClassTransformation extends ClassTransformation
+{
+    /**
+     * Invoked after all {@link ComponentClassTransformWorker}s have had their chance to work over the class. This
+     * performs any final operations for the class transformation, which includes coming up with the final constructor
+     * method for the class.
+     */
+    void finish();
+
+    /**
+     * Called (after {@link #finish()}) to construct an instantiator for the component.
+     *
+     * @return the component's instantiator
+     */
+    Instantiator createInstantiator();
+
+    /**
+     * Returns a copy of the transformation's IdAllocator. Used when creating a child class transformation. May only be
+     * invoked on a frozen transformation.
+     */
+    IdAllocator getIdAllocator();
+
+    /**
+     * Returns a copy of the list of constructor arguments for this class.
+     */
+    List<InternalClassTransformationImpl.ConstructorArg> getConstructorArgs();
+
+    /**
+     * Searchs for an existing injection of an object, returning the name of the protected field into which the value
+     * was injected.
+     * <p/>
+     * TODO: Howard sayz: Uggh! At least define a real key (MultiKey is intended for internal use, never part of an
+     * API). Is this necessary?  The cost of re-injection is tiny.
+     */
+    String searchForPreviousInjection(MultiKey key);
+
+    InternalClassTransformation createChildTransformation(CtClass childClass, MutableComponentModel childModel);
+
+    /**
+     * Creates a new method by copying the body of an existing method.  This is part of the scheme for providing method
+     * advice.
+     *
+     * @param sourceMethod  method to be copied
+     * @param modifiers     modifiers for the new method
+     * @param newMethodName name of new method to create
+     */
+    void copyMethod(TransformMethodSignature sourceMethod, int modifiers, String newMethodName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
new file mode 100644
index 0000000..0727671
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
@@ -0,0 +1,1747 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.*;
+import javassist.expr.ExprEditor;
+import javassist.expr.FieldAccess;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.util.MultiKey;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.*;
+import org.slf4j.Logger;
+
+import static java.lang.String.format;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Implementation of the {@link org.apache.tapestry.internal.services.InternalClassTransformation} interface.
+ */
+public final class InternalClassTransformationImpl implements InternalClassTransformation
+{
+    private static final int INIT_BUFFER_SIZE = 100;
+
+    private boolean frozen;
+
+    private final CtClass ctClass;
+
+    private final Logger logger;
+
+    private final InternalClassTransformation parentTransformation;
+
+    private final ClassPool classPool;
+
+    private final IdAllocator idAllocator;
+
+    /**
+     * Map, keyed on InjectKey, of field name.
+     */
+    private final Map<MultiKey, String> injectionCache = newMap();
+
+    /**
+     * Map from a field to the annotation objects for that field.
+     */
+    private Map<String, List<Annotation>> fieldAnnotations = newMap();
+
+    /**
+     * Used to identify fields that have been "claimed" by other annotations.
+     */
+    private Map<String, Object> claimedFields = newMap();
+
+    private Set<String> addedFieldNames = newSet();
+
+    private Set<CtBehavior> addedMethods = newSet();
+
+    // Cache of class annotation
+
+    private List<Annotation> classAnnotations;
+
+    // Cache of method annotation
+
+    private Map<CtMethod, List<Annotation>> methodAnnotations = newMap();
+
+    private Map<CtMethod, TransformMethodSignature> methodSignatures = newMap();
+
+    private Map<TransformMethodSignature, InvocationBuilder> methodToInvocationBuilder = CollectionFactory.newMap();
+
+    // Key is field name, value is expression used to replace read access
+
+    private Map<String, String> fieldReadTransforms;
+
+    // Key is field name, value is expression used to replace read access
+    private Map<String, String> fieldWriteTransforms;
+
+    private Set<String> removedFieldNames;
+
+    /**
+     * Contains the assembled Javassist code for the class' default constructor.
+     */
+    private StringBuilder constructor = new StringBuilder(INIT_BUFFER_SIZE);
+
+    private final List<ConstructorArg> constructorArgs;
+
+    private final ComponentModel componentModel;
+
+    private final String resourcesFieldName;
+
+    private final StringBuilder description = new StringBuilder(INIT_BUFFER_SIZE);
+
+    private Formatter formatter = new Formatter(description);
+
+    private final ClassFactory classFactory;
+
+    private final ComponentClassCache componentClassCache;
+
+    private final CtClassSource classSource;
+
+    /**
+     * Signature for newInstance() method of Instantiator.
+     */
+    private static final MethodSignature NEW_INSTANCE_SIGNATURE = new MethodSignature(Component.class, "newInstance",
+                                                                                      new Class[] {
+                                                                                              InternalComponentResources.class },
+                                                                                      null);
+
+    /**
+     * Stores transformation type data about one argument to a class constructor.
+     */
+    static class ConstructorArg
+    {
+        private final CtClass type;
+
+        private final Object value;
+
+        /**
+         * Constructs new instance.
+         *
+         * @param type  type of the parameter to be created (may not be null)
+         * @param value value to be injected via the constructor (may be null)
+         */
+        ConstructorArg(CtClass type, Object value)
+        {
+            this.type = Defense.notNull(type, "type");
+            this.value = value;
+        }
+
+    }
+
+    /**
+     * This is a constructor for a base class.
+     */
+    public InternalClassTransformationImpl(ClassFactory classFactory, CtClass ctClass,
+                                           ComponentClassCache componentClassCache,
+                                           ComponentModel componentModel, CtClassSource classSource)
+    {
+        this.ctClass = ctClass;
+        this.componentClassCache = componentClassCache;
+        this.classSource = classSource;
+        classPool = this.ctClass.getClassPool();
+        this.classFactory = classFactory;
+        parentTransformation = null;
+        this.componentModel = componentModel;
+
+        idAllocator = new IdAllocator();
+
+        logger = componentModel.getLogger();
+
+        preloadMemberNames();
+
+        constructorArgs = newList();
+        constructor.append("{\n");
+
+        addImplementedInterface(Component.class);
+
+        resourcesFieldName = addInjectedFieldUncached(InternalComponentResources.class, "resources", null);
+
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC | Modifier.FINAL,
+                                                                    ComponentResources.class.getName(),
+                                                                    "getComponentResources", null, null);
+
+        addMethod(sig, "return " + resourcesFieldName + ";");
+
+        // The "}" will be added later, inside  finish().
+    }
+
+    /**
+     * Constructor for a component sub-class.
+     */
+    private InternalClassTransformationImpl(CtClass ctClass, InternalClassTransformation parentTransformation,
+                                            ClassFactory classFactory, CtClassSource classSource,
+                                            ComponentClassCache componentClassCache,
+                                            ComponentModel componentModel)
+    {
+        this.ctClass = ctClass;
+        this.componentClassCache = componentClassCache;
+        this.classSource = classSource;
+        classPool = this.ctClass.getClassPool();
+        this.classFactory = classFactory;
+        logger = componentModel.getLogger();
+        this.parentTransformation = parentTransformation;
+        this.componentModel = componentModel;
+
+        resourcesFieldName = parentTransformation.getResourcesFieldName();
+
+        idAllocator = parentTransformation.getIdAllocator();
+
+        preloadMemberNames();
+
+        constructorArgs = parentTransformation.getConstructorArgs();
+
+        int count = constructorArgs.size();
+
+        // Build the call to the super-constructor.
+
+        constructor.append("{ super(");
+
+        for (int i = 1; i <= count; i++)
+        {
+            if (i > 1) constructor.append(", ");
+
+            // $0 is implicitly self, so the 0-index ConstructorArg will be Javassisst
+            // pseudeo-variable $1, and so forth.
+
+            constructor.append("$");
+            constructor.append(i);
+        }
+
+        constructor.append(");\n");
+
+        // The "}" will be added later, inside  finish().
+    }
+
+    public InternalClassTransformation createChildTransformation(CtClass childClass, MutableComponentModel childModel)
+    {
+        return new InternalClassTransformationImpl(childClass, this, classFactory, classSource, componentClassCache,
+                                                   childModel
+        );
+    }
+
+    private void freeze()
+    {
+        frozen = true;
+
+        // Free up stuff we don't need after freezing.
+        // Everything else should be final.
+
+        fieldAnnotations = null;
+        claimedFields = null;
+        addedFieldNames = null;
+        addedMethods = null;
+        classAnnotations = null;
+        methodAnnotations = null;
+        methodSignatures = null;
+        fieldReadTransforms = null;
+        fieldWriteTransforms = null;
+        removedFieldNames = null;
+        constructor = null;
+        formatter = null;
+        methodToInvocationBuilder = null;
+    }
+
+    public String getResourcesFieldName()
+    {
+        return resourcesFieldName;
+    }
+
+    /**
+     * Loads the names of all declared fields and methods into the idAllocator.
+     */
+
+    private void preloadMemberNames()
+    {
+        addMemberNames(ctClass.getDeclaredFields());
+        addMemberNames(ctClass.getDeclaredMethods());
+    }
+
+    void verifyFields()
+    {
+        List<String> names = newList();
+
+        for (CtField field : ctClass.getDeclaredFields())
+        {
+            String name = field.getName();
+
+            if (addedFieldNames.contains(name)) continue;
+
+            int modifiers = field.getModifiers();
+
+            // Fields must be either static or private.
+
+            if (Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers)) continue;
+
+            // Groovy injects a public field named metaClass.  We ignore it, and add it as a claimed
+            // field to prevent any of the workers from seeing it.
+
+            if (name.equals("metaClass") && getFieldType(name).equals("groovy.lang.MetaClass"))
+            {
+                claimField(name, "Ignored");
+
+                continue;
+            }
+
+            names.add(name);
+        }
+
+        if (!names.isEmpty())
+            throw new RuntimeException(ServicesMessages.nonPrivateFields(getClassName(), names));
+    }
+
+    private void addMemberNames(CtMember[] members)
+    {
+        for (CtMember member : members)
+        {
+            idAllocator.allocateId(member.getName());
+        }
+    }
+
+    public <T extends Annotation> T getFieldAnnotation(String fieldName, Class<T> annotationClass)
+    {
+        failIfFrozen();
+
+        List<Annotation> annotations = findFieldAnnotations(fieldName);
+
+        return findAnnotationInList(annotationClass, annotations);
+    }
+
+    public <T extends Annotation> T getMethodAnnotation(TransformMethodSignature signature, Class<T> annotationClass)
+    {
+        failIfFrozen();
+
+        CtMethod method = findMethod(signature);
+
+        if (method == null) throw new IllegalArgumentException(ServicesMessages.noDeclaredMethod(ctClass, signature));
+
+        List<Annotation> annotations = findMethodAnnotations(method);
+
+        return findAnnotationInList(annotationClass, annotations);
+    }
+
+    /**
+     * Searches an array of objects (that are really annotations instances) to find one that is of the correct type,
+     * which is returned.
+     *
+     * @param <T>
+     * @param annotationClass the annotation to search for
+     * @param annotations     the available annotations
+     * @return the matching annotation instance, or null if not found
+     */
+    private <T extends Annotation> T findAnnotationInList(Class<T> annotationClass, List<Annotation> annotations)
+    {
+        for (Object annotation : annotations)
+        {
+            if (annotationClass.isInstance(annotation)) return annotationClass.cast(annotation);
+        }
+
+        return null;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return findAnnotationInList(annotationClass, getClassAnnotations());
+    }
+
+    private List<Annotation> findFieldAnnotations(String fieldName)
+    {
+        List<Annotation> annotations = fieldAnnotations.get(fieldName);
+
+        if (annotations == null)
+        {
+            annotations = findAnnotationsForField(fieldName);
+            fieldAnnotations.put(fieldName, annotations);
+        }
+
+        return annotations;
+    }
+
+    private List<Annotation> findMethodAnnotations(CtMethod method)
+    {
+        List<Annotation> annotations = methodAnnotations.get(method);
+
+        if (annotations == null)
+        {
+            annotations = extractAnnotations(method);
+
+            methodAnnotations.put(method, annotations);
+        }
+
+        return annotations;
+    }
+
+    private List<Annotation> findAnnotationsForField(String fieldName)
+    {
+        CtField field = findDeclaredCtField(fieldName);
+
+        return extractAnnotations(field);
+    }
+
+    private List<Annotation> extractAnnotations(CtMember member)
+    {
+        try
+        {
+            List<Annotation> result = newList();
+
+            addAnnotationsToList(result, member.getAnnotations());
+
+            return result;
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private void addAnnotationsToList(List<Annotation> list, Object[] annotations)
+    {
+        for (Object o : annotations)
+        {
+            Annotation a = (Annotation) o;
+            list.add(a);
+        }
+    }
+
+    private CtField findDeclaredCtField(String fieldName)
+    {
+        try
+        {
+            return ctClass.getDeclaredField(fieldName);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ServicesMessages.missingDeclaredField(ctClass, fieldName), ex);
+        }
+    }
+
+    public String newMemberName(String suggested)
+    {
+        failIfFrozen();
+
+        String memberName = InternalUtils.createMemberName(notBlank(suggested, "suggested"));
+
+        return idAllocator.allocateId(memberName);
+    }
+
+    public String newMemberName(String prefix, String baseName)
+    {
+        return newMemberName(prefix + "_" + InternalUtils.stripMemberPrefix(baseName));
+    }
+
+    public void addImplementedInterface(Class interfaceClass)
+    {
+        failIfFrozen();
+
+        String interfaceName = interfaceClass.getName();
+
+        try
+        {
+            CtClass ctInterface = classPool.get(interfaceName);
+
+            if (classImplementsInterface(ctInterface)) return;
+
+            implementDefaultMethodsForInterface(ctInterface);
+
+            ctClass.addInterface(ctInterface);
+
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+    /**
+     * Adds default implementations for the methods defined by the interface (and all of its super-interfaces). The
+     * implementations return null (or 0, or false, as appropriate to to the method type). There are a number of
+     * degenerate cases that are not covered properly: these are related to base interfaces that may be implemented by
+     * base classes.
+     *
+     * @param ctInterface
+     * @throws NotFoundException
+     */
+    private void implementDefaultMethodsForInterface(CtClass ctInterface) throws NotFoundException
+    {
+        // java.lang.Object is the parent interface of interfaces
+
+        if (ctInterface.getName().equals(Object.class.getName())) return;
+
+        for (CtMethod method : ctInterface.getDeclaredMethods())
+        {
+            addDefaultImplementation(method);
+        }
+
+        for (CtClass parent : ctInterface.getInterfaces())
+        {
+            implementDefaultMethodsForInterface(parent);
+        }
+    }
+
+    private void addDefaultImplementation(CtMethod method)
+    {
+        // Javassist has an oddity for interfaces: methods "inherited" from java.lang.Object show
+        // up as methods of the interface. We skip those and only consider the methods
+        // that are abstract.
+
+        if (!Modifier.isAbstract(method.getModifiers())) return;
+
+        try
+        {
+            CtMethod newMethod = CtNewMethod.copy(method, ctClass, null);
+
+            // Methods from interfaces are always public. We definitely
+            // need to change the modifiers of the method so that
+            // it is not abstract.
+
+            newMethod.setModifiers(Modifier.PUBLIC);
+
+            // Javassist will provide a minimal implementation for us (return null, false, 0,
+            // whatever).
+
+            newMethod.setBody(null);
+
+            ctClass.addMethod(newMethod);
+
+            TransformMethodSignature sig = getMethodSignature(newMethod);
+
+            addMethodToDescription("add default", sig, "<default>");
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(ServicesMessages.errorAddingMethod(ctClass, method
+                    .getName(), ex), ex);
+        }
+
+    }
+
+    /**
+     * Check to see if the target class (or any of its super classes) implements the provided interface. This is geared
+     * for simple interfaces (that don't extend other interfaces), thus if the class (or a base class) implement
+     * interface Y that extends interface X, we may not return true for interface X.
+     */
+
+    private boolean classImplementsInterface(CtClass ctInterface) throws NotFoundException
+    {
+
+        for (CtClass current = ctClass; current != null; current = current.getSuperclass())
+        {
+            for (CtClass anInterface : current.getInterfaces())
+            {
+                if (anInterface == ctInterface) return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void claimField(String fieldName, Object tag)
+    {
+        notBlank(fieldName, "fieldName");
+        notNull(tag, "tag");
+
+        failIfFrozen();
+
+        Object existing = claimedFields.get(fieldName);
+
+        if (existing != null)
+        {
+            String message = ServicesMessages.fieldAlreadyClaimed(fieldName, ctClass, existing, tag);
+
+            throw new RuntimeException(message);
+        }
+
+        // TODO: Ensure that fieldName is a known field?
+
+        claimedFields.put(fieldName, tag);
+    }
+
+    public void addMethod(TransformMethodSignature signature, String methodBody)
+    {
+        addOrReplaceMethod(signature, methodBody, true);
+    }
+
+    private void addOrReplaceMethod(TransformMethodSignature signature, String methodBody, boolean addAsNew)
+    {
+        failIfFrozen();
+
+        CtClass returnType = findCtClass(signature.getReturnType());
+        CtClass[] parameters = buildCtClassList(signature.getParameterTypes());
+        CtClass[] exceptions = buildCtClassList(signature.getExceptionTypes());
+
+        String suffix = addAsNew ? "" : " transformed";
+
+        String action = "add" + suffix;
+
+        try
+        {
+            CtMethod existing = ctClass.getDeclaredMethod(signature.getMethodName(), parameters);
+
+            if (existing != null)
+            {
+                action = "replace" + suffix;
+
+                ctClass.removeMethod(existing);
+            }
+        }
+        catch (NotFoundException ex)
+        {
+            // That's ok. Kind of sloppy to rely on a thrown exception; wish getDeclaredMethod()
+            // would return null for
+            // that case. Alternately, we could maintain a set of the method signatures of declared
+            // or added methods.
+        }
+
+        try
+        {
+
+            CtMethod method = new CtMethod(returnType, signature.getMethodName(), parameters, ctClass);
+
+            // TODO: Check for duplicate method add
+
+            method.setModifiers(signature.getModifiers());
+
+            method.setBody(methodBody);
+            method.setExceptionTypes(exceptions);
+
+            ctClass.addMethod(method);
+
+            if (addAsNew) addedMethods.add(method);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new MethodCompileException(ServicesMessages.methodCompileError(signature, methodBody, ex), methodBody,
+                                             ex);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        addMethodToDescription(action, signature, methodBody);
+    }
+
+    public void addTransformedMethod(TransformMethodSignature methodSignature, String methodBody)
+    {
+        addOrReplaceMethod(methodSignature, methodBody, false);
+    }
+
+    private CtClass[] buildCtClassList(String[] typeNames)
+    {
+        CtClass[] result = new CtClass[typeNames.length];
+
+        for (int i = 0; i < typeNames.length; i++)
+            result[i] = findCtClass(typeNames[i]);
+
+        return result;
+    }
+
+    private CtClass findCtClass(String type)
+    {
+        try
+        {
+            return classPool.get(type);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public void extendMethod(TransformMethodSignature methodSignature, String methodBody)
+    {
+        failIfFrozen();
+
+        CtMethod method = findMethod(methodSignature);
+
+        try
+        {
+            method.insertAfter(methodBody);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, methodBody, ex),
+                                             methodBody, ex);
+        }
+
+        addMethodToDescription("extend", methodSignature, methodBody);
+
+        addedMethods.add(method);
+    }
+
+    public void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody)
+    {
+        failIfFrozen();
+
+        CtMethod method = findMethod(methodSignature);
+
+        try
+        {
+            method.insertAfter(methodBody);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, methodBody, ex),
+                                             methodBody, ex);
+        }
+
+        addMethodToDescription("extend existing", methodSignature, methodBody);
+    }
+
+    public void copyMethod(TransformMethodSignature sourceMethod, int modifiers, String newMethodName)
+    {
+        failIfFrozen();
+
+        CtClass returnType = findCtClass(sourceMethod.getReturnType());
+        CtClass[] parameters = buildCtClassList(sourceMethod.getParameterTypes());
+        CtClass[] exceptions = buildCtClassList(sourceMethod.getExceptionTypes());
+        CtMethod source = findMethod(sourceMethod);
+
+        try
+        {
+            CtMethod method = new CtMethod(returnType, newMethodName, parameters, ctClass);
+
+            method.setModifiers(modifiers);
+
+            method.setExceptionTypes(exceptions);
+
+            method.setBody(source, null);
+
+            ctClass.addMethod(method);
+
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(String.format("Error copying method %s to new method %s().",
+                                                     sourceMethod,
+                                                     newMethodName), ex);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        // The new method is *not* considered an added method, so field references inside the method
+        // will be transformed.
+
+        formatter.format("\n%s renamed to %s\n\n", sourceMethod, newMethodName);
+    }
+
+    public void addCatch(TransformMethodSignature methodSignature, String exceptionType, String body)
+    {
+        failIfFrozen();
+
+        CtMethod method = findMethod(methodSignature);
+        CtClass exceptionCtType = findCtClass(exceptionType);
+
+        try
+        {
+            method.addCatch(body, exceptionCtType);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, body, ex),
+                                             body, ex);
+        }
+
+        addMethodToDescription(String.format("catch(%s) in", exceptionType), methodSignature, body);
+
+    }
+
+    public void prefixMethod(TransformMethodSignature methodSignature, String methodBody)
+    {
+        failIfFrozen();
+
+        CtMethod method = findMethod(methodSignature);
+
+        try
+        {
+            method.insertBefore(methodBody);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new MethodCompileException(ServicesMessages.methodCompileError(methodSignature, methodBody, ex),
+                                             methodBody, ex);
+        }
+
+        addMethodToDescription("prefix", methodSignature, methodBody);
+    }
+
+    private void addMethodToDescription(String operation, TransformMethodSignature methodSignature, String methodBody)
+    {
+        formatter.format("%s method: %s %s %s(", operation, Modifier.toString(methodSignature
+                .getModifiers()), methodSignature.getReturnType(), methodSignature.getMethodName());
+
+        String[] parameterTypes = methodSignature.getParameterTypes();
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            if (i > 0) description.append(", ");
+
+            formatter.format("%s $%d", parameterTypes[i], i + 1);
+        }
+
+        description.append(")");
+
+        String[] exceptionTypes = methodSignature.getExceptionTypes();
+        for (int i = 0; i < exceptionTypes.length; i++)
+        {
+            if (i == 0) description.append("\n  throws ");
+            else description.append(", ");
+
+            description.append(exceptionTypes[i]);
+        }
+
+        formatter.format("\n%s\n\n", methodBody);
+    }
+
+    private CtMethod findMethod(TransformMethodSignature methodSignature)
+    {
+        CtMethod method = findDeclaredMethod(methodSignature);
+
+        if (method != null) return method;
+
+        CtMethod result = addOverrideOfSuperclassMethod(methodSignature);
+
+        if (result != null) return result;
+
+        throw new IllegalArgumentException(ServicesMessages.noDeclaredMethod(ctClass, methodSignature));
+    }
+
+    private CtMethod findDeclaredMethod(TransformMethodSignature methodSignature)
+    {
+        for (CtMethod method : ctClass.getDeclaredMethods())
+        {
+            if (match(method, methodSignature)) return method;
+        }
+
+        return null;
+    }
+
+    private CtMethod addOverrideOfSuperclassMethod(TransformMethodSignature methodSignature)
+    {
+        try
+        {
+            for (CtClass current = ctClass; current != null; current = current.getSuperclass())
+            {
+                for (CtMethod method : current.getDeclaredMethods())
+                {
+                    if (match(method, methodSignature))
+                    {
+                        // TODO: If the moethod is not overridable (i.e. private, or final)?
+                        // Perhaps we should limit it to just public methods.
+
+                        CtMethod newMethod = CtNewMethod.delegator(method, ctClass);
+                        ctClass.addMethod(newMethod);
+
+                        return newMethod;
+                    }
+                }
+            }
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        // Not found in a super-class.
+
+        return null;
+    }
+
+    private boolean match(CtMethod method, TransformMethodSignature sig)
+    {
+        if (!sig.getMethodName().equals(method.getName())) return false;
+
+        CtClass[] paramTypes;
+
+        try
+        {
+            paramTypes = method.getParameterTypes();
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        String[] sigTypes = sig.getParameterTypes();
+
+        int count = sigTypes.length;
+
+        if (paramTypes.length != count) return false;
+
+        for (int i = 0; i < count; i++)
+        {
+            String paramType = paramTypes[i].getName();
+
+            if (!paramType.equals(sigTypes[i])) return false;
+        }
+
+        // Ignore exceptions thrown and modifiers.
+        // TODO: Validate a match on return type?
+
+        return true;
+    }
+
+    public List<String> findFieldsWithAnnotation(final Class<? extends Annotation> annotationClass)
+    {
+        return searchFieldsWithAnnotation(annotationClass, true);
+    }
+
+
+    public List<String> findAllFieldsWithAnnotation(Class<? extends Annotation> annotationClass)
+    {
+        return searchFieldsWithAnnotation(annotationClass, false);
+    }
+
+    private List<String> searchFieldsWithAnnotation(final Class<? extends Annotation> annotationClass,
+                                                    boolean skipClaimedFields)
+    {
+        FieldFilter filter = new FieldFilter()
+        {
+            public boolean accept(String fieldName, String fieldType)
+            {
+                return getFieldAnnotation(fieldName, annotationClass) != null;
+            }
+        };
+
+        return searchFieldsAndFilter(filter, skipClaimedFields);
+    }
+
+    public List<String> findFields(FieldFilter filter)
+    {
+        return searchFieldsAndFilter(filter, true);
+    }
+
+    private List<String> searchFieldsAndFilter(FieldFilter filter, boolean skipClaimedFields)
+    {
+        failIfFrozen();
+
+        List<String> result = newList();
+
+        try
+        {
+            for (CtField field : ctClass.getDeclaredFields())
+            {
+                if (!isInstanceField(field)) continue;
+
+                String fieldName = field.getName();
+
+                if (skipClaimedFields && claimedFields.containsKey(fieldName)) continue;
+
+                if (filter.accept(fieldName, field.getType().getName())) result.add(fieldName);
+
+            }
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public List<TransformMethodSignature> findMethodsWithAnnotation(Class<? extends Annotation> annotationClass)
+    {
+        failIfFrozen();
+
+        List<TransformMethodSignature> result = newList();
+
+        for (CtMethod method : ctClass.getDeclaredMethods())
+        {
+            List<Annotation> annotations = findMethodAnnotations(method);
+
+            if (findAnnotationInList(annotationClass, annotations) != null)
+            {
+                TransformMethodSignature sig = getMethodSignature(method);
+                result.add(sig);
+            }
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public List<TransformMethodSignature> findMethods(MethodFilter filter)
+    {
+        notNull(filter, "filter");
+
+        List<TransformMethodSignature> result = newList();
+
+        for (CtMethod method : ctClass.getDeclaredMethods())
+        {
+            TransformMethodSignature sig = getMethodSignature(method);
+
+            if (filter.accept(sig)) result.add(sig);
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    private TransformMethodSignature getMethodSignature(CtMethod method)
+    {
+        TransformMethodSignature result = methodSignatures.get(method);
+        if (result == null)
+        {
+            try
+            {
+                String type = method.getReturnType().getName();
+                String[] parameters = toTypeNames(method.getParameterTypes());
+                String[] exceptions = toTypeNames(method.getExceptionTypes());
+
+                result = new TransformMethodSignature(method.getModifiers(), type, method.getName(), parameters,
+                                                      exceptions);
+
+                methodSignatures.put(method, result);
+            }
+            catch (NotFoundException ex)
+            {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        return result;
+    }
+
+    private String[] toTypeNames(CtClass[] types)
+    {
+        String[] result = new String[types.length];
+
+        for (int i = 0; i < types.length; i++)
+            result[i] = types[i].getName();
+
+        return result;
+    }
+
+    public List<String> findUnclaimedFields()
+    {
+        failIfFrozen();
+
+        List<String> names = newList();
+
+        Set<String> skipped = newSet();
+
+        skipped.addAll(claimedFields.keySet());
+        skipped.addAll(addedFieldNames);
+
+        if (removedFieldNames != null) skipped.addAll(removedFieldNames);
+
+        for (CtField field : ctClass.getDeclaredFields())
+        {
+            if (!isInstanceField(field)) continue;
+
+            String name = field.getName();
+
+            if (skipped.contains(name)) continue;
+
+            // May need to add a filter to edit out explicitly added fields.
+
+            names.add(name);
+        }
+
+        Collections.sort(names);
+
+        return names;
+    }
+
+    private boolean isInstanceField(CtField field)
+    {
+        int modifiers = field.getModifiers();
+
+        return Modifier.isPrivate(modifiers) && !Modifier.isStatic(modifiers);
+    }
+
+    public String getFieldType(String fieldName)
+    {
+        failIfFrozen();
+
+        CtClass type = getFieldCtType(fieldName);
+
+        return type.getName();
+    }
+
+    public boolean isField(String fieldName)
+    {
+        failIfFrozen();
+
+        try
+        {
+            CtField field = ctClass.getDeclaredField(fieldName);
+
+            return isInstanceField(field);
+        }
+        catch (NotFoundException ex)
+        {
+            return false;
+        }
+    }
+
+    public int getFieldModifiers(String fieldName)
+    {
+        failIfFrozen();
+
+        try
+        {
+            return ctClass.getDeclaredField(fieldName).getModifiers();
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private CtClass getFieldCtType(String fieldName)
+    {
+        try
+        {
+            CtField field = ctClass.getDeclaredField(fieldName);
+
+            return field.getType();
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public String addField(int modifiers, String type, String suggestedName)
+    {
+        failIfFrozen();
+
+        String fieldName = newMemberName(suggestedName);
+
+        try
+        {
+            CtClass ctType = convertNameToCtType(type);
+
+            CtField field = new CtField(ctType, fieldName, ctClass);
+            field.setModifiers(modifiers);
+
+            ctClass.addField(field);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        formatter
+                .format("add field: %s %s %s;\n\n", Modifier.toString(modifiers), type, fieldName);
+
+        addedFieldNames.add(fieldName);
+
+        return fieldName;
+    }
+
+    public String addInjectedField(Class type, String suggestedName, Object value)
+    {
+        notNull(type, "type");
+
+        failIfFrozen();
+
+        MultiKey key = new MultiKey(type, value);
+
+        String fieldName = searchForPreviousInjection(key);
+
+        if (fieldName != null) return fieldName;
+
+        // TODO: Probably doesn't handle arrays and primitives.
+
+        fieldName = addInjectedFieldUncached(type, suggestedName, value);
+
+        // Remember the injection in-case this class, or a subclass, injects the value again.
+
+        injectionCache.put(key, fieldName);
+
+        return fieldName;
+    }
+
+    /**
+     * This is split out from {@link #addInjectedField(Class, String, Object)} to handle a special case for the
+     * InternalComponentResources, which is null when "injected" (during the class transformation) and is only
+     * determined when a component is actually instantiated.
+     */
+    private String addInjectedFieldUncached(Class type, String suggestedName, Object value)
+    {
+        CtClass ctType;
+
+        try
+        {
+            ctType = classPool.get(type.getName());
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        String fieldName = addField(Modifier.PROTECTED | Modifier.FINAL, type.getName(), suggestedName);
+
+        addInjectToConstructor(fieldName, ctType, value);
+
+        addedFieldNames.add(fieldName);
+
+        return fieldName;
+    }
+
+    public String searchForPreviousInjection(MultiKey key)
+    {
+        String result = injectionCache.get(key);
+
+        if (result != null) return result;
+
+        if (parentTransformation != null) return parentTransformation.searchForPreviousInjection(key);
+
+        return null;
+    }
+
+    public void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice)
+    {
+        Defense.notNull(methodSignature, "methodSignature");
+        Defense.notNull(advice, "advice");
+
+        InvocationBuilder builder = methodToInvocationBuilder.get(methodSignature);
+
+        if (builder == null)
+        {
+            builder = new InvocationBuilder(this, componentClassCache, methodSignature, classSource);
+            methodToInvocationBuilder.put(methodSignature, builder);
+        }
+
+        builder.addAdvice(advice);
+    }
+
+    /**
+     * Adds a parameter to the constructor for the class; the parameter is used to initialize the value for a field.
+     *
+     * @param fieldName name of field to inject
+     * @param fieldType Javassist type of the field (and corresponding parameter)
+     * @param value     the value to be injected (which will in unusual cases be null)
+     */
+    private void addInjectToConstructor(String fieldName, CtClass fieldType, Object value)
+    {
+        constructorArgs.add(new ConstructorArg(fieldType, value));
+
+        extendConstructor(format("  %s = $%d;", fieldName, constructorArgs.size()));
+    }
+
+    public void injectField(String fieldName, Object value)
+    {
+        notNull(fieldName, "fieldName");
+
+        failIfFrozen();
+
+        CtClass type = getFieldCtType(fieldName);
+
+        addInjectToConstructor(fieldName, type, value);
+
+        makeReadOnly(fieldName);
+    }
+
+    private CtClass convertNameToCtType(String type) throws NotFoundException
+    {
+        return classPool.get(type);
+    }
+
+    public void finish()
+    {
+        failIfFrozen();
+
+        for (InvocationBuilder builder : methodToInvocationBuilder.values())
+        {
+            builder.commit();
+        }
+
+        performFieldTransformations();
+
+        addConstructor();
+
+        verifyFields();
+
+        freeze();
+    }
+
+    private void addConstructor()
+    {
+        String initializer = idAllocator.allocateId("initializer");
+
+        try
+        {
+            CtConstructor defaultConstructor = ctClass.getConstructor("()V");
+
+            CtMethod initializerMethod = defaultConstructor.toMethod(initializer, ctClass);
+
+            ctClass.addMethod(initializerMethod);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        formatter.format("convert default constructor: %s();\n\n", initializer);
+
+        int count = constructorArgs.size();
+
+        CtClass[] types = new CtClass[count];
+
+        for (int i = 0; i < count; i++)
+        {
+            ConstructorArg arg = constructorArgs.get(i);
+
+            types[i] = arg.type;
+        }
+
+        // Add a call to the initializer; the method converted fromt the classes default
+        // constructor.
+
+        constructor.append("  ");
+        constructor.append(initializer);
+
+        // This finally matches the "{" added inside the constructor
+
+        constructor.append("();\n\n}");
+
+        String constructorBody = constructor.toString();
+
+        try
+        {
+            CtConstructor cons = CtNewConstructor.make(types, null, constructorBody, ctClass);
+            ctClass.addConstructor(cons);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        formatter.format("add constructor: %s(", ctClass.getName());
+
+        for (int i = 0; i < count; i++)
+        {
+            if (i > 0) description.append(", ");
+
+            formatter.format("%s $%d", types[i].getName(), i + 1);
+        }
+
+        formatter.format(")\n%s\n\n", constructorBody);
+    }
+
+    public Instantiator createInstantiator()
+    {
+        String componentClassName = ctClass.getName();
+
+        String name = ClassFabUtils.generateClassName("Instantiator");
+
+        ClassFab cf = classFactory.newClass(name, AbstractInstantiator.class);
+
+        BodyBuilder constructor = new BodyBuilder();
+
+        // This is realy -1 + 2: The first value in constructorArgs is the InternalComponentResources, which doesn't
+        // count toward's the Instantiator's constructor ... then we add in the Model and String description.
+        // It's tricky because there's the constructor parameters for the Instantiator, most of which are stored
+        // in fields and then used as the constructor parameters for the Component.
+
+        Class[] constructorParameterTypes = new Class[constructorArgs.size() + 1];
+        Object[] constructorParameterValues = new Object[constructorArgs.size() + 1];
+
+        constructorParameterTypes[0] = ComponentModel.class;
+        constructorParameterValues[0] = componentModel;
+
+        constructorParameterTypes[1] = String.class;
+        constructorParameterValues[1] = String.format("Instantiator[%s]", componentClassName);
+
+        BodyBuilder newInstance = new BodyBuilder();
+
+        newInstance.add("return new %s($1", componentClassName);
+
+        constructor.begin();
+
+        // Pass the model and description to AbstractInstantiator
+
+        constructor.addln("super($1, $2);");
+
+        // Again, skip the (implicit) InternalComponentResources field, that's
+        // supplied to the Instantiator's newInstance() method.
+
+        for (int i = 1; i < constructorArgs.size(); i++)
+        {
+            ConstructorArg arg = constructorArgs.get(i);
+
+            CtClass argCtType = arg.type;
+            Class argType = toClass(argCtType.getName());
+
+            boolean primitive = argCtType.isPrimitive();
+
+            Class fieldType = primitive ? ClassFabUtils.getPrimitiveType(argType) : argType;
+
+            String fieldName = "_param_" + i;
+
+            constructorParameterTypes[i + 1] = argType;
+            constructorParameterValues[i + 1] = arg.value;
+
+            cf.addField(fieldName, fieldType);
+
+            // $1 is model, $2 is description, to $3 is first dynamic parameter.
+
+            // The arguments may be wrapper types, so we cast down to
+            // the primitive type.
+
+            String parameterReference = "$" + (i + 2);
+
+            constructor.addln("%s = %s;",
+                              fieldName,
+                              ClassFabUtils.castReference(parameterReference, fieldType.getName()));
+
+            newInstance.add(", %s", fieldName);
+        }
+
+        constructor.end();
+        newInstance.addln(");");
+
+        cf.addConstructor(constructorParameterTypes, null, constructor.toString());
+
+        cf.addMethod(Modifier.PUBLIC, NEW_INSTANCE_SIGNATURE, newInstance.toString());
+
+        Class instantiatorClass = cf.createClass();
+
+        try
+        {
+            Object instance = instantiatorClass.getConstructors()[0].newInstance(constructorParameterValues);
+
+            return (Instantiator) instance;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private void failIfFrozen()
+    {
+        if (frozen) throw new IllegalStateException(
+                "The ClassTransformation instance (for " + ctClass.getName() + ") has completed all transformations and may not be further modified.");
+    }
+
+    private void failIfNotFrozen()
+    {
+        if (!frozen) throw new IllegalStateException(
+                "The ClassTransformation instance (for " + ctClass.getName() + ") has not yet completed all transformations.");
+    }
+
+    public IdAllocator getIdAllocator()
+    {
+        failIfNotFrozen();
+
+        return idAllocator;
+    }
+
+    public List<ConstructorArg> getConstructorArgs()
+    {
+        failIfNotFrozen();
+
+        return CollectionFactory.newList(constructorArgs);
+    }
+
+    public List<Annotation> getClassAnnotations()
+    {
+        failIfFrozen();
+
+        if (classAnnotations == null) assembleClassAnnotations();
+
+        return classAnnotations;
+    }
+
+    private void assembleClassAnnotations()
+    {
+        classAnnotations = newList();
+
+        try
+        {
+            for (CtClass current = ctClass; current != null; current = current.getSuperclass())
+            {
+                addAnnotationsToList(classAnnotations, current.getAnnotations());
+            }
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder("InternalClassTransformation[\n");
+
+        try
+        {
+            Formatter formatter = new Formatter(builder);
+
+            formatter.format("%s %s extends %s", Modifier.toString(ctClass.getModifiers()), ctClass.getName(),
+                             ctClass.getSuperclass().getName());
+
+            CtClass[] interfaces = ctClass.getInterfaces();
+
+            for (int i = 0; i < interfaces.length; i++)
+            {
+                if (i == 0) builder.append("\n  implements ");
+                else builder.append(", ");
+
+                builder.append(interfaces[i].getName());
+            }
+
+            formatter.format("\n\n%s", description.toString());
+        }
+        catch (NotFoundException ex)
+        {
+            builder.append(ex);
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+
+    public void makeReadOnly(String fieldName)
+    {
+        String methodName = newMemberName("write", fieldName);
+
+        String fieldType = getFieldType(fieldName);
+
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, "void", methodName,
+                                                                    new String[] { fieldType }, null);
+
+        String message = ServicesMessages.readOnlyField(ctClass.getName(), fieldName);
+
+        String body = format("throw new java.lang.RuntimeException(\"%s\");", message);
+
+        addMethod(sig, body);
+
+        replaceWriteAccess(fieldName, methodName);
+    }
+
+    public void removeField(String fieldName)
+    {
+        formatter.format("remove field %s;\n\n", fieldName);
+
+        // TODO: We could check that there's an existing field read and field write transform ...
+
+        if (removedFieldNames == null) removedFieldNames = newSet();
+
+        removedFieldNames.add(fieldName);
+
+    }
+
+    public void replaceReadAccess(String fieldName, String methodName)
+    {
+        // Explicitly reference $0 (aka "this") because of TAPESTRY-1511.
+        // $0 is valid even inside a static method.
+
+        String body = String.format("$_ = $0.%s();", methodName);
+
+        if (fieldReadTransforms == null) fieldReadTransforms = newMap();
+
+        // TODO: Collisions?
+
+        fieldReadTransforms.put(fieldName, body);
+
+        formatter.format("replace read %s: %s();\n\n", fieldName, methodName);
+    }
+
+    public void replaceWriteAccess(String fieldName, String methodName)
+    {
+        // Explicitly reference $0 (aka "this") because of TAPESTRY-1511.
+        // $0 is valid even inside a static method.
+
+        String body = String.format("$0.%s($1);", methodName);
+
+        if (fieldWriteTransforms == null) fieldWriteTransforms = newMap();
+
+        // TODO: Collisions?
+
+        fieldWriteTransforms.put(fieldName, body);
+
+        formatter.format("replace write %s: %s();\n\n", fieldName, methodName);
+    }
+
+    private void performFieldTransformations()
+    {
+        // If no field transformations have been requested, then we can save ourselves some
+        // trouble!
+
+        if (fieldReadTransforms != null || fieldWriteTransforms != null) replaceFieldAccess();
+
+        if (removedFieldNames != null)
+        {
+            for (String fieldName : removedFieldNames)
+            {
+                try
+                {
+                    CtField field = ctClass.getDeclaredField(fieldName);
+                    ctClass.removeField(field);
+                }
+                catch (NotFoundException ex)
+                {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+    }
+
+    static final int SYNTHETIC = 0x00001000;
+
+    private void replaceFieldAccess()
+    {
+        // Provide empty maps here, to make the code in the inner class a tad
+        // easier.
+
+        if (fieldReadTransforms == null) fieldReadTransforms = newMap();
+
+        if (fieldWriteTransforms == null) fieldWriteTransforms = newMap();
+
+        ExprEditor editor = new ExprEditor()
+        {
+            @Override
+            public void edit(FieldAccess access) throws CannotCompileException
+            {
+                CtBehavior where = access.where();
+
+                if (where instanceof CtConstructor) return;
+
+                boolean isRead = access.isReader();
+                String fieldName = access.getFieldName();
+                CtMethod method = (CtMethod) where;
+
+                formatter.format("Checking field %s %s in method %s(): ", isRead ? "read" : "write", fieldName,
+                                 method.getName());
+
+                // Ignore any methods to were added as part of the transformation.
+                // If we reference the field there, we really mean the field.
+
+                if (addedMethods.contains(where))
+                {
+                    formatter.format("added method\n");
+                    return;
+                }
+
+                Map<String, String> transformMap = isRead ? fieldReadTransforms : fieldWriteTransforms;
+
+                String body = transformMap.get(fieldName);
+                if (body == null)
+                {
+                    formatter.format("field not transformed\n");
+                    return;
+                }
+
+                formatter.format("replacing with %s\n", body);
+
+                access.replace(body);
+            }
+        };
+
+        try
+        {
+            ctClass.instrument(editor);
+        }
+        catch (CannotCompileException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        formatter.format("\n");
+    }
+
+    public Class toClass(String type)
+    {
+        String finalType = TransformUtils.getWrapperTypeName(type);
+
+        try
+        {
+            return Class.forName(finalType, true, classFactory.getClassLoader());
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public String getClassName()
+    {
+        return ctClass.getName();
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public void extendConstructor(String statement)
+    {
+        notNull(statement, "statement");
+
+        failIfFrozen();
+
+        constructor.append(statement);
+        constructor.append("\n");
+    }
+
+    public String getMethodIdentifier(TransformMethodSignature signature)
+    {
+        notNull(signature, "signature");
+
+        CtMethod method = findMethod(signature);
+
+        int lineNumber = method.getMethodInfo2().getLineNumber(0);
+        CtClass enclosingClass = method.getDeclaringClass();
+        String sourceFile = enclosingClass.getClassFile2().getSourceFile();
+
+        return format("%s.%s (at %s:%d)", enclosingClass.getName(), signature
+                .getMediumDescription(), sourceFile, lineNumber);
+    }
+
+    public boolean isRootTransformation()
+    {
+        return parentTransformation == null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalModule.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
new file mode 100644
index 0000000..65f334f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
@@ -0,0 +1,245 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.internal.structure.PageResourcesSource;
+import org.apache.tapestry.internal.structure.PageResourcesSourceImpl;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.annotation.Marker;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.PerthreadManager;
+import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
+import org.apache.tapestry.services.*;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+import org.apache.tapestry5.services.RequestGlobals;
+import org.slf4j.Logger;
+
+import javax.servlet.http.Cookie;
+
+/**
+ * {@link org.apache.tapestry.services.TapestryModule} has gotten too complicated and it is nice to demarkate public
+ * (and stable) from internal (and volatile).
+ */
+@Marker(Core.class)
+public class InternalModule
+{
+    private final UpdateListenerHub updateListenerHub;
+
+    private final ComponentInstantiatorSource componentInstantiatorSource;
+
+    private final ComponentTemplateSource componentTemplateSource;
+
+    private final RequestGlobals requestGlobals;
+
+    public InternalModule(UpdateListenerHub updateListenerHub, ComponentInstantiatorSource componentInstantiatorSource,
+                          ComponentTemplateSource componentTemplateSource, RequestGlobals requestGlobals)
+    {
+        this.updateListenerHub = updateListenerHub;
+        this.componentInstantiatorSource = componentInstantiatorSource;
+        this.componentTemplateSource = componentTemplateSource;
+        this.requestGlobals = requestGlobals;
+    }
+
+
+    /**
+     * Bind all the private/internal services of Tapestry.
+     */
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(PersistentFieldManager.class, PersistentFieldManagerImpl.class);
+        binder.bind(TemplateParser.class, TemplateParserImpl.class);
+        binder.bind(PageResponseRenderer.class, PageResponseRendererImpl.class);
+        binder.bind(PageMarkupRenderer.class, PageMarkupRendererImpl.class);
+        binder.bind(ComponentInvocationMap.class, NoOpComponentInvocationMap.class);
+        binder.bind(UpdateListenerHub.class, UpdateListenerHubImpl.class);
+        binder.bind(LinkFactory.class, LinkFactoryImpl.class);
+        binder.bind(LocalizationSetter.class, LocalizationSetterImpl.class);
+        binder.bind(PageElementFactory.class, PageElementFactoryImpl.class);
+        binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class);
+        binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class);
+        binder.bind(RequestEncodingInitializer.class, RequestEncodingInitializerImpl.class);
+        binder.bind(PageRenderQueue.class, PageRenderQueueImpl.class);
+        binder.bind(AjaxPartialResponseRenderer.class, AjaxPartialResponseRendererImpl.class);
+        binder.bind(PageContentTypeAnalyzer.class, PageContentTypeAnalyzerImpl.class);
+        binder.bind(ResponseRenderer.class, ResponseRendererImpl.class);
+        binder.bind(RequestPathOptimizer.class, RequestPathOptimizerImpl.class);
+        binder.bind(PageResourcesSource.class, PageResourcesSourceImpl.class);
+        binder.bind(RequestSecurityManager.class, RequestSecurityManagerImpl.class);
+        binder.bind(InternalRequestGlobals.class, InternalRequestGlobalsImpl.class);
+    }
+
+    /**
+     * Chooses one of two implementations, based on the configured mode.
+     */
+    public static ActionRenderResponseGenerator buildActionRenderResponseGenerator(
+
+            @Symbol(SymbolConstants.SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS)
+            boolean immediateMode,
+
+            ObjectLocator locator)
+    {
+        if (immediateMode) return locator.autobuild(ImmediateActionRenderResponseGenerator.class);
+
+        return locator.autobuild(ActionRenderResponseGeneratorImpl.class);
+    }
+
+    @Scope(PERTHREAD_SCOPE)
+    public static RequestPageCache buildRequestPageCache(PagePool pagePool, PerthreadManager perthreadManager)
+    {
+        RequestPageCacheImpl service = new RequestPageCacheImpl(pagePool);
+
+        perthreadManager.addThreadCleanupListener(service);
+
+        return service;
+    }
+
+    public static PageTemplateLocator buildPageTemplateLocator(@ContextProvider AssetFactory contextAssetFactory,
+
+                                                               ComponentClassResolver componentClassResolver)
+    {
+        return new PageTemplateLocatorImpl(contextAssetFactory.getRootResource(), componentClassResolver);
+    }
+
+
+    public ComponentInstantiatorSource buildComponentInstantiatorSource(@Builtin ClassFactory classFactory,
+
+                                                                        ComponentClassTransformer transformer,
+
+                                                                        Logger logger,
+
+                                                                        InternalRequestGlobals internalRequestGlobals)
+    {
+        ComponentInstantiatorSourceImpl source = new ComponentInstantiatorSourceImpl(logger, classFactory
+                .getClassLoader(), transformer, internalRequestGlobals);
+
+        updateListenerHub.addUpdateListener(source);
+
+        return source;
+    }
+
+    public ComponentClassTransformer buildComponentClassTransformer(ServiceResources resources)
+    {
+        ComponentClassTransformerImpl transformer = resources.autobuild(ComponentClassTransformerImpl.class);
+
+        componentInstantiatorSource.addInvalidationListener(transformer);
+
+        return transformer;
+    }
+
+    public PagePool buildPagePool(PageLoader pageLoader, ComponentMessagesSource componentMessagesSource,
+                                  ServiceResources resources)
+    {
+        PagePoolImpl service = resources.autobuild(PagePoolImpl.class);
+
+        // This covers invalidations due to changes to classes
+
+        pageLoader.addInvalidationListener(service);
+
+        // This covers invalidation due to changes to message catalogs (properties files)
+
+        componentMessagesSource.addInvalidationListener(service);
+
+        // ... and this covers invalidations due to changes to templates
+
+        componentTemplateSource.addInvalidationListener(service);
+
+        // Give the service a chance to clean up its own cache periodically as well
+
+        updateListenerHub.addUpdateListener(service);
+
+        return service;
+    }
+
+    public ComponentClassCache buildComponentClassCache(@ComponentLayer ClassFactory classFactory)
+    {
+        ComponentClassCacheImpl service = new ComponentClassCacheImpl(classFactory);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    public CookieSource buildCookieSource()
+    {
+        return new CookieSource()
+        {
+
+            public Cookie[] getCookies()
+            {
+                return requestGlobals.getHTTPServletRequest().getCookies();
+            }
+        };
+    }
+
+
+    public CookieSink buildCookieSink()
+    {
+        return new CookieSink()
+        {
+
+            public void addCookie(Cookie cookie)
+            {
+                requestGlobals.getHTTPServletResponse().addCookie(cookie);
+            }
+
+        };
+    }
+
+    public ResourceCache buildResourceCache(ResourceDigestGenerator digestGenerator)
+    {
+        ResourceCacheImpl service = new ResourceCacheImpl(digestGenerator);
+
+        updateListenerHub.addUpdateListener(service);
+
+        return service;
+    }
+
+
+    public ComponentTemplateSource buildComponentTemplateSource(TemplateParser parser, PageTemplateLocator locator)
+    {
+        ComponentTemplateSourceImpl service = new ComponentTemplateSourceImpl(parser, locator);
+
+        updateListenerHub.addUpdateListener(service);
+
+        return service;
+    }
+
+    public PageLoader buildPageLoader(ServiceResources resources)
+    {
+        PageLoaderImpl service = resources.autobuild(PageLoaderImpl.class);
+
+        // Recieve invalidations when the class loader is discarded (due to a component class
+        // change). The notification is forwarded to the page loader's listeners.
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    @Marker(ComponentLayer.class)
+    public CtClassSource buildCtClassSource(PropertyShadowBuilder builder)
+    {
+        return builder.build(componentInstantiatorSource, "classSource", CtClassSource.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java
new file mode 100644
index 0000000..76c1507
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobals.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Stores global per-request data internal to the framework.
+ */
+public interface InternalRequestGlobals
+{
+    /**
+     * Stores the throwable for later; only the first such exception is kept (later exceptions are ignored, see
+     * TAPESTRY-2399).
+     */
+    void storeClassLoaderException(Throwable classLoaderException);
+
+    Throwable getClassLoaderException();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java
new file mode 100644
index 0000000..3a1d59e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalRequestGlobalsImpl.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+
+
+@Scope(PERTHREAD_SCOPE)
+public class InternalRequestGlobalsImpl implements InternalRequestGlobals
+{
+    private Throwable classLoaderException;
+
+    public Throwable getClassLoaderException()
+    {
+        return classLoaderException;
+    }
+
+    public void storeClassLoaderException(Throwable classLoaderException)
+    {
+        if (this.classLoaderException == null)
+            this.classLoaderException = classLoaderException;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationBuilder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationBuilder.java
new file mode 100644
index 0000000..c914a2f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationBuilder.java
@@ -0,0 +1,318 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.*;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.internal.services.CtClassSource;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.services.ComponentMethodAdvice;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.reflect.Modifier;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.services.InternalClassTransformationImpl} to manage adding method
+ * invocation advice to arbitrary component methods.
+ *
+ * @see org.apache.tapestry.ioc.MethodAdvice
+ */
+class InvocationBuilder
+{
+    private static final String FIELD_NAME = "_p";
+
+    private static final int PROTECTED_FINAL = Modifier.PROTECTED | Modifier.FINAL;
+
+    private static final int PUBLIC_FINAL = Modifier.PUBLIC | Modifier.FINAL;
+
+    private final InternalClassTransformation transformation;
+
+    private final CtClassSource classSource;
+
+    private final TransformMethodSignature advisedMethod;
+
+    private final MethodInvocationInfo info;
+
+    private final CtClass invocationCtClass;
+
+    private final String invocationClassName;
+
+    private static final AtomicLong UID_GENERATOR = new AtomicLong(System.currentTimeMillis());
+
+    private static String nextUID()
+    {
+        return Long.toHexString(UID_GENERATOR.getAndIncrement());
+    }
+
+    public InvocationBuilder(InternalClassTransformation transformation,
+                             ComponentClassCache componentClassCache, TransformMethodSignature advisedMethod,
+                             CtClassSource classSource)
+    {
+        this.transformation = transformation;
+        this.advisedMethod = advisedMethod;
+        this.classSource = classSource;
+
+        info = new MethodInvocationInfo(advisedMethod, componentClassCache);
+
+        invocationClassName = this.transformation.getClassName() + "$" + this.advisedMethod.getMethodName() + "$invocation_" + nextUID();
+
+        invocationCtClass = this.classSource.newClass(invocationClassName, AbstractComponentMethodInvocation.class);
+
+    }
+
+    public void addAdvice(ComponentMethodAdvice advice)
+    {
+        info.addAdvice(advice);
+    }
+
+    /**
+     * Commit the changes, creating the new class for the invocation, and renaming and rewriting the advised method.
+     */
+    public void commit()
+    {
+        // The class name is the component class name plus the method name plus a unique uid. This places
+        // the invocation in the same package as the component class; the original method will ultimately
+        // be renamed and modified to be package private.
+
+        try
+        {
+            createConstructor();
+
+            implementOverride();
+
+            implementGetParameter();
+
+            String renamed = copyAdvisedMethod();
+
+            implementInvokeAdvisedMethod(renamed);
+
+            classSource.createClass(invocationCtClass);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        rebuildOriginalMethod();
+    }
+
+    private void rebuildOriginalMethod()
+    {
+        String methodInfoField = transformation.addInjectedField(MethodInvocationInfo.class,
+                                                                 advisedMethod.getMethodName() + "Info",
+                                                                 info);
+
+        String componentResourcesField = transformation.getResourcesFieldName();
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        builder.addln("%s invocation = new %<s(%s, %s, $$);", invocationClassName, methodInfoField,
+                      componentResourcesField);
+
+        // Off into the first MethodAdvice
+
+        builder.addln("invocation.proceed();");
+
+        String[] exceptionTypes = advisedMethod.getExceptionTypes();
+        int exceptionCount = exceptionTypes.length;
+
+        if (exceptionCount > 0)
+        {
+            for (int i = 0; i < exceptionCount; i++)
+            {
+                String type = exceptionTypes[i];
+                String name = "ex" + i;
+
+                builder.addln("%s %s = (%1$s) invocation.getThrown(%s.getExceptionType(%d));",
+                              type, name, methodInfoField, i);
+                builder.addln("if (%s != null) throw %<s;", name);
+            }
+        }
+
+        String returnType = advisedMethod.getReturnType();
+
+        if (!returnType.equals("void"))
+        {
+            builder.addln("return %s;",
+                          ClassFabUtils.castReference("invocation.getResult()", returnType));
+        }
+
+
+        builder.end();
+
+        /** Replace the original method with the new implementation. */
+        transformation.addMethod(advisedMethod, builder.toString());
+    }
+
+    private void implementInvokeAdvisedMethod(String advisedMethodName) throws CannotCompileException
+    {
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        boolean isVoid = advisedMethod.getReturnType().equals("void");
+
+        builder.addln("%s component = (%<s) getComponentResources().getComponent();", transformation.getClassName());
+
+        String[] exceptionTypes = advisedMethod.getExceptionTypes();
+        int exceptionCount = exceptionTypes.length;
+
+        if (exceptionCount > 0)
+            builder.add("try").begin();
+
+        if (!isVoid) builder.add("overrideResult(($w) ");
+
+        builder.add("component.%s(", advisedMethodName);
+
+        for (int i = 0; i < advisedMethod.getParameterTypes().length; i++)
+        {
+            if (i > 0) builder.add(", ");
+
+            builder.add("%s%d", FIELD_NAME, i);
+        }
+
+        builder.add(")");
+
+        if (!isVoid) builder.add(")");
+
+        builder.addln(";");
+
+        if (exceptionCount > 0)
+        {
+            builder.end(); // try
+
+            for (int i = 0; i < exceptionCount; i++)
+            {
+                builder.addln("catch (%s ex) { overrideThrown(ex); }", exceptionTypes[i]);
+            }
+        }
+
+        builder.end();
+
+        CtMethod method = new CtMethod(CtClass.voidType, "invokeAdvisedMethod",
+                                       new CtClass[0], invocationCtClass);
+
+        method.setModifiers(PROTECTED_FINAL);
+        method.setBody(builder.toString());
+
+        invocationCtClass.addMethod(method);
+    }
+
+    private String copyAdvisedMethod()
+    {
+        String newName = transformation.newMemberName("advised$" + advisedMethod.getMethodName());
+
+        transformation.copyMethod(advisedMethod, Modifier.FINAL, newName);
+
+        return newName;
+    }
+
+    private void createConstructor() throws CannotCompileException
+    {
+        int parameterCount = info.getParameterCount();
+
+        CtClass[] parameterTypes = new CtClass[parameterCount + 2];
+
+        parameterTypes[0] = toCtClass(MethodInvocationInfo.class);
+        parameterTypes[1] = toCtClass(ComponentResources.class);
+
+        BodyBuilder builder = new BodyBuilder().begin().addln("super($1,$2);");
+
+        for (int i = 0; i < parameterCount; i++)
+        {
+            String name = FIELD_NAME + i;
+
+            String parameterTypeName = advisedMethod.getParameterTypes()[i];
+
+            CtClass parameterType = classSource.toCtClass(parameterTypeName);
+
+            CtField field = new CtField(parameterType, name, invocationCtClass);
+            field.setModifiers(Modifier.PRIVATE);
+            invocationCtClass.addField(field);
+
+            parameterTypes[2 + i] = parameterType;
+
+            builder.addln("%s = $%d;", name, 3 + i);
+        }
+
+        builder.end();
+
+        CtConstructor constructor = new CtConstructor(parameterTypes, invocationCtClass);
+        constructor.setBody(builder.toString());
+
+        invocationCtClass.addConstructor(constructor);
+
+    }
+
+    private CtClass toCtClass(Class input)
+    {
+        return classSource.toCtClass(input);
+    }
+
+    private void implementOverride() throws CannotCompileException
+    {
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        builder.addln("switch ($1)").begin();
+
+        int count = advisedMethod.getParameterTypes().length;
+
+        for (int i = 0; i < count; i++)
+        {
+            String type = advisedMethod.getParameterTypes()[i];
+
+            builder.addln("case %d: %s = %s; break;", i, FIELD_NAME + i, ClassFabUtils.castReference("$2", type));
+        }
+
+        builder.addln("default: throw new IllegalArgumentException(\"Index out of range.\");");
+
+        builder.end().end();
+
+        CtMethod method = new CtMethod(CtClass.voidType, "override",
+                                       new CtClass[] { CtClass.intType, toCtClass(Object.class) }, invocationCtClass);
+
+        method.setModifiers(PUBLIC_FINAL);
+        method.setBody(builder.toString());
+
+        invocationCtClass.addMethod(method);
+    }
+
+    private void implementGetParameter() throws CannotCompileException
+    {
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        builder.addln("switch ($1)").begin();
+
+        int count = advisedMethod.getParameterTypes().length;
+
+        for (int i = 0; i < count; i++)
+        {
+            builder.addln("case %d: return ($w) %s;", i, FIELD_NAME + i);
+        }
+
+        builder.addln("default: throw new IllegalArgumentException(\"Index out of range.\");");
+
+        builder.end().end();
+
+        CtMethod method = new CtMethod(toCtClass(Object.class), "getParameter",
+                                       new CtClass[] { CtClass.intType }, invocationCtClass);
+
+        method.setModifiers(PUBLIC_FINAL);
+        method.setBody(builder.toString());
+
+        invocationCtClass.addMethod(method);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationTarget.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationTarget.java
new file mode 100644
index 0000000..cee7942
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InvocationTarget.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * It represents target for a {@link org.apache.tapestry.internal.services.ComponentInvocation}. For example, it may be
+ * a page or an action for a component within a page.
+ */
+public interface InvocationTarget
+{
+    String getPath();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
new file mode 100644
index 0000000..4ffc5ba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/JSONObjectEventResultProcessor.java
@@ -0,0 +1,48 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry5.json.JSONObject;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+/**
+ * Implemention of {@link ComponentEventResultProcessor} for {@link org.apache.tapestry5.json.JSONObject}, allowing a
+ * component event handler to return a JSONObject that will be sent directly to the client as the reply. This is often
+ * used with custom components that need a custom JSON response.
+ */
+public class JSONObjectEventResultProcessor implements ComponentEventResultProcessor<JSONObject>
+{
+    private final Response response;
+
+    public JSONObjectEventResultProcessor(Response response)
+    {
+        this.response = response;
+    }
+
+    public void processResultValue(JSONObject value) throws IOException
+    {
+        PrintWriter pw = response.getPrintWriter(InternalConstants.JSON_MIME_TYPE);
+
+        pw.print(value.toString());
+
+        pw.flush();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java
new file mode 100644
index 0000000..f218a90
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactory.java
@@ -0,0 +1,76 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * A source for {@link Link} objects.
+ *
+ * @see LinkFactoryListener
+ */
+public interface LinkFactory
+{
+    /**
+     * Creates a stateful action link. Action links are built for components. Action links are encoded by the current
+     * request (that is, bound to the current request's session, if any).
+     *
+     * @param page
+     * @param nestedId
+     * @param eventType the type of event to trigger
+     * @param forForm   true if the link is for a form, false otherwise
+     * @param context   Additional path data, each value will be converted to a string and appended to the URI @return a
+     *                  link
+     * @see org.apache.tapestry.ComponentResources#createActionLink(String, boolean, Object[])
+     */
+    Link createActionLink(Page page, String nestedId, String eventType, boolean forForm, Object... context);
+
+    /**
+     * Creates a render link for the page. If an activation context is supplied then that context is built into the URI.
+     * If no activation context is supplied, then the activation context is obtained from the page itself, by triggering
+     * a passivate event on its root component.
+     * <p/>
+     * When the activationContext is an empty array, the targetted page is checked to see if it can provide an
+     * activation context. This is accomplished by triggering a "passivate" event on the targetted page. If the override
+     * parameter is true, this will not occur (even when the activation context is empty).
+     *
+     * @param page              the page to which a link should be created
+     * @param override          if true, then the provided activation context is always used even if empty
+     * @param activationContext the activation context for the page
+     * @return a link
+     * @see org.apache.tapestry.ComponentResources#createPageLink(String, boolean, Object[])
+     */
+    Link createPageLink(Page page, boolean override, Object... activationContext);
+
+    /**
+     * As with {@link #createPageLink(Page, boolean, Object[])}, but the page is specified by logical name, rather than
+     * as an instance.
+     *
+     * @param logicalPageName the logical name of the page to generate a link to
+     * @param override        if true, then the provided activation context is always used even if empty
+     * @param context         activation context for the page
+     * @return
+     */
+    Link createPageLink(String logicalPageName, boolean override, Object... context);
+
+    /**
+     * Adds a listener, to be notified any time an action or render link is created; this allows the listener to modify
+     * the link (by adding additional query parameters to the link).
+     *
+     * @param listener to add
+     */
+    void addListener(LinkFactoryListener listener);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
new file mode 100644
index 0000000..8c9683a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryImpl.java
@@ -0,0 +1,277 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class LinkFactoryImpl implements LinkFactory
+{
+    private final Request request;
+
+    private final Response response;
+
+    private final ComponentInvocationMap componentInvocationMap;
+
+    private final RequestPageCache pageCache;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    private final RequestPathOptimizer optimizer;
+
+    private final PageRenderQueue pageRenderQueue;
+
+    private final RequestSecurityManager requestSecurityManager;
+
+    private final List<LinkFactoryListener> listeners = newThreadSafeList();
+
+    private final StrategyRegistry<PassivateContextHandler> registry;
+
+
+    private interface PassivateContextHandler<T>
+    {
+        void handle(T result, List context);
+    }
+
+    public LinkFactoryImpl(Request request,
+                           Response response,
+                           ComponentInvocationMap componentInvocationMap,
+                           RequestPageCache pageCache,
+                           RequestPathOptimizer optimizer,
+                           PageRenderQueue pageRenderQueue,
+                           ContextValueEncoder contextValueEncoder,
+                           RequestSecurityManager requestSecurityManager)
+    {
+        this.request = request;
+        this.response = response;
+        this.componentInvocationMap = componentInvocationMap;
+        this.pageCache = pageCache;
+        this.optimizer = optimizer;
+        this.pageRenderQueue = pageRenderQueue;
+        this.contextValueEncoder = contextValueEncoder;
+        this.requestSecurityManager = requestSecurityManager;
+
+        Map<Class, PassivateContextHandler> registrations = newMap();
+
+        registrations.put(Object.class, new PassivateContextHandler()
+        {
+            @SuppressWarnings("unchecked")
+            public void handle(Object result, List context)
+            {
+                context.add(result);
+            }
+        });
+
+        registrations.put(Object[].class, new PassivateContextHandler<Object[]>()
+        {
+
+            @SuppressWarnings("unchecked")
+            public void handle(Object[] result, List context)
+            {
+                context.addAll(Arrays.asList(result));
+            }
+        });
+
+        registrations.put(Collection.class, new PassivateContextHandler<Collection>()
+        {
+            @SuppressWarnings("unchecked")
+            public void handle(Collection result, List context)
+            {
+                context.addAll(result);
+            }
+        });
+
+        registry = StrategyRegistry.newInstance(PassivateContextHandler.class, registrations);
+    }
+
+    public void addListener(LinkFactoryListener listener)
+    {
+        listeners.add(listener);
+    }
+
+    public Link createActionLink(Page page, String nestedId, String eventType, boolean forForm, Object... context)
+    {
+        notNull(page, "page");
+        notBlank(eventType, "action");
+
+        Page activePage = pageRenderQueue.getRenderingPage();
+
+        // See TAPESTRY-2184
+        if (activePage == null) activePage = page;
+
+        ActionLinkTarget target = new ActionLinkTarget(eventType, activePage.getLogicalName(), nestedId);
+
+        String[] contextStrings = toContextStrings(context);
+
+        String[] activationContext = collectActivationContextForPage(activePage);
+
+        ComponentInvocation invocation = new ComponentInvocationImpl(target, contextStrings, activationContext);
+
+        String baseURL = requestSecurityManager.getBaseURL(activePage);
+
+        Link link = new LinkImpl(response, optimizer, baseURL, request.getContextPath(), invocation, forForm);
+
+        // TAPESTRY-2044: Sometimes the active page drags in components from another page and we
+        // need to differentiate that.
+
+        if (activePage != page)
+            link.addParameter(InternalConstants.CONTAINER_PAGE_NAME, page.getLogicalName().toLowerCase());
+
+        // Now see if the page has an activation context.
+
+        addActivationContextToLink(link, activationContext, forForm);
+
+        componentInvocationMap.store(link, invocation);
+
+        for (LinkFactoryListener listener : listeners)
+            listener.createdActionLink(link);
+
+        return link;
+    }
+
+    private void addActivationContextToLink(Link link, String[] activationContext, boolean forForm)
+    {
+        if (activationContext.length == 0) return;
+
+        StringBuilder builder = new StringBuilder();
+
+        for (int i = 0; i < activationContext.length; i++)
+        {
+            if (i > 0) builder.append("/");
+
+            builder.append(forForm
+                           ? TapestryInternalUtils.escapePercentAndSlash(activationContext[i])
+                           : TapestryInternalUtils.encodeContext(activationContext[i]));
+        }
+
+        link.addParameter(InternalConstants.PAGE_CONTEXT_NAME, builder.toString());
+    }
+
+    public Link createPageLink(Page page, boolean override, Object... activationContext)
+    {
+        notNull(page, "page");
+
+        String logicalPageName = page.getLogicalName();
+
+        // When override is true, we use the activation context even if empty.
+
+        String[] context = (override || activationContext.length != 0) ? toContextStrings(
+                activationContext) : collectActivationContextForPage(page);
+
+        // Strip a trailing "/index" from the path.
+
+        int lastSlashx = logicalPageName.lastIndexOf("/");
+
+        String lastTerm = lastSlashx < 0 ? logicalPageName : logicalPageName.substring(lastSlashx + 1);
+
+        // This, alas, duplicates some logic inside ComponentClassResolverImpl ...
+
+        if (lastTerm.equalsIgnoreCase("index"))
+        {
+            logicalPageName = lastSlashx < 0 ? "" : logicalPageName.substring(0, lastSlashx);
+        }
+
+        PageLinkTarget target = new PageLinkTarget(logicalPageName);
+
+        ComponentInvocation invocation = new ComponentInvocationImpl(target, context, null);
+
+        String baseURL = requestSecurityManager.getBaseURL(page);
+
+        Link link = new LinkImpl(response, optimizer, baseURL, request.getContextPath(), invocation, false);
+
+        componentInvocationMap.store(link, invocation);
+
+        for (LinkFactoryListener listener : listeners)
+            listener.createdPageLink(link);
+
+        return link;
+    }
+
+    /**
+     * Returns a list of objects acquired by invoking triggering the passivate event on the page's root element. May
+     * return an empty list.
+     */
+    private String[] collectActivationContextForPage(final Page page)
+    {
+        final List context = newList();
+
+        ComponentEventCallback callback = new ComponentEventCallback()
+        {
+            @SuppressWarnings("unchecked")
+            public boolean handleResult(Object result)
+            {
+                PassivateContextHandler contextHandler = registry.getByInstance(result);
+
+                contextHandler.handle(result, context);
+
+                return true;
+            }
+        };
+
+        ComponentPageElement rootElement = page.getRootElement();
+
+        rootElement.triggerEvent(EventConstants.PASSIVATE, null, callback);
+
+        return toContextStrings(context.toArray());
+    }
+
+    private String[] toContextStrings(Object[] context)
+    {
+        if (context == null) return new String[0];
+
+        String[] result = new String[context.length];
+
+        for (int i = 0; i < context.length; i++)
+        {
+
+            Object value = context[i];
+
+            String encoded = value == null ? null : contextValueEncoder.toClient(value);
+
+            if (InternalUtils.isBlank(encoded))
+                throw new RuntimeException(ServicesMessages.contextValueMayNotBeNull());
+
+            result[i] = encoded;
+        }
+
+        return result;
+    }
+
+    public Link createPageLink(String logicalPageName, boolean override, Object... context)
+    {
+        // This verifies that the page name is valid.
+        Page page = pageCache.get(logicalPageName);
+
+        return createPageLink(page, override, context);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryListener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryListener.java
new file mode 100644
index 0000000..a93cdeb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkFactoryListener.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+
+/**
+ * Listener interface for objects that need to be notified about newly created links.
+ */
+public interface LinkFactoryListener
+{
+    /**
+     * Invoked when a page link (a link that renders a page) is created. The listener may decide to encode additional
+     * query parameters into the link (via {@link Link#addParameter(String, String)}).
+     *
+     * @param link the newly created link
+     */
+    void createdPageLink(Link link);
+
+    /**
+     * Invoked when an action link (a link that asks a component to perform an action) is created. The listener may
+     * decide to encode additional query parameters into the link (via {@link Link#addParameter(String, String)}).
+     *
+     * @param link the newly created link
+     */
+    void createdActionLink(Link link);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java
new file mode 100644
index 0000000..a935788
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LinkImpl.java
@@ -0,0 +1,145 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Response;
+
+import java.util.List;
+
+/**
+ * Default implementation of {@link org.apache.tapestry.Link}.
+ */
+public class LinkImpl implements Link
+{
+    private static final int BUFFER_SIZE = 100;
+
+    private final String baseURL;
+
+    private final String contextPath;
+
+    private final Response response;
+
+    private final RequestPathOptimizer optimizer;
+
+    private final ComponentInvocation invocation;
+
+    private final boolean forForm;
+
+    private String anchor;
+
+    LinkImpl(Response response, RequestPathOptimizer optimizer, String contextPath, String targetPath)
+    {
+        this(response, optimizer, contextPath, targetPath, false);
+    }
+
+    LinkImpl(Response response, RequestPathOptimizer optimizer, String contextPath, String targetPath, boolean forForm)
+    {
+        this(response, optimizer, null, contextPath,
+             new ComponentInvocationImpl(new OpaqueConstantTarget(targetPath), new String[0], null), forForm);
+    }
+
+    /**
+     * Creates a new Link.  Links may be full or optimized; optimization involves creating a relative URI from the
+     * request's URI to the Link's URI.
+     *
+     * @param response    used to encode the response when necessary
+     * @param optimizer   optimizes complete URLs to appropriate relative URLs
+     * @param baseURL     base URL prefix (before the context path), used when switching between secure and non-secure
+     * @param contextPath path for the context {@link org.apache.tapestry.services.Request#getContextPath()}
+     * @param invocation  abstraction around the type of link (needed by {@link org.apache.tapestry.test.PageTester})
+     * @param forForm     if true, then a Form has requested the Link, in which case, the link should not generated
+     */
+    public LinkImpl(Response response, RequestPathOptimizer optimizer, String baseURL, String contextPath,
+                    ComponentInvocation invocation, boolean forForm)
+    {
+        this.response = response;
+        this.optimizer = optimizer;
+        this.baseURL = baseURL;
+        this.contextPath = contextPath;
+        this.invocation = invocation;
+        this.forForm = forForm;
+    }
+
+    public void addParameter(String parameterName, String value)
+    {
+        invocation.addParameter(parameterName, value);
+    }
+
+    public List<String> getParameterNames()
+    {
+        return invocation.getParameterNames();
+    }
+
+    public String getParameterValue(String name)
+    {
+        return invocation.getParameterValue(name);
+    }
+
+    public String toURI()
+    {
+        return response.encodeURL(buildURI(false));
+    }
+
+    public String toAbsoluteURI()
+    {
+        return response.encodeURL(buildURI(true));
+    }
+
+    private String buildURI(boolean full)
+    {
+        boolean absolute = full | baseURL != null;
+
+        StringBuilder builder = new StringBuilder(BUFFER_SIZE);
+
+        if (baseURL != null) builder.append(baseURL);
+
+        builder.append(contextPath);
+        builder.append("/");
+        builder.append(invocation.buildURI(forForm));
+
+        if (InternalUtils.isNonBlank(anchor))
+        {
+            builder.append("#");
+            builder.append(anchor);
+        }
+
+        String fullURI = builder.toString();
+
+        return absolute ? fullURI : optimizer.optimizePath(fullURI);
+    }
+
+    public String toRedirectURI()
+    {
+        return response.encodeRedirectURL(buildURI(true));
+    }
+
+    public String getAnchor()
+    {
+        return anchor;
+    }
+
+    public void setAnchor(String anchor)
+    {
+        this.anchor = anchor;
+    }
+
+    @Override
+    public String toString()
+    {
+        return toURI();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationFilter.java
new file mode 100644
index 0000000..cde6b84
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationFilter.java
@@ -0,0 +1,45 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.RequestFilter;
+import org.apache.tapestry.services.RequestHandler;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+
+/**
+ * Responsible for determining the locale for the current request. Currently, this is based on the client's web browser.
+ * Later extensions will store the current locale as a cookie, or as a session attribute.
+ */
+public class LocalizationFilter implements RequestFilter
+{
+    private final LocalizationSetter setter;
+
+    public LocalizationFilter(LocalizationSetter setter)
+    {
+        this.setter = setter;
+    }
+
+    public boolean service(Request request, Response response, RequestHandler handler)
+            throws IOException
+    {
+        setter.setThreadLocale(request.getLocale());
+
+        return handler.service(request, response);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetter.java
new file mode 100644
index 0000000..d85edf6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetter.java
@@ -0,0 +1,28 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.util.Locale;
+
+/**
+ * Sets the thread's locale given a desired locale. Note that the desired locale is just a hint. It wil try to honor it
+ * but there is no guarantee that it will be used as is.
+ */
+public interface LocalizationSetter
+{
+
+    void setThreadLocale(Locale desiredLocale);
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetterImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetterImpl.java
new file mode 100644
index 0000000..d29988b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/LocalizationSetterImpl.java
@@ -0,0 +1,126 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.services.PersistentLocale;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Given a set of supported locales, for a specified desired locale, sets the current thread's locale to a supported
+ * locale that is closest to the desired.
+ */
+public class LocalizationSetterImpl implements LocalizationSetter
+{
+    private final ThreadLocale threadLocale;
+
+    private final Locale defaultLocale;
+
+    private final Set<String> acceptedLocaleNames;
+
+    private final Map<String, Locale> localeCache = CollectionFactory.newConcurrentMap();
+
+    private final PersistentLocale persistentLocale;
+
+    public LocalizationSetterImpl(PersistentLocale persistentLocale, ThreadLocale threadLocale,
+                                  @Inject
+                                  @Symbol("tapestry.supported-locales")
+                                  String acceptedLocaleNames)
+    {
+        this.persistentLocale = persistentLocale;
+
+        this.threadLocale = threadLocale;
+
+        String[] names = acceptedLocaleNames.split(",");
+
+        defaultLocale = toLocale(names[0]);
+
+        this.acceptedLocaleNames = CollectionFactory.newSet(names);
+    }
+
+    Locale toLocale(String localeName)
+    {
+        Locale result = localeCache.get(localeName);
+
+        if (result == null)
+        {
+            result = constructLocale(localeName);
+            localeCache.put(localeName, result);
+        }
+
+        return result;
+    }
+
+    private Locale constructLocale(String name)
+    {
+        String[] terms = name.split("_");
+
+        switch (terms.length)
+        {
+            case 1:
+                return new Locale(terms[0], "");
+
+            case 2:
+                return new Locale(terms[0], terms[1]);
+
+            case 3:
+
+                return new Locale(terms[0], terms[1], terms[2]);
+
+            default:
+
+                throw new IllegalArgumentException();
+        }
+    }
+
+    public void setThreadLocale(Locale desiredLocale)
+    {
+        if (persistentLocale.get() != null) desiredLocale = persistentLocale.get();
+
+        Locale locale = findClosestAcceptedLocale(desiredLocale);
+
+        threadLocale.setLocale(locale);
+    }
+
+    private Locale findClosestAcceptedLocale(Locale desiredLocale)
+    {
+        String localeName = desiredLocale.toString();
+
+        while (true)
+        {
+            if (acceptedLocaleNames.contains(localeName)) return toLocale(localeName);
+
+            localeName = stripTerm(localeName);
+
+            if (localeName.length() == 0) break;
+        }
+
+        return defaultLocale;
+    }
+
+    static String stripTerm(String localeName)
+    {
+        int scorex = localeName.lastIndexOf('_');
+
+        return scorex < 0 ? "" : localeName.substring(0, scorex);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MapMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MapMessages.java
new file mode 100644
index 0000000..3b4ee87
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MapMessages.java
@@ -0,0 +1,52 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * An implementation  of {@link Messages} that is based on a map.
+ *
+ */
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.util.AbstractMessages;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Implementation of {@link Messages} based on a simple Map (of string keys and values).
+ */
+public class MapMessages extends AbstractMessages
+{
+    private final Map<String, String> properties;
+
+
+    /**
+     * A new instance <strong>retaining</strong> (not copying) the provided map.
+     */
+    public MapMessages(Locale locale, Map<String, String> properties)
+    {
+        super(locale);
+
+        this.properties = properties;
+    }
+
+
+    @Override
+    protected String valueForKey(String key)
+    {
+        return properties.get(key);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterFactoryImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterFactoryImpl.java
new file mode 100644
index 0000000..b05778c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterFactoryImpl.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.DefaultMarkupModel;
+import org.apache.tapestry.dom.MarkupModel;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.services.MarkupWriterFactory;
+
+public class MarkupWriterFactoryImpl implements MarkupWriterFactory
+{
+    private final MarkupModel htmlModel = new DefaultMarkupModel();
+
+    private final MarkupModel xmlModel = new XMLMarkupModel();
+
+    public MarkupWriter newMarkupWriter(ContentType contentType)
+    {
+        boolean isHTML = contentType.getMimeType().equalsIgnoreCase("text/html");
+
+        MarkupModel model = isHTML ? htmlModel : xmlModel;
+
+        // The charset parameter sets the encoding attribute of the XML declaration, if
+        // not null and if using the XML model.
+
+        return new MarkupWriterImpl(model, contentType.getParameter("charset"));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
new file mode 100644
index 0000000..c8c73a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MarkupWriterImpl.java
@@ -0,0 +1,237 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.MarkupWriterListener;
+import org.apache.tapestry.dom.*;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+public class MarkupWriterImpl implements MarkupWriter
+{
+    private final Document document;
+
+    private Element current;
+
+    private Text currentText;
+
+    private final List<MarkupWriterListener> listeners = CollectionFactory.newList();
+
+    public MarkupWriterImpl()
+    {
+        this(new DefaultMarkupModel());
+    }
+
+    public MarkupWriterImpl(MarkupModel model)
+    {
+        this(model, null);
+    }
+
+    public MarkupWriterImpl(MarkupModel model, String encoding)
+    {
+        document = new Document(model, encoding);
+    }
+
+    public void toMarkup(PrintWriter writer)
+    {
+        document.toMarkup(writer);
+    }
+
+    @Override
+    public String toString()
+    {
+        return document.toString();
+    }
+
+    public Document getDocument()
+    {
+        return document;
+    }
+
+    public Element getElement()
+    {
+        return current;
+    }
+
+    public void cdata(String content)
+    {
+        ensureCurrentElement();
+
+        current.cdata(content);
+
+        currentText = null;
+    }
+
+    public void write(String text)
+    {
+        // Whitespace before and after the root element is quietly ignored.
+        if (current == null && InternalUtils.isBlank(text)) return;
+
+        ensureCurrentElement();
+
+        if (text == null) return;
+
+        if (currentText == null)
+        {
+            currentText = current.text(text);
+            return;
+        }
+
+        currentText.write(text);
+    }
+
+    public void writef(String format, Object... args)
+    {
+        // A bit of a cheat:
+
+        write("");
+        currentText.writef(format, args);
+    }
+
+    public void attributes(Object... namesAndValues)
+    {
+        ensureCurrentElement();
+
+        int i = 0;
+
+        while (i < namesAndValues.length)
+        {
+            // name should never be null.
+
+            String name = namesAndValues[i++].toString();
+            Object value = namesAndValues[i++];
+
+            if (value == null) continue;
+
+            current.attribute(name, value.toString());
+        }
+
+    }
+
+    private void ensureCurrentElement()
+    {
+        if (current == null) throw new IllegalStateException(ServicesMessages.markupWriterNoCurrentElement());
+    }
+
+    public Element element(String name, Object... namesAndValues)
+    {
+        if (current == null) current = document.newRootElement(name);
+        else current = current.element(name);
+
+        attributes(namesAndValues);
+
+        currentText = null;
+
+        fireElementDidStart();
+
+        return current;
+    }
+
+    public void writeRaw(String text)
+    {
+        ensureCurrentElement();
+
+        currentText = null;
+
+        current.raw(text);
+    }
+
+    public Element end()
+    {
+        ensureCurrentElement();
+
+        fireElementDidEnd();
+
+        current = current.getParent();
+
+        currentText = null;
+
+        return current;
+    }
+
+    public void comment(String text)
+    {
+        ensureCurrentElement();
+
+        current.comment(text);
+
+        currentText = null;
+    }
+
+    public Element attributeNS(String namespace, String attributeName, String attributeValue)
+    {
+        ensureCurrentElement();
+
+        current.attribute(namespace, attributeName, attributeValue);
+
+        return current;
+    }
+
+    public Element defineNamespace(String namespace, String namespacePrefix)
+    {
+        ensureCurrentElement();
+
+        current.defineNamespace(namespace, namespacePrefix);
+
+        return current;
+    }
+
+    public Element elementNS(String namespace, String elementName)
+    {
+        if (current == null) current = document.newRootElement(namespace, elementName);
+        else current = current.elementNS(namespace, elementName);
+
+        currentText = null;
+
+
+        fireElementDidStart();
+
+        return current;
+    }
+
+    public void addListener(MarkupWriterListener listener)
+    {
+        Defense.notNull(listener, "listener");
+
+        listeners.add(listener);
+    }
+
+    public void removeListener(MarkupWriterListener listener)
+    {
+        listeners.remove(listener);
+    }
+
+    private void fireElementDidStart()
+    {
+        for (MarkupWriterListener l : listeners)
+        {
+            l.elementDidStart(current);
+        }
+    }
+
+    private void fireElementDidEnd()
+    {
+        for (MarkupWriterListener l : listeners)
+        {
+            l.elementDidEnd(current);
+        }
+    }
+}
+
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesBundle.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesBundle.java
new file mode 100644
index 0000000..37fcc8c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesBundle.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+
+/**
+ * Represents a bundle of properties files that can be used to collect properties that are eventually used to form a
+ * {@link Messages}.
+ */
+public interface MessagesBundle
+{
+
+    /**
+     * Returns an object used to identify this particular bundle; this should be a simple immutable value such as a
+     * String.
+     */
+    Object getId();
+
+    /**
+     * Returns the base resource for this bundle of properties files.
+     */
+    Resource getBaseResource();
+
+    /**
+     * Returns a parent bundle for this bundle, or null if this bundle has no parent. Parent bundle provide properties
+     * that are overridden by child bundles.
+     */
+    MessagesBundle getParent();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSource.java
new file mode 100644
index 0000000..b6e8f9d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSource.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.ioc.Messages;
+
+import java.util.Locale;
+
+public interface MessagesSource extends InvalidationEventHub, UpdateListener
+{
+    /**
+     * Used to obtain a {@link Messages} instance for a particular component, within a particular locale. If the
+     * component extends from another component, then its localized properties will merge with its parent's properties
+     * (with the subclass overriding the super class on any conflicts).
+     *
+     * @param bundle defines the set of properties files to read, as well as a series of parent bundles to extend and
+     *               override
+     * @param locale
+     * @return the message catalog for the bundle, in the indicated locale
+     */
+    Messages getMessages(MessagesBundle bundle, Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSourceImpl.java
new file mode 100644
index 0000000..a7f29c9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MessagesSourceImpl.java
@@ -0,0 +1,229 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.util.MultiKey;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.LocalizedNameGenerator;
+
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * A utility class that encapsulates all the logic for reading properties files and assembling {@link Messages} from
+ * them, in accordance with extension rules and locale. This represents code that was refactored out of {@link
+ * ComponentMessagesSourceImpl}. This class can be used as a base class, though the existing code base uses it as a
+ * utility. Composition trumps inheritance!
+ */
+public class MessagesSourceImpl extends InvalidationEventHubImpl implements MessagesSource
+{
+    private final URLChangeTracker tracker;
+
+    /**
+     * Keyed on bundle id and locale.
+     */
+    private final Map<MultiKey, Messages> messagesByBundleIdAndLocale = CollectionFactory.newConcurrentMap();
+
+    /**
+     * Keyed on bundle id and locale, the coooked properties include properties inherited from less locale-specific
+     * properties files, or inherited from parent bundles.
+     */
+    private final Map<MultiKey, Map<String, String>> cookedProperties = CollectionFactory.newConcurrentMap();
+
+    /**
+     * Raw properties represent just the properties read from a specific properties file, in isolation.
+     */
+    private final Map<Resource, Map<String, String>> rawProperties = CollectionFactory.newConcurrentMap();
+
+    private final Map<String, String> emptyMap = Collections.emptyMap();
+
+    public MessagesSourceImpl(URLChangeTracker tracker)
+    {
+        this.tracker = tracker;
+    }
+
+    public void checkForUpdates()
+    {
+        if (tracker.containsChanges())
+        {
+            messagesByBundleIdAndLocale.clear();
+            cookedProperties.clear();
+            rawProperties.clear();
+
+            tracker.clear();
+
+            fireInvalidationEvent();
+        }
+    }
+
+    public Messages getMessages(MessagesBundle bundle, Locale locale)
+    {
+        MultiKey key = new MultiKey(bundle.getId(), locale);
+
+        Messages result = messagesByBundleIdAndLocale.get(key);
+
+        if (result == null)
+        {
+            result = buildMessages(bundle, locale);
+            messagesByBundleIdAndLocale.put(key, result);
+        }
+
+        return result;
+    }
+
+    private Messages buildMessages(MessagesBundle bundle, Locale locale)
+    {
+        Map<String, String> properties = findBundleProperties(bundle, locale);
+
+        return new MapMessages(locale, properties);
+    }
+
+    /**
+     * Assembles a set of properties appropriate for the bundle in question, and the desired locale. The properties
+     * reflect the properties of the bundles' parent (if any) for the locale, overalyed with any properties defined for
+     * this bundle and its locale.
+     */
+    private Map<String, String> findBundleProperties(MessagesBundle bundle, Locale locale)
+    {
+        if (bundle == null) return emptyMap;
+
+        MultiKey key = new MultiKey(bundle.getId(), locale);
+
+        Map<String, String> existing = cookedProperties.get(key);
+
+        if (existing != null) return existing;
+
+        // What would be cool is if we could maintain a cache of bundle id + locale -->
+        // Resource. That would optimize quite a bit of this; may need to use an alternative to
+        // LocalizedNameGenerator.
+
+        Resource propertiesResource = bundle.getBaseResource().withExtension("properties");
+
+        List<Resource> localizations = CollectionFactory.newList();
+
+        for (String localizedFile : new LocalizedNameGenerator(propertiesResource.getFile(), locale))
+        {
+            Resource localized = propertiesResource.forFile(localizedFile);
+
+            localizations.add(localized);
+        }
+
+        // We need them in least-specific to most-specific order, the opposite
+        // of how the LocalizedNameGenerator provides them.
+
+        Collections.reverse(localizations);
+
+        // Localizations are now in least-specific to most-specific order.
+
+        Map<String, String> previous = findBundleProperties(bundle.getParent(), locale);
+
+        for (Resource localization : localizations)
+        {
+            Map<String, String> rawProperties = getRawProperties(localization);
+
+            // Woould be nice to write into the cookedProperties cache here,
+            // but we can't because we don't know the locale part of the MultiKey.
+
+            previous = extend(previous, rawProperties);
+        }
+
+        cookedProperties.put(key, previous);
+
+        return previous;
+    }
+
+    /**
+     * Returns a new map consisting of all the properties in previous overlayed with all the properties in
+     * rawProperties. If rawProperties is empty, returns just the base map.
+     */
+    private Map<String, String> extend(Map<String, String> base, Map<String, String> rawProperties)
+    {
+        if (rawProperties.isEmpty()) return base;
+
+        // Make a copy of the base Map
+
+        Map<String, String> result = CollectionFactory.newCaseInsensitiveMap(base);
+
+        // Add or overwrite properties to the copy
+
+        result.putAll(rawProperties);
+
+        return result;
+    }
+
+    private Map<String, String> getRawProperties(Resource localization)
+    {
+        Map<String, String> result = rawProperties.get(localization);
+
+        if (result == null)
+        {
+            result = readProperties(localization);
+
+            rawProperties.put(localization, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * Creates and returns a new map that contains properties read from the properties file.
+     */
+    private Map<String, String> readProperties(Resource resource)
+    {
+        if (!resource.exists()) return emptyMap;
+
+        tracker.add(resource.toURL());
+
+        Map<String, String> result = CollectionFactory.newCaseInsensitiveMap();
+
+        Properties p = new Properties();
+        InputStream is = null;
+
+        try
+        {
+            is = resource.openStream();
+
+            p.load(is);
+
+            is.close();
+
+            is = null;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServicesMessages.failureReadingMessages(resource, ex), ex);
+        }
+        finally
+        {
+            InternalUtils.close(is);
+        }
+
+        for (Map.Entry e : p.entrySet())
+        {
+            String key = e.getKey().toString();
+
+            String value = p.getProperty(key);
+
+            result.put(key, value);
+        }
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java
new file mode 100644
index 0000000..b219a92
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MetaDataLocatorImpl.java
@@ -0,0 +1,150 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.MetaDataLocator;
+
+import java.util.Map;
+
+public class MetaDataLocatorImpl implements MetaDataLocator, InvalidationListener
+{
+    private final SymbolSource symbolSource;
+
+    private final TypeCoercer typeCoercer;
+
+    private final Map<String, Map<String, String>> defaultsByFolder = CollectionFactory.newCaseInsensitiveMap();
+
+    private final Map<String, String> cache = CollectionFactory.newConcurrentMap();
+
+    public MetaDataLocatorImpl(SymbolSource symbolSource, TypeCoercer typeCoercer, Map<String, String> configuration)
+    {
+        this.symbolSource = symbolSource;
+        this.typeCoercer = typeCoercer;
+
+        loadDefaults(configuration);
+    }
+
+    public void objectWasInvalidated()
+    {
+        cache.clear();
+    }
+
+    private void loadDefaults(Map<String, String> configuration)
+    {
+        for (Map.Entry<String, String> e : configuration.entrySet())
+        {
+            String key = e.getKey();
+
+            int colonx = key.indexOf(':');
+
+            String folderKey = colonx < 0 ? "" : key.substring(0, colonx);
+
+            Map<String, String> forFolder = defaultsByFolder.get(folderKey);
+
+            if (forFolder == null)
+            {
+                forFolder = CollectionFactory.newCaseInsensitiveMap();
+                defaultsByFolder.put(folderKey, forFolder);
+            }
+
+            String defaultKey = colonx < 0 ? key : key.substring(colonx + 1);
+
+            forFolder.put(defaultKey, e.getValue());
+        }
+    }
+
+    public <T> T findMeta(String key, ComponentResources resources, Class<T> expectedType)
+    {
+        String value = getSymbolExpandedValueFromCache(key, resources);
+
+        return typeCoercer.coerce(value, expectedType);
+    }
+
+    private String getSymbolExpandedValueFromCache(String key, ComponentResources resources)
+    {
+        String cacheKey = resources.getCompleteId() + "/" + key;
+
+        if (cache.containsKey(cacheKey)) return cache.get(cacheKey);
+
+        String value = locate(key, resources);
+
+        if (value == null)
+        {
+            value = symbolSource.valueForSymbol(key);
+        }
+        else
+        {
+            value = symbolSource.expandSymbols(value);
+
+        }
+
+        cache.put(cacheKey, value);
+
+        return value;
+    }
+
+    private String locate(String key, ComponentResources resources)
+    {
+        ComponentResources cursor = resources;
+
+        while (true)
+        {
+            String value = cursor.getComponentModel().getMeta(key);
+
+            if (value != null) return value;
+
+            ComponentResources next = cursor.getContainerResources();
+
+            if (next == null) return locateInDefaults(key, cursor);
+
+            cursor = next;
+        }
+    }
+
+    private String locateInDefaults(String key, ComponentResources pageResources)
+    {
+
+        // We're going to peel this apart, slash by slash. Thus for
+        // "mylib/myfolder/mysubfolder/MyPage" we'll be checking: "mylib/myfolder/mysubfolder",
+        // then "mylib/myfolder", then "mylib", then "".
+
+        String path = pageResources.getPageName();
+
+        while (true)
+        {
+            int lastSlashx = path.lastIndexOf('/');
+
+            String folderKey = lastSlashx < 0 ? "" : path.substring(0, lastSlashx);
+
+            Map<String, String> forFolder = defaultsByFolder.get(folderKey);
+
+            if (forFolder != null && forFolder.containsKey(key)) return forFolder.get(key);
+
+            if (lastSlashx < 0) break;
+
+            path = path.substring(0, lastSlashx);
+        }
+
+        // Perhaps from here into the symbol sources? That may come later.
+
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodCompileException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodCompileException.java
new file mode 100644
index 0000000..41736c9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodCompileException.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+/**

+ * Exception thrown when a method body fails to compile; this will allow the method body to be displayed to the user on

+ * the request failure page.

+ */

+public class MethodCompileException extends RuntimeException

+{

+    private static final long serialVersionUID = -2803586049370974986L;

+

+    private final String methodBody;

+

+    public MethodCompileException(String message, String methodBody, Throwable cause)

+    {

+        super(message, cause);

+

+        this.methodBody = methodBody;

+    }

+

+    public String getMethodBody()

+    {

+        return methodBody;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodInvocationInfo.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodInvocationInfo.java
new file mode 100644
index 0000000..cd99bb6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/MethodInvocationInfo.java
@@ -0,0 +1,114 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.services.ComponentMethodAdvice;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.util.List;
+
+/**
+ * A companion to {@link org.apache.tapestry.internal.services.AbstractComponentMethodInvocation} that stores most of
+ * the method and advice information needed.
+ */
+public class MethodInvocationInfo
+{
+    private final TransformMethodSignature methodSignature;
+
+    private final ComponentClassCache componentClassCache;
+
+    private final List<ComponentMethodAdvice> advice = CollectionFactory.newList();
+
+    private Class effectiveResultType;
+
+    public MethodInvocationInfo(TransformMethodSignature methodSignature, ComponentClassCache componentClassCache)
+    {
+        this.methodSignature = methodSignature;
+        this.componentClassCache = componentClassCache;
+    }
+
+    public String getMethodName()
+    {
+        return methodSignature.getMethodName();
+    }
+
+    public Class getResultType()
+    {
+        return componentClassCache.forName(methodSignature.getReturnType());
+    }
+
+    public synchronized Class getEffectiveResultType()
+    {
+        if (effectiveResultType == null)
+        {
+            Class resultType = getResultType();
+
+            effectiveResultType = resultType.isPrimitive() ? ClassFabUtils.getWrapperType(resultType) : resultType;
+        }
+
+        return effectiveResultType;
+    }
+
+    public int getParameterCount()
+    {
+        return methodSignature.getParameterTypes().length;
+    }
+
+    public Class getParameterType(int index)
+    {
+        return componentClassCache.forName(methodSignature.getParameterTypes()[index]);
+    }
+
+    public int getAdviceCount()
+    {
+        return advice.size();
+    }
+
+    public ComponentMethodAdvice getAdvice(int index)
+    {
+        return advice.get(index);
+    }
+
+    public void addAdvice(ComponentMethodAdvice advice)
+    {
+        // Ultimately, the mutable portion of this object's lifecycle all occurs inside a synchronized block defined by
+        // the class loader.  After that the advice list is only accessed for reads.  I don't think there
+        // are any concurrency issues with this approach.
+
+        this.advice.add(advice);
+    }
+
+    public Class[] getExceptionTypes()
+    {
+        String[] exceptionTypes = methodSignature.getExceptionTypes();
+        int count = exceptionTypes.length;
+
+        Class[] result = new Class[count];
+
+        for (int i = 0; i < count; i++)
+        {
+            result[i] = componentClassCache.forName(exceptionTypes[i]);
+        }
+
+        return result;
+    }
+
+    public Class getExceptionType(int index)
+    {
+        return componentClassCache.forName(methodSignature.getExceptionTypes()[index]);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NoOpComponentInvocationMap.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NoOpComponentInvocationMap.java
new file mode 100644
index 0000000..c439ff3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NoOpComponentInvocationMap.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.dom.Element;
+
+/**
+ * The production implementation for {@link org.apache.tapestry.internal.services.ComponentInvocationMap}. It does
+ * absolutely nothing because it is not needed in production.
+ */
+public class NoOpComponentInvocationMap implements ComponentInvocationMap
+{
+    public void store(Element element, Link link)
+    {
+    }
+
+    public void store(Link link, ComponentInvocation invocations)
+    {
+    }
+
+    public ComponentInvocation get(Link link)
+    {
+        return null;
+    }
+
+    public void clear()
+    {
+    }
+
+    public ComponentInvocation get(Element element)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImpl.java
new file mode 100644
index 0000000..14888b9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImpl.java
@@ -0,0 +1,40 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.NullFieldStrategy;
+import org.apache.tapestry.services.NullFieldStrategySource;
+
+import java.util.Map;
+
+public class NullFieldStrategySourceImpl implements NullFieldStrategySource
+{
+    private final Map<String, NullFieldStrategy> configuration;
+
+    public NullFieldStrategySourceImpl(Map<String, NullFieldStrategy> configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public NullFieldStrategy get(String name)
+    {
+        NullFieldStrategy result = configuration.get(name);
+
+        if (result != null) return result;
+
+        throw new IllegalArgumentException(
+                ServicesMessages.unknownNullFieldStrategyName(name, configuration.keySet()));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java
new file mode 100644
index 0000000..5368486
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessor.java
@@ -0,0 +1,42 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * A catch-all for type Object that reports the return value as an error.
+ */
+public class ObjectComponentEventResultProcessor implements ComponentEventResultProcessor<Object>
+{
+    private final Collection<Class> configuredClasses;
+
+    public ObjectComponentEventResultProcessor(Collection<Class> configuredClasses)
+    {
+        this.configuredClasses = configuredClasses;
+    }
+
+    public void processResultValue(Object value) throws IOException
+    {
+        String message = ServicesMessages.invalidComponentEventResult(value,
+                                                                      configuredClasses);
+
+        throw new RuntimeException(message);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/OpaqueConstantTarget.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/OpaqueConstantTarget.java
new file mode 100644
index 0000000..6faf45a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/OpaqueConstantTarget.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * An invocation target that is specified as a path without further meaning.
+ */
+public class OpaqueConstantTarget implements InvocationTarget
+{
+    private final String path;
+
+    public OpaqueConstantTarget(String path)
+    {
+        this.path = path;
+    }
+
+    public String getPath()
+    {
+        return path;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzer.java
new file mode 100644
index 0000000..1b9c044
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzer.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.internal.structure.Page;
+
+public interface PageContentTypeAnalyzer
+{
+    /**
+     * Analyzes the meta-data for the page and identifies the correct {@link org.apache.tapestry.ContentType} (including
+     * encoding).
+     *
+     * @param page to be rendered
+     * @return the content type
+     */
+    ContentType findContentType(Page page);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzerImpl.java
new file mode 100644
index 0000000..9a50771
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageContentTypeAnalyzerImpl.java
@@ -0,0 +1,54 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.MetaDataLocator;
+
+public class PageContentTypeAnalyzerImpl implements PageContentTypeAnalyzer
+{
+    private final MetaDataLocator metaDataLocator;
+
+    public PageContentTypeAnalyzerImpl(MetaDataLocator metaDataLocator)
+    {
+        this.metaDataLocator = metaDataLocator;
+    }
+
+    public ContentType findContentType(Page page)
+    {
+        ComponentResources pageResources = page.getRootComponent().getComponentResources();
+
+        String contentTypeString = metaDataLocator.findMeta(MetaDataConstants.RESPONSE_CONTENT_TYPE, pageResources,
+                                                            String.class);
+        ContentType contentType = new ContentType(contentTypeString);
+
+        // Make sure thre's always a charset specified.
+
+        String encoding = contentType.getParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER);
+
+        if (encoding == null)
+        {
+            encoding = metaDataLocator
+                    .findMeta(MetaDataConstants.RESPONSE_ENCODING, pageResources, String.class);
+            contentType.setParameter(InternalConstants.CHARSET_CONTENT_TYPE_PARAMETER, encoding);
+        }
+
+        return contentType;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java
new file mode 100644
index 0000000..fd99891
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactory.java
@@ -0,0 +1,98 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.internal.parser.ExpansionToken;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.services.BindingSource;
+
+import java.util.Locale;
+
+/**
+ * Used by the {@link org.apache.tapestry.internal.services.PageLoader} to create page elements
+ */
+public interface PageElementFactory
+{
+    PageElement newAttributeElement(ComponentResources componentResources, AttributeToken token);
+
+    PageElement newExpansionElement(ComponentResources componentResources, ExpansionToken token);
+
+    /**
+     * Creates a new binding as with {@link BindingSource#newBinding(String, ComponentResources, ComponentResources,
+     * String, String, Location)}. However, if the binding contains an expansion (i.e., <code>${...}</code>), then a
+     * binding that returns the fully expanded expression will be returned.
+     */
+    Binding newBinding(String parameterName, ComponentResources loadingComponentResources,
+                       ComponentResources embeddedComponentResources, String defaultBindingPrefix, String expression,
+                       Location location);
+
+    /**
+     * Creates a new component and adds it to the page and to its container.
+     * <p/>
+     * Note: doesn't add the component as a child of the container.
+     *
+     * @param page               the page that will ultimately contain the new component
+     * @param container          the existing component that contains the new component
+     * @param id                 the id, unique within the container, of the new component
+     * @param componentType      the type of the component (as defined in the template or the {@link Component}
+     *                           annotation)
+     * @param componentClassName the fully qualfied class name used when the componentType is blank (null or the empty
+     *                           string)
+     * @param elementName        name of element in template
+     * @param location           location of the component's element within its container's template
+     * @return the newly created component page element, after adding it to the page and container
+     */
+    ComponentPageElement newComponentElement(Page page, ComponentPageElement container, String id, String componentType,
+                                             String componentClassName, String elementName, Location location);
+
+    /**
+     * Creates a new root component for a page. Adds any mixins defined by the components model.
+     *
+     * @param page      the page that will contain the root component
+     * @param className the fully qualified class name of the root component
+     * @param locale    the locale for the page
+     * @return the root page element
+     */
+    ComponentPageElement newRootComponentElement(Page page, String className, Locale locale);
+
+    /**
+     * Adds a mixin to the element, resolving the mixin type to a mixin class.
+     * <p/>
+     * Sure, this isn't quite a <em>factory</em> method, but PEF has all the tools to accomplish this handy, as opposed
+     * to PageLoaderImpl.
+     *
+     * @param component the component to which a mixin will be added
+     * @param mixinType used to resolve the mixin class name
+     */
+    void addMixinByTypeName(ComponentPageElement component, String mixinType);
+
+    /**
+     * Adds a mixin to the element.
+     * <p/>
+     * Sure, this isn't quite a <em>factory</em> method, but PEF has all the tools to accomplish this handy, as opposed
+     * to PageLoaderImpl.
+     *
+     * @param component      the component to which a mixin will be added
+     * @param mixinClassName fully qualified class name of the mixin
+     */
+    void addMixinByClassName(ComponentPageElement component, String mixinClassName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java
new file mode 100644
index 0000000..06e20c7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java
@@ -0,0 +1,307 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.internal.parser.ExpansionToken;
+import org.apache.tapestry.internal.structure.*;
+import org.apache.tapestry.ioc.Location;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.ComponentClassResolver;
+
+import java.util.List;
+import java.util.Locale;
+
+public class PageElementFactoryImpl implements PageElementFactory
+{
+    private final ComponentInstantiatorSource componentInstantiatorSource;
+
+    private final ComponentClassResolver componentClassResolver;
+
+    private final TypeCoercer typeCoercer;
+
+    private final BindingSource bindingSource;
+
+    private final PageResourcesSource pageResourcesSource;
+
+    private static final String EXPANSION_START = "${";
+
+    private static class LiteralStringProvider implements StringProvider
+    {
+        private final String string;
+
+        LiteralStringProvider(String string)
+        {
+            this.string = string;
+        }
+
+        public String provideString()
+        {
+            return string;
+        }
+    }
+
+    public PageElementFactoryImpl(ComponentInstantiatorSource componentInstantiatorSource,
+                                  ComponentClassResolver resolver, TypeCoercer typeCoercer, BindingSource bindingSource,
+                                  PageResourcesSource pageResourcesSource)
+    {
+        this.componentInstantiatorSource = componentInstantiatorSource;
+        componentClassResolver = resolver;
+        this.typeCoercer = typeCoercer;
+        this.bindingSource = bindingSource;
+        this.pageResourcesSource = pageResourcesSource;
+    }
+
+    public PageElement newAttributeElement(ComponentResources componentResources, AttributeToken token)
+    {
+        final StringProvider provider = parseAttributeExpansionExpression(token.getValue(), componentResources,
+                                                                          token.getLocation());
+
+        final String namespace = token.getNamespaceURI();
+        final String name = token.getName();
+
+        return new PageElement()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                writer.attributeNS(namespace, name, provider.provideString());
+            }
+        };
+    }
+
+    private StringProvider parseAttributeExpansionExpression(String expression, ComponentResources resources,
+                                                             final Location location)
+    {
+        final List<StringProvider> providers = newList();
+
+        int startx = 0;
+
+        while (true)
+        {
+            int expansionx = expression.indexOf(EXPANSION_START, startx);
+
+            // No more expansions, add in the rest of the string as a literal.
+
+            if (expansionx < 0)
+            {
+                if (startx < expression.length())
+                    providers.add(new LiteralStringProvider(expression.substring(startx)));
+                break;
+            }
+
+            // Add in a literal string chunk for the characters between the last expansion and
+            // this expansion.
+
+            if (startx != expansionx)
+                providers.add(new LiteralStringProvider(expression.substring(startx, expansionx)));
+
+            int endx = expression.indexOf("}", expansionx);
+
+            if (endx < 0) throw new TapestryException(ServicesMessages
+                    .unclosedAttributeExpression(expression), location, null);
+
+            String expansion = expression.substring(expansionx + 2, endx);
+
+            final Binding binding = bindingSource.newBinding("attribute expansion", resources, resources,
+                                                             BindingConstants.PROP, expansion, location);
+
+            final StringProvider provider = new StringProvider()
+            {
+                public String provideString()
+                {
+                    try
+                    {
+                        Object raw = binding.get();
+
+                        return typeCoercer.coerce(raw, String.class);
+                    }
+                    catch (Exception ex)
+                    {
+                        throw new TapestryException(ex.getMessage(), location, ex);
+                    }
+                }
+            };
+
+            providers.add(provider);
+
+            // Restart the search after '}'
+
+            startx = endx + 1;
+        }
+
+        // Simplify the typical case, where the entire attribute is just a single expansion:
+
+        if (providers.size() == 1) return providers.get(0);
+
+        return new StringProvider()
+        {
+
+            public String provideString()
+            {
+                StringBuilder builder = new StringBuilder();
+
+                for (StringProvider provider : providers)
+                    builder.append(provider.provideString());
+
+                return builder.toString();
+            }
+        };
+
+    }
+
+    public PageElement newExpansionElement(ComponentResources componentResources, ExpansionToken token)
+    {
+        Binding binding = bindingSource.newBinding("expansion", componentResources, componentResources,
+                                                   BindingConstants.PROP, token.getExpression(), token.getLocation());
+
+        return new ExpansionPageElement(binding, typeCoercer);
+    }
+
+    public ComponentPageElement newComponentElement(Page page, ComponentPageElement container, String id,
+                                                    String componentType, String componentClassName, String elementName,
+                                                    Location location)
+    {
+        try
+        {
+            String finalClassName = componentClassName;
+
+            // This awkwardness is making me think that the page loader should resolve the component
+            // type before invoking this method (we would then remove the componentType parameter).
+
+            if (InternalUtils.isNonBlank(componentType))
+            {
+                // The type actually overrides the specified class name. The class name is defined
+                // by the type of the field. In many scenarios, the field type is a common
+                // interface,
+                // and the type is used to determine the concrete class to instantiate.
+
+                try
+                {
+                    finalClassName = componentClassResolver
+                            .resolveComponentTypeToClassName(componentType);
+                }
+                catch (IllegalArgumentException ex)
+                {
+                    throw new TapestryException(ex.getMessage(), location, ex);
+                }
+            }
+
+            Instantiator instantiator = componentInstantiatorSource
+                    .findInstantiator(finalClassName);
+
+            // This is actually a good place to check for recursive templates, here where we've
+            // resolved
+            // the component type to a fully qualified class name.
+
+            checkForRecursion(finalClassName, container, location);
+
+            // The container for any components is the loading component, regardless of
+            // how the component elements are nested within the loading component's
+            // template.
+
+            ComponentPageElement result = container.newChild(id, elementName, instantiator, location);
+
+            page.addLifecycleListener(result);
+
+            addMixins(result, instantiator);
+
+            return result;
+        }
+        catch (RuntimeException ex)
+        {
+            throw new TapestryException(ex.getMessage(), location, ex);
+        }
+    }
+
+    private void checkForRecursion(String componentClassName, ComponentPageElement container, Location location)
+    {
+        // Container may be null for a root element;
+
+        if (container == null) return;
+
+        ComponentResources resources = container.getComponentResources();
+
+        while (resources != null)
+        {
+            if (resources.getComponentModel().getComponentClassName().equals(componentClassName))
+                throw new TapestryException(ServicesMessages.componentRecursion(componentClassName), location, null);
+
+            resources = resources.getContainerResources();
+        }
+    }
+
+    public ComponentPageElement newRootComponentElement(Page page, String componentType, Locale locale)
+    {
+        Instantiator instantiator = componentInstantiatorSource.findInstantiator(componentType);
+
+        PageResources pageResources = pageResourcesSource.get(locale);
+
+        ComponentPageElement result = new ComponentPageElementImpl(page, instantiator, pageResources);
+
+        page.addLifecycleListener(result);
+
+        addMixins(result, instantiator);
+
+        return result;
+    }
+
+    private void addMixins(ComponentPageElement component, Instantiator instantiator)
+    {
+        ComponentModel model = instantiator.getModel();
+        for (String mixinClassName : model.getMixinClassNames())
+            addMixinByClassName(component, mixinClassName);
+    }
+
+    public void addMixinByTypeName(ComponentPageElement component, String mixinType)
+    {
+        String mixinClassName = componentClassResolver.resolveMixinTypeToClassName(mixinType);
+
+        addMixinByClassName(component, mixinClassName);
+    }
+
+    public void addMixinByClassName(ComponentPageElement component, String mixinClassName)
+    {
+        Instantiator mixinInstantiator = componentInstantiatorSource.findInstantiator(mixinClassName);
+
+        component.addMixin(mixinInstantiator);
+    }
+
+    public Binding newBinding(String parameterName, ComponentResources loadingComponentResources,
+                              ComponentResources embeddedComponentResources, String defaultBindingPrefix,
+                              String expression, Location location)
+    {
+
+        if (expression.contains(EXPANSION_START))
+        {
+            StringProvider provider = parseAttributeExpansionExpression(expression, loadingComponentResources,
+                                                                        location);
+
+            return new AttributeExpansionBinding(provider, location);
+        }
+
+        return bindingSource.newBinding(parameterName, loadingComponentResources,
+                                        embeddedComponentResources, defaultBindingPrefix, expression, location);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLinkTarget.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLinkTarget.java
new file mode 100644
index 0000000..5325e4d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLinkTarget.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * It represents a component invocation target for a page link. It is passed to an {@link
+ * org.apache.tapestry.services.ComponentEventRequestHandler} by both the {@link org.apache.tapestry.test.PageTester}
+ * and the real Tapestry code {@link org.apache.tapestry.internal.services.PageRenderDispatcher} in order to invoke a
+ * page link.
+ */
+public class PageLinkTarget implements InvocationTarget
+{
+    private final String pageName;
+
+    public PageLinkTarget(String pageName)
+    {
+        this.pageName = pageName;
+
+    }
+
+    public String getPath()
+    {
+        return pageName.toLowerCase();
+    }
+
+    public String getPageName()
+    {
+        return pageName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoader.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoader.java
new file mode 100644
index 0000000..cddb3d1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoader.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResourcesCommon;
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.internal.structure.Page;
+
+import java.util.Locale;
+
+/**
+ * Instantiates a fully loaded, configured instance of a Tapestry page. This is a recursive process, since part of
+ * loading a page is to load the page elements for the page, many of which are components. Further, in some cases, the
+ * full component tree is not identified until after each component's template is loaded. Because this is an expensive
+ * process, loaded pages will be used for many requests (on behalf of many different users) and will be pooled between
+ * requests.
+ *
+ * @see PagePool
+ * @see RequestPageCache
+ */
+public interface PageLoader extends InvalidationEventHub
+{
+    /**
+     * Loads the page in the given locale.
+     *
+     * @param logicalPageName the <em>canonicalized</em> logical name of the page, which will be made available via
+     *                        {@link Page#getLogicalName()} and {@link ComponentResourcesCommon#getPageName()} (for any
+     *                        component within the page).
+     * @param locale          the locale to load the page and its components , which will be made available via {@link
+     *                        Page#getLocale()} and {@link ComponentResourcesCommon#getLocale()} (for any component
+     *                        within the page)
+     * @see Page#getLocale()
+     */
+    Page loadPage(String logicalPageName, Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java
new file mode 100644
index 0000000..71ffee2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderImpl.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ComponentClassResolver;
+
+import java.util.Locale;
+
+public class PageLoaderImpl extends InvalidationEventHubImpl implements PageLoader,
+        InvalidationListener
+{
+    private final ComponentTemplateSource templateSource;
+
+    private final PageElementFactory pageElementFactory;
+
+    private final LinkFactory linkFactory;
+
+    private final PersistentFieldManager persistentFieldManager;
+
+    private final ComponentClassResolver resolver;
+
+    public PageLoaderImpl(ComponentTemplateSource templateSource,
+                          PageElementFactory pageElementFactory, LinkFactory linkFactory,
+                          PersistentFieldManager persistentFieldManager, ComponentClassResolver resolver)
+    {
+        this.templateSource = templateSource;
+        this.pageElementFactory = pageElementFactory;
+        this.linkFactory = linkFactory;
+        this.persistentFieldManager = persistentFieldManager;
+        this.resolver = resolver;
+    }
+
+    public Page loadPage(String logicalPageName, Locale locale)
+    {
+        // For the moment, the processors are used once and discarded. Perhaps it is worth the
+        // effort to pool them for reuse, but not too likely.
+
+        PageLoaderProcessor processor = new PageLoaderProcessor(templateSource,
+                                                                pageElementFactory, linkFactory,
+                                                                persistentFieldManager);
+
+        String pageClassName = resolver.resolvePageNameToClassName(logicalPageName);
+
+        return processor.loadPage(logicalPageName, pageClassName, locale);
+    }
+
+    /**
+     * When the page loader receives an invalidation event, it respawns the event for its listeners. Those listeners
+     * will include page caches and the like.
+     */
+    public void objectWasInvalidated()
+    {
+        fireInvalidationEvent();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
new file mode 100644
index 0000000..c926e4a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
@@ -0,0 +1,811 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.bindings.LiteralBinding;
+import org.apache.tapestry.internal.parser.*;
+import org.apache.tapestry.internal.structure.*;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import static org.apache.tapestry.ioc.internal.util.InternalUtils.isBlank;
+import static org.apache.tapestry.ioc.internal.util.InternalUtils.isNonBlank;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.util.Stack;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.EmbeddedComponentModel;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.BindingSource;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Contains all the work-state related to the {@link PageLoaderImpl}.
+ * <p/>
+ * <em>This is the Tapestry heart, this is the Tapestry soul ...</em>
+ */
+class PageLoaderProcessor
+{
+    /**
+     * Special prefix for parameters that are inherited from named parameters of their container.
+     */
+    private static final String INHERIT_PREFIX = "inherit:";
+
+    private static final Runnable NO_OP = new Runnable()
+    {
+        public void run()
+        {
+            // Do nothing.
+        }
+    };
+
+
+    private static final Pattern COMMA_PATTERN = Pattern.compile(",");
+
+    private Stack<ComponentPageElement> activeElementStack = CollectionFactory.newStack();
+
+    private boolean addAttributesAsComponentBindings = false;
+
+    private boolean dtdAdded;
+
+    private final Stack<BodyPageElement> bodyPageElementStack = CollectionFactory.newStack();
+
+    // You can use a stack as a queue
+    private final Stack<ComponentPageElement> componentQueue = CollectionFactory.newStack();
+
+    private final Stack<Boolean> discardEndTagStack = CollectionFactory.newStack();
+
+    private final Stack<Runnable> endElementCommandStack = CollectionFactory.newStack();
+
+    /**
+     * Used as a queue of Runnable objects used to handle final setup.
+     */
+
+    private final List<Runnable> finalization = CollectionFactory.newList();
+
+    private final IdAllocator idAllocator = new IdAllocator();
+
+    private final LinkFactory linkFactory;
+
+    private ComponentModel loadingComponentModel;
+
+    private ComponentPageElement loadingElement;
+
+    private final Map<String, Map<String, Binding>> componentIdToBindingMap = CollectionFactory.newMap();
+
+    private Locale locale;
+
+    private final OneShotLock lock = new OneShotLock();
+
+    private Page page;
+
+    private final PageElementFactory pageElementFactory;
+
+    private final PersistentFieldManager persistentFieldManager;
+
+    private final ComponentTemplateSource templateSource;
+
+    private static final PageElement END_ELEMENT = new PageElement()
+    {
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            writer.end();
+        }
+
+        @Override
+        public String toString()
+        {
+            return "End";
+        }
+    };
+
+    private static class RenderBodyElement implements PageElement
+    {
+        private final ComponentPageElement component;
+
+        public RenderBodyElement(ComponentPageElement component)
+        {
+            this.component = component;
+        }
+
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            component.enqueueBeforeRenderBody(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return String.format("RenderBody[%s]", component.getNestedId());
+        }
+    }
+
+    PageLoaderProcessor(ComponentTemplateSource templateSource, PageElementFactory pageElementFactory,
+                        LinkFactory linkFactory, PersistentFieldManager persistentFieldManager)
+    {
+        this.templateSource = templateSource;
+        this.pageElementFactory = pageElementFactory;
+        this.linkFactory = linkFactory;
+        this.persistentFieldManager = persistentFieldManager;
+    }
+
+    private void bindParameterFromTemplate(ComponentPageElement component, AttributeToken token)
+    {
+        String name = token.getName();
+        ComponentResources resources = component.getComponentResources();
+
+        // If already bound (i.e., from the component class, via @Component), then
+        // ignore the value in the template. This may need improving to just ignore
+        // the value if it is an unprefixed literal string.
+
+        if (resources.isBound(name)) return;
+
+        // Meta default of literal for the template.
+
+        String defaultBindingPrefix = determineDefaultBindingPrefix(component, name,
+                                                                    BindingConstants.LITERAL);
+
+        Binding binding = findBinding(loadingElement, component, name, token.getValue(), defaultBindingPrefix,
+                                      token.getLocation());
+
+        if (binding != null)
+        {
+            component.bindParameter(name, binding);
+
+            Map<String, Binding> bindingMap = componentIdToBindingMap.get(component
+                    .getCompleteId());
+            bindingMap.put(name, binding);
+        }
+    }
+
+    private void addMixinsToComponent(ComponentPageElement component, EmbeddedComponentModel model, String mixins)
+    {
+        if (model != null)
+        {
+            for (String mixinClassName : model.getMixinClassNames())
+                pageElementFactory.addMixinByClassName(component, mixinClassName);
+        }
+
+        if (mixins != null)
+        {
+            for (String type : COMMA_PATTERN.split(mixins))
+                pageElementFactory.addMixinByTypeName(component, type);
+        }
+    }
+
+
+    /**
+     * @param model                embededded model defining the new component, from an {@link
+     *                             org.apache.tapestry.annotation.Component} annotation
+     * @param loadingComponent     the currently loading container component
+     * @param newComponent         the new child of the container whose parameters are being bound
+     * @param newComponentBindings map of bindings for the new component (used to handle inheriting of informal
+     *                             parameters)
+     */
+    private void bindParametersFromModel(EmbeddedComponentModel model, ComponentPageElement loadingComponent,
+                                         ComponentPageElement newComponent, Map<String, Binding> newComponentBindings)
+    {
+        for (String name : model.getParameterNames())
+        {
+            String value = model.getParameterValue(name);
+
+            String defaultBindingPrefix = determineDefaultBindingPrefix(newComponent, name,
+                                                                        BindingConstants.PROP);
+
+            Binding binding = findBinding(loadingComponent, newComponent, name, value, defaultBindingPrefix,
+                                          newComponent.getLocation());
+
+            if (binding != null)
+            {
+                newComponent.bindParameter(name, binding);
+
+                // So that the binding can be shared if inherited by a subcomponent
+                newComponentBindings.put(name, binding);
+            }
+        }
+    }
+
+    /**
+     * Creates a new binding, or returns an existing binding (or null) for the "inherit:" binding prefix. Mostly a
+     * wrapper around {@link BindingSource#newBinding(String, ComponentResources, ComponentResources, String, String,
+     * Location)
+     *
+     * @return the new binding, or an existing binding (if inherited), or null (if inherited, and the containing
+     *         parameter is not bound)
+     */
+    private Binding findBinding(ComponentPageElement loadingComponent, ComponentPageElement component, String name,
+                                String value, String defaultBindingPrefix, Location location)
+    {
+        if (value.startsWith(INHERIT_PREFIX))
+        {
+            String loadingParameterName = value.substring(INHERIT_PREFIX.length());
+            Map<String, Binding> loadingComponentBindingMap = componentIdToBindingMap
+                    .get(loadingComponent.getCompleteId());
+
+            // This may return null if the parameter is not bound in the loading component.
+
+            Binding existing = loadingComponentBindingMap.get(loadingParameterName);
+
+            if (existing == null) return null;
+
+            String description = String.format("InheritedBinding[parameter %s %s(inherited from %s of %s)]", name,
+                                               component.getCompleteId(), loadingParameterName,
+                                               loadingComponent.getCompleteId());
+
+            // This helps with debugging, and re-orients any thrown exceptions
+            // to the location of the inherited binding, rather than the container component's
+            // binding.
+
+            return new InheritedBinding(description, existing, location);
+        }
+
+        return pageElementFactory.newBinding(name, loadingComponent.getComponentResources(),
+                                             component.getComponentResources(), defaultBindingPrefix, value, location);
+    }
+
+    /**
+     * Determines the default binding prefix for a particular parameter.
+     *
+     * @param component                      the component which will have a parameter bound
+     * @param parameterName                  the name of the parameter
+     * @param informalParameterBindingPrefix the default to use for informal parameters
+     * @return the binding prefix
+     */
+    private String determineDefaultBindingPrefix(ComponentPageElement component, String parameterName,
+                                                 String informalParameterBindingPrefix)
+    {
+        String defaultBindingPrefix = component.getDefaultBindingPrefix(parameterName);
+
+        return defaultBindingPrefix != null ? defaultBindingPrefix : informalParameterBindingPrefix;
+    }
+
+
+    private void addToBody(PageElement element)
+    {
+        bodyPageElementStack.peek().addToBody(element);
+    }
+
+    private void attribute(AttributeToken token)
+    {
+        // This kind of bookkeeping is ugly, we probably should have distinct (if very similar)
+        // tokens for attributes and for parameter bindings.
+
+        if (addAttributesAsComponentBindings)
+        {
+            ComponentPageElement activeElement = activeElementStack.peek();
+
+            bindParameterFromTemplate(activeElement, token);
+            return;
+        }
+
+        PageElement element = pageElementFactory.newAttributeElement(loadingElement
+                .getComponentResources(), token);
+
+        addToBody(element);
+    }
+
+    private void body()
+    {
+        addToBody(new RenderBodyElement(loadingElement));
+
+        // BODY tokens are *not* matched by END_ELEMENT tokens. Nor will there be
+        // text or comment content "inside" the BODY.
+    }
+
+    private void comment(CommentToken token)
+    {
+        PageElement commentElement = new CommentPageElement(token.getComment());
+
+        addToBody(commentElement);
+    }
+
+    /**
+     * Invoked whenever a token (start, startComponent, etc.) is encountered that will eventually have a matching end
+     * token. Sets up the behavior for the end token.
+     *
+     * @param discard if true, the end is discarded (if false the end token is added to the active body element)
+     * @param command command to execute to return processor state back to what it was before the command executed
+     */
+    private void configureEnd(boolean discard, Runnable command)
+    {
+        discardEndTagStack.push(discard);
+        endElementCommandStack.push(command);
+    }
+
+    private void endElement()
+    {
+        // discard will be false if the matching start token was for a static element, and will be
+        // true otherwise (component, block, parameter).
+
+        boolean discard = discardEndTagStack.pop();
+
+        if (!discard) addToBody(END_ELEMENT);
+
+        Runnable command = endElementCommandStack.pop();
+
+        // Used to return environment to prior state.
+
+        command.run();
+    }
+
+    private void expansion(ExpansionToken token)
+    {
+        PageElement element = pageElementFactory.newExpansionElement(loadingElement
+                .getComponentResources(), token);
+
+        addToBody(element);
+    }
+
+    private String generateEmbeddedId(String embeddedType, IdAllocator idAllocator)
+    {
+        // Component types may be in folders; strip off the folder part for starters.
+
+        int slashx = embeddedType.lastIndexOf("/");
+
+        String baseId = embeddedType.substring(slashx + 1).toLowerCase();
+
+        // The idAllocator is pre-loaded with all the component ids from the template, so even
+        // if the lower-case type matches the id of an existing component, there won't be a name
+        // collision.
+
+        return idAllocator.allocateId(baseId);
+    }
+
+    /**
+     * As currently implemented, this should be invoked just once and then the PageLoaderProcessor instance should be
+     * discarded.
+     */
+    public Page loadPage(String logicalPageName, String pageClassName, Locale locale)
+    {
+        // Ensure that loadPage() may only be invoked once.
+
+        lock.lock();
+
+        this.locale = locale;
+
+        page = new PageImpl(logicalPageName, this.locale, linkFactory, persistentFieldManager);
+
+        loadRootComponent(pageClassName);
+
+        workComponentQueue();
+
+        // Take care of any finalization logic that's been deferred out.
+
+        for (Runnable r : finalization)
+        {
+            r.run();
+        }
+
+        // The page is *loaded* before it is attached to the request.
+        // This is to help ensure that no client-specific information leaks
+        // into the page.
+
+        page.loaded();
+
+        return page;
+    }
+
+    private void loadRootComponent(String className)
+    {
+        ComponentPageElement rootComponent = pageElementFactory.newRootComponentElement(page, className, locale);
+
+        page.setRootElement(rootComponent);
+
+        componentQueue.push(rootComponent);
+    }
+
+    /**
+     * Do you smell something? I'm smelling that this class needs to be redesigned to not need a central method this
+     * large and hard to test. I think a lot of instance and local variables need to be bundled up into some kind of
+     * process object. This code is effectively too big to be tested except through integration testing.
+     */
+    private void loadTemplateForComponent(final ComponentPageElement loadingElement)
+    {
+        this.loadingElement = loadingElement;
+        loadingComponentModel = loadingElement.getComponentResources().getComponentModel();
+
+        String componentClassName = loadingComponentModel.getComponentClassName();
+        ComponentTemplate template = templateSource.getTemplate(loadingComponentModel, locale);
+
+        // When the template for a component is missing, we pretend it consists of just a RenderBody
+        // phase. Missing is not an error ... many component simply do not have a template.
+
+        if (template.isMissing())
+        {
+            this.loadingElement.addToTemplate(new RenderBodyElement(this.loadingElement));
+            return;
+        }
+
+        // Pre-allocate ids to avoid later name collisions.
+
+        Logger logger = loadingComponentModel.getLogger();
+
+        // Don't have a case-insensitive Set, so we'll make due with a Map
+        Map<String, Boolean> embeddedIds = newCaseInsensitiveMap();
+
+        for (String id : loadingComponentModel.getEmbeddedComponentIds())
+            embeddedIds.put(id, true);
+
+        idAllocator.clear();
+
+        for (String id : template.getComponentIds())
+        {
+            idAllocator.allocateId(id);
+            embeddedIds.remove(id);
+        }
+
+        if (!embeddedIds.isEmpty())
+            logger.error(ServicesMessages.embeddedComponentsNotInTemplate(embeddedIds.keySet(), componentClassName));
+
+        addAttributesAsComponentBindings = false;
+
+        // The outermost elements of the template belong in the loading component's template list,
+        // not its body list. This shunt allows everyone else to not have to make that decision,
+        // they can add to the "body" and (if there isn't an active component), the shunt will
+        // add the element to the component's template.
+
+        BodyPageElement shunt = new BodyPageElement()
+        {
+            public void addToBody(PageElement element)
+            {
+                loadingElement.addToTemplate(element);
+            }
+        };
+
+        bodyPageElementStack.push(shunt);
+
+        for (TemplateToken token : template.getTokens())
+        {
+            switch (token.getTokenType())
+            {
+                case TEXT:
+                    text((TextToken) token);
+                    break;
+
+                case EXPANSION:
+                    expansion((ExpansionToken) token);
+                    break;
+
+                case BODY:
+                    body();
+                    break;
+
+                case START_ELEMENT:
+                    startElement((StartElementToken) token);
+                    break;
+
+                case START_COMPONENT:
+                    startComponent((StartComponentToken) token);
+                    break;
+
+                case ATTRIBUTE:
+                    attribute((AttributeToken) token);
+                    break;
+
+                case END_ELEMENT:
+                    endElement();
+                    break;
+
+                case COMMENT:
+                    comment((CommentToken) token);
+                    break;
+
+                case BLOCK:
+                    block((BlockToken) token);
+                    break;
+
+                case PARAMETER:
+                    parameter((ParameterToken) token);
+                    break;
+
+                case DTD:
+                    dtd((DTDToken) token);
+                    break;
+
+                case DEFINE_NAMESPACE_PREFIX:
+                    defineNamespacePrefix((DefineNamespacePrefixToken) token);
+                    break;
+
+                case CDATA:
+                    cdata((CDATAToken) token);
+                    break;
+
+                default:
+                    throw new IllegalStateException("Not implemented yet: " + token);
+            }
+        }
+
+        // For neatness / symmetry:
+
+        bodyPageElementStack.pop(); // the shunt
+
+        // TODO: Check that all stacks are empty. That should never happen, as long
+        // as the ComponentTemplate is valid.
+    }
+
+    private void cdata(CDATAToken token)
+    {
+        final String content = token.getContent();
+
+        PageElement element = new PageElement()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                writer.cdata(content);
+            }
+        };
+
+        addToBody(element);
+    }
+
+    private void defineNamespacePrefix(final DefineNamespacePrefixToken token)
+    {
+        PageElement element = new PageElement()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                writer.defineNamespace(token.getNamespaceURI(), token.getNamespacePrefix());
+            }
+        };
+
+        addToBody(element);
+    }
+
+    private void parameter(ParameterToken token)
+    {
+        BlockImpl block = new BlockImpl(token.getLocation());
+        String name = token.getName();
+
+        Binding binding = new LiteralBinding("block parameter " + name, block, token.getLocation());
+
+        // TODO: Check that the t:parameter doesn't appear outside of an embedded component.
+
+        activeElementStack.peek().bindParameter(name, binding);
+
+        setupBlock(block);
+    }
+
+    private void setupBlock(BodyPageElement block)
+    {
+        bodyPageElementStack.push(block);
+
+        Runnable cleanup = new Runnable()
+        {
+            public void run()
+            {
+                bodyPageElementStack.pop();
+            }
+        };
+
+        configureEnd(true, cleanup);
+    }
+
+    private void block(BlockToken token)
+    {
+        // Don't use the page element factory here becauses we need something that is both Block and
+        // BodyPageElement and don't want to use casts.
+
+        BlockImpl block = new BlockImpl(token.getLocation());
+
+        String id = token.getId();
+
+        if (id != null) loadingElement.addBlock(id, block);
+
+        setupBlock(block);
+    }
+
+    private void startComponent(StartComponentToken token)
+    {
+        String elementName = token.getElementName();
+
+        // Initial guess: the type from the token (but this may be null in many cases).
+        String embeddedType = token.getComponentType();
+
+        String embeddedId = token.getId();
+
+        String embeddedComponentClassName = null;
+
+        // We know that if embeddedId is null, embeddedType is not.
+
+        if (embeddedId == null) embeddedId = generateEmbeddedId(embeddedType, idAllocator);
+
+        final EmbeddedComponentModel embeddedModel = loadingComponentModel
+                .getEmbeddedComponentModel(embeddedId);
+
+        if (embeddedModel != null)
+        {
+            String modelType = embeddedModel.getComponentType();
+
+            if (isNonBlank(modelType) && embeddedType != null)
+            {
+                Logger log = loadingComponentModel.getLogger();
+                log.error(ServicesMessages.compTypeConflict(embeddedId, embeddedType, modelType));
+            }
+
+            embeddedType = modelType;
+            embeddedComponentClassName = embeddedModel.getComponentClassName();
+        }
+
+        if (isBlank(embeddedType) && isBlank(embeddedComponentClassName)) throw new TapestryException(
+                ServicesMessages.noTypeForEmbeddedComponent(embeddedId, loadingComponentModel.getComponentClassName()),
+                token, null);
+
+        final ComponentPageElement newComponent = pageElementFactory.newComponentElement(page, loadingElement,
+                                                                                         embeddedId, embeddedType,
+                                                                                         embeddedComponentClassName,
+                                                                                         elementName,
+                                                                                         token.getLocation());
+
+        addMixinsToComponent(newComponent, embeddedModel, token.getMixins());
+
+        final Map<String, Binding> newComponentBindings = newMap();
+        componentIdToBindingMap.put(newComponent.getCompleteId(), newComponentBindings);
+
+        if (embeddedModel != null)
+            bindParametersFromModel(embeddedModel, loadingElement, newComponent, newComponentBindings);
+
+        addToBody(newComponent);
+
+        // Remember to load the template for this new component
+        componentQueue.push(newComponent);
+
+        // Any attribute tokens that immediately follow should be
+        // used to bind parameters.
+
+        addAttributesAsComponentBindings = true;
+
+        // Any attributes (including component parameters) that come up belong on this component.
+
+        activeElementStack.push(newComponent);
+
+        // Set things up so that content inside the component is added to the component's body.
+
+        bodyPageElementStack.push(newComponent);
+
+        // And clean that up when the end element is reached.
+
+
+        final ComponentModel newComponentModel = newComponent.getComponentResources().getComponentModel();
+
+        // If the component was from an embedded @Component annotation, and it is inheritting informal parameters,
+        // and the component in question supports informal parameters, than get those inheritted informal parameters ...
+        // but later (this helps ensure that <t:parameter> elements that may provide informal parameters are
+        // visible when the informal parameters are copied to the child component).
+
+        if (embeddedModel != null && embeddedModel.getInheritInformalParameters() && newComponentModel.getSupportsInformalParameters())
+        {
+            final ComponentPageElement loadingElement = this.loadingElement;
+
+            Runnable finalizer = new Runnable()
+            {
+                public void run()
+                {
+                    handleInformalParameters(loadingElement, embeddedModel, newComponent, newComponentModel,
+                                             newComponentBindings);
+
+                }
+            };
+
+            finalization.add(finalizer);
+        }
+
+
+        Runnable cleanup = new Runnable()
+        {
+            public void run()
+            {
+                // May need a separate queue for this, to execute at the very end of page loading.
+
+
+                activeElementStack.pop();
+                bodyPageElementStack.pop();
+            }
+        };
+
+        // The start tag is not added to the body of the component, so neither should
+        // the end tag.
+        configureEnd(true, cleanup);
+    }
+
+    /**
+     * Invoked when a component's end tag is reached, to check and process informal parameters as per the {@link
+     * org.apache.tapestry.model.EmbeddedComponentModel#getInheritInformalParameters()} flag.
+     *
+     * @param loadingComponent     the container component that was loaded
+     * @param model
+     * @param newComponent
+     * @param newComponentBindings
+     */
+    private void handleInformalParameters(ComponentPageElement loadingComponent, EmbeddedComponentModel model,
+                                          ComponentPageElement newComponent, ComponentModel newComponentModel,
+                                          Map<String, Binding> newComponentBindings)
+    {
+
+        Map<String, Binding> informals = loadingComponent.getInformalParameterBindings();
+
+
+        for (String name : informals.keySet())
+        {
+            if (newComponentModel.getParameterModel(name) != null) continue;
+
+            Binding binding = informals.get(name);
+
+            newComponent.bindParameter(name, binding);
+            newComponentBindings.put(name, binding);
+        }
+    }
+
+    private void startElement(StartElementToken token)
+    {
+        PageElement element = new StartElementPageElement(token.getNamespaceURI(), token.getName());
+
+        addToBody(element);
+
+        // Controls how attributes are interpretted.
+        addAttributesAsComponentBindings = false;
+
+        // Index will be matched by end:
+
+        // Do NOT discard the end tag; add it to the body.
+
+        configureEnd(false, NO_OP);
+    }
+
+    private void text(TextToken token)
+    {
+        PageElement element = new TextPageElement(token.getText());
+
+        addToBody(element);
+    }
+
+    private void dtd(DTDToken token)
+    {
+        // first DTD encountered wins.
+        if (dtdAdded) return;
+
+        PageElement element = new DTDPageElement(token.getName(), token.getPublicId(), token.getSystemId());
+        // since rendering via the markup writer is to the document tree,
+        // we don't really care where this gets placed in the tree; the
+        // DTDPageElement will set the dtd of the document directly, rather than
+        // writing anything to the markup writer
+        page.getRootElement().addToTemplate(element);
+
+        dtdAdded = true;
+    }
+
+    /**
+     * Works the component queue, until exausted.
+     */
+    private void workComponentQueue()
+    {
+        while (!componentQueue.isEmpty())
+        {
+            ComponentPageElement componentElement = componentQueue.pop();
+
+            loadTemplateForComponent(componentElement);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLocator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLocator.java
new file mode 100644
index 0000000..ed8574e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLocator.java
@@ -0,0 +1,57 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.util.Locale;
+
+/**
+ * Used as a key to lookup a page from the {@link org.apache.tapestry.internal.services.PagePool}.
+ */
+public class PageLocator
+{
+    private final String pageName;
+
+    private final Locale locale;
+
+    public PageLocator(String pageName, Locale locale)
+    {
+        this.pageName = pageName;
+        this.locale = locale;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null || !(obj instanceof PageLocator))
+        {
+            return false;
+        }
+        PageLocator locator = (PageLocator) obj;
+        return pageName.equals(locator.pageName) && locale.equals(locator.locale);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return pageName.hashCode() * 17 + locale.hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("%s[%s, %s]", getClass().getSimpleName(), pageName, locale
+                .toString());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java
new file mode 100644
index 0000000..fb2d09c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRenderer.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.internal.structure.Page;

+

+/**

+ * Service used to render page markup using a MarkupWriter.  This is  used when rendering a complete page as part of a

+ * {@linkplain org.apache.tapestry.internal.services.PageRenderRequestHandlerImpl page render request},

+ */

+public interface PageMarkupRenderer

+{

+    /**

+     * Initializes the rendering using the {@link org.apache.tapestry.services.MarkupRenderer} pipeline.

+     *

+     * @param page   page to render

+     * @param writer receives the markup

+     */

+    void renderPageMarkup(Page page, MarkupWriter writer);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRendererImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRendererImpl.java
new file mode 100644
index 0000000..531f1c1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageMarkupRendererImpl.java
@@ -0,0 +1,60 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.MarkupRenderer;
+
+public class PageMarkupRendererImpl implements PageMarkupRenderer
+{
+    private final Environment environment;
+
+    private final PageRenderQueue pageRenderQueue;
+
+    private final MarkupRenderer markupRendererPipeline;
+
+    public PageMarkupRendererImpl(MarkupRenderer markupRendererPipeline, PageRenderQueue pageRenderQueue,
+                                  Environment environment)
+    {
+        // We have to go through some awkward tricks here:
+        // - MarkupRenderer and MarkupRendererFilter are PUBLIC
+        // - Page, PageMarkupRenderer, PageRenderQueue are PRIVATE
+        // - This service is the bridge between public and private
+
+
+        this.pageRenderQueue = pageRenderQueue;
+        this.environment = environment;
+
+        this.markupRendererPipeline = markupRendererPipeline;
+    }
+
+    public void renderPageMarkup(Page page, MarkupWriter writer)
+    {
+        environment.clear();
+
+        // This is why the PRQ is scope perthread; we tell it what to render here ...
+
+        pageRenderQueue.initializeForCompletePage(page);
+
+        // ... then our statically fixed pipeline is able to (eventually) call into it.
+
+        markupRendererPipeline.renderMarkup(writer);
+
+        if (writer.getDocument().getRootElement() == null)
+            throw new RuntimeException(ServicesMessages.noMarkupFromPageRender(page));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePool.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePool.java
new file mode 100644
index 0000000..bd2d063
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePool.java
@@ -0,0 +1,41 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * Provides access to pages, creating them as necessary, and pooling them between requests.
+ */
+public interface PagePool
+{
+    /**
+     * Obtains a page instance from the pool via a logical page name. A page instance is created if no such page is
+     * currently available.  The page pool enforces limits on the number of page instances (for any page name / locale
+     * combination) and may wait for a page to become available rather than create a new instance. There's also a hard
+     * limit, at which point an exception is raised.
+     *
+     * @param logicalPageName logical name used to identify the page
+     * @return a page instance
+     * @throws RuntimeException if the name is not valid, if the page cannot be loaded, or if an instance of the page
+     *                          can't be created.
+     */
+    Page checkout(String logicalPageName);
+
+    /**
+     * @param page a previously checked-out page
+     */
+    void release(Page page);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolCache.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolCache.java
new file mode 100644
index 0000000..63e30ce
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolCache.java
@@ -0,0 +1,352 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Used by  {@link org.apache.tapestry.internal.services.PagePoolImpl} to maintain a cache of available and in-use page
+ * instances.
+ * <p/>
+ * This code is designed to handle high volume sites and deal with request fluctuations.
+ * <p/>
+ * Page instances, once created, are tracked with <strong>soft</strong> references.
+ * <p/>
+ * A <em>soft limit</em> on the number of page instances is enforced. Requesting a page instance when the soft limit has
+ * been reached (or exceeded) will result in a delay until a page instance (released from another thread) is available.
+ * The delay time is configurable.
+ * <p/>
+ * A <em>hard limit</em> on the number of page instances is enforced. This number may not be exceeded. Requesting a page
+ * instance when at the hard limit will result in a runtime exception.
+ */
+final class PagePoolCache
+{
+    private final String pageName;
+
+    private final Locale locale;
+
+    private final int softLimit;
+
+    private final long softWait;
+
+    private final int hardLimit;
+
+    private final long activeWindow;
+
+    private final PageLoader pageLoader;
+
+    /**
+     * Pages that are available for use.
+     */
+    private LinkedList<CachedPage> available = CollectionFactory.newLinkedList();
+
+    /**
+     * Pages that are currently in use.
+     */
+    private LinkedList<CachedPage> inUse = CollectionFactory.newLinkedList();
+
+    /**
+     * Guards access to the available and in use lists.
+     */
+    private final Lock lock = new ReentrantLock();
+
+    /**
+     * Condition signalled whenever an in-use page is returned to the cache, which is useful if some other thread may be
+     * waiting for a page to be available.
+     */
+    private final Condition pageAvailable = lock.newCondition();
+
+    /**
+     * Tracks the usage of a page instance, allowing a last access property to be associated with the page. CachedPage
+     * instances are only accessed from within a {@link org.apache.tapestry.internal.services.PagePoolCache}, which
+     * handles synchronization concerns.
+     * <p/>
+     * An earlier version of this code used <em>soft references</em>, but those seem to be problematic (the test suite
+     * started behaving erratically and response time suffered).  Perhaps that could be addressed via tuning of the VM,
+     * but for the meantime, we use hard references and rely more on the soft and hard limits and the culling of unused
+     * pages periodically.
+     */
+    static class CachedPage
+    {
+        private final Page page;
+
+        private long lastAccess;
+
+        CachedPage(Page page)
+        {
+            this.page = page;
+        }
+    }
+
+    /**
+     * @param pageName     logical name of page, needed when creating a fresh instance
+     * @param locale       locale of the page, needed when creating a fresh instance
+     * @param pageLoader   used to create a fresh page instance, if necessary
+     * @param softLimit    soft limit on pages, point at which the cache will wait for an existing page to be made
+     *                     available
+     * @param softWait     interval, in milliseconds, to wait for a page to become available
+     * @param hardLimit    maximum number of page instances that will ever be created
+     * @param activeWindow interval, in milliseconds, beyond which an available page is simply discarded
+     */
+    public PagePoolCache(String pageName, Locale locale, PageLoader pageLoader, int softLimit, long softWait,
+                         int hardLimit, long activeWindow)
+    {
+        this.pageName = pageName;
+        this.locale = locale;
+        this.pageLoader = pageLoader;
+        this.softLimit = softLimit;
+        this.softWait = softWait;
+        this.hardLimit = hardLimit;
+        this.activeWindow = activeWindow;
+    }
+
+    /**
+     * Finds an available page instance and returns it.  If no page instance is available, will wait up to the soft wait
+     * for one to become available. After that time, it will either create a new instance, or give up (the hard instance
+     * limit has been reached) and throw an exception.
+     *
+     * @return page instance
+     * @throws RuntimeException if the hard limit is reached, or if there is an error loading a new page instance
+     */
+    Page checkout()
+    {
+        // The only problem here is that *each* new page attached to the request
+        // may wait the soft limit.  The alternative would be to timestamp the request
+        // itself, and compute the wait period from that ... a dangerous and expensive option.
+
+        long start = System.currentTimeMillis();
+
+        // We don't set a wait on acquiring the lock; it is assumed that any given thread will
+        // only have the lock for an instant whether it is checking for an available page, or
+        // releasing pages from the in use list back into the active list. We go to some trouble to
+        // ensure that the PageLoader is invoked OUTSIDE of the lock.
+
+        lock.lock();
+
+        try
+        {
+
+
+            while (true)
+            {
+                // We have the write lock, see if there is an available cached page we can use.
+
+                Page page = findAvailablePage();
+
+                if (page != null) return page;
+
+                // Now it starts to get tricky.  Have we hit the soft limit yet?
+                // We assume that none of the in use pages' soft references are cleared,
+                // which is largely accurate as long as there haven't been a lot
+                // of request exceptions.  We'll take the count at face value.
+
+                if (inUse.size() < softLimit) break;
+
+                // We'll wait for pages to be available, but careful that the
+                // total wait period is less than the soft wait limit.
+
+                long waitMillis = (start + softWait) - System.currentTimeMillis();
+
+                // We've run out of time to wait.
+
+                if (waitMillis < 1) break;
+
+                try
+                {
+                    // Note: await() will release the lock, but will re-acquire it
+                    // before returning. 
+                    pageAvailable.await(waitMillis, TimeUnit.MILLISECONDS);
+                }
+                catch (InterruptedException ex)
+                {
+                    // Not sure who is interrupting us (the servlet container)? But returning null
+                    // is the fastest way to bounce out of the thread.
+
+                    return null;
+                }
+
+                // Loop back up and see if an active page is available.  It won't always be,
+                // because of race conditions, so we may wait again.
+            }
+
+            // We get here if we exhausted the softWait interval without actually
+            // acquiring a page.            
+
+            // If past the hard limit, we don't try to create the page fresh.
+
+            if (inUse.size() >= hardLimit)
+                throw new RuntimeException(ServicesMessages.pagePoolExausted(pageName, locale, hardLimit));
+        }
+        finally
+        {
+            lock.unlock();
+        }
+
+        // This may take a moment, so we're careful to do it outside of a write lock.
+        // That does mean that we may slip over a hard or soft limit momentarily, if
+        // just the right race condition occurs.
+
+        Page page = pageLoader.loadPage(pageName, locale);
+
+        lock.lock();
+
+        try
+        {
+            inUse.addFirst(new CachedPage(page));
+        }
+        finally
+        {
+            lock.unlock();
+        }
+
+        return page;
+    }
+
+    /**
+     * Finds and returns the first available page.
+     * <p/>
+     * Side effect: removes the {@link org.apache.tapestry.internal.services.PagePoolCache.CachedPage} from the
+     * available list and moves it to the in use list.
+     *
+     * @return the page, if any found, or null if no page is available
+     */
+    private Page findAvailablePage()
+    {
+        if (available.isEmpty()) return null;
+
+        CachedPage cachedPage = available.removeFirst();
+
+        inUse.addFirst(cachedPage);
+
+        return cachedPage.page;
+    }
+
+    /**
+     * Invoked to release an active page back into the pool.
+     */
+    void release(Page page)
+    {
+        lock.lock();
+
+        try
+        {
+            CachedPage cached = null;
+
+            ListIterator<CachedPage> i = inUse.listIterator();
+
+            while (i.hasNext())
+            {
+                cached = i.next();
+
+                if (cached.page == page)
+                {
+                    i.remove();
+                    break;
+                }
+
+            }
+
+            // This should not ever happen. The only scenario I can think of is if a page instance
+            // was in use before the page pool was cleared (due to a file check invalidation notification).
+            // That's not supposed to happen, CheckForUpdatesFilter ensures that all threads but one
+            // or blocked on the outside when a file check occurs.
+
+            // So, cached is null means that the page instance was not created by this
+            // PagePoolCache, so we're not interested in keeping it.
+
+            if (cached == null) return;
+
+            cached.lastAccess = System.currentTimeMillis();
+
+            available.addFirst(cached);
+
+            pageAvailable.signal();
+
+        }
+        finally
+        {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Called for dirty pages, pages that are in an unknown state after being used for the request. Such pages are
+     * removed from the in use list and NOT added back to the active list.
+     */
+    void remove(Page page)
+    {
+        lock.lock();
+
+        try
+        {
+            ListIterator<CachedPage> i = inUse.listIterator();
+
+            while (i.hasNext())
+            {
+                CachedPage cached = i.next();
+
+                if (cached.page == page)
+                {
+                    i.remove();
+
+                    break;
+                }
+            }
+        }
+        finally
+        {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Finds any cached pages whose last modified time is beyond the active window, meaning they haven't been used in
+     * some amount of time., and releases them to the garbage collector.
+     */
+    void cleanup()
+    {
+        long cutoff = System.currentTimeMillis() - activeWindow;
+
+        lock.lock();
+
+        try
+        {
+
+            ListIterator<CachedPage> i = available.listIterator();
+
+            while (i.hasNext())
+            {
+                CachedPage cached = i.next();
+
+                if (cached.lastAccess < cutoff) i.remove();
+            }
+        }
+        finally
+        {
+            lock.unlock();
+        }
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java
new file mode 100644
index 0000000..f1248ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PagePoolImpl.java
@@ -0,0 +1,163 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.ioc.util.TimeInterval;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.slf4j.Logger;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Registered as an invalidation listener with the page loader, the component messages source, and the component
+ * template source. Any time any of those notice a change, then the entire page pool is wiped.
+ * <p/>
+ * The master page pool is, itself, divided into individual sub-pools, one for each combination of
+ * <p/>
+ * This code is designed to handle high volume sites and deal with request fluctuations.
+ * <p/>
+ * A <em>soft limit</em> on the number of page instances is enforced. Asking for a page instance when the soft limit has
+ * been reached (or exceeded) will result in a delay until a page instance (released from another thread) is available.
+ * The delay time is configurable.
+ * <p/>
+ * A <em>hard limit</em> on the number of page instances is enforced. This number may not be exceeded. Requesting a page
+ * instance when at the hard limit will result in a runtime exception.
+ * <p/>
+ * As an {@link org.apache.tapestry.internal.events.UpdateListener}, the service will reduce the size of each page's
+ * pool by eliminating pages that haven't been used recently.
+ *
+ * @see org.apache.tapestry.internal.services.PagePoolCache
+ */
+public class PagePoolImpl implements PagePool, InvalidationListener, UpdateListener
+{
+    private final Logger logger;
+
+    private final PageLoader pageLoader;
+
+    private final ThreadLocale threadLocale;
+
+    private final ComponentClassResolver resolver;
+
+    private final int softLimit;
+
+    private final long softWait;
+
+    private final int hardLimit;
+
+    private final long activeWindow;
+
+    private final Map<PageLocator, PagePoolCache> pool = CollectionFactory.newMap();
+
+    public PagePoolImpl(Logger logger,
+
+                        PageLoader pageLoader,
+
+                        ThreadLocale threadLocale,
+
+                        ComponentClassResolver resolver,
+
+                        @Symbol("tapestry.page-pool.soft-limit")
+                        int softLimit,
+
+                        @Symbol("tapestry.page-pool.soft-wait") @IntermediateType(TimeInterval.class)
+                        long softWait,
+
+                        @Symbol("tapestry.page-pool.hard-limit")
+                        int hardLimit,
+
+                        @Symbol("tapestry.page-pool.active-window") @IntermediateType(TimeInterval.class)
+                        long activeWindow)
+    {
+        this.logger = logger;
+        this.pageLoader = pageLoader;
+        this.threadLocale = threadLocale;
+        this.resolver = resolver;
+        this.softLimit = softLimit;
+        this.softWait = softWait;
+        this.hardLimit = hardLimit;
+        this.activeWindow = activeWindow;
+    }
+
+    public Page checkout(String logicalPageName)
+    {
+        String canonicalPageName = resolver.canonicalizePageName(logicalPageName);
+
+        PagePoolCache cache = get(canonicalPageName, threadLocale.getLocale());
+
+        return cache.checkout();
+    }
+
+    public void release(Page page)
+    {
+        PagePoolCache cache = get(page.getLogicalName(), page.getLocale());
+
+        // If the page is not "clean" of any request/client state, it can't go
+        // back in the pool.
+
+        if (page.detached())
+        {
+            logger.error(ServicesMessages.pageIsDirty(page));
+
+            cache.remove(page);
+
+            return;
+        }
+
+        cache.release(page);
+
+    }
+
+    private synchronized PagePoolCache get(String pageName, Locale locale)
+    {
+        PageLocator locator = new PageLocator(pageName, locale);
+
+        PagePoolCache result = pool.get(locator);
+
+        if (result == null)
+        {
+            // TODO: It might be nice to allow individual pages to override the default limits.
+
+            result = new PagePoolCache(pageName, locale, pageLoader, softLimit, softWait, hardLimit, activeWindow);
+
+            pool.put(locator, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * Any time templates, classes or messages change, we throw out all instances.
+     */
+    public synchronized void objectWasInvalidated()
+    {
+        pool.clear();
+    }
+
+    public synchronized void checkForUpdates()
+    {
+        for (PagePoolCache cache : pool.values())
+        {
+            cache.cleanup();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
new file mode 100644
index 0000000..b46274d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderDispatcher.java
@@ -0,0 +1,120 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.URLEventContext;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+/**
+ * Dispatches incoming requests for render requests. Render requests consist of either just a logical page name (case
+ * insensitive) or a logical page name plus additional context. Because of this structure, it take a little bit of work
+ * to identify the split point between the page name and the context.
+ */
+public class PageRenderDispatcher implements Dispatcher
+{
+    private final ComponentClassResolver componentClassResolver;
+
+    private final PageRenderRequestHandler handler;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    public PageRenderDispatcher(ComponentClassResolver componentClassResolver, PageRenderRequestHandler handler,
+                                ContextValueEncoder contextValueEncoder)
+    {
+        this.componentClassResolver = componentClassResolver;
+        this.handler = handler;
+        this.contextValueEncoder = contextValueEncoder;
+    }
+
+    public boolean dispatch(Request request, final Response response) throws IOException
+    {
+
+        // The extended name may include a page activation context. The trick is
+        // to figure out where the logical page name stops and where the
+        // activation context begins. Further, strip out the leading slash.
+
+        String path = request.getPath();
+
+        // TAPESTRY-1343: Sometimes path is the empty string (it should always be at least a slash,
+        // but Tomcat may return the empty string for a root context request).
+
+        String extendedName = path.length() == 0 ? path : path.substring(1);
+
+        // Ignore trailing slashes in the path.
+        while (extendedName.endsWith("/"))
+            extendedName = extendedName.substring(0, extendedName.length() - 1);
+
+        int slashx = extendedName.length();
+        boolean atEnd = true;
+
+        while (slashx > 0)
+        {
+
+            String pageName = extendedName.substring(0, slashx);
+            String pageActivationContext = atEnd ? "" :
+                                           extendedName.substring(slashx + 1);
+
+            if (process(pageName, pageActivationContext)) return true;
+
+            // Work backwards, splitting at the next slash.
+            slashx = extendedName.lastIndexOf('/', slashx - 1);
+
+            atEnd = false;
+        }
+
+        // OK, maybe its all page activation context for the root Index page.
+
+        return process("", extendedName);
+    }
+
+    private boolean process(String pageName, String pageActivationContext) throws IOException
+    {
+        if (!componentClassResolver.isPageName(pageName)) return false;
+
+        String[] values = convertActivationContext(pageActivationContext);
+
+        EventContext activationContext
+                = new URLEventContext(contextValueEncoder, values);
+
+        PageRenderRequestParameters parameters = new PageRenderRequestParameters(pageName, activationContext);
+
+        handler.handle(parameters);
+
+        return true;
+    }
+
+    /**
+     * Converts the "extra path", the portion after the page name (and after the slash seperating the page name from the
+     * activation context) into an array of strings. LinkFactory and friends URL encode each value, so we URL decode the
+     * value (we assume that page names are "URL safe").
+     */
+    private String[] convertActivationContext(String extraPath)
+    {
+        if (extraPath.length() == 0) return new String[0];
+
+        String[] context = TapestryInternalUtils.splitPath(extraPath);
+
+        for (int i = 0; i < context.length; i++)
+        {
+            context[i] = TapestryInternalUtils.unescapePercentAndSlash(context[i]);
+        }
+
+        return context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
new file mode 100644
index 0000000..3cc4be2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
@@ -0,0 +1,78 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry5.json.JSONObject;
+
+
+/**
+ * A wrapper around {@link org.apache.tapestry.runtime.RenderQueue}, but referencable as a (per-thread) service. This
+ * service is scoped so that we can tell it what to render in one method, then have it do the render in another. Part of
+ * an elaborate scheme to keep certain interfaces public and other closely related ones private.
+ */
+public interface PageRenderQueue
+{
+    /**
+     * Initializes the queue for rendering of a complete page.
+     */
+    void initializeForCompletePage(Page page);
+
+    /**
+     * Sets the default page that will render the response.
+     */
+    void setRenderingPage(Page page);
+
+    /**
+     * Returns the page that is rendering markup content.
+     */
+    Page getRenderingPage();
+
+    /**
+     * Initializes the queue for rendering of a portion of a page.
+     */
+    void initializeForPartialPageRender(RenderCommand rootCommand);
+
+    /**
+     * Obtains the value previously supplied to {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)}.
+     * This allows the "natural" renderer to be substituted or otherwise manipulated.
+     *
+     * @return the root renderer
+     */
+    RenderCommand getRootRenderCommand();
+
+    /**
+     * Returns true if {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)} has been
+     * invoked.
+     */
+    boolean isPartialRenderInitialized();
+
+    /**
+     * Render to the write, as setup by the initialize method.
+     *
+     * @param writer to write markup to
+     */
+    void render(MarkupWriter writer);
+
+    /**
+     * Performs a partial markup render, as configured via {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)}.
+     *
+     * @param writer to which markup should be written
+     * @param reply  JSONObject which will contain the partial response
+     */
+    void renderPartial(MarkupWriter writer, JSONObject reply);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
new file mode 100644
index 0000000..8e135ca
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
@@ -0,0 +1,104 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.structure.Page;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry5.json.JSONObject;
+
+/**
+ * This services keeps track of the page being rendered and the root command for the partial render, it is therefore
+ * request/thread scoped.  There's a filter pipeline around the rendering, and that gets to be stateless because this
+ * service, at the end of the pipeline, is stateful.
+ */
+@Scope(PERTHREAD_SCOPE)
+public class PageRenderQueueImpl implements PageRenderQueue
+{
+    private Page page;
+
+    private RenderCommand rootCommand;
+
+    public void initializeForCompletePage(Page page)
+    {
+        this.page = page;
+        rootCommand = page.getRootElement();
+    }
+
+
+    public void setRenderingPage(Page page)
+    {
+        Defense.notNull(page, "page");
+
+        this.page = page;
+    }
+
+    public boolean isPartialRenderInitialized()
+    {
+        return rootCommand != null;
+    }
+
+    public void initializeForPartialPageRender(RenderCommand rootCommand)
+    {
+        Defense.notNull(rootCommand, "rootCommand");
+
+        if (page == null) throw new IllegalStateException("Page must be specified before root render command.");
+
+        this.rootCommand = rootCommand;
+    }
+
+    public RenderCommand getRootRenderCommand()
+    {
+        return rootCommand;
+    }
+
+    public Page getRenderingPage()
+    {
+        return page;
+    }
+
+    public void render(MarkupWriter writer)
+    {
+        RenderQueueImpl queue = new RenderQueueImpl(page.getLogger());
+
+        queue.push(rootCommand);
+
+        // Run the queue until empty.
+
+        queue.run(writer);
+    }
+
+    public void renderPartial(MarkupWriter writer, JSONObject reply)
+    {
+        // The partial will quite often contain multiple elements (or just a block of plain text),
+        // so those must be enclosed in a root element.
+
+        Element root = writer.element("ajax-partial");
+
+        // The initialize methods will already have been invoked.
+
+        render(writer);
+
+        writer.end();
+
+        String content = root.getChildMarkup().trim();
+
+        reply.put("content", content);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java
new file mode 100644
index 0000000..4a1ede0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderRequestHandlerImpl.java
@@ -0,0 +1,61 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.services.PageRenderRequestHandler;
+import org.apache.tapestry.services.PageRenderRequestParameters;
+import org.apache.tapestry.services.Traditional;
+
+import java.io.IOException;
+
+/**
+ * Handles a PageLink as specified by a PageLinkPathSource by activating and then rendering the page.
+ */
+public class PageRenderRequestHandlerImpl implements PageRenderRequestHandler
+{
+    private final RequestPageCache cache;
+
+    private final ComponentEventResultProcessor resultProcessor;
+
+    private final PageResponseRenderer pageResponseRenderer;
+
+    public PageRenderRequestHandlerImpl(RequestPageCache cache,
+                                        @Traditional ComponentEventResultProcessor resultProcessor,
+                                        PageResponseRenderer pageResponseRenderer)
+    {
+        this.cache = cache;
+        this.resultProcessor = resultProcessor;
+        this.pageResponseRenderer = pageResponseRenderer;
+    }
+
+    public void handle(PageRenderRequestParameters parameters) throws IOException
+    {
+        Page page = cache.get(parameters.getLogicalPageName());
+
+        ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(resultProcessor);
+
+        page.getRootElement().triggerContextEvent(EventConstants.ACTIVATE, parameters.getActivationContext(),
+                                                  callback);
+
+        // The handler will have asked the result processor to send a response.
+
+        if (callback.isAborted()) return;
+
+        pageResponseRenderer.renderPageResponse(page);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
new file mode 100644
index 0000000..70b25de
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRenderer.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+import java.io.IOException;
+
+/**
+ * Service responsible for writing a full page markup response.
+ */
+public interface PageResponseRenderer
+{
+    void renderPageResponse(Page page) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java
new file mode 100644
index 0000000..e997fb8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageResponseRendererImpl.java
@@ -0,0 +1,65 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class PageResponseRendererImpl implements PageResponseRenderer
+{
+    private final PageMarkupRenderer markupRenderer;
+
+    private final MarkupWriterFactory markupWriterFactory;
+
+    private final PageContentTypeAnalyzer pageContentTypeAnalyzer;
+
+    private final Response response;
+
+    public PageResponseRendererImpl(MarkupWriterFactory markupWriterFactory, PageMarkupRenderer markupRenderer,
+                                    PageContentTypeAnalyzer pageContentTypeAnalyzer, Response response)
+    {
+        this.markupWriterFactory = markupWriterFactory;
+        this.markupRenderer = markupRenderer;
+        this.pageContentTypeAnalyzer = pageContentTypeAnalyzer;
+        this.response = response;
+    }
+
+    public void renderPageResponse(Page page) throws IOException
+    {
+        Defense.notNull(page, "page");
+
+        ContentType contentType = pageContentTypeAnalyzer.findContentType(page);
+
+        // For the moment, the content type is all that's used determine the model for the markup writer.
+        // It's something of a can of worms.
+
+        MarkupWriter writer = markupWriterFactory.newMarkupWriter(contentType);
+
+        markupRenderer.renderPageMarkup(page, writer);
+
+        PrintWriter pw = response.getPrintWriter(contentType.toString());
+
+        writer.toMarkup(pw);
+
+        pw.flush();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocator.java
new file mode 100644
index 0000000..8b556fd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocator.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.model.ComponentModel;
+
+import java.util.Locale;
+
+/**
+ * Responsible for locating page templates in the web application context.
+ */
+public interface PageTemplateLocator
+{
+    /**
+     * Given model, determines if the model is for a page (rather than a component) and if so, sees if there is a
+     * localized template for the page in the web application context.
+     *
+     * @param model  the component model defining the page to search for
+     * @param locale the desired localization of the template
+     * @return the template resource, or null if not found or the model is not a page
+     */
+    Resource findPageTemplateResource(ComponentModel model, Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocatorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocatorImpl.java
new file mode 100644
index 0000000..7822cf0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageTemplateLocatorImpl.java
@@ -0,0 +1,65 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ComponentClassResolver;
+
+import static java.lang.String.format;
+import java.util.Locale;
+
+public class PageTemplateLocatorImpl implements PageTemplateLocator
+{
+    private final Resource contextRoot;
+
+    private final ComponentClassResolver resolver;
+
+    public PageTemplateLocatorImpl(Resource contextRoot, ComponentClassResolver resolver)
+    {
+        this.contextRoot = contextRoot;
+        this.resolver = resolver;
+    }
+
+    public Resource findPageTemplateResource(ComponentModel model, Locale locale)
+    {
+        String className = model.getComponentClassName();
+
+        // A bit of a hack, but should work.
+
+        if (!className.contains(".pages.")) return null;
+
+        String logicalName = resolver.resolvePageClassNameToPageName(className);
+
+        int slashx = logicalName.lastIndexOf('/');
+
+        if (slashx > 0)
+        {
+            // However, the logical name isn't quite what we want. It may have been somewhat
+            // trimmed.
+
+            String simpleClassName = InternalUtils.lastTerm(className);
+
+            logicalName = logicalName.substring(0, slashx + 1) + simpleClassName;
+        }
+
+        String path = format("%s.%s", logicalName, InternalConstants.TEMPLATE_EXTENSION);
+
+        return contextRoot.forFile(path).forLocale(locale);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldBundleImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldBundleImpl.java
new file mode 100644
index 0000000..9a7401f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldBundleImpl.java
@@ -0,0 +1,65 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.ioc.internal.util.CollectionFactory;

+import org.apache.tapestry.services.PersistentFieldBundle;

+import org.apache.tapestry.services.PersistentFieldChange;

+

+import java.util.Collection;

+import java.util.Map;

+

+public class PersistentFieldBundleImpl implements PersistentFieldBundle

+{

+    /**

+     * Keyed on componentId + fieldName.

+     */

+    private final Map<String, Object> values = CollectionFactory.newMap();

+

+    public PersistentFieldBundleImpl(Collection<PersistentFieldChange> changes)

+    {

+        for (PersistentFieldChange change : changes)

+        {

+            String key = buildKey(change.getComponentId(), change.getFieldName());

+

+            values.put(key, change.getValue());

+        }

+    }

+

+    private String buildKey(String componentId, String fieldName)

+    {

+        StringBuilder builder = new StringBuilder();

+        if (componentId != null) builder.append(componentId);

+        builder.append(':');

+        builder.append(fieldName);

+

+        return builder.toString();

+    }

+

+    public boolean containsValue(String componentId, String fieldName)

+    {

+        String key = buildKey(componentId, fieldName);

+

+        return values.containsKey(key);

+    }

+

+    public Object getValue(String componentId, String fieldName)

+    {

+        String key = buildKey(componentId, fieldName);

+

+        return values.get(key);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldChangeImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldChangeImpl.java
new file mode 100644
index 0000000..ab3f9cb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldChangeImpl.java
@@ -0,0 +1,54 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.services.PersistentFieldChange;
+
+public class PersistentFieldChangeImpl implements PersistentFieldChange
+{
+    private final String componentId;
+
+    private final String fieldName;
+
+    private final Object value;
+
+    public PersistentFieldChangeImpl(final String componentId, final String fieldName,
+                                     final Object value)
+    {
+        notNull(componentId, "componentId");
+        notBlank(fieldName, "fieldName");
+
+        this.componentId = componentId;
+        this.fieldName = fieldName;
+        this.value = value;
+    }
+
+    public String getComponentId()
+    {
+        return componentId;
+    }
+
+    public String getFieldName()
+    {
+        return fieldName;
+    }
+
+    public Object getValue()
+    {
+        return value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java
new file mode 100644
index 0000000..44026fd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManager.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.services.PersistentFieldBundle;
+
+/**
+ * Handle persistent property changes. Primarily, delegates to a number of {@link org.apache.tapestry.services.PersistentFieldStrategy}
+ * instances.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributePersistentFieldManager(org.apache.tapestry.ioc.MappedConfiguration,
+ *      org.apache.tapestry.services.Request , org.apache.tapestry.services.PersistentFieldStrategy)
+ */
+public interface PersistentFieldManager
+{
+    /**
+     * Posts a change of a persistent property.
+     *
+     * @param pageName  the logical name of the page containing the component
+     * @param resources the resources for the component or mixin (used to determine the persistence strategy)
+     * @param fieldName the name of the field whose persistent value has changed
+     * @param newValue  the new value for the field, possibly null
+     */
+    void postChange(String pageName, ComponentResources resources, String fieldName, Object newValue);
+
+    /**
+     * Locates all persistently stored changes to all properties within the page (for the current session and request)
+     * and gathers them together into a bundle.
+     *
+     * @param pageName the logical name of the page to gather changes for
+     * @return a bundle identifying all such changes
+     */
+    PersistentFieldBundle gatherChanges(String pageName);
+
+    /**
+     * Discards all changes for the indicated page. This will not affect pages that have already been attached to this
+     * request, but will affect subsequent page attachments in this and later requests.
+     *
+     * @param pageName logical name of page whose persistent field data is to be discarded
+     */
+    void discardChanges(String pageName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
new file mode 100644
index 0000000..8eff5fd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentFieldManagerImpl.java
@@ -0,0 +1,98 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.PersistentFieldBundle;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class PersistentFieldManagerImpl implements PersistentFieldManager
+{
+    public static final String META_KEY = "tapestry.persistence-strategy";
+
+    public static final String DEFAULT_STRATEGY = "session";
+
+    private final MetaDataLocator metaDataLocator;
+
+    private final Map<String, PersistentFieldStrategy> strategies;
+
+    public PersistentFieldManagerImpl(MetaDataLocator locator,
+                                      Map<String, PersistentFieldStrategy> strategies)
+    {
+        metaDataLocator = locator;
+
+        this.strategies = strategies;
+    }
+
+    private PersistentFieldStrategy getStrategy(String strategyName)
+    {
+        PersistentFieldStrategy result = strategies.get(strategyName);
+
+        if (result == null)
+            throw new RuntimeException(ServicesMessages.unknownPersistentFieldStrategy(
+                    strategyName,
+                    strategies.keySet()));
+
+        return result;
+    }
+
+    public PersistentFieldBundle gatherChanges(String pageName)
+    {
+        Collection<PersistentFieldChange> allChanges = CollectionFactory.newList();
+
+        for (PersistentFieldStrategy strategy : strategies.values())
+        {
+            allChanges.addAll(strategy.gatherFieldChanges(pageName));
+        }
+
+        return new PersistentFieldBundleImpl(allChanges);
+    }
+
+    public void discardChanges(String pageName)
+    {
+        for (PersistentFieldStrategy strategy : strategies.values())
+        {
+            strategy.discardChanges(pageName);
+        }
+    }
+
+    public void postChange(String pageName, ComponentResources resources, String fieldName,
+                           Object newValue)
+    {
+        String strategyName = findStrategy(resources, fieldName);
+        PersistentFieldStrategy strategy = getStrategy(strategyName);
+
+        strategy.postChange(pageName, resources.getNestedId(), fieldName, newValue);
+    }
+
+    private String findStrategy(ComponentResources resources, String fieldName)
+    {
+        ComponentModel model = resources.getComponentModel();
+
+        String strategy = model.getFieldPersistenceStrategy(fieldName);
+
+        if (InternalUtils.isNonBlank(strategy)) return strategy;
+
+        return metaDataLocator.findMeta(META_KEY, resources, String.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentLocaleImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentLocaleImpl.java
new file mode 100644
index 0000000..68e5193
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PersistentLocaleImpl.java
@@ -0,0 +1,58 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Cookies;
+import org.apache.tapestry.services.PersistentLocale;
+
+import java.util.Locale;
+
+public class PersistentLocaleImpl implements PersistentLocale
+{
+    /**
+     * Name of the cookie written to the client web browser to identify the locale.
+     */
+    private static final String LOCALE_COOKIE_NAME = "org.apache.tapestry.locale";
+
+    private final Cookies cookieSource;
+
+    public PersistentLocaleImpl(Cookies cookieSource)
+    {
+        this.cookieSource = cookieSource;
+    }
+
+    public void set(Locale locale)
+    {
+        cookieSource.writeCookieValue(LOCALE_COOKIE_NAME, locale.toString());
+    }
+
+    public Locale get()
+    {
+        String localeCookieValue = getCookieValue();
+
+        return localeCookieValue != null ? new Locale(localeCookieValue) : null;
+    }
+
+    private String getCookieValue()
+    {
+        return cookieSource.readCookieValue(LOCALE_COOKIE_NAME);
+    }
+
+    public boolean isSet()
+    {
+        return getCookieValue() != null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
new file mode 100644
index 0000000..fdb9c09
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PropertyConduitSourceImpl.java
@@ -0,0 +1,513 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.util.MultiKey;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.GenericsUtils;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.services.ComponentLayer;
+import org.apache.tapestry.services.PropertyConduitSource;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class PropertyConduitSourceImpl implements PropertyConduitSource, InvalidationListener
+{
+    private interface ReadInfo extends AnnotationProvider
+    {
+        /**
+         * The name of the method to invoke.
+         */
+        String getMethodName();
+
+        /**
+         * The return type of the method, or the type of the property.
+         */
+        Class getType();
+
+        /**
+         * True if an explicit cast to the return type is needed (typically because of generics).
+         */
+        boolean isCastRequired();
+    }
+
+
+    /**
+     * Result from writing the property navigation portion of the expression.  For getter methods, the navigation is all
+     * terms in the expression; for setter methods, the navigation is all but the last term.
+     */
+    private interface PropertyNavigationResult
+    {
+        /**
+         * The name of the variable holding the final step in the expression.
+         */
+        String getFinalStepVariable();
+
+        /**
+         * The type of the final step variable.
+         */
+        Class getFinalStepType();
+
+        /**
+         * The method read information for the final term in the navigation portion of the expression.
+         */
+        ReadInfo getFinalReadInfo();
+    }
+
+    private static final String PARENS = "()";
+
+    private final PropertyAccess access;
+
+    private final ClassFactory classFactory;
+
+    private final Map<Class, Class> classToEffectiveClass = newConcurrentMap();
+
+    /**
+     * Keyed on combination of root class and expression.
+     */
+    private final Map<MultiKey, PropertyConduit> cache = newConcurrentMap();
+
+    private static final MethodSignature GET_SIGNATURE = new MethodSignature(Object.class, "get",
+                                                                             new Class[] { Object.class }, null);
+
+    private static final MethodSignature SET_SIGNATURE = new MethodSignature(void.class, "set",
+                                                                             new Class[] { Object.class, Object.class },
+                                                                             null);
+
+    private final Pattern SPLIT_AT_DOTS = Pattern.compile("\\.");
+
+    public PropertyConduitSourceImpl(PropertyAccess access, @ComponentLayer ClassFactory classFactory)
+    {
+        this.access = access;
+        this.classFactory = classFactory;
+    }
+
+    public PropertyConduit create(Class rootClass, String expression)
+    {
+        notNull(rootClass, "rootClass");
+        notBlank(expression, "expression");
+
+        Class effectiveClass = toEffectiveClass(rootClass);
+
+        MultiKey key = new MultiKey(effectiveClass, expression);
+
+        PropertyConduit result = cache.get(key);
+
+        if (result == null)
+        {
+            result = build(effectiveClass, expression);
+            cache.put(key, result);
+
+        }
+
+        return result;
+    }
+
+    private Class toEffectiveClass(Class rootClass)
+    {
+        Class result = classToEffectiveClass.get(rootClass);
+
+        if (result == null)
+        {
+            result = classFactory.importClass(rootClass);
+
+            classToEffectiveClass.put(rootClass, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * Clears its caches when the component class loader is invalidated; this is because it will be common to generate
+     * conduits rooted in a component class (which will no longer be valid and must be released to the garbage
+     * collector).
+     */
+    public void objectWasInvalidated()
+    {
+        cache.clear();
+        classToEffectiveClass.clear();
+    }
+
+
+    /**
+     * Builds a subclass of {@link BasePropertyConduit} that implements the get() and set() methods and overrides the
+     * constructor. In a worst-case race condition, we may build two (or more) conduits for the same
+     * rootClass/expression, and it will get sorted out when the conduit is stored into the cache.
+     *
+     * @param rootClass
+     * @param expression
+     * @return the conduit
+     */
+    private PropertyConduit build(Class rootClass, String expression)
+    {
+        String name = ClassFabUtils.generateClassName("PropertyConduit");
+
+        ClassFab classFab = classFactory.newClass(name, BasePropertyConduit.class);
+
+        classFab.addConstructor(new Class[] { Class.class, AnnotationProvider.class, String.class }, null,
+                                "super($$);");
+
+        String[] terms = SPLIT_AT_DOTS.split(expression);
+
+        final ReadInfo readInfo = buildGetter(rootClass, classFab, expression, terms);
+        final Method writeMethod = buildSetter(rootClass, classFab, expression, terms);
+
+        // A conduit is either readable or writable, otherwise there will already have been
+        // an error about unknown method name or property name.
+
+        Class propertyType = readInfo != null ? readInfo.getType() : writeMethod
+                .getParameterTypes()[0];
+
+        String description = String.format("PropertyConduit[%s %s]", rootClass.getName(), expression);
+
+        Class conduitClass = classFab.createClass();
+
+        AnnotationProvider provider = new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                T result = readInfo == null ? null : readInfo.getAnnotation(annotationClass);
+
+                if (result == null && writeMethod != null) result = writeMethod.getAnnotation(annotationClass);
+
+                return result;
+            }
+
+        };
+
+        try
+        {
+            return (PropertyConduit) conduitClass.getConstructors()[0].newInstance(propertyType, provider, description);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+    private ReadInfo buildGetter(Class rootClass, ClassFab classFab, String expression, String[] terms)
+    {
+        BodyBuilder builder = new BodyBuilder();
+
+        builder.begin();
+
+        PropertyNavigationResult result = writePropertyNavigationCode(builder, rootClass, expression, terms, false);
+
+
+        if (result == null)
+        {
+            builder.clear();
+            builder
+                    .addln("throw new RuntimeException(\"Expression %s for class %s is write-only.\");", expression,
+                           rootClass.getName());
+        }
+        else
+        {
+            builder.addln("return %s;", result.getFinalStepVariable());
+
+            builder.end();
+        }
+
+        classFab.addMethod(Modifier.PUBLIC, GET_SIGNATURE, builder.toString());
+
+
+        return result == null ? null : result.getFinalReadInfo();
+    }
+
+    /**
+     * Writes the code for navigation
+     *
+     * @param builder
+     * @param rootClass
+     * @param expression
+     * @param terms
+     * @param forSetter  if true, then the last term is not read since it will be updated
+     * @return
+     */
+    private PropertyNavigationResult writePropertyNavigationCode(BodyBuilder builder, Class rootClass,
+                                                                 String expression, String[] terms, boolean forSetter)
+    {
+        builder.addln("%s root = (%<s) $1;", ClassFabUtils.toJavaClassName(rootClass));
+        String previousStep = "root";
+
+        builder.addln(
+                "if (root == null) throw new NullPointerException(\"Root object of property expression '%s' is null.\");",
+                expression);
+
+        Class activeType = rootClass;
+        ReadInfo readInfo = null;
+
+        // For a setter method, the navigation stops with  the penultimate
+        // term in the expression (the final term is what gets updated).
+
+        int lastIndex = forSetter ? terms.length - 1 : terms.length;
+
+        for (int i = 0; i < lastIndex; i++)
+        {
+            String thisStep = "step" + (i + 1);
+            String term = terms[i];
+
+            boolean nullable = term.endsWith("?");
+            if (nullable) term = term.substring(0, term.length() - 1);
+
+            // All the navigation terms in the expression must be readable properties.
+            // The only exception is the final term in a reader method.
+
+            boolean mustExist = forSetter || i < terms.length - 1;
+
+            readInfo = readInfoForTerm(activeType, expression, term, mustExist);
+
+            // Means the property for this step exists but is write only, which is a problem!
+            // This can only happen for getter methods, we return null to indicate that
+            // the expression is write-only.
+
+            if (readInfo == null) return null;
+
+            // If a primitive type, convert to wrapper type
+
+            Class termType = readInfo.getType();
+            Class wrappedType = ClassFabUtils.getWrapperType(termType);
+
+            String termJavaName = ClassFabUtils.toJavaClassName(wrappedType);
+            builder.add("%s %s = ", termJavaName, thisStep);
+
+            // Casts are needed for primitives, and for the case where
+            // generics are involved.
+
+            if (termType.isPrimitive())
+            {
+                builder.add(" ($w) ");
+            }
+            else if (readInfo.isCastRequired())
+            {
+                builder.add(" (%s) ", termJavaName);
+            }
+
+            builder.addln("%s.%s();", previousStep, readInfo.getMethodName());
+
+            if (nullable)
+            {
+                builder.add("if (%s == null) return", thisStep);
+
+                if (!forSetter) builder.add(" null");
+
+                builder.addln(";");
+            }
+            else
+            {
+                // Perform a null check on intermediate terms.
+                if (i < lastIndex - 1)
+                {
+                    builder.addln("if (%s == null) throw new NullPointerException(%s.nullTerm(\"%s\", \"%s\", root));",
+                                  thisStep, getClass().getName(), term, expression);
+                }
+            }
+
+            activeType = wrappedType;
+            previousStep = thisStep;
+        }
+
+        final String finalStepVariable = previousStep;
+        final Class finalStepType = activeType;
+        final ReadInfo finalReadInfo = readInfo;
+
+        return new PropertyNavigationResult()
+        {
+            public String getFinalStepVariable()
+            {
+                return finalStepVariable;
+            }
+
+            public Class getFinalStepType()
+            {
+                return finalStepType;
+            }
+
+            public ReadInfo getFinalReadInfo()
+            {
+                return finalReadInfo;
+            }
+        };
+    }
+
+    private Method buildSetter(Class rootClass, ClassFab classFab, String expression, String[] terms)
+    {
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        PropertyNavigationResult result = writePropertyNavigationCode(builder, rootClass, expression, terms, true);
+
+        // Because we pass true for the forSetter parameter, we know that the expression for the leading
+        // terms is a chain of readable expressions.  But is the final term writable?
+
+        Method writeMethod = writeMethodForTerm(result.getFinalStepType(), expression, terms[terms.length - 1]);
+
+        if (writeMethod == null)
+        {
+            builder.clear();
+            builder
+                    .addln("throw new RuntimeException(\"Expression %s for class %s is read-only.\");", expression,
+                           rootClass.getName());
+            classFab.addMethod(Modifier.PUBLIC, SET_SIGNATURE, builder.toString());
+
+            return null;
+        }
+
+        Class propertyType = writeMethod.getParameterTypes()[0];
+        String propertyTypeName = ClassFabUtils.toJavaClassName(propertyType);
+
+        // Cast the parameter from Object to the expected type for the method.
+
+        builder.addln("%s value = %s;", propertyTypeName, ClassFabUtils.castReference("$2", propertyTypeName));
+
+        // Invoke the method.
+
+        builder.addln("%s.%s(value);", result.getFinalStepVariable(), writeMethod.getName());
+
+        builder.end();
+
+        classFab.addMethod(Modifier.PUBLIC, SET_SIGNATURE, builder.toString());
+
+        return writeMethod;
+    }
+
+    private Method writeMethodForTerm(Class activeType, String expression, String term)
+    {
+        if (term.endsWith(PARENS)) return null;
+
+        ClassPropertyAdapter classAdapter = access.getAdapter(activeType);
+        PropertyAdapter adapter = classAdapter.getPropertyAdapter(term);
+
+        if (adapter == null) throw new RuntimeException(
+                ServicesMessages.noSuchProperty(activeType, term, expression, classAdapter.getPropertyNames()));
+
+        return adapter.getWriteMethod();
+    }
+
+    private ReadInfo readInfoForTerm(Class activeType, String expression, String term, boolean mustExist)
+    {
+        if (term.endsWith(PARENS))
+        {
+            String methodName = term.substring(0, term.length() - PARENS.length());
+
+            try
+            {
+                final Method method = findMethod(activeType, methodName);
+
+                if (method.getReturnType().equals(void.class))
+                    throw new RuntimeException(ServicesMessages.methodIsVoid(term, activeType, expression));
+
+
+                final Class genericType = GenericsUtils.extractGenericReturnType(activeType, method);
+
+                return new ReadInfo()
+                {
+                    public String getMethodName()
+                    {
+                        return method.getName();
+                    }
+
+                    public Class getType()
+                    {
+                        return genericType;
+                    }
+
+                    public boolean isCastRequired()
+                    {
+                        return genericType != method.getReturnType();
+                    }
+
+                    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+                    {
+                        return method.getAnnotation(annotationClass);
+                    }
+                };
+
+            }
+            catch (NoSuchMethodException ex)
+            {
+                throw new RuntimeException(ServicesMessages.methodNotFound(term, activeType, expression), ex);
+            }
+
+        }
+
+        // Otherwise, just a property name.
+
+        ClassPropertyAdapter classAdapter = access.getAdapter(activeType);
+        final PropertyAdapter adapter = classAdapter.getPropertyAdapter(term);
+
+        if (adapter == null) throw new RuntimeException(
+                ServicesMessages.noSuchProperty(activeType, term, expression, classAdapter.getPropertyNames()));
+
+        if (!adapter.isRead())
+        {
+            if (mustExist) throw new RuntimeException(ServicesMessages.writeOnlyProperty(term, activeType, expression));
+
+            return null;
+        }
+
+        return new ReadInfo()
+        {
+            public String getMethodName()
+            {
+                return adapter.getReadMethod().getName();
+            }
+
+            public Class getType()
+            {
+                return adapter.getType();
+            }
+
+            public boolean isCastRequired()
+            {
+                return adapter.isCastRequired();
+            }
+
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return adapter.getAnnotation(annotationClass);
+            }
+        };
+    }
+
+    private Method findMethod(Class activeType, String methodName) throws NoSuchMethodException
+    {
+        for (Method method : activeType.getMethods())
+        {
+
+            if (method.getParameterTypes().length == 0 && method.getName().equalsIgnoreCase(methodName)) return method;
+
+        }
+
+        throw new NoSuchMethodException(ServicesMessages.noSuchMethod(activeType, methodName));
+    }
+
+    public static String nullTerm(String term, String expression, Object root)
+    {
+        return String.format("Property '%s' (within property expression '%s', of %s) is null.",
+                             term, expression, root);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java
new file mode 100644
index 0000000..78a86c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderCommandComponentEventResultProcessor.java
@@ -0,0 +1,40 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * Processor for objects that implement {@link RenderCommand} (such as {@link org.apache.tapestry.internal.structure.BlockImpl}).
+ *
+ * @see AjaxPartialResponseRenderer#renderPartialPageMarkup()
+ */
+public class RenderCommandComponentEventResultProcessor implements ComponentEventResultProcessor<RenderCommand>
+{
+    private PageRenderQueue pageRenderQueue;
+
+    public RenderCommandComponentEventResultProcessor(PageRenderQueue pageRenderQueue)
+    {
+        this.pageRenderQueue = pageRenderQueue;
+    }
+
+    public void processResultValue(RenderCommand value) throws IOException
+    {
+        pageRenderQueue.initializeForPartialPageRender(value);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java
new file mode 100644
index 0000000..9a7e826
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueException.java
@@ -0,0 +1,38 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+/**
+ * Exception used when rendering, to capture the stack of active components (for propery reporting in the exception
+ * page).
+ */
+public class RenderQueueException extends TapestryException
+{
+    private final Object[] activeComponents;
+
+    public RenderQueueException(String message, Object[] activeComponents, Throwable cause)
+    {
+        super(message, cause);
+
+        this.activeComponents = activeComponents;
+    }
+
+    public Object[] getActiveComponents()
+    {
+        return activeComponents;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
new file mode 100644
index 0000000..4056f95
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderQueueImpl.java
@@ -0,0 +1,109 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.util.Stack;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.slf4j.Logger;
+
+public class RenderQueueImpl implements RenderQueue
+{
+    private static final int INITIAL_QUEUE_DEPTH = 100;
+
+    private final Stack<RenderCommand> queue = CollectionFactory.newStack(INITIAL_QUEUE_DEPTH);
+
+    private final Stack<ComponentResources> renderingComponents = CollectionFactory.newStack();
+
+    private final Logger logger;
+
+    public RenderQueueImpl(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    public void push(RenderCommand command)
+    {
+        queue.push(command);
+    }
+
+    public void run(MarkupWriter writer)
+    {
+        RenderCommand command = null;
+
+        boolean traceEnabled = logger.isTraceEnabled();
+
+        long startNanos = System.nanoTime();
+        int commandCount = 0;
+
+        // Seems to make sense to use one try/finally around the whole process, rather than
+        // around each call to render() since the end result (in a failure scenario) is the same.
+
+        try
+        {
+            while (!queue.isEmpty())
+            {
+                command = queue.pop();
+
+                commandCount++;
+
+                if (traceEnabled) logger.trace(String.format("Executing: %s", command));
+
+                command.render(writer, this);
+            }
+        }
+        catch (RuntimeException ex)
+        {
+            // This will likely leave the page in a dirty state, and it will not go back into the
+            // page pool.
+
+            String message = ServicesMessages.renderQueueError(command, ex);
+
+            logger.error(message, ex);
+
+            throw new RenderQueueException(message, renderingComponents.getSnapshot(), ex);
+        }
+
+        long endNanos = System.nanoTime();
+
+        if (logger.isDebugEnabled())
+        {
+
+            long elapsedNanos = endNanos - startNanos;
+            double elapsedSeconds = ((float) elapsedNanos) / 1000000000F;
+
+            logger.debug(String.format("Executed %,d rendering commands in %.3f seconds",
+                                       commandCount,
+                                       elapsedSeconds));
+        }
+
+    }
+
+    public void startComponent(ComponentResources resources)
+    {
+        Defense.notNull(resources, "resources");
+
+        renderingComponents.push(resources);
+    }
+
+    public void endComponent()
+    {
+        renderingComponents.pop();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderSupportImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderSupportImpl.java
new file mode 100644
index 0000000..403b776
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RenderSupportImpl.java
@@ -0,0 +1,206 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+
+import static java.lang.String.format;
+import java.util.Arrays;
+import java.util.List;
+
+public class RenderSupportImpl implements RenderSupport
+{
+    private final IdAllocator idAllocator;
+
+    private final DocumentLinker linker;
+
+    private final SymbolSource symbolSource;
+
+    private final AssetSource assetSource;
+
+    private final List<String> coreScripts;
+
+    private boolean coreAssetsAdded;
+
+    private final JSONObject init = new JSONObject();
+
+    /**
+     * @param linker       Used to assemble JavaScript includes and snippets
+     * @param symbolSource Used to example symbols (in {@linkplain #addClasspathScriptLink(String...) in classpath
+     *                     scripts)
+     * @param assetSource  Used to convert classpath scripts to {@link org.apache.tapestry.Asset}s
+     * @param coreScripts  core scripts (evaluated as classpaths scripts) that are added to any page that includes a
+     *                     script link or script block
+     */
+    public RenderSupportImpl(DocumentLinker linker, SymbolSource symbolSource,
+                             AssetSource assetSource, String... coreScripts)
+    {
+        this(linker, symbolSource, assetSource, new IdAllocator(), coreScripts);
+    }
+
+    /**
+     * @param linker       Used to assemble JavaScript includes and snippets
+     * @param symbolSource Used to example symbols (in {@linkplain #addClasspathScriptLink(String...) in classpath
+     *                     scripts)
+     * @param assetSource  Used to convert classpath scripts to {@link org.apache.tapestry.Asset}s
+     * @param idAllocator  Used to allocate unique client ids during the render
+     * @param coreScripts  core scripts (evaluated as classpaths scripts) that are added to any page that includes a
+     *                     script link or script block
+     */
+
+    public RenderSupportImpl(DocumentLinker linker, SymbolSource symbolSource,
+                             AssetSource assetSource, IdAllocator idAllocator, String... coreScripts)
+
+    {
+        this.linker = linker;
+        this.symbolSource = symbolSource;
+        this.assetSource = assetSource;
+        this.idAllocator = idAllocator;
+
+        this.coreScripts = Arrays.asList(coreScripts);
+    }
+
+    public String allocateClientId(String id)
+    {
+        return idAllocator.allocateId(id);
+    }
+
+    public String allocateClientId(ComponentResources resources)
+    {
+        return allocateClientId(resources.getId());
+    }
+
+    public void addScriptLink(Asset... scriptAssets)
+    {
+        addCore();
+
+        for (Asset asset : scriptAssets)
+        {
+            notNull(asset, "scriptAsset");
+
+            linker.addScriptLink(asset.toClientURL());
+        }
+    }
+
+    public void addClasspathScriptLink(String... classpaths)
+    {
+        addCore();
+
+        for (String path : classpaths)
+            addScriptLinkFromClasspath(path);
+    }
+
+    private void addScriptLinkFromClasspath(String path)
+    {
+        String expanded = symbolSource.expandSymbols(path);
+
+        Asset asset = assetSource.getAsset(null, expanded, null);
+
+        linker.addScriptLink(asset.toClientURL());
+    }
+
+    public void addScript(String format, Object... arguments)
+    {
+        notNull(format, "format");
+
+        addCore();
+
+        String script = format(format, arguments);
+
+        linker.addScript(script);
+    }
+
+    public void addInit(String functionName, JSONArray parameterList)
+    {
+        addInitFunctionInvocation(functionName, parameterList);
+    }
+
+    public void addInit(String functionName, JSONObject parameter)
+    {
+        addInitFunctionInvocation(functionName, parameter);
+    }
+
+    public void addInit(String functionName, String... parameters)
+    {
+        if (parameters.length == 1)
+        {
+            addInitFunctionInvocation(functionName, parameters[0]);
+            return;
+        }
+
+        JSONArray array = new JSONArray();
+
+        for (String parameter : parameters)
+        {
+            array.put(parameter);
+        }
+
+        addInitFunctionInvocation(functionName, array);
+    }
+
+    private void addInitFunctionInvocation(String functionName, Object parameters)
+    {
+        Defense.notBlank(functionName, "functionName");
+        Defense.notNull(parameters, "parameters");
+
+        JSONArray invocations = init.has(functionName) ? init.getJSONArray(functionName) : null;
+
+        if (invocations == null)
+        {
+            invocations = new JSONArray();
+            init.put(functionName, invocations);
+        }
+
+        invocations.put(parameters);
+    }
+
+    /**
+     * Commit any outstanding changes.
+     */
+    public void commit()
+    {
+        if (init.length() > 0)
+        {
+            addScript("Tapestry.init(%s);", init);
+        }
+    }
+
+    public void addStylesheetLink(Asset stylesheet, String media)
+    {
+        notNull(stylesheet, "stylesheet");
+
+        linker.addStylesheetLink(stylesheet.toClientURL(), media);
+    }
+
+    private void addCore()
+    {
+        if (!coreAssetsAdded)
+        {
+            for (String path : coreScripts)
+                addScriptLinkFromClasspath(path);
+
+            coreAssetsAdded = true;
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestConstants.java
new file mode 100644
index 0000000..0bdbd54
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestConstants.java
@@ -0,0 +1,29 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Constants used when processing requests from the client web browser.
+ */
+public final class RequestConstants
+{
+
+    /**
+     * Request path prefix that identifies an internal (on the classpath) asset.
+     */
+    public static final String ASSET_PATH_PREFIX = "/assets/";
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializer.java
new file mode 100644
index 0000000..50a00e0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializer.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Determines the reuest encoding for the given page and applies that to the request, so that parameters may be properly
+ * decoded.
+ */
+public interface RequestEncodingInitializer
+{
+    /**
+     * Initializes the request encoding to match the encoding defined for the page.
+     *
+     * @param pageName logical name of the page
+     */
+    void initializeRequestEncoding(String pageName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImpl.java
new file mode 100644
index 0000000..6e0ebdc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImpl.java
@@ -0,0 +1,56 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.Request;
+
+public class RequestEncodingInitializerImpl implements RequestEncodingInitializer
+{
+    private final RequestPageCache cache;
+
+    private final MetaDataLocator locator;
+
+    private final Request request;
+
+    public RequestEncodingInitializerImpl(RequestPageCache cache, MetaDataLocator locator, Request request)
+    {
+        this.cache = cache;
+        this.locator = locator;
+        this.request = request;
+    }
+
+    public void initializeRequestEncoding(String pageName)
+    {
+        Page page = cache.get(pageName);
+        ComponentResources pageResources = page.getRootElement().getComponentResources();
+
+        String contentTypeString = locator.findMeta(MetaDataConstants.RESPONSE_CONTENT_TYPE, pageResources,
+                                                    String.class);
+        ContentType contentType = new ContentType(contentTypeString);
+
+        String encoding = contentType.getParameter("charset");
+
+        if (encoding == null)
+            encoding = locator.findMeta(MetaDataConstants.RESPONSE_ENCODING, pageResources, String.class);
+
+        request.setEncoding(encoding);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java
new file mode 100644
index 0000000..784ab31
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestErrorFilter.java
@@ -0,0 +1,94 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+/**
+ * Filter for the {@link org.apache.tapestry.services.RequestHandler} pipeline used to intercept and report exceptions.
+ */
+public class RequestErrorFilter implements RequestFilter
+{
+    private final InternalRequestGlobals internalRequestGlobals;
+    private final RequestExceptionHandler exceptionHandler;
+
+    public RequestErrorFilter(InternalRequestGlobals internalRequestGlobals, RequestExceptionHandler exceptionHandler)
+    {
+        this.internalRequestGlobals = internalRequestGlobals;
+        this.exceptionHandler = exceptionHandler;
+    }
+
+    public boolean service(Request request, Response response, RequestHandler handler) throws IOException
+    {
+        try
+        {
+            return handler.service(request, response);
+        }
+        catch (IOException ex)
+        {
+            // Pass it through.
+            throw ex;
+        }
+        catch (Throwable ex)
+        {
+            // Most of the time, we've got exception linked up the kazoo ... but when ClassLoaders
+            // get involved, things go screwy.  Exceptions when transforming classes can cause
+            // a NoClassDefFoundError with no cause; here we're trying to link the cause back in.
+            // TAPESTRY-2078
+
+            Throwable exceptionToReport = attachNewCause(ex, internalRequestGlobals.getClassLoaderException());
+
+            exceptionHandler.handleRequestException(exceptionToReport);
+
+            // We assume a reponse has been sent and there's no need to handle the request
+            // further.
+
+            return true;
+        }
+    }
+
+    private Throwable attachNewCause(Throwable exception, Throwable underlyingCause)
+    {
+        if (underlyingCause == null) return exception;
+
+        Throwable current = exception;
+
+        while (current != null)
+        {
+
+            if (current == underlyingCause) return exception;
+
+            Throwable cause = current.getCause();
+
+            // Often, exceptions report themselves as their own cause.
+
+            if (current == cause) break;
+
+            if (cause == null)
+            {
+
+                try
+                {
+                    current.initCause(underlyingCause);
+
+                    return exception;
+                }
+                catch (IllegalStateException ex)
+                {
+                    // TAPESTRY-2284: sometimes you just can't init the cause, and there's no way to
+                    // find out without trying.
+
+                }
+            }
+
+            // Otherwise, continue working down the chain until we find a place where we can attach
+
+            current = cause;
+        }
+
+        // Found no place to report the exeption, so report the underlying cause (and lose out
+        // on all the other context).
+
+        return underlyingCause;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestGlobalsImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestGlobalsImpl.java
new file mode 100644
index 0000000..e883d34
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestGlobalsImpl.java
@@ -0,0 +1,72 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry5.services.RequestGlobals;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Dumb data holder for per-request data.
+ */
+@Scope(PERTHREAD_SCOPE)
+public class RequestGlobalsImpl implements RequestGlobals
+{
+    private HttpServletRequest servletRequest;
+
+    private HttpServletResponse servletResponse;
+
+    private Request request;
+
+    private Response response;
+
+    public void storeServletRequestResponse(HttpServletRequest request, HttpServletResponse response)
+    {
+        servletRequest = request;
+        servletResponse = response;
+    }
+
+    public HttpServletRequest getHTTPServletRequest()
+    {
+        return servletRequest;
+    }
+
+    public HttpServletResponse getHTTPServletResponse()
+    {
+        return servletResponse;
+    }
+
+    public void storeRequestResponse(Request request, Response response)
+    {
+        this.request = request;
+        this.response = response;
+    }
+
+    public Request getRequest()
+    {
+        return request;
+    }
+
+    public Response getResponse()
+    {
+        return response;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestImpl.java
new file mode 100644
index 0000000..52a5ed9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestImpl.java
@@ -0,0 +1,144 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Basic implementation of {@link org.apache.tapestry.services.Request} that wraps around an {@link
+ * javax.servlet.http.HttpServletRequest}.
+ */
+public class RequestImpl implements Request
+{
+    static final String REQUESTED_WITH_HEADER = "X-Requested-With";
+
+    static final String XML_HTTP_REQUEST = "XMLHttpRequest";
+
+    private final HttpServletRequest request;
+
+    public RequestImpl(HttpServletRequest request)
+    {
+        this.request = request;
+    }
+
+    public List<String> getParameterNames()
+    {
+        return InternalUtils.toList(request.getParameterNames());
+    }
+
+    public List<String> getHeaderNames()
+    {
+        return InternalUtils.toList(request.getHeaderNames());
+    }
+
+    public String getParameter(String name)
+    {
+        return request.getParameter(name);
+    }
+
+    public String[] getParameters(String name)
+    {
+        return request.getParameterValues(name);
+    }
+
+    public String getHeader(String name)
+    {
+        return request.getHeader(name);
+    }
+
+    public String getPath()
+    {
+        String pathInfo = request.getPathInfo();
+
+        if (pathInfo == null) return request.getServletPath();
+
+        // Websphere 6.1 is a bit wonky (see TAPESTRY-1713), and tends to return the empty string
+        // for the servlet path, and return the true path in pathInfo.
+
+        return pathInfo.length() == 0 ? "/" : pathInfo;
+    }
+
+    public String getContextPath()
+    {
+        return request.getContextPath();
+    }
+
+    public Session getSession(boolean create)
+    {
+        HttpSession session = request.getSession(create);
+
+        return session == null ? null : new SessionImpl(session);
+    }
+
+    public Locale getLocale()
+    {
+        return request.getLocale();
+    }
+
+    public long getDateHeader(String name)
+    {
+        return request.getDateHeader(name);
+    }
+
+    public void setEncoding(String requestEncoding)
+    {
+        try
+        {
+            request.setCharacterEncoding(requestEncoding);
+        }
+        catch (UnsupportedEncodingException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public boolean isXHR()
+    {
+        return XML_HTTP_REQUEST.equals(request.getHeader(REQUESTED_WITH_HEADER));
+    }
+
+    public boolean isSecure()
+    {
+        return request.isSecure();
+    }
+
+    public boolean isRequestedSessionIdValid()
+    {
+        return request.isRequestedSessionIdValid();
+    }
+
+    public Object getAttribute(String name)
+    {
+        return request.getAttribute(name);
+    }
+
+    public void setAttribute(String name, Object value)
+    {
+        request.setAttribute(name, value);
+    }
+
+    public String getServerName()
+    {
+        return request.getServerName();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
new file mode 100644
index 0000000..d76b3d6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * Per-thread service that caches page instances for the duration of the request, and is also responsible for tracking
+ * the active page (the page which will ultimately render the response).
+ * <p/>
+ * <p/>
+ * Since {@link org.apache.tapestry.internal.structure.Page} is internal, most user-code should use the {@link
+ * org.apache.tapestry.services.ComponentSource} service instead.
+ */
+public interface RequestPageCache
+{
+    /**
+     * Gets the page via its page name, in the current locale. The page name is resolved to a class name, which is used
+     * to obtain the page (from the page pool).
+     *
+     * @param logicalPageName the name of the page to retrieve (this is the logical page name, not the fully qualified
+     *                        class name)
+     * @return a page instance reserved for this request
+     * @throws IllegalArgumentException if the name can not be resolved to a page instance
+     */
+    Page get(String logicalPageName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
new file mode 100644
index 0000000..c58f0eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
@@ -0,0 +1,62 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+
+import java.util.Map;
+
+public class RequestPageCacheImpl implements RequestPageCache, ThreadCleanupListener
+{
+    private final PagePool pagePool;
+
+    /**
+     * Keyed on logical page name (case insensitive).
+     */
+    private final Map<String, Page> cache = CollectionFactory.newCaseInsensitiveMap();
+
+    public RequestPageCacheImpl(PagePool pagePool)
+    {
+        this.pagePool = pagePool;
+    }
+
+    public Page get(String logicalPageName)
+    {
+        Page page = cache.get(logicalPageName);
+
+        if (page == null)
+        {
+            page = pagePool.checkout(logicalPageName);
+
+            page.attached();
+
+            cache.put(logicalPageName, page);
+        }
+
+        return page;
+    }
+
+    /**
+     * At the end of the request, when the thread cleanup event occurs, release any pages attached to the request back
+     * to the page pool.
+     */
+    public void threadDidCleanup()
+    {
+        for (Page p : cache.values())
+            pagePool.release(p);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizer.java
new file mode 100644
index 0000000..831c910
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizer.java
@@ -0,0 +1,37 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Used to optimize a path for inclusion in the rendered output of the page. When using lots of libraries, nested
+ * folders, and page acivation contexts, you can often create a shorter URL as a relative path from the current request
+ * URL.  Of course, you need to make sure that's turned off inside an Ajax request since the base URL of the client it
+ * totally unknown in that situation.
+ *
+ * @see org.apache.tapestry.SymbolConstants#FORCE_ABSOLUTE_URIS
+ */
+public interface RequestPathOptimizer
+{
+    /**
+     * Optimizes the provided path, returning a new path that is shorter but (combined with the current requests' base
+     * URL) will result in the same request URI.  In many cases, this will return the provided path unchanged. During
+     * {@linkplain org.apache.tapestry.services.Request#isXHR() XHR} requests, this will always return the provided path
+     * (no optimization takes place, since the base URI of the client is unknown).
+     *
+     * @param path to be optimized
+     * @return the same path, or a new path that is equivalent, relative to the current request's URL
+     */
+    String optimizePath(String path);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizerImpl.java
new file mode 100644
index 0000000..1b2f555
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestPathOptimizerImpl.java
@@ -0,0 +1,132 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.services.Request;
+
+import java.util.regex.Pattern;
+
+public class RequestPathOptimizerImpl implements RequestPathOptimizer
+{
+    private final Request request;
+
+    private final boolean forceAbsolute;
+
+    /**
+     * Used to split a URI up into individual folder/file names. Any number of consecutive slashes is treated as a
+     * single slash.
+     */
+    private final Pattern SLASH_PATTERN = Pattern.compile("/+");
+
+    public RequestPathOptimizerImpl(Request request,
+
+                                    @Symbol(SymbolConstants.FORCE_ABSOLUTE_URIS)
+                                    boolean forceAbsolute)
+    {
+        this.request = request;
+
+        this.forceAbsolute = forceAbsolute;
+    }
+
+    public String optimizePath(String absolutePath)
+    {
+        if (forceAbsolute || request.isXHR()) return absolutePath;
+
+        String requestPath = request.getPath();
+
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(request.getContextPath());
+
+        builder.append(requestPath);
+
+        String requestURI = builder.toString();
+
+        String[] requestTerms = SLASH_PATTERN.split(requestURI);
+
+        // Degenerate case when getting the root application
+
+        if (requestPath.endsWith("/") || requestPath.equals("")) requestTerms = add(requestTerms, "");
+
+        String[] pathTerms = SLASH_PATTERN.split(absolutePath);
+
+        builder.setLength(0);
+
+        int i = 0;
+        while (true)
+        {
+
+            if (i >= requestTerms.length - 1) break;
+
+            if (i >= pathTerms.length - 1) break;
+
+            if (!requestTerms[i].equals(pathTerms[i])) break;
+
+            i++;
+        }
+
+        // Found the point of divergence.
+
+        for (int j = i; j < requestTerms.length - 1; j++)
+        {
+            builder.append("../");
+        }
+
+        String sep = "";
+
+        for (int j = i; j < pathTerms.length; j++)
+        {
+            builder.append(sep);
+
+            builder.append(pathTerms[j]);
+
+            sep = "/";
+        }
+
+        // A colon before the first slash confuses the browser; it thinks its a really long
+        // protocol specifier (like "http:").
+
+        int firstColon = builder.indexOf(":");
+        if (firstColon > 0)
+        {
+            int slashx = builder.indexOf("/");
+
+            // Prefixing with "./" disambiguates the path and the colon, though
+            // most likely we're going to end up choosing the full path rather than
+            // the relative one.
+
+            if (slashx < 0 || slashx > firstColon) builder.insert(0, "./");
+        }
+
+        if (builder.length() < absolutePath.length()) return builder.toString();
+
+        // The absolute path is actually shorter than the relative path, so just return the absolute
+        // path.
+
+        return absolutePath;
+    }
+
+    private String[] add(String[] array, String s)
+    {
+        String[] newArray = new String[array.length + 1];
+
+        System.arraycopy(array, 0, newArray, 0, array.length);
+        newArray[array.length] = s;
+
+        return newArray;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManager.java
new file mode 100644
index 0000000..effa027
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManager.java
@@ -0,0 +1,48 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+import java.io.IOException;
+
+/**
+ * Used to manage the relationship between the security of a request and the security of a page. By secure, we mean
+ * whether a request uses HTTPS and whether a page demands the use of HTTPS.
+ *
+ * @see org.apache.tapestry.services.Request#isSecure()
+ */
+public interface RequestSecurityManager
+{
+    /**
+     * Checks the page to see if it is secure; if so, and the request is not secure, then a redirect to the page is
+     * generated and sent.
+     *
+     * @param pageName page for the current request
+     * @return true if a redirect was sent, false if normal processing should continue
+     * @throws IOException
+     */
+    boolean checkForInsecureRequest(String pageName) throws IOException;
+
+    /**
+     * Determines if the page security does not match the request's security. If so, returns a base URL (to which the
+     * context path and servlet path may be appended).
+     *
+     * @param page for the security check
+     * @return a base URL when switching security levels, or null if the page's security matches the request security
+     * @see org.apache.tapestry.services.BaseURLSource#getBaseURL(boolean)
+     */
+    String getBaseURL(Page page);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManagerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManagerImpl.java
new file mode 100644
index 0000000..22183b9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RequestSecurityManagerImpl.java
@@ -0,0 +1,86 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.BaseURLSource;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+
+import java.io.IOException;
+
+public class RequestSecurityManagerImpl implements RequestSecurityManager
+{
+    private final Request request;
+
+    private final Response response;
+
+    private final LinkFactory linkFactory;
+
+    private final MetaDataLocator locator;
+
+    private final BaseURLSource baseURLSource;
+
+    private final RequestPageCache requestPageCache;
+
+    public RequestSecurityManagerImpl(Request request, Response response, LinkFactory linkFactory,
+                                      MetaDataLocator locator, BaseURLSource baseURLSource,
+                                      RequestPageCache requestPageCache)
+    {
+        this.request = request;
+        this.response = response;
+        this.linkFactory = linkFactory;
+        this.locator = locator;
+        this.baseURLSource = baseURLSource;
+        this.requestPageCache = requestPageCache;
+    }
+
+    public boolean checkForInsecureRequest(String pageName) throws IOException
+    {
+        // We don't (at this time) redirect from secure to insecure, just form insecure to secure.
+
+        if (request.isSecure()) return false;
+
+        Page page = requestPageCache.get(pageName);
+
+        if (!isSecure(page)) return false;
+
+        // Page is secure but request is not, so redirect.
+
+        Link link = linkFactory.createPageLink(page, false);
+
+        response.sendRedirect(link);
+
+        return true;
+    }
+
+    private boolean isSecure(Page page)
+    {
+        return locator.findMeta(MetaDataConstants.SECURE_PAGE,
+                                page.getRootComponent().getComponentResources(), Boolean.class);
+    }
+
+    public String getBaseURL(Page page)
+    {
+        boolean securePage = isSecure(page);
+
+        if (securePage == request.isSecure()) return null;
+
+        return baseURLSource.getBaseURL(securePage);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCache.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCache.java
new file mode 100644
index 0000000..cf43fd2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCache.java
@@ -0,0 +1,53 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.services.ResourceDigestGenerator;
+
+/**
+ * Caches information about resources on the classpath. In addition, acts as an invalidation hub for any resources for
+ * which information is obtained (when any of the resources are changed, invalidation listeners are notified so they can
+ * clear their caches).
+ */
+public interface ResourceCache extends InvalidationEventHub
+{
+    /**
+     * Returns true if the path requires that the client URL for the resource include a digest to validate that the
+     * client is authorized to access the resource.
+     *
+     * @param resource
+     * @return true if digest is required for the resource
+     * @see ResourceDigestGenerator#requiresDigest(String)
+     */
+    boolean requiresDigest(Resource resource);
+
+    /**
+     * Returns the digest for the given path.
+     *
+     * @param resource
+     * @return the digest, or null if the resource does not exist
+     */
+    String getDigest(Resource resource);
+
+    /**
+     * Returns the time modified for the resource.
+     *
+     * @param resource
+     * @return the date time modified for the path, or a negative value if the resource does not exist
+     */
+    long getTimeModified(Resource resource);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCacheImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCacheImpl.java
new file mode 100644
index 0000000..cc39fba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceCacheImpl.java
@@ -0,0 +1,110 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.ResourceDigestGenerator;
+
+import java.net.URL;
+import java.util.Map;
+
+public class ResourceCacheImpl extends InvalidationEventHubImpl implements ResourceCache,
+        UpdateListener
+{
+    private final URLChangeTracker tracker;
+
+    private final ResourceDigestGenerator digestGenerator;
+
+    private final Map<Resource, Cached> cache = CollectionFactory.newConcurrentMap();
+
+    final static long MISSING_RESOURCE_TIME_MODIFIED = -1L;
+
+    private class Cached
+    {
+        final boolean requiresDigest;
+
+        final String digest;
+
+        final long timeModified;
+
+        Cached(Resource resource)
+        {
+            requiresDigest = digestGenerator.requiresDigest(resource.getPath());
+
+            URL url = resource.toURL();
+
+            // The url may be null when a request for a protected asset arrives, because the
+            // Resource initially is for the file with the digest incorporated into the path, which
+            // means
+            // no underlying file exists. Subsequently, we'll strip out the digest and resolve
+            // to an actual resource.
+
+            digest = (requiresDigest && url != null) ? digestGenerator.generateDigest(url)
+                     : null;
+
+            timeModified = url != null ? tracker.add(url) : MISSING_RESOURCE_TIME_MODIFIED;
+        }
+    }
+
+    public ResourceCacheImpl(final ResourceDigestGenerator digestGenerator)
+    {
+        this.digestGenerator = digestGenerator;
+        tracker = new URLChangeTracker(true);
+    }
+
+    public void checkForUpdates()
+    {
+        if (tracker.containsChanges())
+        {
+            cache.clear();
+            tracker.clear();
+
+            fireInvalidationEvent();
+        }
+    }
+
+    private Cached get(Resource resource)
+    {
+        Cached result = cache.get(resource);
+
+        if (result == null)
+        {
+            result = new Cached(resource);
+            cache.put(resource, result);
+        }
+
+        return result;
+    }
+
+    public String getDigest(Resource resource)
+    {
+        return get(resource).digest;
+    }
+
+    public long getTimeModified(Resource resource)
+    {
+        return get(resource).timeModified;
+    }
+
+    public boolean requiresDigest(Resource resource)
+    {
+        return get(resource).requiresDigest;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImpl.java
new file mode 100644
index 0000000..118698b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImpl.java
@@ -0,0 +1,99 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.ResourceDigestGenerator;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Implementation of {@link ResourceDigestGenerator} that generates MD5 digests.
+ */
+public class ResourceDigestGeneratorImpl implements ResourceDigestGenerator
+{
+    private static final int BUFFER_SIZE = 5000;
+
+    private final Set<String> digestExtensions;
+
+    public ResourceDigestGeneratorImpl(Collection<String> configuration)
+    {
+        digestExtensions = CollectionFactory.newSet(configuration);
+    }
+
+    public String generateDigest(URL url)
+    {
+        InputStream stream = null;
+
+        try
+        {
+            MessageDigest digest = MessageDigest.getInstance("MD5");
+
+            stream = new BufferedInputStream(url.openStream());
+
+            digestStream(digest, stream);
+
+            stream.close();
+            stream = null;
+
+            byte[] bytes = digest.digest();
+            char[] encoded = Hex.encodeHex(bytes);
+
+            return new String(encoded);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        finally
+        {
+            InternalUtils.close(stream);
+        }
+    }
+
+    private void digestStream(MessageDigest digest, InputStream stream) throws IOException
+    {
+        byte[] buffer = new byte[BUFFER_SIZE];
+
+        while (true)
+        {
+            int length = stream.read(buffer);
+
+            if (length < 0) return;
+
+            digest.update(buffer, 0, length);
+        }
+    }
+
+    /**
+     * Current implementation is based on the path extension, and a configured list of extensions.
+     */
+    public boolean requiresDigest(String path)
+    {
+        int dotx = path.lastIndexOf('.');
+        String extension = path.substring(dotx + 1).toLowerCase();
+
+        return digestExtensions.contains(extension);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamer.java
new file mode 100644
index 0000000..cb34acc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamer.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+
+import java.io.IOException;
+
+/**
+ * Responsible for streaming the contents of a resource to the client. The {@link Resource} to stream is almost always a
+ * {@link ClasspathResource}.
+ */
+public interface ResourceStreamer
+{
+    /**
+     * Streams the content of the resource to the client.
+     */
+    void streamResource(Resource resource) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamerImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamerImpl.java
new file mode 100644
index 0000000..8ab5d1a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResourceStreamerImpl.java
@@ -0,0 +1,115 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.TimeInterval;
+import org.apache.tapestry.services.Response;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+public class ResourceStreamerImpl implements ResourceStreamer
+{
+    private static final long TEN_YEARS = new TimeInterval("10y").milliseconds();
+
+    private static final int BUFFER_SIZE = 5000;
+
+    private final Response response;
+
+    private final Map<String, String> configuration;
+
+    public ResourceStreamerImpl(final Response response, Map<String, String> configuration)
+    {
+        this.response = response;
+        this.configuration = configuration;
+    }
+
+    public void streamResource(Resource resource) throws IOException
+    {
+        URL url = resource.toURL();
+
+        URLConnection connection = url.openConnection();
+
+        int contentLength = connection.getContentLength();
+
+        if (contentLength >= 0) response.setContentLength(contentLength);
+
+        // Could get this from the ResourceCache, but can't imagine
+        // it's very expensive.
+
+        long lastModified = connection.getLastModified();
+
+        response.setDateHeader("Last-Modified", lastModified);
+        response.setDateHeader("Expires", lastModified + TEN_YEARS);
+
+        String contentType = connection.getContentType();
+
+        if ("content/unknown".equals(contentType)) contentType = null;
+
+        if (contentType == null)
+        {
+            String file = resource.getFile();
+            int dotx = file.lastIndexOf('.');
+
+            if (dotx > 0)
+            {
+                String extension = file.substring(dotx + 1);
+
+                contentType = configuration.get(extension);
+            }
+
+            if (contentType == null) contentType = "application/octet-stream";
+        }
+
+        InputStream is = null;
+
+        try
+        {
+            connection.connect();
+
+            is = new BufferedInputStream(connection.getInputStream());
+
+            OutputStream os = response.getOutputStream(contentType);
+
+            byte[] buffer = new byte[BUFFER_SIZE];
+
+            while (true)
+            {
+                int length = is.read(buffer);
+
+                if (length < 0) break;
+
+                os.write(buffer, 0, length);
+            }
+
+            is.close();
+            is = null;
+
+            os.flush();
+        }
+        finally
+        {
+            InternalUtils.close(is);
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseImpl.java
new file mode 100644
index 0000000..5c85483
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseImpl.java
@@ -0,0 +1,112 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.services.Response;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+/**
+ * Implementation of {@link Response} that wraps around an underlying {@link HttpServletResponse}.
+ */
+public class ResponseImpl implements Response
+{
+    private final HttpServletResponse response;
+
+    public ResponseImpl(HttpServletResponse response)
+    {
+        Defense.notNull(response, "response");
+
+        this.response = response;
+    }
+
+    public PrintWriter getPrintWriter(String contentType) throws IOException
+    {
+        notBlank(contentType, "contentType");
+
+        response.setContentType(contentType);
+
+        return response.getWriter();
+    }
+
+    public String encodeURL(String URL)
+    {
+        return response.encodeURL(URL);
+    }
+
+    public String encodeRedirectURL(String URL)
+    {
+        return response.encodeRedirectURL(URL);
+    }
+
+    public void sendRedirect(String URL) throws IOException
+    {
+        response.sendRedirect(URL);
+    }
+
+    public void sendRedirect(Link link) throws IOException
+    {
+        Defense.notNull(link, "link");
+
+        String redirectURL = encodeRedirectURL(link.toRedirectURI());
+
+        sendRedirect(redirectURL);
+    }
+
+    public OutputStream getOutputStream(String contentType) throws IOException
+    {
+        notBlank(contentType, "contentType");
+
+        response.setContentType(contentType);
+
+        return response.getOutputStream();
+    }
+
+    public void sendError(int sc, String message) throws IOException
+    {
+        response.sendError(sc, message);
+    }
+
+    public void setContentLength(int length)
+    {
+        response.setContentLength(length);
+    }
+
+    public void setDateHeader(String name, long date)
+    {
+        response.setDateHeader(name, date);
+    }
+
+    public void setHeader(String name, String value)
+    {
+        response.setHeader(name, value);
+    }
+
+    public void setIntHeader(String name, int value)
+    {
+        response.setIntHeader(name, value);
+    }
+
+    public boolean isCommitted()
+    {
+        return response.isCommitted();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRenderer.java
new file mode 100644
index 0000000..693be63
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRenderer.java
@@ -0,0 +1,42 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+
+import java.io.IOException;
+
+/**
+ * Public facade around internal services related to rendering a markup response.
+ */
+public interface ResponseRenderer
+{
+    /**
+     * Renders a markup response by rendering the named page.
+     *
+     * @param pageName logical name of page to provide the markup
+     */
+    void renderPageMarkupResponse(String pageName) throws IOException;
+
+
+    /**
+     * Finds the content type for the page containing the indicated component.
+     *
+     * @param component a component within a page
+     * @return the content type
+     * @throws IllegalArgumentException if the component parameter is not a component
+     */
+    ContentType findContentType(Object component);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRendererImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRendererImpl.java
new file mode 100644
index 0000000..a472e60
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ResponseRendererImpl.java
@@ -0,0 +1,57 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.runtime.Component;
+
+import java.io.IOException;
+
+public class ResponseRendererImpl implements ResponseRenderer
+{
+    private final RequestPageCache pageCache;
+
+    private final PageContentTypeAnalyzer pageContentAnalyzer;
+
+    private final PageResponseRenderer renderer;
+
+    public ResponseRendererImpl(RequestPageCache pageCache, PageContentTypeAnalyzer pageContentAnalyzer,
+                                PageResponseRenderer renderer)
+    {
+        this.pageCache = pageCache;
+        this.pageContentAnalyzer = pageContentAnalyzer;
+        this.renderer = renderer;
+    }
+
+    public ContentType findContentType(Object component)
+    {
+        Component c = Defense.cast(component, Component.class, "component");
+
+        String pageName = c.getComponentResources().getPageName();
+
+        Page page = pageCache.get(pageName);
+
+        return pageContentAnalyzer.findContentType(page);
+    }
+
+    public void renderPageMarkupResponse(String pageName) throws IOException
+    {
+        Page page = pageCache.get(pageName);
+
+        renderer.renderPageResponse(page);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java
new file mode 100644
index 0000000..834fdaa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/RootPathDispatcher.java
@@ -0,0 +1,69 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.EmptyEventContext;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+
+/**
+ * Recognizes a request for the application root (i.e., "/") and handles this the same as a render request for the
+ * "Start" page.    Support for the Start page is kept for legacy purposes, Index pages are the correct approach.
+ */
+public class RootPathDispatcher implements Dispatcher
+{
+    private static final EventContext EMPTY_CONTEXT = new EmptyEventContext();
+
+    private final ComponentClassResolver componentClassResolver;
+
+    private final PageRenderRequestHandler handler;
+
+    private final String startPageName;
+
+    private final PageRenderRequestParameters parameters;
+
+    public RootPathDispatcher(ComponentClassResolver componentClassResolver,
+
+                              PageRenderRequestHandler handler,
+
+                              @Inject @Symbol("tapestry.start-page-name")
+                              String startPageName)
+    {
+        this.componentClassResolver = componentClassResolver;
+        this.handler = handler;
+        this.startPageName = startPageName;
+
+        parameters = new PageRenderRequestParameters(this.startPageName, EMPTY_CONTEXT);
+    }
+
+    public boolean dispatch(Request request, final Response response) throws IOException
+    {
+        // Only match the root path
+
+        if (request.getPath().equals("/") && componentClassResolver.isPageName(startPageName))
+        {
+            handler.handle(parameters);
+
+            return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProvider.java
new file mode 100644
index 0000000..b8b5e9f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProvider.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotation.Service;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+
+/**
+ * Adds support for the {@link Service} annotation (which can be applied to fields or parameters), which is used to
+ * disambiguate injection when multiple services implement the same service interface.
+ */
+public class ServiceAnnotationObjectProvider implements ObjectProvider
+{
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
+                         ObjectLocator locator)
+    {
+        Service annotation = annotationProvider.getAnnotation(Service.class);
+
+        if (annotation == null) return null;
+
+        return locator.getService(annotation.value(), objectType);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java
new file mode 100644
index 0000000..c9eeed8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServiceInjectionProvider.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+
+/**
+ * A very late worker related to the {@link Inject} annotation that, when all other forms of injection have failed,
+ * matches the field type to a service interface.
+ */
+public class ServiceInjectionProvider implements InjectionProvider
+{
+    private final ObjectLocator locator;
+
+    public ServiceInjectionProvider(ObjectLocator locator)
+    {
+        this.locator = locator;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                                    ClassTransformation transformation, MutableComponentModel componentModel)
+    {
+        Object inject = this.locator.getService(fieldType);
+
+        assert inject != null;
+
+        transformation.injectField(fieldName, inject);
+
+        // If we make it this far without an exception, then we were successful
+        // and should claim the field.
+
+        return true;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
new file mode 100644
index 0000000..74c4f62
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
@@ -0,0 +1,412 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.CtClass;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+
+class ServicesMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(ServicesMessages.class);
+
+    static String duplicateContribution(Object conflict, Class contributionType, Object existing)
+    {
+        return MESSAGES.format("duplicate-contribution", conflict, contributionType.getName(), existing);
+    }
+
+    static String markupWriterNoCurrentElement()
+    {
+        return MESSAGES.get("markup-writer-no-current-element");
+    }
+
+    static String noConstructorFound(Class instanceClass)
+    {
+        return MESSAGES.format("no-constructor-found", instanceClass.getName());
+    }
+
+    static String missingDeclaredField(CtClass ctClass, String fieldName)
+    {
+        return MESSAGES.format("missing-declared-field", ctClass.getName(), fieldName);
+    }
+
+    static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
+    {
+        return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
+    }
+
+    static String fieldAlreadyClaimed(String fieldName, CtClass ctClass, Object existingTag, Object newTag)
+    {
+        return MESSAGES.format("field-already-claimed", fieldName, ctClass.getName(), existingTag, newTag);
+    }
+
+    static String noDeclaredMethod(CtClass ctClass, TransformMethodSignature methodSignature)
+    {
+        return MESSAGES.format("no-declared-method", ctClass.getName(), methodSignature);
+    }
+
+    static String classNotTransformed(String className)
+    {
+        return MESSAGES.format("class-not-transformed", className);
+    }
+
+    static String newParserError(Resource resource, Throwable cause)
+    {
+        return MESSAGES.format("new-parser-error", resource, cause);
+    }
+
+    static String missingTemplateResource(Resource resource)
+    {
+        return MESSAGES.format("missing-template-resource", resource);
+    }
+
+    static String templateParseError(Resource resource, Throwable cause)
+    {
+        return MESSAGES.format("template-parse-error", resource, cause);
+    }
+
+    static String contentInsideBodyNotAllowed(Location location)
+    {
+        return MESSAGES.format("content-inside-body-not-allowed", location);
+    }
+
+    static String mayNotNestElementsInsideBody(String elementName)
+    {
+        return MESSAGES.format("may-not-nest-elements-inside-body", elementName);
+    }
+
+    static String methodCompileError(TransformMethodSignature signature, String methodBody, Throwable cause)
+    {
+        return MESSAGES.format("method-compile-error", signature, methodBody, cause);
+    }
+
+    static String renderQueueError(RenderCommand command, Throwable cause)
+    {
+        return MESSAGES.format("render-queue-error", command, cause);
+    }
+
+    static String readOnlyField(String className, String fieldName)
+    {
+        return MESSAGES.format("read-only-field", className, fieldName);
+    }
+
+    static String nonPrivateFields(String className, List<String> names)
+    {
+        return MESSAGES.format("non-private-fields", className, InternalUtils.joinSorted(names));
+    }
+
+    static String compTypeConflict(String embeddedId, String templateType, String modelType)
+    {
+        return MESSAGES.format("comp-type-conflict", embeddedId, templateType, modelType);
+    }
+
+    static String noTypeForEmbeddedComponent(String embeddedId, String componentClassName)
+    {
+        return MESSAGES.format("no-type-for-embedded-component", embeddedId, componentClassName);
+    }
+
+    static String embeddedComponentsNotInTemplate(Collection<String> ids, String componentClassName)
+    {
+        return MESSAGES.format("embedded-components-not-in-template", InternalUtils.joinSorted(ids),
+                               componentClassName);
+    }
+
+    static String bindingSourceFailure(String expression, Throwable cause)
+    {
+        return MESSAGES.format("binding-source-failure", expression, cause);
+    }
+
+    static String contextIndexOutOfRange(String methodDescription)
+    {
+        return MESSAGES.format("context-index-out-of-range", methodDescription);
+    }
+
+    static String pageNameUnresolved(String pageClassName)
+    {
+        return MESSAGES.format("page-name-unresolved", pageClassName);
+    }
+
+    static String exceptionInMethodParameter(String methodDescription, int index, Throwable cause)
+    {
+        return MESSAGES
+                .format("exception-in-method-parameter", methodDescription, index + 1, cause);
+    }
+
+    static String componentEventIsAborted(String methodDescription)
+    {
+        return MESSAGES.format("component-event-is-aborted", methodDescription);
+    }
+
+    static String unknownPersistentFieldStrategy(String stategyName, Collection<String> strategyNames)
+    {
+        return MESSAGES.format("unknown-persistent-field-strategy", stategyName, InternalUtils
+                .joinSorted(strategyNames));
+    }
+
+    static String couldNotResolvePageName(String pageName, Collection<String> pageNames)
+    {
+        return MESSAGES.format("could-not-resolve-page-name", pageName, InternalUtils
+                .joinSorted(pageNames));
+    }
+
+    static String couldNotCanonicalizePageName(String pageName, Collection<String> pageNames)
+    {
+        return MESSAGES.format("could-not-canonicalize-page-name", pageName, InternalUtils
+                .joinSorted(pageNames));
+    }
+
+    static String couldNotResolveComponentType(String componentType, Collection<String> componentTypes)
+    {
+        return MESSAGES.format("could-not-resolve-component-type", componentType, InternalUtils
+                .joinSorted(componentTypes));
+    }
+
+    static String couldNotResolveMixinType(String mixinType, Collection<String> mixinTypes)
+    {
+        return MESSAGES.format("could-not-resolve-mixin-type", mixinType, InternalUtils
+                .joinSorted(mixinTypes));
+    }
+
+    static String parameterNameMustBeUnique(String parameterName, String parameterValue)
+    {
+        return MESSAGES.format("parameter-name-must-be-unique", parameterName, parameterValue);
+    }
+
+    static String pageIsDirty(Object page)
+    {
+        return MESSAGES.format("page-is-dirty", page);
+    }
+
+    static String componentInstanceIsNotAPage(Component result)
+    {
+        return MESSAGES.format("component-instance-is-not-a-page", result.getComponentResources()
+                .getCompleteId());
+    }
+
+    static String failureReadingMessages(Resource url, Throwable cause)
+    {
+        return MESSAGES.format("failure-reading-messages", url, cause);
+    }
+
+    static String unknownAssetPrefix(String path)
+    {
+        return MESSAGES.format("unknown-asset-prefix", path);
+    }
+
+    static String assetDoesNotExist(Resource resource)
+    {
+        return MESSAGES.format("asset-does-not-exist", resource);
+    }
+
+    static String wrongAssetDigest(Resource resource)
+    {
+        return MESSAGES.format("wrong-asset-digest", resource.getPath());
+    }
+
+
+    static String unknownValidatorType(String validatorType, List<String> knownValidatorTypes)
+    {
+        return MESSAGES.format("unknown-validator-type", validatorType, InternalUtils
+                .join(knownValidatorTypes));
+    }
+
+    static String unknownTranslatorType(String translatorType, List<String> knownTranslatorTypes)
+    {
+        return MESSAGES.format("unknown-translator-type", translatorType, InternalUtils
+                .join(knownTranslatorTypes));
+    }
+
+    static String validatorSpecificationParseError(int cursor, String specification)
+    {
+        return MESSAGES.format("validator-specification-parse-error", specification.charAt(cursor), cursor + 1,
+                               specification);
+    }
+
+    static String mixinsInvalidWithoutIdOrType(String elementName)
+    {
+        return MESSAGES.format("mixins-invalid-without-id-or-type", elementName);
+    }
+
+    static String missingFromEnvironment(Class type, Collection<Class> availableTypes)
+    {
+        List<String> types = CollectionFactory.newList();
+
+        for (Class c : availableTypes)
+            types.add(c.getName());
+
+        return MESSAGES.format("missing-from-environment", type.getName(), InternalUtils
+                .joinSorted(types));
+
+    }
+
+    static String invalidComponentEventResult(Object result,
+                                              Collection<Class> configuredResultTypes)
+    {
+        List<String> classNames = CollectionFactory.newList();
+
+        for (Class c : configuredResultTypes)
+            classNames.add(c.getName());
+
+        return MESSAGES.format("invalid-component-event-result", result, ClassFabUtils.toJavaClassName(result
+                .getClass()), InternalUtils.joinSorted(classNames));
+    }
+
+    static String undefinedTapestryAttribute(String elementName, String attributeName, String allowedAttributeName)
+    {
+        return MESSAGES.format("undefined-tapestry-attribute", elementName, attributeName, allowedAttributeName);
+    }
+
+    static String parameterElementNameRequired()
+    {
+        return MESSAGES.get("parameter-element-name-required");
+    }
+
+    static String missingApplicationStatePersistenceStrategy(String name, Collection<String> availableNames)
+    {
+        return MESSAGES.format("missing-application-state-persistence-strategy", name,
+                               InternalUtils.joinSorted(availableNames));
+    }
+
+    static String methodIsVoid(String methodName, Class inClass, String propertyExpression)
+    {
+        return MESSAGES.format("method-is-void", methodName, inClass.getName(), propertyExpression);
+    }
+
+    static String methodNotFound(String methodName, Class inClass, String propertyExpression)
+    {
+        return MESSAGES.format("method-not-found", methodName, inClass.getName(), propertyExpression);
+    }
+
+    static String noSuchProperty(Class targetClass, String propertyName, String propertyExpression,
+                                 Collection<String> propertyNames)
+    {
+        return MESSAGES.format("no-such-property", targetClass.getName(), propertyName, propertyExpression,
+                               InternalUtils.joinSorted(propertyNames));
+    }
+
+    static String writeOnlyProperty(String propertyName, Class clazz, String propertyExpression)
+    {
+        return MESSAGES.format("write-only-property", propertyName, clazz.getName(), propertyExpression);
+    }
+
+    static String requestException(Throwable cause)
+    {
+        return MESSAGES.format("request-exception", cause);
+    }
+
+    static String componentRecursion(String componentClassName)
+    {
+        return MESSAGES.format("component-recursion", componentClassName);
+    }
+
+
+    static String clientStateMustBeSerializable(Object newValue)
+    {
+        return MESSAGES.format("client-state-must-be-serializable", newValue);
+    }
+
+    static String corruptClientState()
+    {
+        return MESSAGES.get("corrupt-client-state");
+    }
+
+    static String unclosedAttributeExpression(String expression)
+    {
+        return MESSAGES.format("unclosed-attribute-expression", expression);
+    }
+
+    static String noDisplayForDataType(String datatype)
+    {
+        return MESSAGES.format("no-display-for-data-type", datatype);
+    }
+
+    static String noEditForDataType(String datatype)
+    {
+        return MESSAGES.format("no-edit-for-data-type", datatype);
+    }
+
+    static String missingValidatorConstraint(String validatorType, Class type)
+    {
+        return MESSAGES.format("missing-validator-constraint", validatorType, type.getName());
+    }
+
+    static String resourcesAccessForbidden(String URI)
+    {
+        return MESSAGES.format("resource-access-forbidden", URI);
+    }
+
+    static String noMarkupFromPageRender(org.apache.tapestry.internal.structure.Page page)
+    {
+        return MESSAGES.format("no-markup-from-page-render", page.getLogicalName());
+    }
+
+    static String baseClassInWrongPackage(String parentClassName, String className, String suggestedPackage)
+    {
+        return MESSAGES.format("base-class-in-wrong-package", parentClassName, className, suggestedPackage);
+    }
+
+    static String invalidId(String messageKey, String idValue)
+    {
+        return MESSAGES.format(messageKey, idValue);
+    }
+
+    static String attributeNotAllowed(String elementName)
+    {
+        return MESSAGES.format("attribute-not-allowed", elementName);
+    }
+
+    static String pagePoolExausted(String pageName, Locale locale, int hardLimit)
+    {
+        return MESSAGES.format("page-pool-exausted", pageName, locale.toString(), hardLimit);
+    }
+
+    static String unknownNullFieldStrategyName(String name, Collection<String> names)
+    {
+        return MESSAGES.format("unknown-null-field-strategy-name", name, InternalUtils.joinSorted(names));
+    }
+
+    public static String noTranslatorForType(Class valueType, Collection<String> typeNames)
+    {
+        return MESSAGES.format("no-translator-for-type", ClassFabUtils.toJavaClassName(valueType),
+                               InternalUtils.joinSorted(typeNames));
+    }
+
+    static String emptyBinding(String parameterName)
+    {
+        return MESSAGES.format("parameter-binding-must-not-be-empty", parameterName);
+    }
+
+    static String noSuchMethod(Class clazz, String methodName)
+    {
+        return MESSAGES.format("no-such-method", ClassFabUtils.toJavaClassName(clazz), methodName);
+    }
+
+    static String contextValueMayNotBeNull()
+    {
+        return MESSAGES.get("context-value-may-not-be-null");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategy.java
new file mode 100644
index 0000000..0ff4a7f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategy.java
@@ -0,0 +1,84 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.ApplicationStateCreator;
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategy;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+/**
+ * Stores ASOs in the {@link Session}, which will be created as necessary.
+ * <p/>
+ * TODO: Re-storing the object back into the session at the end of the request. That's going to require some kind of
+ * end-of-request notification.
+ */
+public class SessionApplicationStatePersistenceStrategy implements
+        ApplicationStatePersistenceStrategy
+{
+    static final String PREFIX = "aso:";
+
+    private final Request request;
+
+    public SessionApplicationStatePersistenceStrategy(Request request)
+    {
+        this.request = request;
+    }
+
+    private Session getSession()
+    {
+        return request.getSession(true);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T get(Class<T> asoClass, ApplicationStateCreator<T> creator)
+    {
+        Session session = getSession();
+
+        String key = buildKey(asoClass);
+
+        T aso = (T) session.getAttribute(key);
+
+        if (aso == null)
+        {
+            aso = creator.create();
+            session.setAttribute(key, aso);
+        }
+
+        return aso;
+    }
+
+    private <T> String buildKey(Class<T> asoClass)
+    {
+        return PREFIX + asoClass.getName();
+    }
+
+    public <T> void set(Class<T> asoClass, T aso)
+    {
+        String key = buildKey(asoClass);
+
+        getSession().setAttribute(key, aso);
+    }
+
+    public <T> boolean exists(Class<T> asoClass)
+    {
+        String key = buildKey(asoClass);
+
+        Session session = request.getSession(false);
+
+        return session != null && session.getAttribute(key) != null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionImpl.java
new file mode 100644
index 0000000..a9d0866
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionImpl.java
@@ -0,0 +1,85 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Session;
+
+import javax.servlet.http.HttpSession;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * A thin wrapper around {@link HttpSession}.
+ */
+public class SessionImpl implements Session
+{
+    private final HttpSession session;
+
+    public SessionImpl(HttpSession session)
+    {
+        this.session = session;
+    }
+
+    public Object getAttribute(String name)
+    {
+        return session.getAttribute(name);
+    }
+
+    public List<String> getAttributeNames()
+    {
+        return InternalUtils.toList(session.getAttributeNames());
+    }
+
+    public void setAttribute(String name, Object value)
+    {
+        session.setAttribute(name, value);
+    }
+
+    public List<String> getAttributeNames(String prefix)
+    {
+        List<String> result = newList();
+
+        Enumeration e = session.getAttributeNames();
+        while (e.hasMoreElements())
+        {
+            String name = (String) e.nextElement();
+
+            if (name.startsWith(prefix)) result.add(name);
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public int getMaxInactiveInterval()
+    {
+        return session.getMaxInactiveInterval();
+    }
+
+    public void invalidate()
+    {
+        session.invalidate();
+    }
+
+    public void setMaxInactiveInterval(int seconds)
+    {
+        session.setMaxInactiveInterval(seconds);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategy.java
new file mode 100644
index 0000000..11982cf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategy.java
@@ -0,0 +1,37 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+
+/**
+ * A strategy for storing persistent page properties into the {@link Session session}.
+ * <p/>
+ * Builds attribute names as: <code>state:<em>page-name</em>:<em>component-id</em>:<em>field-name</em></code>
+ */
+
+public class SessionPersistentFieldStrategy extends AbstractSessionPersistentFieldStrategy
+{
+    /**
+     * Prefix used to identify keys stored in the session that are being used to store persistent field data.
+     */
+    static final String PREFIX = "state:";
+
+    public SessionPersistentFieldStrategy(Request request)
+    {
+        super(PREFIX, request);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StaticFilesFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StaticFilesFilter.java
new file mode 100644
index 0000000..97d4896
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StaticFilesFilter.java
@@ -0,0 +1,81 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.services.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Identifies requests that are for actual resource files in the context. For those, Tapestry allows the servlet
+ * container to process the request.
+ */
+public class StaticFilesFilter implements RequestFilter
+{
+    private final Context context;
+
+    public StaticFilesFilter(Context context)
+    {
+        this.context = context;
+    }
+
+    public boolean service(Request request, Response response, RequestHandler handler)
+            throws IOException
+    {
+        String path = request.getPath();
+
+        // TAPESTRY-1322: Treat requests from the browser for a favorites icon via the normal
+        // servlet even if the file doesn't exist, to keep the request from looking like a
+        // component action request.
+
+        if (path.equals("/favicon.ico")) return false;
+
+        // We are making the questionable assumption that all files to be vended out will contain
+        // an extension (with a dot separator). Without this, the filter tends to match against
+        // folder names when we don't want it to (especially for the root context path).
+
+        int dotx = path.lastIndexOf(".");
+
+        if (dotx > 0)
+        {
+            URL url = context.getResource(path);
+
+            if (url != null)
+            {
+                String suffix = path.substring(dotx + 1);
+
+                // We never allow access to Tapestry component templates, even if they exist.
+                // It is considered a security risk, like seeing a raw JSP. Earlier alpha versions
+                // of Tapestry required that the templates be stored in WEB-INF.
+
+                if (suffix.equalsIgnoreCase(InternalConstants.TEMPLATE_EXTENSION))
+                {
+
+                    response.sendError(HttpServletResponse.SC_FORBIDDEN, ServicesMessages
+                            .resourcesAccessForbidden(path));
+
+                    return true;
+                }
+
+                return false;
+            }
+        }
+
+        return handler.service(request, response);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StreamResponseResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StreamResponseResultProcessor.java
new file mode 100644
index 0000000..294adf8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StreamResponseResultProcessor.java
@@ -0,0 +1,79 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.StreamResponse;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.services.Response;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class StreamResponseResultProcessor implements ComponentEventResultProcessor<StreamResponse>
+{
+    private static final int BUFFER_SIZE = 5000;
+
+    private final Response response;
+
+    public StreamResponseResultProcessor(Response response)
+    {
+        this.response = response;
+    }
+
+    public void processResultValue(StreamResponse streamResponse)
+            throws IOException
+    {
+        OutputStream os = null;
+        InputStream is = null;
+
+        streamResponse.prepareResponse(response);
+
+        try
+        {
+            is = new BufferedInputStream(streamResponse.getStream());
+
+            os = response.getOutputStream(streamResponse.getContentType());
+
+            byte[] buffer = new byte[BUFFER_SIZE];
+
+            while (true)
+            {
+                int length = is.read(buffer, 0, buffer.length);
+                if (length < 0) break;
+
+                os.write(buffer, 0, length);
+            }
+
+            // TAPESTRY-2415: WebLogic needs this flush() call.            
+            os.flush();
+
+            os.close();
+            os = null;
+
+            is.close();
+            is = null;
+        }
+        finally
+        {
+            InternalUtils.close(is);
+            InternalUtils.close(os);
+        }
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringProvider.java
new file mode 100644
index 0000000..5d1bcac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringProvider.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+/**
+ * Interface used when assembling an attribute value that contains expansions.
+ */
+public interface StringProvider
+{
+    /**
+     * Ask the object to provide the desired string. Often this involves computing the string value dynamically, or
+     * aggregating together multiple StringProviders.
+     */
+    String provideString();
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringResultProcessor.java
new file mode 100644
index 0000000..0c43b3a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringResultProcessor.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+
+import java.io.IOException;
+
+/**
+ * Used when a component event handler returns a string value. The value is interpreted as the logical name of a page. A
+ * link to the page will be sent as a redirect.
+ */
+public class StringResultProcessor implements ComponentEventResultProcessor<String>
+{
+    private final RequestPageCache requestPageCache;
+
+    private final ActionRenderResponseGenerator generator;
+
+    public StringResultProcessor(RequestPageCache requestPageCache, ActionRenderResponseGenerator generator)
+    {
+        this.requestPageCache = requestPageCache;
+        this.generator = generator;
+    }
+
+    public void processResultValue(String value) throws IOException
+    {
+        Page page = requestPageCache.get(value);
+
+        generator.generateResponse(page);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringValueEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringValueEncoder.java
new file mode 100644
index 0000000..7ccdabf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/StringValueEncoder.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+
+/**
+ * Passes the string value from the server to the client and vice-versa without any translation.
+ */
+public class StringValueEncoder implements ValueEncoder<String>
+{
+    public String toClient(String value)
+    {
+        return value;
+    }
+
+    public String toValue(String clientValue)
+    {
+        return clientValue;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParser.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParser.java
new file mode 100644
index 0000000..7125fb2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParser.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.ioc.Resource;
+
+/**
+ * Parses a resource into a {@link org.apache.tapestry.internal.parser.ComponentTemplate}.
+ *
+ * @see PageLoader
+ */
+public interface TemplateParser
+{
+    /**
+     * Parses the given resource into a component template.
+     *
+     * @param templateResource the path
+     * @return the parsed template contents
+     * @throws RuntimeException if the resource does not exist, or if there is any kind of parse error
+     */
+    ComponentTemplate parseTemplate(Resource templateResource);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
new file mode 100644
index 0000000..1a68b91
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
@@ -0,0 +1,807 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.internal.parser.*;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.LocationImpl;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.util.Stack;
+import org.slf4j.Logger;
+import org.xml.sax.*;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Non-threadsafe implementation; the IOC service uses the perthread lifecycle.
+ */
+@Scope(PERTHREAD_SCOPE)
+public class TemplateParserImpl implements TemplateParser, LexicalHandler, ContentHandler, EntityResolver
+{
+    private static final String MIXINS_ATTRIBUTE_NAME = "mixins";
+
+    private static final String TYPE_ATTRIBUTE_NAME = "type";
+
+    private static final String ID_ATTRIBUTE_NAME = "id";
+
+    public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
+
+    /**
+     * Used as the namespace URI for Tapestry templates.
+     */
+    public static final String TAPESTRY_SCHEMA_5_0_0 = "http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";
+
+    private static final Pattern ID_PATTERN = Pattern.compile("^[a-z]\\w*$", Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Any amount of mixed simple whitespace (space, tab, form feed) mixed with at least one carriage return or line
+     * feed, followed by any amount of whitespace.  Will be reduced to a single linefeed.
+     */
+    private static final Pattern REDUCE_LINEBREAKS_PATTERN = Pattern.compile("[ \\t\\f]*[\\r\\n]\\s*",
+                                                                             Pattern.MULTILINE);
+
+    /**
+     * Used when compressing whitespace, matches any sequence of simple whitespace (space, tab, formfeed). Applied after
+     * REDUCE_LINEBREAKS_PATTERN.
+     */
+    private static final Pattern REDUCE_WHITESPACE_PATTERN = Pattern.compile("[ \\t\\f]+", Pattern.MULTILINE);
+
+    // Note the use of the non-greedy modifier; this prevents the pattern from merging multiple
+    // expansions on the same text line into a single large
+    // but invalid expansion.
+
+    private static final String EXPANSION_REGEXP = "\\$\\{\\s*(.*?)\\s*}";
+
+    private static final Pattern EXPANSION_PATTERN = Pattern.compile(EXPANSION_REGEXP);
+
+
+    private XMLReader reader;
+
+    // Resource being parsed
+    private Resource templateResource;
+
+    private Locator locator;
+
+    private final List<TemplateToken> tokens = CollectionFactory.newList();
+
+    private final boolean compressWhitespaceDefault;
+
+    /**
+     * Because {@link org.xml.sax.ContentHandler#startPrefixMapping(String, String)} events arrive before the
+     * corresponding {@link org.xml.sax.ContentHandler#startElement(String, String, String, org.xml.sax.Attributes)}
+     * events, we need to accumlate the {@link org.apache.tapestry.internal.parser.DefineNamespacePrefixToken}s ahead of
+     * time to get the correct ordering in the output tokens list.
+     */
+    private final List<DefineNamespacePrefixToken> defineNamespaceTokens = newList();
+
+    // Non-blank ids from start component elements
+
+    private final Set<String> componentIds = CollectionFactory.newSet();
+
+    // Used to accumulate text provided by the characters() method. Even contiguous characters may
+    // be broken up across multiple invocations due to parser internals. We accumulate those
+    // together before forming a text token.
+
+    private final StringBuilder textBuffer = new StringBuilder();
+
+    private Location textStartLocation;
+
+    private boolean textIsCData;
+
+    private boolean insideBody;
+
+    private boolean insideBodyErrorLogged;
+
+    private boolean ignoreEvents;
+
+    private final Logger logger;
+
+    private final Map<String, URL> configuration;
+
+    private final Stack<Runnable> endTagHandlerStack = new Stack<Runnable>();
+
+    private boolean compressWhitespace;
+
+    private final Stack<Boolean> compressWhitespaceStack = new Stack<Boolean>();
+
+    private final Runnable endOfElementHandler = new Runnable()
+    {
+        public void run()
+        {
+            tokens.add(new EndElementToken(getCurrentLocation()));
+
+            // Restore the flag to how it was before the element was parsed.
+
+            compressWhitespace = compressWhitespaceStack.pop();
+        }
+    };
+
+    private final Runnable ignoreEndElement = new Runnable()
+    {
+        public void run()
+        {
+            compressWhitespace = compressWhitespaceStack.pop();
+        }
+    };
+
+
+    public TemplateParserImpl(Logger logger, Map<String, URL> configuration,
+
+                              @Symbol(SymbolConstants.COMPRESS_WHITESPACE)
+                              boolean compressWhitespaceDefault)
+    {
+        this.logger = logger;
+        this.configuration = configuration;
+        this.compressWhitespaceDefault = compressWhitespaceDefault;
+
+        reset();
+    }
+
+    private void reset()
+    {
+        tokens.clear();
+        defineNamespaceTokens.clear();
+        componentIds.clear();
+        templateResource = null;
+        locator = null;
+        textBuffer.setLength(0);
+        textStartLocation = null;
+        textIsCData = false;
+        insideBody = false;
+        insideBodyErrorLogged = false;
+        ignoreEvents = true;
+
+        endTagHandlerStack.clear();
+        compressWhitespaceStack.clear();
+    }
+
+    public ComponentTemplate parseTemplate(Resource templateResource)
+    {
+        compressWhitespace = compressWhitespaceDefault;
+
+        if (reader == null)
+        {
+            try
+            {
+                reader = XMLReaderFactory.createXMLReader();
+
+                reader.setContentHandler(this);
+
+                reader.setEntityResolver(this);
+
+                reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+
+                reader.setProperty("http://xml.org/sax/properties/lexical-handler", this);
+            }
+            catch (Exception ex)
+            {
+                throw new RuntimeException(ServicesMessages.newParserError(templateResource, ex), ex);
+            }
+        }
+
+        if (!templateResource.exists())
+            throw new RuntimeException(ServicesMessages.missingTemplateResource(templateResource));
+
+        this.templateResource = templateResource;
+
+        try
+        {
+            InputSource source = new InputSource(templateResource.openStream());
+
+            reader.parse(source);
+
+            return new ComponentTemplateImpl(this.templateResource, tokens, componentIds);
+        }
+        catch (Exception ex)
+        {
+            // Some parsers get in an unknown state when an error occurs, and are are not
+            // subsequently useable.
+
+            reader = null;
+
+            throw new TapestryException(ServicesMessages.templateParseError(templateResource, ex), getCurrentLocation(),
+                                        ex);
+        }
+        finally
+        {
+            reset();
+        }
+    }
+
+    public void setDocumentLocator(Locator locator)
+    {
+        this.locator = locator;
+    }
+
+    /**
+     * Accumulates the characters into a text buffer.
+     */
+    public void characters(char[] ch, int start, int length) throws SAXException
+    {
+        if (ignoreEvents) return;
+
+        if (insideBody()) return;
+
+        if (textBuffer.length() == 0) textStartLocation = getCurrentLocation();
+
+        textBuffer.append(ch, start, length);
+    }
+
+
+    /**
+     * Adds tokens corresponding to the content in the text buffer. For a non-CDATA section, we also search for
+     * expansions (thus we may add more than one token). Clears the text buffer.
+     */
+    private void processTextBuffer()
+    {
+        if (textBuffer.length() == 0) return;
+
+        String text = textBuffer.toString();
+
+        textBuffer.setLength(0);
+
+        if (textIsCData)
+        {
+            tokens.add(new CDATAToken(text, textStartLocation));
+
+            return;
+        }
+
+        if (compressWhitespace)
+        {
+            text = compressWhitespaceInText(text);
+
+            if (InternalUtils.isBlank(text)) return;
+        }
+
+
+        addTokensForText(text);
+    }
+
+    private String compressWhitespaceInText(String text)
+    {
+        String linebreaksReduced = REDUCE_LINEBREAKS_PATTERN.matcher(text).replaceAll("\n");
+
+        return REDUCE_WHITESPACE_PATTERN.matcher(linebreaksReduced).replaceAll(" ");
+    }
+
+    /**
+     * Scans the text, using a regular expression pattern, for expansion patterns, and adds appropriate tokens for what
+     * it finds.
+     *
+     * @param text to add as {@link org.apache.tapestry.internal.parser.TextToken}s and {@link
+     *             org.apache.tapestry.internal.parser.ExpansionToken}s
+     */
+    private void addTokensForText(String text)
+    {
+        Matcher matcher = EXPANSION_PATTERN.matcher(text);
+
+        int startx = 0;
+
+        // The big problem with all this code is that everything gets assigned to the
+        // start of the text block, even if there are line breaks leading up to it.
+        // That's going to take a lot more work and there are bigger fish to fry.  In addition,
+        // TAPESTRY-2028 means that the whitespace has likely been stripped out of the text
+        // already anyway.
+
+        while (matcher.find())
+        {
+            int matchStart = matcher.start();
+
+            if (matchStart != startx)
+            {
+                String prefix = text.substring(startx, matchStart);
+
+                tokens.add(new TextToken(prefix, textStartLocation));
+            }
+
+            // Group 1 includes the real text of the expansion, with whitespace around the
+            // expression (but inside the curly braces) excluded.
+
+            String expression = matcher.group(1);
+
+            tokens.add(new ExpansionToken(expression, textStartLocation));
+
+            startx = matcher.end();
+        }
+
+        // Catch anything after the final regexp match.
+
+        if (startx < text.length())
+            tokens.add(new TextToken(text.substring(startx, text.length()), textStartLocation));
+    }
+
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
+    {
+        ignoreEvents = false;
+
+        if (insideBody) throw new IllegalStateException(ServicesMessages
+                .mayNotNestElementsInsideBody(localName));
+
+        // Add any accumulated text into a text token
+        processTextBuffer();
+
+        if (TAPESTRY_SCHEMA_5_0_0.equals(uri))
+        {
+            startTapestryElement(localName, attributes);
+            return;
+        }
+
+        startPossibleComponent(attributes, uri, localName, null);
+    }
+
+    /**
+     * Checks to see if currently inside a t:body element (which should always be empty). Content is ignored inside a
+     * body. If inside a body, then a warning is logged (but only one warning per body element).
+     *
+     * @return true if inside t:body, false otherwise
+     */
+    private boolean insideBody()
+    {
+        if (insideBody)
+        {
+            // Limit to one logged error per infraction.
+
+            if (!insideBodyErrorLogged)
+                logger.error(ServicesMessages.contentInsideBodyNotAllowed(getCurrentLocation()));
+
+            insideBodyErrorLogged = true;
+        }
+
+        return insideBody;
+    }
+
+    private void startTapestryElement(String localName, Attributes attributes)
+    {
+        if (localName.equalsIgnoreCase("body"))
+        {
+            startBody();
+            return;
+        }
+
+        if (localName.equalsIgnoreCase("parameter"))
+        {
+            startParameter(attributes);
+            return;
+        }
+
+        if (localName.equalsIgnoreCase("block"))
+        {
+            startBlock(attributes);
+            return;
+        }
+
+        if (localName.equalsIgnoreCase("container"))
+        {
+            startContainer(localName, attributes);
+            return;
+        }
+
+        // The component type is derived from the element name. Since element names may not contain
+        // slashes, we convert periods to slashes. Later down the pipeline, they'll probably be
+        // converted back into periods, as part of a fully qualified class name.
+
+        String componentType = localName.replace('.', '/');
+
+        // With a component type specified, it's not just possibly a component ...
+        startPossibleComponent(attributes, null, null, componentType);
+    }
+
+    private void startContainer(String elementName, Attributes attributes)
+    {
+        compressWhitespaceStack.push(compressWhitespace);
+
+        // Neither the container nor its end tag are considered tokens, just the contents inside.
+
+        endTagHandlerStack.push(ignoreEndElement);
+
+        for (int i = 0; i < attributes.getLength(); i++)
+        {
+            String name = attributes.getLocalName(i);
+
+            // The name will be blank for an xmlns: attribute
+
+            if (InternalUtils.isBlank(name)) continue;
+
+            String uri = attributes.getURI(i);
+            String value = attributes.getValue(i);
+
+            if (isXMLSpaceAttribute(uri, name, value)) continue;
+
+            throw new TapestryException(ServicesMessages.attributeNotAllowed(elementName), getCurrentLocation(), null);
+        }
+    }
+
+    private void startBlock(Attributes attributes)
+    {
+        addEndOfElementHandler();
+
+        String blockId = findSingleParameter("block", "id", attributes);
+
+        validateId(blockId, "invalid-block-id");
+
+        // null is ok for blockId
+
+        tokens.add(new BlockToken(blockId, getCurrentLocation()));
+
+        // TODO: Check for an xml:space attribute
+    }
+
+    private void startParameter(Attributes attributes)
+    {
+        addEndOfElementHandler();
+
+        String parameterName = findSingleParameter("parameter", "name", attributes);
+
+        if (InternalUtils.isBlank(parameterName))
+            throw new TapestryException(ServicesMessages.parameterElementNameRequired(), getCurrentLocation(), null);
+
+        tokens.add(new ParameterToken(parameterName, getCurrentLocation()));
+    }
+
+    /**
+     * Should be called *before* the _compressWhitespace is changed.
+     */
+    private void addEndOfElementHandler()
+    {
+        // Record how the flag was set at the start of the element
+
+        compressWhitespaceStack.push(compressWhitespace);
+
+        endTagHandlerStack.push(endOfElementHandler);
+
+
+    }
+
+    private String findSingleParameter(String elementName, String attributeName, Attributes attributes)
+    {
+        String result = null;
+
+        for (int i = 0; i < attributes.getLength(); i++)
+        {
+            String uri = attributes.getURI(i);
+            String name = attributes.getLocalName(i);
+            String value = attributes.getValue(i);
+
+            if (isXMLSpaceAttribute(uri, name, value)) continue;
+
+            if (name.equals(attributeName))
+            {
+                result = value;
+                continue;
+            }
+
+            // Only the named attribute is allowed.
+
+            throw new TapestryException(ServicesMessages.undefinedTapestryAttribute(elementName, name, attributeName),
+                                        getCurrentLocation(), null);
+        }
+
+        return result;
+    }
+
+    private boolean isXMLSpaceAttribute(String uri, String name, String value)
+    {
+
+        if (uri.equals(XML_NAMESPACE_URI) && name.equals("space"))
+        {
+            // "preserve" turns off whitespace compression
+            // "default" (the other option, but we'll accept anything) turns it on (or leaves it on, more likely).
+
+            compressWhitespace = !"preserve".equalsIgnoreCase(value);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private String nullForBlank(String input)
+    {
+        return InternalUtils.isBlank(input) ? null : input;
+    }
+
+    /**
+     * @param attributes     the attributes for the element
+     * @param namespaceURI   the namespace URI for the element (or the empty string)
+     * @param elementName    the name of the element (to be assigned to the new token), may be null for a component in
+     *                       the Tapestry namespace
+     * @param identifiedType the type of the element, usually null, but may be the component type derived from
+     */
+    private void startPossibleComponent(Attributes attributes, String namespaceURI, String elementName,
+                                        String identifiedType)
+    {
+
+        // Add an end handler to match this start tag.
+
+        addEndOfElementHandler();
+
+        String id = null;
+        String type = identifiedType;
+        String mixins = null;
+        int count = attributes.getLength();
+        Location location = getCurrentLocation();
+        List<TemplateToken> attributeTokens = newList();
+
+        for (int i = 0; i < count; i++)
+        {
+            String name = attributes.getLocalName(i);
+
+            // The name will be blank for an xmlns: attribute
+
+            if (InternalUtils.isBlank(name)) continue;
+
+            String uri = attributes.getURI(i);
+
+            String value = attributes.getValue(i);
+
+            if (TAPESTRY_SCHEMA_5_0_0.equals(uri))
+            {
+                if (name.equalsIgnoreCase(ID_ATTRIBUTE_NAME))
+                {
+                    id = nullForBlank(value);
+
+                    validateId(id, "invalid-component-id");
+
+                    continue;
+                }
+
+                if (type == null && name.equalsIgnoreCase(TYPE_ATTRIBUTE_NAME))
+                {
+                    type = nullForBlank(value);
+                    continue;
+                }
+
+                if (name.equalsIgnoreCase(MIXINS_ATTRIBUTE_NAME))
+                {
+                    mixins = nullForBlank(value);
+                    continue;
+                }
+
+                // Anything else is the name of a Tapestry component parameter that is simply
+                // not part of the template's doctype for the element being instrumented.
+            }
+
+
+            if (isXMLSpaceAttribute(uri, name, value)) continue;
+
+            attributeTokens.add(new AttributeToken(uri, name, value, location));
+        }
+
+        boolean isComponent = (id != null || type != null);
+
+        // If provided t:mixins but not t:id or t:type, then its not quite a component
+
+        if (mixins != null && !isComponent)
+            throw new TapestryException(ServicesMessages.mixinsInvalidWithoutIdOrType(elementName), location, null);
+
+        if (isComponent)
+        {
+            tokens.add(new StartComponentToken(elementName, id, type, mixins, location));
+        }
+        else
+        {
+            tokens.add(new StartElementToken(namespaceURI, elementName, location));
+        }
+
+        addDefineNamespaceTokens();
+
+        tokens.addAll(attributeTokens);
+
+        if (id != null) componentIds.add(id);
+
+        // TODO: Is there value in having different end elements for components vs. ordinary
+        // elements?
+
+    }
+
+    private void validateId(String id, String messageKey)
+    {
+        if (id == null) return;
+
+        if (ID_PATTERN.matcher(id).matches()) return;
+
+        // Not a match.
+
+        throw new TapestryException(ServicesMessages.invalidId(messageKey, id), getCurrentLocation(), null);
+    }
+
+    private void startBody()
+    {
+        tokens.add(new BodyToken(getCurrentLocation()));
+
+        insideBody = true;
+        insideBodyErrorLogged = false;
+
+        endTagHandlerStack.push(new Runnable()
+        {
+            public void run()
+            {
+                insideBody = false;
+
+                // And don't add an end element token.
+            }
+        });
+    }
+
+    public void endElement(String uri, String localName, String qName) throws SAXException
+    {
+        processTextBuffer();
+
+        endTagHandlerStack.pop().run();
+    }
+
+    private Location getCurrentLocation()
+    {
+        if (locator == null) return null;
+
+        return new LocationImpl(templateResource, locator.getLineNumber(), locator
+                .getColumnNumber());
+    }
+
+    /**
+     * Adds any namespace tokens accumulated from just before the current element. The list of namespace tokens is then
+     * cleared.
+     */
+    private void addDefineNamespaceTokens()
+    {
+        tokens.addAll(defineNamespaceTokens);
+
+        defineNamespaceTokens.clear();
+    }
+
+    public void comment(char[] ch, int start, int length) throws SAXException
+    {
+        if (ignoreEvents || insideBody()) return;
+
+        processTextBuffer();
+
+        // Remove excess whitespace. The Comment DOM node will add a leadig and trailing space.
+
+        String comment = new String(ch, start, length).trim();
+
+        // TODO: Perhaps comments need to be "aggregated" the same way we aggregate text and CDATA.
+        // Hm. Probably not. Any whitespace between one comment and the next will become a
+        // TextToken.
+        // Unless we trim whitespace between consecutive comments ... and on down the rabbit hole.
+        // Oops -- unless a single comment may be passed into this method as multiple calls
+        // (have to check how multiline comments are handled).
+        // Tests against Sun's built in parser does show that multiline comments are still
+        // provided as a single call to comment(), so we're good for the meantime (until we find
+        // out some parsers aren't so compliant).
+
+        tokens.add(new CommentToken(comment, getCurrentLocation()));
+    }
+
+    public void endCDATA() throws SAXException
+    {
+        // Add a token for any accumulated CDATA.
+
+        processTextBuffer();
+
+        // Again, CDATA doesn't nest, so we know we're back to ordinary markup.
+
+        textIsCData = false;
+    }
+
+    public void startCDATA() throws SAXException
+    {
+        if (ignoreEvents || insideBody()) return;
+
+        processTextBuffer();
+
+        // Because CDATA doesn't mix with any other SAX/lexical events, we can simply turn on a flag
+        // here and turn it off when we see the end.
+
+        textIsCData = true;
+    }
+
+    // Empty methods defined by the various interfaces.
+
+    public void endDTD() throws SAXException
+    {
+    }
+
+    public void endEntity(String name) throws SAXException
+    {
+    }
+
+    public void startDTD(String name, String publicId, String systemId) throws SAXException
+    {
+        // notes:
+        // 1) a DTD has to occur at the very start of a document. Since we don't start
+        // recording characters until we hit the first element of a document (see
+        // characters and startElement), there should be no text to process.
+        // It's worth noting that the sax parser will puke if any of the following
+        // occur:
+        // 1) a doctype is encountered multiple times in the same document
+        // 2) a doctype is encountered anywhere other than the very first item
+        // in a document.
+        // Hence, the assumption made in 1 should hold.
+        // Since an exception is thrown for case #1 above, we can just add the DTDToken.
+        // When we go to process the token (in PageLoaderProcessor), we can make sure
+        // that the final page has only a single DTDToken (the first one).
+        tokens.add(new DTDToken(name, publicId, systemId, getCurrentLocation()));
+    }
+
+    public void startEntity(String name) throws SAXException
+    {
+    }
+
+    public void endDocument() throws SAXException
+    {
+    }
+
+
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
+    {
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException
+    {
+    }
+
+    public void skippedEntity(String name) throws SAXException
+    {
+    }
+
+    public void startDocument() throws SAXException
+    {
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException
+    {
+        // Not interested in the Tapestry namespace (that is never sent to the client).
+
+        if (uri.equals(TAPESTRY_SCHEMA_5_0_0)) return;
+
+        // The prefix may be blank, which happens when the xmlns attribute is used to define the
+        // namespace for the default namespace, and when a document has an explicit DOCTYPE.
+
+        DefineNamespacePrefixToken token = new DefineNamespacePrefixToken(uri, prefix, getCurrentLocation());
+
+        defineNamespaceTokens.add(token);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException
+    {
+    }
+
+    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
+    {
+        URL url = configuration.get(publicId);
+
+        if (url != null) return new InputSource(url.openStream());
+
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TransformationException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TransformationException.java
new file mode 100644
index 0000000..4fe6f75
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TransformationException.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.ClassTransformation;
+
+/**
+ * Exception thrown when there is a failure transforming a class, or instantiating a transformed class. The cause may be
+ * an Error. The goal is to get the {@link ClassTransformation} into the exception report page, properly formatted.
+ */
+public class TransformationException extends TapestryException
+{
+    private static final long serialVersionUID = -7312854113157232961L;
+
+    private final ClassTransformation transformation;
+
+    public TransformationException(ClassTransformation transformation, Throwable cause)
+    {
+        super(cause.getMessage(), cause);
+
+        this.transformation = transformation;
+    }
+
+    public ClassTransformation getTransformation()
+    {
+        return transformation;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TranslatorSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TranslatorSourceImpl.java
new file mode 100644
index 0000000..5ceb654
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TranslatorSourceImpl.java
@@ -0,0 +1,87 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.TranslatorSource;
+
+import java.util.List;
+import java.util.Map;
+
+public class TranslatorSourceImpl implements TranslatorSource, InvalidationListener
+{
+    private final Map<String, Translator> translators;
+
+    private final StrategyRegistry<Translator> registry;
+
+    public TranslatorSourceImpl(Map<String, Translator> translators)
+    {
+        this.translators = translators;
+
+        Map<Class, Translator> typeToTranslator = CollectionFactory.newMap();
+
+        for (Translator t : translators.values())
+        {
+            typeToTranslator.put(t.getType(), t);
+        }
+
+        registry = StrategyRegistry.newInstance(Translator.class, typeToTranslator, true);
+    }
+
+    public Translator get(String name)
+    {
+
+        Translator result = translators.get(name);
+
+        if (result == null)
+            throw new RuntimeException(ServicesMessages.unknownTranslatorType(name, InternalUtils
+                    .sortedKeys(translators)));
+
+        return result;
+    }
+
+    public Translator getByType(Class valueType)
+    {
+        Translator result = registry.get(valueType);
+
+        if (result == null)
+        {
+            List<String> names = CollectionFactory.newList();
+
+            for (Class type : registry.getTypes())
+            {
+                names.add(type.getName());
+            }
+
+            throw new IllegalArgumentException(ServicesMessages.noTranslatorForType(valueType, names));
+        }
+
+        return result;
+    }
+
+    public Translator findByType(Class valueType)
+    {
+        return registry.get(valueType);
+    }
+
+    public void objectWasInvalidated()
+    {
+        registry.clearCache();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TypeCoercedValueEncoderFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TypeCoercedValueEncoderFactory.java
new file mode 100644
index 0000000..800f29c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TypeCoercedValueEncoderFactory.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.ValueEncoderFactory;
+
+/**
+ * Provides {@link org.apache.tapestry.ValueEncoder} instances that are backed by the {@link
+ * org.apache.tapestry.ioc.services.TypeCoercer} service.
+ */
+public class TypeCoercedValueEncoderFactory implements ValueEncoderFactory<Object>
+{
+    private final TypeCoercer typeCoercer;
+
+    public TypeCoercedValueEncoderFactory(TypeCoercer typeCoercer)
+    {
+        this.typeCoercer = typeCoercer;
+    }
+
+    public ValueEncoder<Object> create(final Class<Object> type)
+    {
+        return new ValueEncoder<Object>()
+        {
+            public String toClient(Object value)
+            {
+                return typeCoercer.coerce(value, String.class);
+            }
+
+            public Object toValue(String clientValue)
+            {
+                return typeCoercer.coerce(clientValue, type);
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java
new file mode 100644
index 0000000..b4655e1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHub.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.internal.events.UpdateListener;

+

+/**

+ * Manages a set of {@link org.apache.tapestry.internal.events.UpdateListener}s. Periodically (say, every request during

+ * development, or every minute or so during production), request processing is locked down so that only a single thread

+ * is active, and the active thread invokes {@link #fireUpdateEvent()}. Various services that are dependent on external

+ * resource files (such as classes or template files) can check to see if any file they've used has changed. If so, the

+ * service can invalidate its internal cache, or notify other services (typically via {@link

+ * org.apache.tapestry.internal.events.InvalidationListener} that they should do the same.

+ *

+ * @see org.apache.tapestry.internal.util.URLChangeTracker

+ */

+public interface UpdateListenerHub

+{

+    void addUpdateListener(UpdateListener listener);

+

+    /**

+     * Invoked periodically to allow services to check if underlying state has changed. For example, a template file may

+     * have changed. Listeners will typically notify applicable listeners of their own (they usually implement {@link

+     * org.apache.tapestry.internal.event.InvalidationEventHub}) when such a change occurs.

+     */

+    void fireUpdateEvent();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHubImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHubImpl.java
new file mode 100644
index 0000000..8ca275b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/UpdateListenerHubImpl.java
@@ -0,0 +1,42 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+public class UpdateListenerHubImpl implements UpdateListenerHub
+{
+    private final List<UpdateListener> listeners = CollectionFactory.newThreadSafeList();
+
+    public void addUpdateListener(UpdateListener listener)
+    {
+        listeners.add(listener);
+
+    }
+
+    /**
+     * Notifies all {@link UpdateListener}s.
+     */
+    public void fireUpdateEvent()
+    {
+        for (UpdateListener listener : listeners)
+        {
+            listener.checkForUpdates();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationConstraintGeneratorImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationConstraintGeneratorImpl.java
new file mode 100644
index 0000000..47ab6bd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationConstraintGeneratorImpl.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+
+import java.util.List;
+
+public class ValidationConstraintGeneratorImpl implements ValidationConstraintGenerator
+{
+    private final List<ValidationConstraintGenerator> configuration;
+
+    public ValidationConstraintGeneratorImpl(final List<ValidationConstraintGenerator> configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider)
+    {
+        notNull(propertyType, "propertyType");
+        notNull(annotationProvider, "annotationProvider");
+
+        List<String> result = CollectionFactory.newList();
+
+        for (ValidationConstraintGenerator g : configuration)
+        {
+            List<String> constraints = g.buildConstraints(propertyType, annotationProvider);
+
+            if (constraints != null)
+                result.addAll(constraints);
+        }
+
+        // TODO: How to handle duplicate or conflicting constraints from different generators?
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImpl.java
new file mode 100644
index 0000000..4ccbef8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImpl.java
@@ -0,0 +1,153 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.ValidationMessagesSource;
+
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+
+public class ValidationMessagesSourceImpl implements ValidationMessagesSource, UpdateListener
+{
+    private final MessagesSource messagesSource;
+
+    private final MessagesBundle bundle;
+
+    private final Map<Locale, Messages> cache = CollectionFactory.newConcurrentMap();
+
+    private class ValidationMessagesBundle implements MessagesBundle
+    {
+        private final Resource baseResource;
+
+        private final MessagesBundle parent;
+
+        public ValidationMessagesBundle(final Resource baseResource, final MessagesBundle parent)
+        {
+            this.baseResource = baseResource;
+            this.parent = parent;
+        }
+
+        public Resource getBaseResource()
+        {
+            return baseResource;
+        }
+
+        public Object getId()
+        {
+            return baseResource.getPath();
+        }
+
+        public MessagesBundle getParent()
+        {
+            return parent;
+        }
+
+    }
+
+    /**
+     * Delegates to a {@link Messages} instance obtained from the {@link MessagesSource}. This ensures that changes to
+     * the underlying properties files will be reflected.
+     */
+    private class ValidationMessages implements Messages
+    {
+        private final Locale locale;
+
+        public ValidationMessages(final Locale locale)
+        {
+            this.locale = locale;
+        }
+
+        private Messages messages()
+        {
+            // The MessagesSource caches the value returned, until any underlying file is touched,
+            // at which point an updated Messages will be returned.
+
+            return messagesSource.getMessages(bundle, locale);
+        }
+
+        public boolean contains(String key)
+        {
+            return messages().contains(key);
+        }
+
+        public String format(String key, Object... args)
+        {
+            return messages().format(key, args);
+        }
+
+        public String get(String key)
+        {
+            return messages().get(key);
+        }
+
+        public MessageFormatter getFormatter(String key)
+        {
+            // Ideally, there would be a MessageFormatterImpl that would delegate to a fresh copy
+            // of a MessageFormatter obtained from the source, but that's probably overkill.
+
+            return messages().getFormatter(key);
+        }
+    }
+
+    public ValidationMessagesSourceImpl(Collection<String> bundles, Resource classpathRoot)
+    {
+        this(bundles, classpathRoot, new URLChangeTracker());
+    }
+
+    ValidationMessagesSourceImpl(Collection<String> bundles, Resource classpathRoot, URLChangeTracker tracker)
+    {
+        messagesSource = new MessagesSourceImpl(tracker);
+
+        MessagesBundle parent = null;
+
+        for (String bundle : bundles)
+        {
+            Resource bundleResource = classpathRoot.forFile(bundle);
+
+            parent = new ValidationMessagesBundle(bundleResource, parent);
+        }
+
+        bundle = parent;
+    }
+
+    public Messages getValidationMessages(Locale locale)
+    {
+        Messages result = cache.get(locale);
+
+        if (result == null)
+        {
+            result = new ValidationMessages(locale);
+            cache.put(locale, result);
+        }
+
+        return result;
+    }
+
+    public void checkForUpdates()
+    {
+        // When there are changes, the Messages cached inside the MessagesSource will be discarded
+        // and will be rebuilt on demand by the ValidatonMessages instances.
+
+        messagesSource.checkForUpdates();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidatorSpecification.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidatorSpecification.java
new file mode 100644
index 0000000..fcab6b6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValidatorSpecification.java
@@ -0,0 +1,66 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.TapestryInternalUtils;
+
+/**
+ * Validator type and constraint values parsed from a validator specification.
+ */
+class ValidatorSpecification
+{
+    private final String validatorType;
+
+    private final String constraintValue;
+
+    public ValidatorSpecification(String validatorType)
+    {
+        this(validatorType, null);
+    }
+
+    public ValidatorSpecification(String validatorType, String constraintValue)
+    {
+        this.validatorType = validatorType;
+        this.constraintValue = constraintValue;
+    }
+
+    public String getConstraintValue()
+    {
+        return constraintValue;
+    }
+
+    public String getValidatorType()
+    {
+        return validatorType;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("ValidatorSpecification[%s %s]", validatorType, constraintValue);
+    }
+
+    @Override
+    public boolean equals(Object other)
+    {
+        if (other == null || other.getClass() != getClass()) return false;
+
+        ValidatorSpecification ov = (ValidatorSpecification) other;
+
+        if (!validatorType.equals(ov.validatorType)) return false;
+
+        return TapestryInternalUtils.isEqual(constraintValue, ov.constraintValue);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java
new file mode 100644
index 0000000..fa8f333
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ValueEncoderSourceImpl.java
@@ -0,0 +1,62 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.services.ValueEncoderFactory;
+import org.apache.tapestry.services.ValueEncoderSource;
+
+import java.util.Map;
+
+public class ValueEncoderSourceImpl implements ValueEncoderSource, InvalidationListener
+{
+    private final StrategyRegistry<ValueEncoderFactory> registry;
+
+    private final Map<Class, ValueEncoder> cache = CollectionFactory.newConcurrentMap();
+
+    public ValueEncoderSourceImpl(Map<Class, ValueEncoderFactory> configuration)
+    {
+        registry = StrategyRegistry.newInstance(ValueEncoderFactory.class, configuration);
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public <T> ValueEncoder<T> getValueEncoder(Class<T> type)
+    {
+        Defense.notNull(type, "type");
+
+        ValueEncoder<T> result = cache.get(type);
+
+        if (result == null)
+        {
+            ValueEncoderFactory<T> factory = registry.get(type);
+
+            result = factory.create(type);
+
+            cache.put(type, result);
+        }
+
+        return result;
+    }
+
+    public void objectWasInvalidated()
+    {
+        registry.clearCache();
+        cache.clear();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BlockImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BlockImpl.java
new file mode 100644
index 0000000..ea16a40
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BlockImpl.java
@@ -0,0 +1,54 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+
+import java.util.List;
+
+public class BlockImpl extends BaseLocatable implements Block, BodyPageElement, RenderCommand
+{
+    // We could lazily create this, but for <t:block> and <t:parameter>, the case
+    // for an empty block is extremely rare.
+
+    private final List<PageElement> elements = CollectionFactory.newList();
+
+    public BlockImpl(Location location)
+    {
+        super(location);
+    }
+
+    public void addToBody(PageElement element)
+    {
+        elements.add(element);
+    }
+
+    /**
+     * Pushes all the elements of the body of this block onto the queue in appropriate order.
+     */
+    public void render(MarkupWriter writer, RenderQueue queue)
+    {
+        int count = elements.size();
+        for (int i = count - 1; i >= 0; i--)
+            queue.push(elements.get(i));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BodyPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BodyPageElement.java
new file mode 100644
index 0000000..1582cad
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/BodyPageElement.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.services.PageLoader;
+
+/**
+ * A type of {@link PageElement} that has a body that can be added to. This is part of the constuction phase that is
+ * faciliated by the {@link PageLoader}.
+ */
+public interface BodyPageElement
+{
+    /**
+     * Used during the construction of the page. Adds a page element as part of the body of the component. The body of a
+     * component is defined as the portion of the container's template directly enclosed by component's start and end
+     * elements.
+     */
+    void addToBody(PageElement element);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/CommentPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/CommentPageElement.java
new file mode 100644
index 0000000..d75933e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/CommentPageElement.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.parser.CommentToken;
+import org.apache.tapestry.runtime.RenderQueue;
+
+/**
+ * Renders a text comment.
+ *
+ * @see CommentToken
+ */
+public class CommentPageElement implements PageElement
+{
+    private final String text;
+
+    public CommentPageElement(final String text)
+    {
+        this.text = text;
+    }
+
+    public void render(MarkupWriter writer, RenderQueue queue)
+    {
+        writer.comment(text);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("Comment[%s]", text);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentCallback.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentCallback.java
new file mode 100644
index 0000000..84439fb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentCallback.java
@@ -0,0 +1,28 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.runtime.Component;

+

+/**

+ * Callback interface, used when invoking lifecycle methods on components.

+ */

+public interface ComponentCallback

+{

+    /**

+     * Callback method, passed a component to operate upon.

+     */

+    void run(Component component);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
new file mode 100644
index 0000000..db2105d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
@@ -0,0 +1,139 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.Block;

+import org.apache.tapestry.ComponentResources;

+import org.apache.tapestry.ComponentResourcesCommon;

+import org.apache.tapestry.internal.InternalComponentResources;

+import org.apache.tapestry.internal.InternalComponentResourcesCommon;

+import org.apache.tapestry.internal.services.Instantiator;

+import org.apache.tapestry.ioc.Location;

+import org.apache.tapestry.model.ParameterModel;

+import org.apache.tapestry.runtime.Component;

+import org.apache.tapestry.runtime.ComponentEvent;

+import org.apache.tapestry.runtime.PageLifecycleListener;

+import org.apache.tapestry.runtime.RenderQueue;

+

+/**

+ * Extended version of {@link org.apache.tapestry.internal.structure.PageElement} for elements that are, in fact,

+ * components (rather than just static markup).

+ */

+public interface ComponentPageElement extends ComponentResourcesCommon, InternalComponentResourcesCommon, PageElement, BodyPageElement, PageLifecycleListener

+{

+    /**

+     * Returns the core component associated with this page element (as opposed to any mixins attached to the

+     * component).

+     */

+    Component getComponent();

+

+    /**

+     * Returns the resources associated with the core component.

+     */

+    InternalComponentResources getComponentResources();

+

+    /**

+     * Returns the page which contains this component.

+     */

+    Page getContainingPage();

+

+    /**

+     * Containing component (or null for the root component of a page).

+     */

+    ComponentPageElement getContainerElement();

+

+    /**

+     * Used during the construction of a page. Adds a page element as part of the template for this page element. A page

+     * element will eventually render by sequentially rendering these elements. A page elements template is really just

+     * the outermost portions of the component's template ... where a template contains elements that are all

+     * components, those components will receive portions of the template as their body.

+     */

+    void addToTemplate(PageElement element);

+

+    /**

+     * Used during the contruction of a page to add a non-anonymous Block to the component.

+     *

+     * @see ComponentResourcesCommon#getBlock(String)

+     */

+    void addBlock(String blockId, Block block);

+

+    /**

+     * Adds a component to its container. The embedded component's id must be unique within the container (after the id

+     * is converted to lower case).

+     */

+    void addEmbeddedElement(ComponentPageElement child);

+

+    /**

+     * Adds a mixin.

+     *

+     * @param instantiator used to instantiate an instance of the mixin

+     */

+    void addMixin(Instantiator instantiator);

+

+    /**

+     * Retrieves a component page element by its id. The search is caseless.

+     *

+     * @param id used to locate the element

+     * @return the page element

+     * @throws IllegalArgumentException if no component exists with the given id

+     */

+    ComponentPageElement getEmbeddedElement(String id);

+

+    /**

+     * Returns the {@link org.apache.tapestry.ComponentResources} for a mixin attached to this component element. Mixin

+     * ids are the simple names of the mixin class.

+     *

+     * @param mixinId the mixin id (case insensitive)

+     * @return the resources for the component

+     * @throws IllegalArgumentException if no mixin with the given id exists

+     */

+    ComponentResources getMixinResources(String mixinId);

+

+    /**

+     * Invoked when the component should render its body.

+     */

+    void enqueueBeforeRenderBody(RenderQueue queue);

+

+    /**

+     * Asks each mixin and component to {@link Component#dispatchComponentEvent(ComponentEvent)}, returning true if any

+     * handler was found.

+     *

+     * @param event to be handled

+     * @return true if a handler was found

+     */

+    boolean dispatchEvent(ComponentEvent event);

+

+    /**

+     * Searches the component (and its mixins) for a formal parameter matching the given name. If found, the {@link

+     * ParameterModel#getDefaultBindingPrefix() default binding prefix} is returned. Otherwise the parameter is an

+     * informal parameter, and null is returned.

+     *

+     * @param parameterName the name of the parameter, possibly qualified with the mixin class name

+     * @return the default binding prefix, or null

+     */

+    String getDefaultBindingPrefix(String parameterName);

+

+    /**

+     * Creates a new child component of the invoked component.  The new element will be added as an embedded element of

+     * its container.

+     *

+     * @param id           simple id of the new component

+     * @param elementName  name of the component's element in its container's template

+     * @param instantiator used to create a component instance, and access the component's model

+     * @param location     location of the element within its container's template

+     * @return the new component

+     */

+    ComponentPageElement newChild(String id, String elementName, Instantiator instantiator, Location location);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
new file mode 100644
index 0000000..baaaeda
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
@@ -0,0 +1,1171 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.services.ComponentEventImpl;
+import org.apache.tapestry.internal.services.EventImpl;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.util.NotificationEventCallback;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.ParameterModel;
+import org.apache.tapestry.runtime.*;
+import org.slf4j.Logger;
+
+import java.util.*;
+
+/**
+ * Implements {@link org.apache.tapestry.internal.structure.PageElement} and represents a component within an overall
+ * page. Much of a component page element's behavior is delegated to user code, via a {@link
+ * org.apache.tapestry.runtime.Component} instance.
+ * <p/>
+ * Once instantiated, a ComponentPageElement should be registered as a {@linkplain
+ * org.apache.tapestry.internal.structure.Page#addLifecycleListener(org.apache.tapestry.runtime.PageLifecycleListener)
+ * lifecycle listener}. This could be done inside the constructors, but that tends to complicate unit tests, so its done
+ * by {@link org.apache.tapestry.internal.services.PageElementFactoryImpl}.
+ * <p/>
+ */
+public class ComponentPageElementImpl extends BaseLocatable implements ComponentPageElement, PageLifecycleListener
+{
+    /**
+     * @see #render(org.apache.tapestry.MarkupWriter, org.apache.tapestry.runtime.RenderQueue)
+     */
+    private static final RenderCommand POP_COMPONENT_ID = new RenderCommand()
+    {
+        public void render(MarkupWriter writer, RenderQueue queue)
+        {
+            queue.endComponent();
+        }
+    };
+
+    private static final ComponentCallback CONTAINING_PAGE_DID_ATTACH = new ComponentCallback()
+    {
+        public void run(Component component)
+        {
+            component.containingPageDidAttach();
+        }
+    };
+
+    private static final ComponentCallback CONTAINING_PAGE_DID_DETACH = new ComponentCallback()
+    {
+        public void run(Component component)
+        {
+            component.containingPageDidDetach();
+        }
+    };
+
+    private static final ComponentCallback CONTAINING_PAGE_DID_LOAD = new ComponentCallback()
+    {
+        public void run(Component component)
+        {
+            component.containingPageDidLoad();
+        }
+    };
+
+    private static final ComponentCallback POST_RENDER_CLEANUP = new ComponentCallback()
+    {
+        public void run(Component component)
+        {
+            component.postRenderCleanup();
+        }
+    };
+
+    // For the moment, every component will have a template, even if it consists of
+    // just a page element to queue up a BeforeRenderBody phase.
+
+    private static void pushElements(RenderQueue queue, List<PageElement> list)
+    {
+        int count = size(list);
+        for (int i = count - 1; i >= 0; i--)
+            queue.push(list.get(i));
+    }
+
+    private static int size(List<?> list)
+    {
+        return list == null ? 0 : list.size();
+    }
+
+    private static class RenderPhaseEventHandler implements ComponentEventCallback
+    {
+        private boolean result = true;
+
+        private List<RenderCommand> commands;
+
+        boolean getResult()
+        {
+            return result;
+        }
+
+        public boolean handleResult(Object result)
+        {
+            if (result instanceof Boolean)
+            {
+                this.result = (Boolean) result;
+                return true; // abort other handler methods
+            }
+
+            if (result instanceof RenderCommand)
+            {
+                RenderCommand command = (RenderCommand) result;
+
+                add(command);
+
+                return false; // do not abort!
+            }
+
+            if (result instanceof Renderable)
+            {
+                final Renderable renderable = (Renderable) result;
+
+                RenderCommand wrapper = new RenderCommand()
+                {
+                    public void render(MarkupWriter writer, RenderQueue queue)
+                    {
+                        renderable.render(writer);
+                    }
+                };
+
+                add(wrapper);
+
+                return false;
+            }
+
+            throw new RuntimeException(StructureMessages.wrongPhaseResultType(Boolean.class));
+        }
+
+        private void add(RenderCommand command)
+        {
+            if (commands == null) commands = CollectionFactory.newList();
+
+            commands.add(command);
+        }
+
+        public void queueCommands(RenderQueue queue)
+        {
+            if (commands == null) return;
+
+            for (RenderCommand command : commands)
+                queue.push(command);
+        }
+    }
+
+    private final RenderCommand afterRender = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.afterRender(writer, event);
+                }
+            };
+
+            invoke(true, callback);
+
+            if (!handler.getResult()) queue.push(beginRender);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("AfterRender");
+        }
+    };
+
+    private final RenderCommand afterRenderBody = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.afterRenderBody(writer, event);
+                }
+            };
+
+            invoke(true, callback);
+
+            if (!handler.getResult()) queue.push(beforeRenderBody);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("AfterRenderBody");
+        }
+    };
+
+    private final RenderCommand afterRenderTemplate = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, final RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.afterRenderTemplate(writer, event);
+                }
+            };
+
+            invoke(true, callback);
+
+            if (!handler.getResult()) queue.push(beforeRenderTemplate);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("AfterRenderTemplate");
+        }
+    };
+
+    private final RenderCommand beforeRenderBody = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.beforeRenderBody(writer, event);
+                }
+            };
+
+            invoke(false, callback);
+
+            queue.push(afterRenderBody);
+
+            if (handler.getResult()) pushElements(queue, body);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("BeforeRenderBody");
+        }
+    };
+
+    private final RenderCommand beforeRenderTemplate = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, final RenderQueue queue)
+        {
+            final RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.beforeRenderTemplate(writer, event);
+                }
+            };
+
+            invoke(false, callback);
+
+            queue.push(afterRenderTemplate);
+
+            if (handler.getResult()) pushElements(queue, template);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("BeforeRenderTemplate");
+        }
+    };
+
+    private final RenderCommand beginRender = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, final RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.beginRender(writer, event);
+                }
+            };
+
+            invoke(false, callback);
+
+            queue.push(afterRender);
+
+            // If the component has no template whatsoever, then a
+            // renderBody element is added as the lone element of the component's template.
+            // So every component will have a non-empty template.
+
+            if (handler.getResult()) queue.push(beforeRenderTemplate);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("BeginRender");
+        }
+    };
+
+    private Map<String, Block> blocks;
+
+    private List<PageElement> body;
+
+    private Map<String, ComponentPageElement> children;
+
+    private final String elementName;
+
+    private final PageResources pageResources;
+
+    private final RenderCommand cleanupRender = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, RenderQueue queue)
+        {
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.cleanupRender(writer, event);
+                }
+            };
+
+            invoke(true, callback);
+
+            if (handler.getResult())
+            {
+                rendering = false;
+
+                Element current = writer.getElement();
+
+                if (current != elementAtSetup)
+                    throw new TapestryException(StructureMessages.unbalancedElements(completeId), getLocation(), null);
+
+                elementAtSetup = null;
+
+                invoke(false, POST_RENDER_CLEANUP);
+
+                // NOW and only now the component is done rendering and fully cleaned up. Decrement
+                // the page's dirty count. If the entire render goes well, then the page will be
+                // clean and can be stored into the pool for later reuse.
+
+                page.decrementDirtyCount();
+            }
+            else
+            {
+                queue.push(setupRender);
+            }
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("CleanupRender");
+        }
+    };
+
+    private final String completeId;
+
+    // The user-provided class, with runtime code enhancements. In a component with mixins, this
+    // is the component to which the mixins are attached.
+    private final Component coreComponent;
+
+    /**
+     * Component lifecycle instances for all mixins; the core component is added to this list during page load. This is
+     * only used in the case that a component has mixins (in which case, the core component is listed last).
+     */
+    private List<Component> components = null;
+
+    private final ComponentPageElement container;
+
+    private final InternalComponentResources coreResources;
+
+    private final String id;
+
+    private boolean loaded;
+
+    /**
+     * Map from mixin id (the simple name of the mixin class) to resources for the mixin. Created when first mixin is
+     * added.
+     */
+    private Map<String, InternalComponentResources> mixinIdToComponentResources;
+
+    private final String nestedId;
+
+    private final Page page;
+
+    private boolean rendering;
+
+    /**
+     * Used to detect mismatches calls to {@link MarkupWriter#element(String, Object[])} } and {@link
+     * org.apache.tapestry.MarkupWriter#end()}.  The expectation is that any element(s) begun by this component during
+     * rendering will be balanced by end() calls, resulting in the current element reverting to its initial value.
+     */
+    private Element elementAtSetup;
+
+    private final RenderCommand setupRender = new RenderCommand()
+    {
+        public void render(final MarkupWriter writer, RenderQueue queue)
+        {
+            // TODO: Check for recursive rendering.
+
+            rendering = true;
+
+            elementAtSetup = writer.getElement();
+
+            RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
+            final Event event = new EventImpl(handler);
+
+            ComponentCallback callback = new ComponentCallback()
+            {
+                public void run(Component component)
+                {
+                    component.setupRender(writer, event);
+                }
+            };
+
+            invoke(false, callback);
+
+            queue.push(cleanupRender);
+
+            if (handler.getResult()) queue.push(beginRender);
+
+            handler.queueCommands(queue);
+        }
+
+        @Override
+        public String toString()
+        {
+            return phaseToString("SetupRender");
+        }
+    };
+
+    // We know that, at the very least, there will be an element to force the component to render
+    // its body, so there's no reason to wait to initialize the list.
+
+    private final List<PageElement> template = CollectionFactory.newList();
+
+
+    public ComponentPageElement newChild(String id, String elementName, Instantiator instantiator, Location location)
+    {
+        ComponentPageElementImpl child = new ComponentPageElementImpl(page, this, id, elementName, instantiator,
+                                                                      location, pageResources);
+
+        addEmbeddedElement(child);
+
+        return child;
+    }
+
+    /**
+     * Constructor for other components embedded within the root component or at deeper levels of the hierarchy.
+     *
+     * @param page          ultimately containing this component
+     * @param container     component immediately containing this component (may be null for a root component)
+     * @param id            unique (within the container) id for this component (may be null for a root component)
+     * @param elementName   the name of the element which represents this component in the template, or null for
+     *                      &lt;comp&gt; element or a page component
+     * @param instantiator  used to create the new component instance and access the component's model
+     * @param location      location of the element (within a template), used as part of exception reporting
+     * @param pageResources Provides access to common methods of various services
+     */
+
+    ComponentPageElementImpl(Page page, ComponentPageElement container, String id, String elementName,
+                             Instantiator instantiator, Location location, PageResources pageResources)
+    {
+        super(location);
+
+        this.page = page;
+        this.container = container;
+        this.id = id;
+        this.elementName = elementName;
+        this.pageResources = pageResources;
+
+        ComponentResources containerResources = container == null
+                                                ? null
+                                                : container.getComponentResources();
+
+        String pageName = this.page.getLogicalName();
+
+        // A page (really, the root component of a page) does not have a container.
+
+        if (container == null)
+        {
+            completeId = pageName;
+            nestedId = null;
+        }
+        else
+        {
+            String caselessId = id.toLowerCase();
+
+            String parentNestedId = container.getNestedId();
+
+            // The root element has no nested id.
+            // The children of the root element have an id.
+
+            if (parentNestedId == null)
+            {
+                nestedId = caselessId;
+                completeId = pageName + ":" + caselessId;
+            }
+            else
+            {
+                nestedId = parentNestedId + "." + caselessId;
+                completeId = container.getCompleteId() + "." + caselessId;
+            }
+        }
+
+        coreResources = new InternalComponentResourcesImpl(this.page, this, containerResources, this.pageResources,
+                                                           completeId, nestedId, instantiator);
+
+        coreComponent = coreResources.getComponent();
+    }
+
+    /**
+     * Constructor for the root component of a page.
+     */
+    public ComponentPageElementImpl(Page page, Instantiator instantiator, PageResources pageResources)
+    {
+        this(page, null, null, null, instantiator, null, pageResources);
+    }
+
+    public void addEmbeddedElement(ComponentPageElement child)
+    {
+        if (children == null) children = CollectionFactory.newCaseInsensitiveMap();
+
+        String childId = child.getId();
+
+        ComponentPageElement existing = children.get(childId);
+        if (existing != null)
+            throw new TapestryException(StructureMessages.duplicateChildComponent(this, childId), child, null);
+
+        children.put(childId, child);
+    }
+
+    public void addMixin(Instantiator instantiator)
+    {
+        if (mixinIdToComponentResources == null)
+        {
+            mixinIdToComponentResources = CollectionFactory.newCaseInsensitiveMap();
+            components = CollectionFactory.newList();
+        }
+
+        String mixinClassName = instantiator.getModel().getComponentClassName();
+        String mixinName = TapestryInternalUtils.lastTerm(mixinClassName);
+
+        String mixinExtension = "$" + mixinName.toLowerCase();
+
+        InternalComponentResourcesImpl resources = new InternalComponentResourcesImpl(page, this, coreResources,
+                                                                                      pageResources,
+                                                                                      completeId + mixinExtension,
+                                                                                      nestedId + mixinExtension,
+                                                                                      instantiator);
+
+        // TODO: Check for name collision?
+
+        mixinIdToComponentResources.put(mixinName, resources);
+
+        components.add(resources.getComponent());
+    }
+
+    public void bindParameter(String parameterName, Binding binding)
+    {
+        // Maybe should use colon here? Depends on what works best in the template,
+        // don't want to lock this out as just
+        int dotx = parameterName.lastIndexOf('.');
+
+        if (dotx > 0)
+        {
+            String mixinName = parameterName.substring(0, dotx);
+            InternalComponentResources mixinResources = InternalUtils.get(mixinIdToComponentResources, mixinName);
+
+            if (mixinResources == null) throw new TapestryException(
+                    StructureMessages.missingMixinForParameter(completeId, mixinName, parameterName), binding, null);
+
+            String simpleName = parameterName.substring(dotx + 1);
+
+            mixinResources.bindParameter(simpleName, binding);
+            return;
+        }
+
+        InternalComponentResources informalParameterResources = null;
+
+        // Does it match a formal parameter name of the core component? That takes precedence
+
+        if (coreResources.getComponentModel().getParameterModel(parameterName) != null)
+        {
+            coreResources.bindParameter(parameterName, binding);
+            return;
+        }
+
+        for (String mixinName : InternalUtils.sortedKeys(mixinIdToComponentResources))
+        {
+            InternalComponentResources resources = mixinIdToComponentResources.get(mixinName);
+            if (resources.getComponentModel().getParameterModel(parameterName) != null)
+            {
+                resources.bindParameter(parameterName, binding);
+                return;
+            }
+
+            if (informalParameterResources == null && resources.getComponentModel().getSupportsInformalParameters())
+                informalParameterResources = resources;
+        }
+
+        // An informal parameter
+
+        if (informalParameterResources == null && coreResources.getComponentModel().getSupportsInformalParameters())
+            informalParameterResources = coreResources;
+
+        // For the moment, informal parameters accumulate in the core component's resources, but
+        // that will likely change.
+
+        if (informalParameterResources != null) informalParameterResources.bindParameter(parameterName, binding);
+    }
+
+    public void addToBody(PageElement element)
+    {
+        if (body == null) body = CollectionFactory.newList();
+
+        body.add(element);
+    }
+
+    public void addToTemplate(PageElement element)
+    {
+        template.add(element);
+    }
+
+    private void addUnboundParameterNames(String prefix, List<String> unbound, InternalComponentResources resource)
+    {
+        ComponentModel model = resource.getComponentModel();
+
+        for (String name : model.getParameterNames())
+        {
+            if (resource.isBound(name)) continue;
+
+            ParameterModel parameterModel = model.getParameterModel(name);
+
+            if (parameterModel.isRequired())
+            {
+                String fullName = prefix == null ? name : prefix + "." + name;
+
+                unbound.add(fullName);
+            }
+        }
+    }
+
+    public void containingPageDidAttach()
+    {
+        invoke(false, CONTAINING_PAGE_DID_ATTACH);
+    }
+
+    public void containingPageDidDetach()
+    {
+        invoke(false, CONTAINING_PAGE_DID_DETACH);
+    }
+
+    public void containingPageDidLoad()
+    {
+        // If this component has mixins, add the core component to the end of the list, after the
+        // mixins.
+
+        if (components != null)
+        {
+            List<Component> ordered = CollectionFactory.newList();
+
+            Iterator<Component> i = components.iterator();
+
+            // Add all the normal components to the final list.
+
+            while (i.hasNext())
+            {
+                Component mixin = i.next();
+
+                if (mixin.getComponentResources().getComponentModel().isMixinAfter()) continue;
+
+                ordered.add(mixin);
+
+                // Remove from list, leaving just the late executing mixins
+
+                i.remove();
+            }
+
+            ordered.add(coreComponent);
+
+            // Add the remaining, late executing mixins
+
+            ordered.addAll(components);
+
+            components = ordered;
+        }
+
+        loaded = true;
+
+        // For some parameters, bindings (from defaults) are provided inside the callback method, so
+        // that is invoked first, before we check for unbound parameters.
+
+        invoke(false, CONTAINING_PAGE_DID_LOAD);
+
+        verifyRequiredParametersAreBound();
+    }
+
+
+    public void enqueueBeforeRenderBody(RenderQueue queue)
+    {
+        // If no body, then no beforeRenderBody or afterRenderBody
+
+        if (body != null) queue.push(beforeRenderBody);
+    }
+
+    public String getCompleteId()
+    {
+        return completeId;
+    }
+
+    public Component getComponent()
+    {
+        return coreComponent;
+    }
+
+    public InternalComponentResources getComponentResources()
+    {
+        return coreResources;
+    }
+
+    public ComponentPageElement getContainerElement()
+    {
+        return container;
+    }
+
+    public Page getContainingPage()
+    {
+        return page;
+    }
+
+    public ComponentPageElement getEmbeddedElement(String embeddedId)
+    {
+        ComponentPageElement embeddedElement = InternalUtils.get(children, embeddedId
+                .toLowerCase());
+
+        if (embeddedElement == null)
+        {
+            Set<String> ids = children == null ? null : children.keySet();
+
+            throw new TapestryException(StructureMessages.noSuchComponent(this, embeddedId, ids), this, null);
+        }
+
+        return embeddedElement;
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public Logger getLogger()
+    {
+        return coreResources.getLogger();
+    }
+
+    public Component getMixinByClassName(String mixinClassName)
+    {
+        Component result = null;
+
+        if (mixinIdToComponentResources != null)
+        {
+            for (InternalComponentResources resources : mixinIdToComponentResources.values())
+            {
+                if (resources.getComponentModel().getComponentClassName().equals(mixinClassName))
+                {
+                    result = resources.getComponent();
+                    break;
+                }
+            }
+        }
+
+        if (result == null) throw new TapestryException(StructureMessages.unknownMixin(completeId, mixinClassName),
+                                                        getLocation(), null);
+
+        return result;
+    }
+
+    public ComponentResources getMixinResources(String mixinId)
+    {
+        ComponentResources result = null;
+
+        if (mixinIdToComponentResources != null)
+            result = mixinIdToComponentResources.get(mixinId);
+
+        if (result == null)
+            throw new IllegalArgumentException(
+                    String.format("Unable to locate mixin '%s' for component '%s'.", mixinId, completeId));
+
+        return result;
+    }
+
+    public String getNestedId()
+    {
+        return nestedId;
+    }
+
+    public boolean dispatchEvent(ComponentEvent event)
+    {
+        if (components == null) return coreComponent.dispatchComponentEvent(event);
+
+        // Otherwise, iterate over mixins + core component
+
+        boolean result = false;
+
+        for (Component component : components)
+        {
+            result |= component.dispatchComponentEvent(event);
+
+            if (event.isAborted()) break;
+        }
+
+        return result;
+    }
+
+    /**
+     * Invokes a callback on the component instances (the core component plus any mixins).
+     *
+     * @param reverse  if true, the callbacks are in the reverse of the normal order (this is associated with AfterXXX
+     *                 phases)
+     * @param callback the object to receive each component instance
+     */
+    private void invoke(boolean reverse, ComponentCallback callback)
+    {
+        try
+        { // Optimization: In the most general case (just the one component, no mixins)
+            // invoke the callback on the component and be done ... no iterators, no nothing.
+
+            if (components == null)
+            {
+                callback.run(coreComponent);
+                return;
+            }
+
+            Iterator<Component> i = reverse ? InternalUtils.reverseIterator(components) : components.iterator();
+
+            while (i.hasNext()) callback.run(i.next());
+        }
+        catch (RuntimeException ex)
+        {
+            throw new TapestryException(ex.getMessage(), getLocation(), ex);
+        }
+    }
+
+    public boolean isLoaded()
+    {
+        return loaded;
+    }
+
+    public boolean isRendering()
+    {
+        return rendering;
+    }
+
+    /**
+     * Generate a toString() for the inner classes that represent render phases.
+     */
+    private String phaseToString(String phaseName)
+    {
+        return String.format("%s[%s]", phaseName, completeId);
+    }
+
+
+    /**
+     * Pushes the SetupRender phase state onto the queue.
+     */
+    public final void render(MarkupWriter writer, RenderQueue queue)
+    {
+        // TODO: An error if the _render flag is already set (recursive rendering not
+        // allowed or advisable).
+
+        // Once we start rendering, the page is considered dirty, until we cleanup post render.
+
+        page.incrementDirtyCount();
+
+        queue.startComponent(coreResources);
+
+        queue.push(POP_COMPONENT_ID);
+
+        queue.push(setupRender);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("ComponentPageElement[%s]", completeId);
+    }
+
+    public boolean triggerEvent(String eventType, Object[] contextValues, ComponentEventCallback callback)
+    {
+        return triggerContextEvent(eventType,
+                                   createParameterContext(contextValues == null ? new Object[0] : contextValues),
+                                   callback);
+    }
+
+    private EventContext createParameterContext(final Object... values)
+    {
+
+        return new EventContext()
+        {
+            public int getCount()
+            {
+                return values.length;
+            }
+
+            public <T> T get(Class<T> desiredType, int index)
+            {
+                return pageResources.coerce(values[index], desiredType);
+            }
+        };
+    }
+
+
+    public boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback)
+    {
+        Defense.notBlank(eventType, "eventType");
+        Defense.notNull(context, "context");
+
+        boolean result = false;
+
+        ComponentPageElement component = this;
+        String componentId = "";
+
+        // Provide a default handler for when the provided handler is null.
+        final ComponentEventCallback providedHandler = callback == null ? new NotificationEventCallback(eventType,
+                                                                                                        completeId) : callback;
+
+        ComponentEventCallback wrapped = new ComponentEventCallback()
+        {
+            public boolean handleResult(Object result)
+            {
+                // Boolean value is not passed to the handler; it will be true (abort event)
+                // or false (continue looking for event handlers).
+
+                if (result instanceof Boolean) return (Boolean) result;
+
+                return providedHandler.handleResult(result);
+            }
+        };
+
+        RuntimeException rootException = null;
+
+        // Because I don't like to reassign parameters.
+
+        String currentEventType = eventType;
+        EventContext currentContext = context;
+
+        // Track the location of the original component for the event, even as we work our way up
+        // the hierarchy. This may not be ideal if we trigger an "exception" event ... or maybe
+        // it's right (it's the location of the originally thrown exception).
+
+        Location location = component.getComponentResources().getLocation();
+
+        while (component != null)
+        {
+            try
+            {
+                ComponentEvent event = new ComponentEventImpl(currentEventType, componentId, currentContext, wrapped,
+                                                              pageResources);
+
+                result |= component.dispatchEvent(event);
+
+                if (event.isAborted()) return result;
+            }
+            catch (RuntimeException ex)
+            {
+                // An exception in an event handler method
+                // while we're trying to handle a previous exception!
+
+                if (rootException != null) throw rootException;
+
+                // We know component is not null and therefore has a component resources that
+                // should have a location.
+
+                // Wrap it up to help ensure that a location is available to the event handler method or,
+                // more likely, to the exception report page.
+
+                rootException = new ComponentEventException(ex.getMessage(), eventType, context, location, ex);
+
+                // Switch over to triggering an "exception" event, starting in the component that
+                // threw the exception.
+
+                currentEventType = "exception";
+                currentContext = createParameterContext(rootException);
+
+                continue;
+            }
+
+            // On each bubble up, make the event appear to come from the previous component
+            // in which the event was triggered.
+
+            componentId = component.getId();
+
+            component = component.getContainerElement();
+        }
+
+        // If there was a handler for the exception event, it is required to return a non-null (and non-boolean) value
+        // to tell Tapestry what to do.  Since that didn't happen, we have no choice but to rethrow the (wrapped)
+        // exception.
+
+        if (rootException != null) throw rootException;
+
+        return result;
+    }
+
+    private void verifyRequiredParametersAreBound()
+    {
+        List<String> unbound = CollectionFactory.newList();
+
+        addUnboundParameterNames(null, unbound, coreResources);
+
+        for (String name : InternalUtils.sortedKeys(mixinIdToComponentResources))
+            addUnboundParameterNames(name, unbound, mixinIdToComponentResources.get(name));
+
+        if (unbound.isEmpty()) return;
+
+        throw new TapestryException(StructureMessages.missingParameters(unbound, this), this, null);
+    }
+
+    public Locale getLocale()
+    {
+        return page.getLocale();
+    }
+
+    public String getElementName(String defaultElementName)
+    {
+        return elementName != null ? elementName : defaultElementName;
+    }
+
+    public Block getBlock(String id)
+    {
+        Block result = findBlock(id);
+
+        if (result == null)
+            throw new BlockNotFoundException(StructureMessages.blockNotFound(completeId, id), getLocation());
+
+        return result;
+    }
+
+    public Block findBlock(String id)
+    {
+        notBlank(id, "id");
+
+        return InternalUtils.get(blocks, id);
+    }
+
+    public void addBlock(String blockId, Block block)
+    {
+        if (blocks == null) blocks = CollectionFactory.newCaseInsensitiveMap();
+
+        if (blocks.containsKey(blockId))
+            throw new TapestryException(StructureMessages.duplicateBlock(this, blockId), block, null);
+
+        blocks.put(blockId, block);
+    }
+
+    public String getDefaultBindingPrefix(String parameterName)
+    {
+        int dotx = parameterName.lastIndexOf('.');
+
+        if (dotx > 0)
+        {
+            String mixinName = parameterName.substring(0, dotx);
+            InternalComponentResources mixinResources = InternalUtils.get(mixinIdToComponentResources, mixinName);
+
+            if (mixinResources == null) throw new TapestryException(
+                    StructureMessages.missingMixinForParameter(completeId, mixinName, parameterName), null, null);
+
+            String simpleName = parameterName.substring(dotx + 1);
+
+            ParameterModel pm = mixinResources.getComponentModel().getParameterModel(simpleName);
+
+            return pm != null ? pm.getDefaultBindingPrefix() : null;
+        }
+
+        // A formal parameter of the core component?
+
+        ParameterModel pm = coreResources.getComponentModel().getParameterModel(parameterName);
+
+        if (pm != null) return pm.getDefaultBindingPrefix();
+
+        // Search for mixin that it is a formal parameter of
+
+        for (String mixinName : InternalUtils.sortedKeys(mixinIdToComponentResources))
+        {
+            InternalComponentResources resources = mixinIdToComponentResources.get(mixinName);
+
+            pm = resources.getComponentModel().getParameterModel(parameterName);
+
+            if (pm != null) return pm.getDefaultBindingPrefix();
+        }
+
+        // Not a formal parameter of the core component or any mixin.
+
+        return null;
+    }
+
+    public String getPageName()
+    {
+        return page.getLogicalName();
+    }
+
+    public Map<String, Binding> getInformalParameterBindings()
+    {
+        return coreResources.getInformalParameterBindings();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/DTDPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/DTDPageElement.java
new file mode 100644
index 0000000..294d6ff
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/DTDPageElement.java
@@ -0,0 +1,51 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+ * Created on Mar 15, 2007
+ * 
+ * 
+ */
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.RenderQueue;
+
+public class DTDPageElement implements PageElement
+{
+    private final String name;
+
+    private final String publicId;
+
+    private final String systemId;
+
+    public DTDPageElement(String name, String publicId, String systemId)
+    {
+        this.name = name;
+        this.publicId = publicId;
+        this.systemId = systemId;
+    }
+
+    public void render(MarkupWriter writer, RenderQueue queue)
+    {
+        writer.getDocument().dtd(name, publicId, systemId);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("DTD[name=%s; publicId=%s; systemId=%s]", name, publicId, systemId);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java
new file mode 100644
index 0000000..3f8d58f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ExpansionPageElement.java
@@ -0,0 +1,63 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.Binding;

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.ioc.services.TypeCoercer;

+import org.apache.tapestry.runtime.RenderQueue;

+

+/**

+ *

+ */

+public class ExpansionPageElement implements PageElement

+{

+    private final Binding binding;

+

+    private final boolean invariant;

+

+    private final TypeCoercer coercer;

+

+    private boolean cached;

+

+    private String cachedValue;

+

+    public ExpansionPageElement(Binding binding, TypeCoercer coercer)

+    {

+        this.binding = binding;

+        this.coercer = coercer;

+

+        invariant = this.binding.isInvariant();

+    }

+

+    public void render(MarkupWriter writer, RenderQueue queue)

+    {

+        String value = cached ? cachedValue : coercer.coerce(binding.get(), String.class);

+

+        if (invariant && !cached)

+        {

+            cachedValue = value;

+            cached = true;

+        }

+

+        writer.write(value);

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Expansion[%s]", binding.toString());

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
new file mode 100644
index 0000000..b3ce43d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
@@ -0,0 +1,449 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.slf4j.Logger;
+
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * The bridge between a component and its {@link ComponentPageElement}, that supplies all kinds of resources to the
+ * component, including access to its parameters, parameter bindings, and persistent field data.
+ */
+public class InternalComponentResourcesImpl implements InternalComponentResources
+{
+    private final Page page;
+
+    private final String completeId;
+
+    private final String nestedId;
+
+    private final ComponentModel componentModel;
+
+    private final ComponentPageElement element;
+
+    private final Component component;
+
+    private final ComponentResources containerResources;
+
+    private final PageResources pageResources;
+
+    // Case insensitive
+    private Map<String, Binding> bindings;
+
+    private Messages messages;
+
+    // Case insensitive
+    private Map<String, Object> renderVariables;
+
+    public InternalComponentResourcesImpl(Page page, ComponentPageElement element,
+                                          ComponentResources containerResources, PageResources pageResources,
+                                          String completeId, String nestedId, Instantiator componentInstantiator
+    )
+    {
+        this.page = page;
+        this.element = element;
+        this.containerResources = containerResources;
+        this.pageResources = pageResources;
+        this.completeId = completeId;
+        this.nestedId = nestedId;
+
+        componentModel = componentInstantiator.getModel();
+        component = componentInstantiator.newInstance(this);
+    }
+
+    public Location getLocation()
+    {
+        return element.getLocation();
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("InternalComponentResources[%s]", getCompleteId());
+    }
+
+    public ComponentModel getComponentModel()
+    {
+        return componentModel;
+    }
+
+    public Component getEmbeddedComponent(String embeddedId)
+    {
+        return element.getEmbeddedElement(embeddedId).getComponent();
+    }
+
+    public Object getFieldChange(String fieldName)
+    {
+        return page.getFieldChange(nestedId, fieldName);
+    }
+
+    public String getId()
+    {
+        return element.getId();
+    }
+
+    public boolean hasFieldChange(String fieldName)
+    {
+        return getFieldChange(fieldName) != null;
+    }
+
+    /**
+     * Delegates to the {@link Page#createActionLink(String, String, boolean, Object[])} on the containing page. Uses
+     * the element's nested id (i.e., a mixin can generate a link, but the link targets the component, not the mixin
+     * itself). Why the extra layer? Trying to avoid some unwanted injection (of LinkFactory, into every component page
+     * element).
+     */
+    public Link createActionLink(String action, boolean forForm, Object... context)
+    {
+        return page.createActionLink(element.getNestedId(), action, forForm, context);
+    }
+
+    public Link createPageLink(String pageName, boolean override, Object... context)
+    {
+        return page.createPageLink(pageName, override, context);
+    }
+
+    public void discardPersistentFieldChanges()
+    {
+        page.discardPersistentFieldChanges();
+    }
+
+    public String getElementName()
+    {
+        return getElementName(null);
+    }
+
+    public String getCompleteId()
+    {
+        return completeId;
+    }
+
+    public Component getComponent()
+    {
+        return component;
+    }
+
+    public boolean isBound(String parameterName)
+    {
+        return getBinding(parameterName) != null;
+    }
+
+    public <T extends Annotation> T getParameterAnnotation(String parameterName, Class<T> annotationType)
+    {
+        Binding b = getBinding(parameterName);
+
+        if (b == null) return null;
+
+        return b.getAnnotation(annotationType);
+    }
+
+    public boolean isRendering()
+    {
+        return element.isRendering();
+    }
+
+    public boolean triggerEvent(String eventType, Object[] context, ComponentEventCallback handler)
+    {
+        return element.triggerEvent(eventType, context, handler);
+    }
+
+    public boolean triggerContextEvent(String eventType, EventContext context, ComponentEventCallback callback)
+    {
+        return element.triggerContextEvent(eventType, context, callback);
+    }
+
+    public String getNestedId()
+    {
+        return nestedId;
+    }
+
+    public Component getPage()
+    {
+        return element.getContainingPage().getRootComponent();
+    }
+
+    public boolean isInvariant(String parameterName)
+    {
+        Binding b = getBinding(parameterName);
+
+        return b != null && b.isInvariant();
+    }
+
+    public boolean isLoaded()
+    {
+        return element.isLoaded();
+    }
+
+    public void persistFieldChange(String fieldName, Object newValue)
+    {
+        try
+        {
+            page.persistFieldChange(this, fieldName, newValue);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(StructureMessages.fieldPersistFailure(getCompleteId(), fieldName, ex),
+                                        getLocation(), ex);
+        }
+    }
+
+    public void bindParameter(String parameterName, Binding binding)
+    {
+        if (bindings == null) bindings = CollectionFactory.newCaseInsensitiveMap();
+
+        bindings.put(parameterName, binding);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T readParameter(String parameterName, Class<T> expectedType)
+    {
+        Binding b = getBinding(parameterName);
+
+        try
+        {
+            // Will throw NPE if binding is null, but this should never be called if the
+            // parameter is not bound.
+
+            Object boundValue = b.get();
+
+            return pageResources.coerce(boundValue, expectedType);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(StructureMessages.getParameterFailure(parameterName, getCompleteId(), ex), b,
+                                        ex);
+        }
+    }
+
+    public Object readParameter(String parameterName, String desiredTypeName)
+    {
+        Class parameterType = pageResources.toClass(desiredTypeName);
+
+        return readParameter(parameterName, parameterType);
+    }
+
+    public Class getBoundType(String parameterName)
+    {
+        Binding b = getBinding(parameterName);
+
+        return b != null ? b.getBindingType() : null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> void writeParameter(String parameterName, T parameterValue)
+    {
+        Binding b = getBinding(parameterName);
+
+        Class bindingType = b.getBindingType();
+
+        try
+        {
+            Object coerced = pageResources.coerce(parameterValue, bindingType);
+
+            b.set(coerced);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(StructureMessages.writeParameterFailure(parameterName, getCompleteId(), ex), b,
+                                        ex);
+        }
+    }
+
+    private Binding getBinding(String parameterName)
+    {
+        return bindings == null ? null : bindings.get(parameterName);
+    }
+
+    public AnnotationProvider getAnnotationProvider(String parameterName)
+    {
+        return getBinding(parameterName);
+    }
+
+    public Logger getLogger()
+    {
+        return componentModel.getLogger();
+    }
+
+    public Component getMixinByClassName(String mixinClassName)
+    {
+        return element.getMixinByClassName(mixinClassName);
+    }
+
+    public void renderInformalParameters(MarkupWriter writer)
+    {
+        if (bindings == null) return;
+
+        for (String name : bindings.keySet())
+        {
+            // Skip all formal parameters.
+
+            if (componentModel.getParameterModel(name) != null) continue;
+
+            Binding b = bindings.get(name);
+
+            Object value = b.get();
+
+            if (value == null) continue;
+
+            // Because Blocks can be passed in (right from the template, using <t:parameter>,
+            // we want to skip those when rending informal parameters.
+
+            if (value instanceof Block) continue;
+
+            String valueString = pageResources.coerce(value, String.class);
+
+            writer.attributes(name, valueString);
+        }
+    }
+
+    public Component getContainer()
+    {
+        if (containerResources == null) return null;
+
+        return containerResources.getComponent();
+    }
+
+    public ComponentResources getContainerResources()
+    {
+        return containerResources;
+    }
+
+    public Messages getContainerMessages()
+    {
+        return containerResources != null ? containerResources.getMessages() : null;
+    }
+
+    public Locale getLocale()
+    {
+        return element.getLocale();
+    }
+
+    public Messages getMessages()
+    {
+        if (messages == null) messages = pageResources.getMessages(componentModel);
+
+        return messages;
+    }
+
+    public String getElementName(String defaultElementName)
+    {
+        return element.getElementName(defaultElementName);
+    }
+
+    public void queueRender(RenderQueue queue)
+    {
+        queue.push(element);
+    }
+
+    public Block getBlock(String blockId)
+    {
+        return element.getBlock(blockId);
+    }
+
+    public Block getBlockParameter(String parameterName)
+    {
+        // Is allowed explicitly to not exist and be informal, otherwise the
+        // component in question would just use @Parameter.
+
+        if (getBinding(parameterName) != null) return readParameter(parameterName, Block.class);
+
+        return null;
+    }
+
+    public Block findBlock(String blockId)
+    {
+        return element.findBlock(blockId);
+    }
+
+    public Resource getBaseResource()
+    {
+        return componentModel.getBaseResource();
+    }
+
+    public String getPageName()
+    {
+        return element.getPageName();
+    }
+
+    public Map<String, Binding> getInformalParameterBindings()
+    {
+        Map<String, Binding> result = CollectionFactory.newMap();
+
+        if (bindings != null)
+        {
+            for (String name : bindings.keySet())
+            {
+
+                if (componentModel.getParameterModel(name) != null) continue;
+
+                result.put(name, bindings.get(name));
+            }
+        }
+
+        return result;
+    }
+
+    public Object getRenderVariable(String name)
+    {
+        Object result = InternalUtils.get(renderVariables, name);
+
+        if (result == null) throw new IllegalArgumentException(StructureMessages.missingRenderVariable(getCompleteId(),
+                                                                                                       name,
+                                                                                                       renderVariables == null ? null : renderVariables.keySet()));
+
+        return result;
+    }
+
+    public void storeRenderVariable(String name, Object value)
+    {
+        Defense.notBlank(name, "name");
+        Defense.notNull(value, "value");
+
+        if (!element.isRendering())
+            throw new IllegalStateException(StructureMessages.renderVariableSetWhenNotRendering(getCompleteId(), name));
+
+        if (renderVariables == null) renderVariables = CollectionFactory.newCaseInsensitiveMap();
+
+        renderVariables.put(name, value);
+    }
+
+    public void postRenderCleanup()
+    {
+        if (renderVariables != null) renderVariables.clear();
+    }
+
+    public void addPageLifecycleListener(PageLifecycleListener listener)
+    {
+        page.addLifecycleListener(listener);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java
new file mode 100644
index 0000000..910195e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/Page.java
@@ -0,0 +1,164 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+import org.slf4j.Logger;
+
+import java.util.Locale;
+
+/**
+ * Represents a unique page within the application. Pages are part of the <em>internal</em> structure of a Tapestry
+ * application; end developers who refer to "page" are really referring to the {@link #getRootComponent() root
+ * component} of the actual page.
+ * <p/>
+ * One of the most important aspects of a Page is that it <em>does not</em> have to be coded in a thread-safe manner.
+ * Pages are always accessed within a single thread, associated with a single incoming request.
+ * <p/>
+ * The Page object is never visible to end-user code. The page also exists to provide a kind of service to components
+ * embedded (directly or indirectly) within the page.
+ */
+public interface Page
+{
+    /**
+     * Returns the short, logical name for the page. This is the page name as it might included in an action or page
+     * render URL (though it will be converted to lower case when it is included).
+     */
+    String getLogicalName();
+
+    /**
+     * The locale for which the page is localized. This is set when the page is created and does not change.
+     */
+    Locale getLocale();
+
+    /**
+     * Invoked during page construction time to connect the page's root component to the page instance.
+     */
+    void setRootElement(ComponentPageElement component);
+
+    /**
+     * The root component of the page. This is the wrapper around the end developer's view of the page.
+     */
+    ComponentPageElement getRootElement();
+
+    /**
+     * The root component of the page. A convenience over invoking getRootElement().getComponent().
+     */
+    Component getRootComponent();
+
+    /**
+     * Invoked to inform the page that it is being detached from the current request. This occurs just before the page
+     * is returned to the page pool.
+     * <p/>
+     * A page may be clean or dirty. A page is dirty if its dirty count is greater than zero (meaning that, during the
+     * render of the page, some components did not fully render), or if any of its listeners throw an exception from
+     * containingPageDidDetech().
+     * <p/>
+     * The page pool should discard pages that are dirty, rather than store them into the pool.
+     *
+     * @return true if the page is "dirty", false otherwise
+     * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidDetach()
+     */
+    boolean detached();
+
+    /**
+     * Invoked to inform the page that it is attached to the current request. This occurs when a page is first
+     * referenced within a request. If the page was created from scratch for this request, the call to {@link #loaded()}
+     * will preceded the call to {@link #attached()}.
+     */
+
+    void attached();
+
+    /**
+     * Inform the page that it is now completely loaded.
+     *
+     * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()
+     */
+
+    void loaded();
+
+    /**
+     * Adds a listener that is notified of large scale page events.
+     */
+    void addLifecycleListener(PageLifecycleListener listener);
+
+    /**
+     * Returns the logger of the root component element. Any logging about page construction or activity should be sent
+     * to this logger.
+     */
+    Logger getLogger();
+
+    /**
+     * Retrieves a component element by its nested id (a sequence of simple ids, separated by dots). The individual
+     * names in the nested id are matched without regards to case. A nested id of '' (the empty string) returns the root
+     * element of the page.
+     *
+     * @throws IllegalArgumentException if the nestedId does not correspond to a component
+     */
+    ComponentPageElement getComponentElementByNestedId(String nestedId);
+
+    /**
+     * Creates a link that will trigger behavior in a component within the page.
+     *
+     * @see org.apache.tapestry.ComponentResources#createActionLink(String, boolean, Object[])
+     */
+    Link createActionLink(String nestedId, String eventType, boolean forForm, Object... context);
+
+    /**
+     * Creates a link to the named page.
+     *
+     * @see org.apache.tapestry.ComponentResources#createPageLink(String, boolean, Object[])
+     */
+    Link createPageLink(String pageName, boolean override, Object... context);
+
+    /**
+     * Posts a change to a persistent field.
+     *
+     * @param resources the component resources for the component or mixin containing the field whose value changed
+     * @param fieldName the name of the field
+     * @param newValue  the new value for the field
+     */
+    void persistFieldChange(ComponentResources resources, String fieldName, Object newValue);
+
+    /**
+     * Gets a change for a field within the component.
+     *
+     * @param nestedId  the nested component id of the component containing the field
+     * @param fieldName the name of the persistent field
+     * @return the value, or null if no value is stored
+     */
+    Object getFieldChange(String nestedId, String fieldName);
+
+    /**
+     * Called as a component initially starts to render itself. This is used to check for the cases where a component
+     * causes a runtime exception that aborts the render early, leaving the page in an invalid state.
+     */
+    void incrementDirtyCount();
+
+    /**
+     * Called as a component finishes rendering itself.
+     */
+    void decrementDirtyCount();
+
+    /**
+     * Discards all persistent field changes for the page containing the component.  Changes are eliminated from
+     * persistent storage (such as the {@link org.apache.tapestry.services.Session}) which will take effect in the
+     * <em>next</em> request (the attached page instance is not affected).
+     */
+    void discardPersistentFieldChanges();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageElement.java
new file mode 100644
index 0000000..29ffe9f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageElement.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.runtime.RenderCommand;

+

+/**

+ * An element within a page. Page elements are placeholders that delegate much of their behavior to application-specific

+ * component classes.

+ */

+public interface PageElement extends RenderCommand

+{

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
new file mode 100644
index 0000000..ccd1ba6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageImpl.java
@@ -0,0 +1,195 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.services.LinkFactory;
+import org.apache.tapestry.internal.services.PersistentFieldManager;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+import org.apache.tapestry.services.PersistentFieldBundle;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Locale;
+
+public class PageImpl implements Page
+{
+    private final String logicalPageName;
+
+    private final Locale locale;
+
+    private final LinkFactory linkFactory;
+
+    private final PersistentFieldManager persistentFieldManager;
+
+    private ComponentPageElement rootElement;
+
+    private final List<PageLifecycleListener> listeners = CollectionFactory.newList();
+
+    private int dirtyCount;
+
+    /**
+     * Obtained from the {@link org.apache.tapestry.internal.services.PersistentFieldManager} when first needed,
+     * discarded at the end of the request.
+     */
+    private PersistentFieldBundle fieldBundle;
+
+    public PageImpl(String logicalPageName, Locale locale, LinkFactory linkFactory,
+                    PersistentFieldManager persistentFieldManager)
+    {
+        this.logicalPageName = logicalPageName;
+        this.locale = locale;
+        this.linkFactory = linkFactory;
+        this.persistentFieldManager = persistentFieldManager;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("Page[%s %s]", logicalPageName, locale);
+    }
+
+    public ComponentPageElement getComponentElementByNestedId(String nestedId)
+    {
+        notNull(nestedId, "nestedId");
+
+        // TODO: Especially with the addition of all the caseless logic, and with respect to how
+        // forms are implemented, it may be worthwhile to cache the key to element mapping. I think
+        // we're going to do it a lot!
+
+        ComponentPageElement element = rootElement;
+
+        if (InternalUtils.isNonBlank(nestedId))
+        {
+            for (String id : nestedId.split("\\."))
+                element = element.getEmbeddedElement(id);
+        }
+
+        return element;
+    }
+
+    public Locale getLocale()
+    {
+        return locale;
+    }
+
+    public void setRootElement(ComponentPageElement component)
+    {
+        rootElement = component;
+    }
+
+    public ComponentPageElement getRootElement()
+    {
+        return rootElement;
+    }
+
+    public Component getRootComponent()
+    {
+        return rootElement.getComponent();
+    }
+
+    public void addLifecycleListener(PageLifecycleListener listener)
+    {
+        listeners.add(listener);
+    }
+
+    public boolean detached()
+    {
+        boolean result = dirtyCount > 0;
+
+        for (PageLifecycleListener listener : listeners)
+        {
+            try
+            {
+                listener.containingPageDidDetach();
+            }
+            catch (RuntimeException ex)
+            {
+                getLogger().error(StructureMessages.detachFailure(listener, ex), ex);
+                result = true;
+            }
+        }
+
+        fieldBundle = null;
+
+        return result;
+    }
+
+    public void loaded()
+    {
+        for (PageLifecycleListener listener : listeners)
+            listener.containingPageDidLoad();
+    }
+
+    public void attached()
+    {
+        if (dirtyCount != 0) throw new IllegalStateException(StructureMessages.pageIsDirty(this));
+
+        for (PageLifecycleListener listener : listeners)
+            listener.containingPageDidAttach();
+    }
+
+    public Logger getLogger()
+    {
+        return rootElement.getLogger();
+    }
+
+    public Link createActionLink(String nestedId, String eventType, boolean forForm, Object... context)
+    {
+        return linkFactory.createActionLink(this, nestedId, eventType, forForm, context);
+    }
+
+    public Link createPageLink(String pageName, boolean override, Object... context)
+    {
+        return linkFactory.createPageLink(pageName, override, context);
+    }
+
+    public void persistFieldChange(ComponentResources resources, String fieldName, Object newValue)
+    {
+        persistentFieldManager.postChange(logicalPageName, resources, fieldName, newValue);
+    }
+
+    public Object getFieldChange(String nestedId, String fieldName)
+    {
+        if (fieldBundle == null) fieldBundle = persistentFieldManager.gatherChanges(logicalPageName);
+
+        return fieldBundle.getValue(nestedId, fieldName);
+    }
+
+    public void decrementDirtyCount()
+    {
+        dirtyCount--;
+    }
+
+    public void discardPersistentFieldChanges()
+    {
+        persistentFieldManager.discardChanges(logicalPageName);
+    }
+
+    public void incrementDirtyCount()
+    {
+        dirtyCount++;
+    }
+
+    public String getLogicalName()
+    {
+        return logicalPageName;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java
new file mode 100644
index 0000000..6594655
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResources.java
@@ -0,0 +1,61 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ContextValueEncoder;
+
+/**
+ * Provides access to common methods of various services, needed by implementations of {@link ComponentPageElement} and
+ * {@link org.apache.tapestry.internal.InternalComponentResources}.
+ */
+public interface PageResources extends ContextValueEncoder
+{
+    /**
+     * Used to obtain a {@link org.apache.tapestry.ioc.Messages} instance for a particular component. If the component
+     * extends from another component, then its localized properties will merge with its parent's properties (with the
+     * subclass overriding the super class on any conflicts).
+     *
+     * @param componentModel
+     * @return the message catalog for the component, in the indicated locale
+     * @see org.apache.tapestry5.services.ComponentMessagesSource
+     */
+    Messages getMessages(ComponentModel componentModel);
+
+    /**
+     * Performs a coercion from an input type to a desired output type. When the target type is a primitive, the actual
+     * conversion will be to the equivalent wrapper type. In some cases, the TypeCoercer will need to search for an
+     * appropriate coercion, and may even combine existing coercions to form new ones; in those cases, the results of
+     * the search are cached.
+     *
+     * @param <S>        source type (input)
+     * @param <T>        target type (output)
+     * @param input
+     * @param targetType defines the target type
+     * @return the coerced value
+     * @see org.apache.tapestry.ioc.services.TypeCoercer
+     */
+    <S, T> T coerce(S input, Class<T> targetType);
+
+    /**
+     * Gets the Class instance for then give name.
+     *
+     * @param className fully qualified class name
+     * @return the class instance
+     * @see org.apache.tapestry.internal.services.ComponentClassCache
+     */
+    Class toClass(String className);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java
new file mode 100644
index 0000000..3a652bc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesImpl.java
@@ -0,0 +1,72 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.services.ComponentClassCache;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+
+import java.util.Locale;
+
+public class PageResourcesImpl implements PageResources
+{
+    private final Locale locale;
+
+    private final ComponentMessagesSource componentMessagesSource;
+
+    private final TypeCoercer typeCoercer;
+
+    private final ComponentClassCache componentClassCache;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    public PageResourcesImpl(Locale locale, ComponentMessagesSource componentMessagesSource, TypeCoercer typeCoercer,
+                             ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder)
+    {
+        this.componentMessagesSource = componentMessagesSource;
+        this.locale = locale;
+        this.typeCoercer = typeCoercer;
+        this.componentClassCache = componentClassCache;
+        this.contextValueEncoder = contextValueEncoder;
+    }
+
+    public Messages getMessages(ComponentModel componentModel)
+    {
+        return componentMessagesSource.getMessages(componentModel, locale);
+    }
+
+    public <S, T> T coerce(S input, Class<T> targetType)
+    {
+        return typeCoercer.coerce(input, targetType);
+    }
+
+    public Class toClass(String className)
+    {
+        return componentClassCache.forName(className);
+    }
+
+    public String toClient(Object value)
+    {
+        return contextValueEncoder.toClient(value);
+    }
+
+    public <T> T toValue(Class<T> requiredType, String clientValue)
+    {
+        return contextValueEncoder.toValue(requiredType, clientValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSource.java
new file mode 100644
index 0000000..d33d0e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSource.java
@@ -0,0 +1,31 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import java.util.Locale;
+
+/**
+ * Provides access to the {@link PageResources} facade.
+ */
+public interface PageResourcesSource
+{
+    /**
+     * Gets (or creates) an instance of {@link PageResources} for the indicated locale.
+     *
+     * @param locale to create the resources for
+     * @return the resources
+     */
+    PageResources get(Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java
new file mode 100644
index 0000000..802df68
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/PageResourcesSourceImpl.java
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.services.ComponentClassCache;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+
+import java.util.Locale;
+import java.util.Map;
+
+public class PageResourcesSourceImpl implements PageResourcesSource
+{
+    private final Map<Locale, PageResources> cache = CollectionFactory.newConcurrentMap();
+
+    private final ComponentMessagesSource componentMessagesSource;
+
+    private final TypeCoercer typeCoercer;
+
+    private final ComponentClassCache componentClassCache;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    public PageResourcesSourceImpl(ComponentMessagesSource componentMessagesSource, TypeCoercer typeCoercer,
+                                   ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder)
+    {
+        this.componentMessagesSource = componentMessagesSource;
+        this.typeCoercer = typeCoercer;
+        this.componentClassCache = componentClassCache;
+        this.contextValueEncoder = contextValueEncoder;
+    }
+
+    public PageResources get(Locale locale)
+    {
+        Defense.notNull(locale, "locale");
+
+        PageResources result = cache.get(locale);
+
+        if (result == null)
+        {
+            result = new PageResourcesImpl(locale, componentMessagesSource, typeCoercer, componentClassCache,
+                                           contextValueEncoder);
+
+            // Small race condition here, where we may create two instances of PRI for the same locale,
+            // but that's not worth worrying about.
+
+            cache.put(locale, result);
+        }
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java
new file mode 100644
index 0000000..5c316eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StartElementPageElement.java
@@ -0,0 +1,46 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.runtime.RenderQueue;

+

+/**

+ *

+ */

+public class StartElementPageElement implements PageElement

+{

+    private final String namespaceURI;

+

+    private final String name;

+

+    public StartElementPageElement(String namespaceURI, String name)

+    {

+        this.namespaceURI = namespaceURI;

+

+        this.name = name;

+    }

+

+    public void render(MarkupWriter writer, RenderQueue queue)

+    {

+        writer.elementNS(namespaceURI, name);

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Start[%s %s]", namespaceURI, name);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
new file mode 100644
index 0000000..d1a7579
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java
@@ -0,0 +1,116 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+final class StructureMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(StructureMessages.class);
+
+    private StructureMessages()
+    {
+    }
+
+    static String missingParameters(List<String> parameters, ComponentPageElement element)
+    {
+        return MESSAGES.format("missing-parameters", InternalUtils.joinSorted(parameters), element
+                .getComponentResources().getComponentModel().getComponentClassName());
+    }
+
+    static String noSuchComponent(ComponentPageElement parent, String embeddedId, Set<String> components)
+    {
+        return MESSAGES.format("no-such-component", parent.getCompleteId(), embeddedId,
+                               InternalUtils.joinSorted(components));
+    }
+
+    static String getParameterFailure(String parameterName, String componentId, Throwable cause)
+    {
+        return MESSAGES.format("get-parameter-failure", parameterName, componentId, cause);
+    }
+
+    static String writeParameterFailure(String parameterName, String componentId, Throwable cause)
+    {
+        return MESSAGES.format("write-parameter-failure", parameterName, componentId, cause);
+    }
+
+    static String missingMixinForParameter(String componentId, String mixinName, String parameterName)
+    {
+        return MESSAGES
+                .format("missing-mixin-for-parameter", componentId, mixinName, parameterName);
+    }
+
+    static String unknownMixin(String componentId, String mixinClassName)
+    {
+        return MESSAGES.format("unknown-mixin", componentId, mixinClassName);
+    }
+
+    static String detachFailure(Object listener, Throwable cause)
+    {
+        return MESSAGES.format("detach-failure", listener, cause);
+    }
+
+    static String wrongPhaseResultType(Class expectedType)
+    {
+        return MESSAGES.format("wrong-phase-result-type", expectedType.getName());
+    }
+
+    static String blockNotFound(String componentId, String blockId)
+    {
+        return MESSAGES.format("block-not-found", componentId, blockId);
+    }
+
+    static String unbalancedElements(String componentId)
+    {
+        return MESSAGES.format("unbalanced-elements", componentId);
+    }
+
+    static String pageIsDirty(Page page)
+    {
+        return MESSAGES.format("page-is-dirty", page);
+    }
+
+    static String duplicateChildComponent(ComponentPageElement container, String childId)
+    {
+        return MESSAGES.format("duplicate-child-component", container.getCompleteId(), childId);
+    }
+
+    static String duplicateBlock(ComponentPageElement component, String blockId)
+    {
+        return MESSAGES.format("duplicate-block", component.getCompleteId(), blockId);
+    }
+
+    static String fieldPersistFailure(String componentId, String fieldName, Throwable cause)
+    {
+        return MESSAGES.format("field-persist-failure", componentId, fieldName, cause);
+    }
+
+    static String missingRenderVariable(String componentId, String name, Collection<String> names)
+    {
+
+        return MESSAGES.format("missing-render-variable", componentId, name, InternalUtils.joinSorted(names));
+    }
+
+    static String renderVariableSetWhenNotRendering(String completeId, String name)
+    {
+        return MESSAGES.format("render-variable-set-when-not-rendering", completeId, name);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java
new file mode 100644
index 0000000..b37ba58
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/TextPageElement.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.runtime.RenderQueue;

+

+/**

+ *

+ */

+public class TextPageElement implements PageElement

+{

+    private final String text;

+

+    public TextPageElement(String text)

+    {

+        this.text = text;

+    }

+

+    public void render(MarkupWriter writer, RenderQueue queue)

+    {

+        writer.write(text);

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("Text[%s]", text);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java
new file mode 100644
index 0000000..955a2e9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ActionLinkInvoker.java
@@ -0,0 +1,119 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.internal.URLEventContext;
+import org.apache.tapestry.internal.services.ActionLinkTarget;
+import org.apache.tapestry.internal.services.ComponentInvocation;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.InvocationTarget;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.services.ComponentEventRequestHandler;
+import org.apache.tapestry.services.ComponentEventRequestParameters;
+import org.apache.tapestry.services.ContextValueEncoder;
+
+import java.io.IOException;
+
+/**
+ * Simulates a click on an action link.
+ */
+public class ActionLinkInvoker implements ComponentInvoker
+{
+    private final Registry registry;
+
+    private final ComponentInvoker followupInvoker;
+
+    private final ComponentEventRequestHandler componentEventRequestHandler;
+
+    private final ComponentInvocationMap componentInvocationMap;
+
+    private final TestableResponse response;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    public ActionLinkInvoker(Registry registry, ComponentInvoker followupInvoker,
+                             ComponentInvocationMap componentInvocationMap)
+    {
+        this.registry = registry;
+        this.followupInvoker = followupInvoker;
+        componentEventRequestHandler = this.registry.getService("ComponentEventRequestHandler",
+                                                                ComponentEventRequestHandler.class);
+
+        response = this.registry.getObject(TestableResponse.class, null);
+
+        this.componentInvocationMap = componentInvocationMap;
+        contextValueEncoder = this.registry.getService(ContextValueEncoder.class);
+
+    }
+
+    /**
+     * Click on the action link and get another link in return. Then follow up the link with another {@link
+     * ComponentInvoker}.
+     *
+     * @param invocation The ComponentInvocation object corresponding to the action link.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document invoke(ComponentInvocation invocation)
+    {
+        click(invocation);
+
+        Link link = response.getRedirectLink();
+
+        response.clear();
+
+        if (link == null) throw new RuntimeException("Action did not set a redirect link.");
+
+
+        ComponentInvocation followup = componentInvocationMap.get(link);
+
+        return followupInvoker.invoke(followup);
+    }
+
+    private void click(ComponentInvocation invocation)
+    {
+        try
+        {
+            InvocationTarget target = invocation.getTarget();
+
+            ActionLinkTarget actionLinkTarget = Defense.cast(target, ActionLinkTarget.class, "target");
+
+            ComponentEventRequestParameters parameters = new ComponentEventRequestParameters(
+                    actionLinkTarget.getPageName(),
+
+                    actionLinkTarget.getPageName(),
+
+                    actionLinkTarget.getComponentNestedId(),
+
+                    actionLinkTarget.getEventType(),
+
+                    new URLEventContext(contextValueEncoder, invocation.getActivationContext()),
+
+                    new URLEventContext(contextValueEncoder, invocation.getContext()));
+
+            componentEventRequestHandler.handle(parameters);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+        finally
+        {
+            registry.cleanupThread();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/CodeEq.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/CodeEq.java
new file mode 100644
index 0000000..27f5553
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/CodeEq.java
@@ -0,0 +1,61 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.test;

+

+import static org.easymock.EasyMock.reportMatcher;

+import org.easymock.IArgumentMatcher;

+

+/**

+ * Special version of string equality used to compare two snippets of code. This is somewhat simpleminded (it certainly

+ * doesn't understand about literal strings in quotes). It works by eliminating unecessary whitespace around curly

+ * braces, then reducing all whitespace to a single space.

+ */

+public class CodeEq implements IArgumentMatcher

+{

+    private final String code;

+

+    public CodeEq(String input)

+    {

+        code = strip(input);

+    }

+

+    public boolean matches(Object argument)

+    {

+        String string = (String) argument;

+        String stripped = strip(string);

+

+        return code.equals(stripped);

+    }

+

+    public void appendTo(StringBuffer buffer)

+    {

+        buffer.append("codeEq(");

+        buffer.append(code);

+        buffer.append(")");

+    }

+

+    public static String codeEq(String input)

+    {

+        reportMatcher(new CodeEq(input));

+

+        return null;

+    }

+

+    static String strip(String input)

+    {

+        return input.trim().replaceAll("\\s*\\{\\s*", "{").replaceAll("\\s*\\}\\s*", "}")

+                .replaceAll("\\s+", " ");

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ComponentInvoker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ComponentInvoker.java
new file mode 100644
index 0000000..b49f96a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/ComponentInvoker.java
@@ -0,0 +1,31 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.internal.services.ComponentInvocation;
+
+/**
+ * Invokes a {@link org.apache.tapestry.internal.services.ComponentInvocation}.
+ */
+public interface ComponentInvoker
+{
+    /**
+     * @param invocation The ComponentInvocation object to be invoked.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    Document invoke(ComponentInvocation invocation);
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java
new file mode 100644
index 0000000..0f1d8a6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageLinkInvoker.java
@@ -0,0 +1,91 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.internal.URLEventContext;
+import org.apache.tapestry.internal.services.ComponentInvocation;
+import org.apache.tapestry.internal.services.InvocationTarget;
+import org.apache.tapestry.internal.services.PageLinkTarget;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.PageRenderRequestHandler;
+import org.apache.tapestry.services.PageRenderRequestParameters;
+
+import java.io.IOException;
+
+/**
+ * Simulates a click on a page link.
+ */
+public class PageLinkInvoker implements ComponentInvoker
+{
+    private final Registry registry;
+
+    private final PageRenderRequestHandler pageRenderRequestHandler;
+
+    private final TestableMarkupWriterFactory markupWriterFactory;
+
+    private final TestableResponse response;
+
+    private final ContextValueEncoder contextValueEncoder;
+
+    public PageLinkInvoker(Registry registry)
+    {
+        this.registry = registry;
+
+        pageRenderRequestHandler = this.registry.getService(PageRenderRequestHandler.class);
+        markupWriterFactory = this.registry.getService(TestableMarkupWriterFactory.class);
+        response = this.registry.getService(TestableResponse.class);
+        contextValueEncoder = this.registry.getService(ContextValueEncoder.class);
+    }
+
+    /**
+     * Click on the page link.
+     *
+     * @param invocation The ComponentInvocation object corresponding to the page link.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document invoke(ComponentInvocation invocation)
+    {
+        try
+        {
+            InvocationTarget target = invocation.getTarget();
+
+            PageLinkTarget pageLinkTarget = (PageLinkTarget) target;
+
+            EventContext activationContext
+                    = new URLEventContext(contextValueEncoder, invocation.getContext());
+            PageRenderRequestParameters parameters = new PageRenderRequestParameters(pageLinkTarget.getPageName(),
+                                                                                     activationContext);
+
+            pageRenderRequestHandler.handle(parameters);
+
+            return markupWriterFactory.getLatestMarkupWriter().getDocument();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+        finally
+        {
+            response.clear();
+
+            registry.cleanupThread();
+        }
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterComponentInvocationMap.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterComponentInvocationMap.java
new file mode 100644
index 0000000..0f37c3f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterComponentInvocationMap.java
@@ -0,0 +1,65 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ComponentInvocation;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.NoOpComponentInvocationMap;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.test.PageTester;
+
+import java.util.Map;
+
+/**
+ * This is the real implementation, used by {@link PageTester}. The typical implementation, {@link
+ * NoOpComponentInvocationMap}, is used in production as a place holder.
+ */
+public class PageTesterComponentInvocationMap implements ComponentInvocationMap
+{
+    private final Map<Element, Link> elementToLink = CollectionFactory.newMap();
+
+    private final Map<Link, ComponentInvocation> linkToInvocation = CollectionFactory.newMap();
+
+    public void store(Element element, Link link)
+    {
+        elementToLink.put(element, link);
+    }
+
+    public void store(Link link, ComponentInvocation invocation)
+    {
+        linkToInvocation.put(link, invocation);
+    }
+
+    public void clear()
+    {
+        elementToLink.clear();
+        linkToInvocation.clear();
+    }
+
+    public ComponentInvocation get(Element element)
+    {
+        Link link = elementToLink.get(element);
+
+        return get(link);
+    }
+
+    public ComponentInvocation get(Link link)
+    {
+        return linkToInvocation.get(link);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterContext.java
new file mode 100644
index 0000000..675dc7a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterContext.java
@@ -0,0 +1,74 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.services.Context;
+import org.apache.tapestry.test.TapestryTestConstants;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+public class PageTesterContext implements Context
+{
+    private final File contextRoot;
+
+    public PageTesterContext(String contextRoot)
+    {
+        this.contextRoot = new File(TapestryTestConstants.MODULE_BASE_DIR, contextRoot);
+    }
+
+    public String getInitParameter(String name)
+    {
+        return null;
+    }
+
+    public URL getResource(String path)
+    {
+        File f = new File(contextRoot + path);
+
+        if (!f.exists() || !f.isFile())
+        {
+            return null;
+        }
+        try
+        {
+            return f.toURL();
+        }
+        catch (MalformedURLException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public List<String> getResourcePaths(String path)
+    {
+        throw new UnsupportedOperationException("getResourcePaths() is not supported for ContextForPageTester.");
+    }
+
+    public Object getAttribute(String name)
+    {
+        throw new UnsupportedOperationException("getAttribute() is not supported for ContextForPageTester.");
+    }
+
+    /**
+     * Always returns null.
+     */
+    public File getRealFile(String path)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterModule.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterModule.java
new file mode 100644
index 0000000..9366936
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterModule.java
@@ -0,0 +1,79 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.CookieSink;
+import org.apache.tapestry.internal.services.CookieSource;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.services.AliasContribution;
+import org.apache.tapestry.services.MarkupWriterFactory;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry.test.PageTester;
+
+/**
+ * Used in conjuction with {@link PageTester} to mock up and/or stub out portions of Tapestry that need to be handled
+ * differently when testing.
+ */
+public class PageTesterModule
+{
+    public static final String TEST_MODE = "test";
+
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(TestableRequest.class, TestableRequestImpl.class);
+        binder.bind(TestableResponse.class, TestableResponseImpl.class);
+        binder.bind(TestableMarkupWriterFactory.class, TestableMarkupWriterFactoryImpl.class);
+    }
+
+    public static void contributeAlias(Configuration<AliasContribution> configuration, ObjectLocator locator)
+    {
+        add(configuration, ComponentInvocationMap.class, new PageTesterComponentInvocationMap());
+
+        add(configuration, locator, Request.class, "TestableRequest");
+        add(configuration, locator, Response.class, "TestableResponse");
+        add(configuration, locator, MarkupWriterFactory.class, "TestableMarkupWriterFactory");
+
+        TestableCookieSinkSource cookies = new TestableCookieSinkSource();
+
+        add(configuration, CookieSink.class, cookies);
+        add(configuration, CookieSource.class, cookies);
+    }
+
+    private static <T> void add(Configuration<AliasContribution> configuration, ObjectLocator locator,
+                                Class<T> serviceClass, String serviceId)
+    {
+        T service = locator.getService(serviceId, serviceClass);
+
+        add(configuration, serviceClass, service);
+    }
+
+    private static <T> void add(Configuration<AliasContribution> configuration, Class<T> serviceClass, T service)
+    {
+        AliasContribution<T> contribution = AliasContribution.create(serviceClass, TEST_MODE, service);
+
+        configuration.add(contribution);
+    }
+
+    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add(SymbolConstants.FORCE_ABSOLUTE_URIS, "true");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterSession.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterSession.java
new file mode 100644
index 0000000..b0475c7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/PageTesterSession.java
@@ -0,0 +1,85 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Session;
+
+import java.util.List;
+import java.util.Map;
+
+public class PageTesterSession implements Session
+{
+    private final Map<String, Object> attributes = CollectionFactory.newMap();
+
+    public List<String> getAttributeNames()
+    {
+        return InternalUtils.sortedKeys(attributes);
+    }
+
+    public List<String> getAttributeNames(String prefix)
+    {
+        List<String> result = newList();
+
+        for (String name : getAttributeNames())
+            if (name.startsWith(prefix)) result.add(name);
+
+        return result;
+    }
+
+    public Object getAttribute(String name)
+    {
+        return attributes.get(name);
+    }
+
+    public void setAttribute(String name, Object value)
+    {
+        if (value == null)
+        {
+            attributes.remove(name);
+        }
+        else
+        {
+            attributes.put(name, value);
+        }
+
+    }
+
+    private void nyi(String name)
+    {
+        throw new IllegalStateException(String.format("%s.%s() is not yet implemented.", getClass()
+                .getName(), name));
+    }
+
+    public int getMaxInactiveInterval()
+    {
+        nyi("getMaxInativeInterval");
+
+        return 0;
+    }
+
+    public void invalidate()
+    {
+        nyi("invalidate");
+    }
+
+    public void setMaxInactiveInterval(int seconds)
+    {
+        nyi("setMaxInactiveInterval");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableCookieSinkSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableCookieSinkSource.java
new file mode 100644
index 0000000..081739a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableCookieSinkSource.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.internal.services.CookieSink;
+import org.apache.tapestry.internal.services.CookieSource;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import javax.servlet.http.Cookie;
+import java.util.Map;
+
+public class TestableCookieSinkSource implements CookieSource, CookieSink
+{
+    private final Map<String, Cookie> cookies = CollectionFactory.newMap();
+
+    public Cookie[] getCookies()
+    {
+        return cookies.values().toArray(new Cookie[cookies.size()]);
+    }
+
+    public void addCookie(Cookie cookie)
+    {
+        cookies.put(cookie.getName(), cookie);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactory.java
new file mode 100644
index 0000000..f1a3530
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactory.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.services.MarkupWriterFactory;
+
+/**
+ * Extension of {@link MarkupWriterFactory} that tracks the most recently created markup writer so that it can be
+ * accessed after the page has rendered.
+ */
+public interface TestableMarkupWriterFactory extends MarkupWriterFactory
+{
+    /**
+     * Returns the most recently created markup writer.
+     */
+    MarkupWriter getLatestMarkupWriter();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactoryImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactoryImpl.java
new file mode 100644
index 0000000..e87b56d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableMarkupWriterFactoryImpl.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.MarkupWriter;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.services.Core;
+import org.apache.tapestry.services.MarkupWriterFactory;
+
+@Scope(PERTHREAD_SCOPE)
+public class TestableMarkupWriterFactoryImpl implements TestableMarkupWriterFactory
+{
+    private final MarkupWriterFactory delegate;
+
+    private MarkupWriter lastCreated;
+
+    /**
+     * Using Core annotation to reference to framework-provided version, which this implementation wraps around.
+     */
+    public TestableMarkupWriterFactoryImpl(@Core MarkupWriterFactory delegate)
+    {
+        this.delegate = delegate;
+    }
+
+    public MarkupWriter getLatestMarkupWriter()
+    {
+        return lastCreated;
+    }
+
+    public MarkupWriter newMarkupWriter(ContentType contentType)
+    {
+        MarkupWriter result = delegate.newMarkupWriter(contentType);
+
+        lastCreated = result;
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequest.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequest.java
new file mode 100644
index 0000000..817def2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequest.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.test.PageTester;
+
+import java.util.Map;
+
+/**
+ * An extended version of {@link Request} that allows the {@link PageTester} to control and override behavior,
+ * effectively simulating the portions of {@link Request} that are provided normally by a servlet container.
+ */
+public interface TestableRequest extends Request
+{
+    /**
+     * Clears the internal parameters map.
+     */
+    void clear();
+
+    /**
+     * Loads new parameter/value pairs into the map.
+     */
+    void loadParameters(Map<String, String> parameterValues);
+
+    /**
+     * Loads a single parameter/value pair.
+     */
+    void loadParameter(String parameterName, String parameterValue);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java
new file mode 100644
index 0000000..edc9652
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java
@@ -0,0 +1,162 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.Session;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+public class TestableRequestImpl implements TestableRequest
+{
+    private final String contextPath;
+
+    private final Map<String, String> parameters = CollectionFactory.newMap();
+
+    private final Map<String, Object> attributes = CollectionFactory.newMap();
+
+    private Session session;
+
+    public TestableRequestImpl()
+    {
+        this("/foo");
+    }
+
+    public TestableRequestImpl(String contextPath)
+    {
+        this.contextPath = contextPath;
+    }
+
+    private <T> T nyi(String methodName)
+    {
+        throw new RuntimeException(
+                String.format("Request: method %s() not yet implemented by TestableRequestImpl.", methodName));
+    }
+
+    public void clear()
+    {
+        parameters.clear();
+    }
+
+    public void loadParameter(String parameterName, String parameterValue)
+    {
+        parameters.put(parameterName, parameterValue);
+    }
+
+    public void loadParameters(Map<String, String> parameterValues)
+    {
+        parameters.putAll(parameterValues);
+    }
+
+    public long getDateHeader(String name)
+    {
+        nyi("getDateHeader");
+        return 0;
+    }
+
+    public String getHeader(String name)
+    {
+        return nyi("getHeader");
+    }
+
+    public List<String> getHeaderNames()
+    {
+        return nyi("getHeaderNames");
+    }
+
+    public Locale getLocale()
+    {
+        return nyi("getLocale");
+    }
+
+    public List<String> getParameterNames()
+    {
+        return InternalUtils.sortedKeys(parameters);
+    }
+
+    public String[] getParameters(String name)
+    {
+        String value = getParameter(name);
+
+        return value == null ? null : new String[] { value };
+    }
+
+    public String getPath()
+    {
+        return nyi("getPath");
+    }
+
+    public String getContextPath()
+    {
+        return contextPath;
+    }
+
+    public String getParameter(String name)
+    {
+        return parameters.get(name);
+    }
+
+    public Session getSession(boolean create)
+    {
+        if (!create) return session;
+
+        if (session == null) session = new PageTesterSession();
+
+        return session;
+    }
+
+    public void setEncoding(String requestEncoding)
+    {
+    }
+
+    /**
+     * Always returns false. If you need to test Ajax functionality, you need to be using Selenium.
+     */
+    public boolean isXHR()
+    {
+        return false;
+    }
+
+    public boolean isSecure()
+    {
+        return false;
+    }
+
+    /**
+     * Always returns true.
+     */
+    public boolean isRequestedSessionIdValid()
+    {
+        return true;
+    }
+
+    public Object getAttribute(String name)
+    {
+        return attributes.get(name);
+    }
+
+    public void setAttribute(String name, Object value)
+    {
+        attributes.put(name, value);
+    }
+
+    public String getServerName()
+    {
+        return nyi("getServerName");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponse.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponse.java
new file mode 100644
index 0000000..9738d6f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponse.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.services.Response;
+
+public interface TestableResponse extends Response
+{
+    /**
+     * Returns the link redirected to via {@link org.apache.tapestry.services.Response#sendRedirect(org.apache.tapestry.Link)}.
+     */
+    Link getRedirectLink();
+
+    /**
+     * Clears internal state, in preparation for the next test.
+     */
+    void clear();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponseImpl.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponseImpl.java
new file mode 100644
index 0000000..64a7add
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableResponseImpl.java
@@ -0,0 +1,113 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.Link;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+public class TestableResponseImpl implements TestableResponse
+{
+    private Link link;
+
+    private boolean committed;
+
+    private void nyi(String methodName)
+    {
+        throw new RuntimeException(String.format("TestableResponse: Method %s() not yet implemented.", methodName));
+    }
+
+    public OutputStream getOutputStream(String contentType) throws IOException
+    {
+        nyi("getOutputStream");
+
+        return null;
+    }
+
+    public PrintWriter getPrintWriter(String contentType) throws IOException
+    {
+        committed = true;
+
+        // Well, the output isn't accessible, but I guess we see that it could be generated from
+        // the DOM.
+        return new PrintWriter(new ByteArrayOutputStream());
+    }
+
+    public void sendError(int sc, String message) throws IOException
+    {
+        nyi("sendError");
+    }
+
+    public void sendRedirect(String URL) throws IOException
+    {
+        nyi("sendRedirect");
+    }
+
+    public void setContentLength(int length)
+    {
+        nyi("setContentLength");
+    }
+
+    public void setDateHeader(String name, long date)
+    {
+        nyi("setDateHeader");
+    }
+
+    public void setHeader(String name, String value)
+    {
+        nyi("setHeader");
+    }
+
+    public void setIntHeader(String name, int value)
+    {
+        nyi("setIntHeader");
+    }
+
+    public void sendRedirect(Link link) throws IOException
+    {
+        committed = true;
+
+        this.link = link;
+    }
+
+    public String encodeRedirectURL(String URL)
+    {
+        return URL;
+    }
+
+    public String encodeURL(String URL)
+    {
+        return URL;
+    }
+
+    public Link getRedirectLink()
+    {
+        return link;
+    }
+
+    public boolean isCommitted()
+    {
+        return committed;
+    }
+
+    public void clear()
+    {
+        committed = false;
+        link = null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/AbstractIncludeAssetWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/AbstractIncludeAssetWorker.java
new file mode 100644
index 0000000..f05a8f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/AbstractIncludeAssetWorker.java
@@ -0,0 +1,106 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.services.ComponentResourcesOperation;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Base class for workers that automatically inlcude assets in the page (via methods on {@link
+ * org.apache.tapestry.RenderSupport}).
+ */
+public abstract class AbstractIncludeAssetWorker implements ComponentClassTransformWorker
+{
+    private final AssetSource assetSource;
+
+    private final SymbolSource symbolSource;
+
+    public AbstractIncludeAssetWorker(AssetSource assetSource, SymbolSource symbolSource)
+    {
+        this.assetSource = assetSource;
+        this.symbolSource = symbolSource;
+    }
+
+    /**
+     * Expands symbols in the path, then adds an operation into the setup render phase of the component. Ultimately,
+     * {@link #handleAsset(org.apache.tapestry.Asset)} will be invoked for each asset (dervied from assetPaths).
+     *
+     * @param transformation transformation process for component
+     * @param model          component model for component
+     * @param assetPaths     raw paths to be converted to assets
+     */
+    protected final void addOperationForAssetPaths(ClassTransformation transformation,
+                                                   final MutableComponentModel model, String[] assetPaths)
+    {
+        final List<String> paths = CollectionFactory.newList();
+
+        for (String value : assetPaths)
+        {
+            String expanded = symbolSource.expandSymbols(value);
+
+            paths.add(expanded);
+        }
+
+        ComponentResourcesOperation op = new ComponentResourcesOperation()
+        {
+            // Remember that ONE instances of this op will be injected into EVERY instance
+            // of the component ... that means that we can't do any aggresive caching
+            // inside the operation (the operation must be threadsafe).
+
+            public void perform(ComponentResources resources)
+            {
+                Locale locale = resources.getLocale();
+
+                for (String assetPath : paths)
+                {
+                    Asset asset = assetSource.getAsset(model.getBaseResource(), assetPath, locale);
+
+                    handleAsset(asset);
+                }
+            }
+        };
+
+        String opFieldName = transformation.addInjectedField(ComponentResourcesOperation.class, "operation", op);
+
+        String resourcesName = transformation.getResourcesFieldName();
+
+        String body = String.format("%s.perform(%s);", opFieldName, resourcesName);
+
+        // This is what I like about this approach; the injected body is tiny.  The downside is that
+        // the object that gets injected is hard to test, hard enough that we'll just concentrate on
+        // the integration test, thank you.
+
+        transformation.extendMethod(TransformConstants.SETUP_RENDER_SIGNATURE, body);
+    }
+
+    /**
+     * Invoked, from the component's setup render phase, for each asset. This method must be threadsafe.  Most
+     * implementation pass the asset to a particular method of {@link org.apache.tapestry.RenderSupport}.
+     *
+     * @param asset to be processed
+     */
+    protected abstract void handleAsset(Asset asset);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ApplicationStateWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ApplicationStateWorker.java
new file mode 100644
index 0000000..bee46c8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ApplicationStateWorker.java
@@ -0,0 +1,136 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.internal.services.ComponentClassCache;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ApplicationStateManager;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import static java.lang.String.format;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Looks for the {@link ApplicationState} annotation and converts read and write access on such fields into calls to the
+ * {@link ApplicationStateManager}.
+ */
+public class ApplicationStateWorker implements ComponentClassTransformWorker
+{
+    private final ApplicationStateManager applicationStateManager;
+
+    private final ComponentClassCache componentClassCache;
+
+    public ApplicationStateWorker(ApplicationStateManager applicationStateManager,
+                                  ComponentClassCache componentClassCache)
+    {
+        this.applicationStateManager = applicationStateManager;
+        this.componentClassCache = componentClassCache;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> names = transformation.findFieldsWithAnnotation(ApplicationState.class);
+
+        if (names.isEmpty()) return;
+
+        String managerFieldName = transformation.addInjectedField(ApplicationStateManager.class,
+                                                                  "applicationStateManager", applicationStateManager);
+
+        for (String fieldName : names)
+        {
+            processField(fieldName, managerFieldName, transformation);
+        }
+    }
+
+    private void processField(String fieldName, String managerFieldName, ClassTransformation transformation)
+    {
+        String fieldType = transformation.getFieldType(fieldName);
+
+        Class fieldClass = componentClassCache.forName(fieldType);
+
+        String typeFieldName = transformation.addInjectedField(Class.class, fieldName + "_type", fieldClass);
+
+        replaceRead(transformation, fieldName, fieldType, managerFieldName, typeFieldName);
+
+        replaceWrite(transformation, fieldName, fieldType, managerFieldName, typeFieldName);
+
+        transformation.removeField(fieldName);
+
+        String booleanFieldName = fieldName + "Exists";
+
+        if (transformation.isField(booleanFieldName) && transformation.getFieldType(booleanFieldName).equals("boolean"))
+        {
+            replaceFlagRead(transformation, booleanFieldName, typeFieldName, managerFieldName);
+        }
+    }
+
+    private void replaceFlagRead(ClassTransformation transformation, String booleanFieldName, String typeFieldName,
+                                 String managerFieldName)
+    {
+        String readMethodName = transformation.newMemberName("read", booleanFieldName);
+
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, "boolean", readMethodName, null,
+                                                                    null);
+
+        String body = format("return %s.exists(%s);", managerFieldName, typeFieldName);
+
+        transformation.addMethod(sig, body);
+
+        transformation.replaceReadAccess(booleanFieldName, readMethodName);
+        transformation.makeReadOnly(booleanFieldName);
+        transformation.removeField(booleanFieldName);
+    }
+
+    private void replaceWrite(ClassTransformation transformation, String fieldName, String fieldType,
+                              String managerFieldName, String typeFieldName)
+    {
+        String writeMethodName = transformation.newMemberName("write", fieldName);
+
+        TransformMethodSignature writeSignature = new TransformMethodSignature(Modifier.PRIVATE, "void",
+                                                                               writeMethodName,
+                                                                               new String[] { fieldType },
+                                                                               null);
+
+        String body = format("%s.set(%s, $1);", managerFieldName, typeFieldName);
+
+        transformation.addMethod(writeSignature, body);
+
+        transformation.replaceWriteAccess(fieldName, writeMethodName);
+    }
+
+    private void replaceRead(ClassTransformation transformation, String fieldName, String fieldType,
+                             String managerFieldName, String typeFieldName)
+    {
+        ApplicationState annotation = transformation.getFieldAnnotation(fieldName, ApplicationState.class);
+
+
+        String readMethodName = transformation.newMemberName("read", fieldName);
+
+        TransformMethodSignature readMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, fieldType,
+                                                                                    readMethodName, null, null);
+
+        String methodName = annotation.create() ? "get" : "getIfExists";
+
+        String body = format("return (%s) %s.%s(%s);", fieldType, managerFieldName, methodName, typeFieldName);
+
+        transformation.addMethod(readMethodSignature, body);
+
+        transformation.replaceReadAccess(fieldName, readMethodName);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/CachedWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/CachedWorker.java
new file mode 100644
index 0000000..7aa158c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/CachedWorker.java
@@ -0,0 +1,140 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.annotation.Cached;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import static java.lang.reflect.Modifier.PRIVATE;
+import java.util.List;
+
+/**
+ * Caches method return values for methods annotated with {@link Cached}.
+ */
+public class CachedWorker implements ComponentClassTransformWorker
+{
+    private final BindingSource bindingSource;
+
+    public CachedWorker(BindingSource bindingSource)
+    {
+        this.bindingSource = bindingSource;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<TransformMethodSignature> methods = transformation.findMethodsWithAnnotation(Cached.class);
+        if (methods.isEmpty())
+            return;
+
+        for (TransformMethodSignature method : methods)
+        {
+            if (method.getReturnType().equals("void"))
+                throw new IllegalArgumentException(TransformMessages.cachedMethodMustHaveReturnValue(method));
+
+            if (method.getParameterTypes().length != 0)
+                throw new IllegalArgumentException(TransformMessages.cachedMethodsHaveNoParameters(method));
+
+            String propertyName = method.getMethodName();
+
+            // add a property to store whether or not the method has been called
+            String fieldName = transformation.addField(PRIVATE, method.getReturnType(), propertyName);
+            String calledField = transformation.addField(PRIVATE, "boolean", fieldName + "$called");
+
+            Cached once = transformation.getMethodAnnotation(method, Cached.class);
+            String bindingField = null;
+            String bindingValueField = null;
+            boolean watching = once.watch().length() > 0;
+
+            if (watching)
+            {
+                // add fields to store the binding and the value
+                bindingField = transformation.addField(PRIVATE, Binding.class.getCanonicalName(),
+                                                       fieldName + "$binding");
+                bindingValueField = transformation.addField(PRIVATE, "java.lang.Object", fieldName + "$bindingValue");
+
+                String bindingSourceField = transformation.addInjectedField(BindingSource.class,
+                                                                            fieldName + "$bindingsource",
+                                                                            bindingSource);
+
+                String body = String.format("%s = %s.newBinding(\"Watch expression\", %s, \"%s\", \"%s\");",
+                                            bindingField,
+                                            bindingSourceField,
+                                            transformation.getResourcesFieldName(),
+                                            BindingConstants.PROP,
+                                            once.watch());
+
+                transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
+            }
+
+            BodyBuilder b = new BodyBuilder();
+
+            // on cleanup, reset the field values
+            b.begin();
+
+            if (!TransformUtils.isPrimitive(method.getReturnType()))
+                b.addln("%s = null;", fieldName);
+            b.addln("%s = false;", calledField);
+
+            if (watching)
+                b.addln("%s = null;", bindingValueField);
+
+            b.end();
+
+            // TAPESTRY-2338: Cleanup at page detach, not render cleanup.  In an Ajax request, the rendering
+            // objects may reference properties of components that don't render and so won't execute the
+            // PostCleanupRender phase.
+
+            transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, b.toString());
+
+            // prefix the existing method to cache the result
+            b.clear();
+            b.begin();
+
+            // if it has been called and watch is set and the old value is the same as the new value then return
+            // get the old value and cache it
+            /* NOTE: evaluates the binding twice when checking the new value.
+                * this is probably not a problem because in most cases properties
+                * that are being watched are not expensive operations. plus, we
+                * never guaranteed that it would be called exactly once when
+                * watching.
+                */
+            if (watching)
+            {
+                b.addln("if (%s && %s == %s.get()) return %s;",
+                        calledField, bindingValueField, bindingField, fieldName);
+                b.addln("%s = %s.get();", bindingValueField, bindingField);
+            }
+            else
+            {
+                b.addln("if (%s) return %s;", calledField, fieldName);
+            }
+
+            b.addln("%s = true;", calledField);
+            b.end();
+            transformation.prefixMethod(method, b.toString());
+
+            // cache the return value
+            b.clear();
+            b.begin();
+            b.addln("%s = $_;", fieldName);
+            b.end();
+            transformation.extendExistingMethod(method, b.toString());
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorker.java
new file mode 100644
index 0000000..16a3c0e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorker.java
@@ -0,0 +1,182 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.util.MethodInvocationBuilder;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.MethodFilter;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Converts one of the methods of {@link org.apache.tapestry.runtime.Component} into a chain of command that, itself,
+ * invokes certain methods (render phase methods) marked with an annotation, or named in a specific way.
+ */
+public class ComponentLifecycleMethodWorker implements ComponentClassTransformWorker
+{
+    private static final String CHECK_ABORT_FLAG = "if ($2.isAborted()) return;";
+
+    private final Class<? extends Annotation> methodAnnotation;
+
+    private final TransformMethodSignature lifecycleMethodSignature;
+
+    private final String lifecycleMethodName;
+
+    private final boolean reverse;
+
+    private final MethodInvocationBuilder invocationBuilder = new MethodInvocationBuilder();
+
+    /**
+     * Normal method invocation: parent class, then methods in ascending alphabetical order. Reverse order: method in
+     * descending alphabetical order, then parent class.
+     *
+     * @param lifecycleMethodSignature the signature of the method to be implemented in the component class
+     * @param methodAnnotation         the class of the corresponding annotation
+     * @param reverse                  if true, the normal method invocation order is reversed
+     */
+    public ComponentLifecycleMethodWorker(TransformMethodSignature lifecycleMethodSignature,
+                                          Class<? extends Annotation> methodAnnotation, boolean reverse)
+    {
+        this.lifecycleMethodSignature = lifecycleMethodSignature;
+        this.methodAnnotation = methodAnnotation;
+        this.reverse = reverse;
+        lifecycleMethodName = lifecycleMethodSignature.getMethodName();
+
+        // If we ever add more parameters to the methods, then we can add more to the invocation
+        // builder.
+        // *Never* expose the Event parameter ($2), it is for internal use only.
+
+        invocationBuilder.addParameter(MarkupWriter.class.getName(), "$1");
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("ComponentLifecycleMethodWorker[%s]", methodAnnotation.getName());
+    }
+
+    public void transform(final ClassTransformation transformation, MutableComponentModel model)
+    {
+        MethodFilter filter = new MethodFilter()
+        {
+            public boolean accept(TransformMethodSignature signature)
+            {
+                // These methods get added to base classes and otherwise fall into this filter. If
+                // we don't
+                // include this filter, then we get endless loops.
+
+                if (signature.equals(lifecycleMethodSignature)) return false;
+
+                // A degenerate case would be a method, say beginRender(), with an conflicting
+                // annotation, say @AfterRender. In that case, this code is broken, as the method
+                // will be invoked for both phases!
+
+                return signature.getMethodName().equals(lifecycleMethodName)
+                        || transformation.getMethodAnnotation(signature, methodAnnotation) != null;
+            }
+        };
+
+        List<TransformMethodSignature> methods = transformation.findMethods(filter);
+
+        // Except in the root class, don't bother to add a new method unless there's something to
+        // call (beside super).
+
+        if (methods.isEmpty()) return;
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        // If in a subclass, and in normal order mode, invoke the super class version first.
+
+        if (!(reverse || model.isRootClass()))
+        {
+            builder.addln("super.%s($$);", lifecycleMethodName);
+            builder.addln(CHECK_ABORT_FLAG);
+        }
+
+        Iterator<TransformMethodSignature> i = reverse ? InternalUtils.reverseIterator(methods) : methods
+                .iterator();
+
+        builder.addln("try");
+        builder.begin();
+
+        while (i.hasNext())
+            addMethodCallToBody(builder, i.next(), transformation);
+
+        // In reverse order in a a subclass, invoke the super method last.
+
+        if (reverse && !model.isRootClass()) builder.addln("super.%s($$);", lifecycleMethodName);
+
+
+        builder.end(); // try
+
+        // Let runtime exceptions work up (they'll be caught at a higher level.
+        // Wrap checked exceptions for later reporting.
+
+        builder.addln("catch (RuntimeException ex) { throw ex; }");
+        builder.addln("catch (Exception ex) { throw new RuntimeException(ex); }");
+
+        builder.end();
+
+        // Let's see if this works; for base classes, we are adding an empty method the adding a
+        // non-empty
+        // method "on top of it".
+
+        transformation.addMethod(lifecycleMethodSignature, builder.toString());
+    }
+
+    private void addMethodCallToBody(BodyBuilder builder, TransformMethodSignature sig,
+                                     ClassTransformation transformation)
+    {
+        boolean isVoid = sig.getReturnType().equals("void");
+
+        builder.addln("$2.setMethodDescription(\"%s\");", transformation.getMethodIdentifier(sig));
+
+        if (!isVoid)
+        {
+            // If we're not going to invoke storeResult(), then there's no reason to invoke
+            // setMethodDescription().
+
+            builder.add("if ($2.storeResult(($w) ");
+        }
+
+        // This is the best part; the method can even be private and this still works. It's a lot
+        // like how javac enables access to private members for inner classes (by introducing
+        // synthetic, static methods).
+
+        builder.add(invocationBuilder.buildMethodInvocation(sig, transformation));
+
+        // Now, if non void ...
+
+        if (!isVoid)
+        {
+            // Complete the call to storeResult(). If storeResult() returns true, then
+            // the event is aborted and no further processing is required.
+
+            builder.addln(")) return;");
+        }
+        else
+            builder.addln(";");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentWorker.java
new file mode 100644
index 0000000..0e01838
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ComponentWorker.java
@@ -0,0 +1,116 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.MixinClasses;
+import org.apache.tapestry.annotation.Mixins;
+import org.apache.tapestry.internal.KeyValue;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.services.StringLocation;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.model.MutableEmbeddedComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Finds fields with the {@link org.apache.tapestry.annotation.Component} annotation and updates the model. Also checks
+ * for the {@link Mixins} and {@link MixinClasses} annotations and uses them to update the {@link ComponentModel}.
+ */
+public class ComponentWorker implements ComponentClassTransformWorker
+{
+    private final ComponentClassResolver resolver;
+
+    public ComponentWorker(final ComponentClassResolver resolver)
+    {
+        this.resolver = resolver;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (String fieldName : transformation.findFieldsWithAnnotation(Component.class))
+        {
+            Component annotation = transformation.getFieldAnnotation(fieldName, Component.class);
+
+            String id = annotation.id();
+
+            if (InternalUtils.isBlank(id)) id = InternalUtils.stripMemberPrefix(fieldName);
+
+            String type = transformation.getFieldType(fieldName);
+
+            Location location = new StringLocation(String.format("%s.%s", transformation
+                    .getClassName(), fieldName), 0);
+
+            MutableEmbeddedComponentModel embedded = model.addEmbeddedComponent(id, annotation
+                    .type(), type, annotation.inheritInformalParameters(), location);
+
+            addParameters(embedded, annotation.parameters());
+
+            transformation.makeReadOnly(fieldName);
+
+            String body = String.format("%s = (%s) %s.getEmbeddedComponent(\"%s\");", fieldName, type,
+                                        transformation.getResourcesFieldName(), id);
+
+            transformation
+                    .extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
+
+            addMixinClasses(fieldName, transformation, embedded);
+            addMixinTypes(fieldName, transformation, embedded);
+
+            transformation.claimField(fieldName, annotation);
+        }
+    }
+
+    private void addMixinClasses(String fieldName, ClassTransformation transformation,
+                                 MutableEmbeddedComponentModel model)
+    {
+        MixinClasses annotation = transformation.getFieldAnnotation(fieldName, MixinClasses.class);
+
+        if (annotation == null) return;
+
+        for (Class c : annotation.value())
+            model.addMixin(c.getName());
+    }
+
+    private void addMixinTypes(String fieldName, ClassTransformation transformation,
+                               MutableEmbeddedComponentModel model)
+    {
+        Mixins annotation = transformation.getFieldAnnotation(fieldName, Mixins.class);
+
+        if (annotation == null) return;
+
+        for (String typeName : annotation.value())
+        {
+            String mixinClassName = resolver.resolveMixinTypeToClassName(typeName);
+            model.addMixin(mixinClassName);
+        }
+    }
+
+    private void addParameters(MutableEmbeddedComponentModel embedded, String[] parameters)
+    {
+        for (String parameter : parameters)
+        {
+            KeyValue kv = TapestryInternalUtils.parseKeyValue(parameter);
+
+            embedded.addParameter(kv.getKey(), kv.getValue());
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ContentTypeWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ContentTypeWorker.java
new file mode 100644
index 0000000..0e69a68
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ContentTypeWorker.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.annotation.ContentType;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Checks for the {@link org.apache.tapestry.annotation.ContentType} annotation, adding a corresponding meta-data value
+ * when found.
+ */
+public class ContentTypeWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        ContentType annotation = transformation.getAnnotation(ContentType.class);
+
+        if (annotation != null) model.setMeta(MetaDataConstants.RESPONSE_CONTENT_TYPE, annotation.value());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/EnvironmentalWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/EnvironmentalWorker.java
new file mode 100644
index 0000000..8177fd9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/EnvironmentalWorker.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Obtains a value from the {@link Environment} service based on the field type. This is triggered by the presence of
+ * the {@link Environmental} annotation.
+ */
+public class EnvironmentalWorker implements ComponentClassTransformWorker
+{
+    private final Environment environment;
+
+    public EnvironmentalWorker(Environment environment)
+    {
+        this.environment = environment;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> names = transformation.findFieldsWithAnnotation(Environmental.class);
+
+        if (names.isEmpty())
+            return;
+
+        // TODO: addInjectField should be smart about if the field has already been injected (with
+        // the same type)
+        // for this transformation, or the parent transformation.
+
+        String envField = transformation.addInjectedField(
+                Environment.class,
+                "environment",
+                environment);
+
+        for (String name : names)
+        {
+            Environmental annotation = transformation.getFieldAnnotation(name, Environmental.class);
+
+            String type = transformation.getFieldType(name);
+
+            // TODO: Check for primitives
+
+            // Caching might be good for efficiency at some point.
+
+            String methodName = transformation.newMemberName("environment_read", name);
+
+            TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, type, methodName, null,
+                                                                        null);
+
+            String body = String.format(
+                    "return ($r) %s.%s($type);",
+                    envField,
+                    annotation.value() ? "peekRequired" : "peek");
+
+            transformation.addMethod(sig, body);
+
+            transformation.replaceReadAccess(name, methodName);
+            transformation.makeReadOnly(name);
+            transformation.removeField(name);
+
+            transformation.claimField(name, annotation);
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeJavaScriptLibraryWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeJavaScriptLibraryWorker.java
new file mode 100644
index 0000000..378587c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeJavaScriptLibraryWorker.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.annotation.IncludeJavaScriptLibrary;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+
+/**
+ * Recognizes the {@link org.apache.tapestry.annotation.IncludeJavaScriptLibrary} annotation, and ensures that {@link
+ * org.apache.tapestry.RenderSupport#addScriptLink(org.apache.tapestry.Asset[])} is invoked.
+ */
+public class IncludeJavaScriptLibraryWorker extends AbstractIncludeAssetWorker
+{
+    private final RenderSupport renderSupport;
+
+    public IncludeJavaScriptLibraryWorker(AssetSource assetSource, RenderSupport renderSupport,
+                                          SymbolSource symbolSource)
+    {
+        super(assetSource, symbolSource);
+
+        this.renderSupport = renderSupport;
+    }
+
+    public void transform(ClassTransformation transformation, final MutableComponentModel model)
+    {
+        IncludeJavaScriptLibrary annotation = transformation.getAnnotation(IncludeJavaScriptLibrary.class);
+
+        if (annotation != null) addOperationForAssetPaths(transformation, model, annotation.value());
+    }
+
+    protected void handleAsset(Asset asset)
+    {
+        renderSupport.addScriptLink(asset);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeStylesheetWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeStylesheetWorker.java
new file mode 100644
index 0000000..f2dc044
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/IncludeStylesheetWorker.java
@@ -0,0 +1,53 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.annotation.IncludeStylesheet;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+
+/**
+ * Recognizes the {@link org.apache.tapestry.annotation.IncludeStylesheet} annotation and ensures that {@link
+ * org.apache.tapestry.RenderSupport#addStylesheetLink(org.apache.tapestry.Asset, String)} is invoked.
+ */
+public class IncludeStylesheetWorker extends AbstractIncludeAssetWorker
+{
+    private final RenderSupport renderSupport;
+
+    public IncludeStylesheetWorker(AssetSource assetSource, RenderSupport renderSupport,
+                                   SymbolSource symbolSource)
+    {
+        super(assetSource, symbolSource);
+
+        this.renderSupport = renderSupport;
+    }
+
+    public void transform(ClassTransformation transformation, final MutableComponentModel model)
+    {
+        IncludeStylesheet annotation = transformation.getAnnotation(IncludeStylesheet.class);
+
+        if (annotation != null) addOperationForAssetPaths(transformation, model, annotation.value());
+    }
+
+
+    protected void handleAsset(Asset asset)
+    {
+        renderSupport.addStylesheetLink(asset, null);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectComponentWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectComponentWorker.java
new file mode 100644
index 0000000..712129a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectComponentWorker.java
@@ -0,0 +1,76 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.InjectComponent;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Recognizes the {@link org.apache.tapestry.annotation.InjectComponent} annotation, and converts the field into a
+ * read-only field containing the component.  The id of the component may be explicitly stated or will be determined
+ * from the field name.
+ */
+public class InjectComponentWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation,
+                          MutableComponentModel model)
+    {
+        for (String fieldName : transformation.findFieldsWithAnnotation(InjectComponent.class))
+        {
+            InjectComponent annotation = transformation.getFieldAnnotation(fieldName, InjectComponent.class);
+
+            String type = transformation.getFieldType(fieldName);
+
+            String resourcesFieldName = transformation.getResourcesFieldName();
+
+            String componentId = annotation.value();
+            if (InternalUtils.isBlank(componentId))
+                componentId = InternalUtils.stripMemberPrefix(fieldName);
+
+            transformation.makeReadOnly(fieldName);
+
+            BodyBuilder builder = new BodyBuilder().addln("try").begin();
+
+            builder.addln(
+                    "%s = (%s) %s.getEmbeddedComponent(\"%s\");",
+                    fieldName,
+                    type,
+                    resourcesFieldName,
+                    componentId);
+            builder.end();
+            builder.addln("catch (ClassCastException ex)").begin();
+            builder.addln("throw new RuntimeException(%s.formatMessage(%s, \"%s\", \"%s\", \"%s\"), ex);",
+                          getClass().getName(), resourcesFieldName, fieldName, type, componentId);
+            builder.end();
+
+            transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder.toString());
+        }
+    }
+
+    public static String formatMessage(ComponentResources resources, String fieldName, String fieldType,
+                                       String componentId)
+    {
+        return String.format(
+                "Unable to inject component '%s' into field %s of component %s.  Class %s is not assignable to a field of type %s.",
+                componentId, fieldName, resources.getCompleteId(),
+                resources.getEmbeddedComponent(componentId).getClass().getName(), fieldType);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectContainerWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectContainerWorker.java
new file mode 100644
index 0000000..64fe249
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectContainerWorker.java
@@ -0,0 +1,88 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.InjectContainer;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+import java.util.List;
+
+/**
+ * Identifies the {@link org.apache.tapestry.annotation.InjectContainer} annotation and adds code to initialize it to
+ * the core component.
+ */
+public class InjectContainerWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> names = transformation.findFieldsWithAnnotation(InjectContainer.class);
+
+        if (names.isEmpty())
+            return;
+
+        // I can't imagine a scenario where a component would have more than one
+        // field with InjectComponent, but that's the way these APIs work, lists of names.
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        builder.addln("%s container = %s.getContainer();", Component.class.getName(), transformation
+                .getResourcesFieldName());
+
+        for (String fieldName : names)
+        {
+            InjectContainer annotation = transformation.getFieldAnnotation(
+                    fieldName,
+                    InjectContainer.class);
+
+            String fieldType = transformation.getFieldType(fieldName);
+
+            builder.addln("try");
+            builder.begin();
+            builder.addln("this.%s = (%s) container;", fieldName, fieldType);
+            builder.end();
+            builder.addln("catch (ClassCastException ex)");
+            builder.begin();
+            builder.addln(
+                    "String message = %s.buildCastExceptionMessage(container, \"%s.%s\", \"%s\");",
+                    InjectContainerWorker.class.getName(),
+                    model.getComponentClassName(),
+                    fieldName,
+                    fieldType);
+            builder.addln("throw new RuntimeException(message, ex);");
+            builder.end();
+
+            transformation.makeReadOnly(fieldName);
+            transformation.claimField(fieldName, annotation);
+        }
+
+        builder.end();
+
+        transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
+                .toString());
+    }
+
+    public static String buildCastExceptionMessage(Component component, String fieldName,
+                                                   String fieldType)
+    {
+        return TransformMessages.componentNotAssignableToField(component, fieldName, fieldType);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectPageWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectPageWorker.java
new file mode 100644
index 0000000..5c85818
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectPageWorker.java
@@ -0,0 +1,87 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Peforms transformations that allow pages to be injected into components.
+ *
+ * @see org.apache.tapestry.annotation.InjectPage
+ */
+public class InjectPageWorker implements ComponentClassTransformWorker
+{
+    private final ComponentSource componentSource;
+
+    private final ComponentClassResolver resolver;
+
+    public InjectPageWorker(ComponentSource componentSource, ComponentClassResolver resolver)
+    {
+        this.componentSource = componentSource;
+        this.resolver = resolver;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> names = transformation.findFieldsWithAnnotation(InjectPage.class);
+
+        if (names.isEmpty()) return;
+
+        String componentSource = transformation.addInjectedField(ComponentSource.class, "componentSource",
+                                                                 this.componentSource);
+
+
+        for (String name : names)
+            addInjectedPage(transformation, name, componentSource);
+
+    }
+
+    private void addInjectedPage(ClassTransformation transformation, String fieldName, String componentSource)
+    {
+        InjectPage annotation = transformation.getFieldAnnotation(fieldName, InjectPage.class);
+
+        String pageName = annotation.value();
+
+        String fieldType = transformation.getFieldType(fieldName);
+        String methodName = transformation.newMemberName("read_inject_page", fieldName);
+
+        String injectedPageName = InternalUtils.isBlank(pageName) ? resolver
+                .resolvePageClassNameToPageName(fieldType) : pageName;
+
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, fieldType, methodName, null,
+                                                                    null);
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        builder.addln("return (%s) %s.getPage(\"%s\");", fieldType, componentSource, injectedPageName);
+
+        builder.end();
+
+        transformation.addMethod(sig, builder.toString());
+        transformation.replaceReadAccess(fieldName, methodName);
+        transformation.makeReadOnly(fieldName);
+        transformation.removeField(fieldName);
+
+        transformation.claimField(fieldName, annotation);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectWorker.java
new file mode 100644
index 0000000..8bc8abf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InjectWorker.java
@@ -0,0 +1,74 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.InjectionProvider;
+
+/**
+ * Performs injection triggered by any field annotated with the {@link org.apache.tapestry.ioc.annotation.Inject}
+ * annotation.
+ * <p/>
+ * The implementation of this worker mostly delegates to a chain of command of {@link
+ * org.apache.tapestry.services.InjectionProvider}s.
+ */
+public class InjectWorker implements ComponentClassTransformWorker
+{
+    private final ObjectLocator locator;
+
+    // Really, a chain of command
+
+    private final InjectionProvider injectionProvider;
+
+    public InjectWorker(ObjectLocator locator, InjectionProvider injectionProvider)
+    {
+        this.locator = locator;
+        this.injectionProvider = injectionProvider;
+    }
+
+    public final void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
+        {
+            Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
+
+            try
+            {
+                String fieldType = transformation.getFieldType(fieldName);
+
+                Class type = transformation.toClass(fieldType);
+
+                boolean success = injectionProvider.provideInjection(
+                        fieldName,
+                        type,
+                        locator,
+                        transformation,
+                        model);
+
+                if (success) transformation.claimField(fieldName, annotation);
+            }
+            catch (RuntimeException ex)
+            {
+                throw new RuntimeException(TransformMessages.fieldInjectionError(transformation
+                        .getClassName(), fieldName, ex), ex);
+            }
+
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java
new file mode 100644
index 0000000..eccc6d8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorker.java
@@ -0,0 +1,37 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Extends a <em>root</em> component class' postRenderCleanup() method to invoke {@link
+ * org.apache.tapestry.internal.InternalComponentResources#postRenderCleanup()}.
+ */
+public class InvokePostRenderCleanupOnResourcesWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        if (!transformation.isRootTransformation()) return;
+
+        String resourcesFieldName = transformation.getResourcesFieldName();
+
+        transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE,
+                                    resourcesFieldName + ".postRenderCleanup();");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/LogWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/LogWorker.java
new file mode 100644
index 0000000..a537bd9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/LogWorker.java
@@ -0,0 +1,61 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Log;
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.internal.services.LoggingAdvice;
+import org.apache.tapestry.ioc.services.ExceptionTracker;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import java.util.List;
+
+/**
+ * Looks for the {@link org.apache.tapestry.annotation.Log} marker annotation and adds method advice to perform the
+ * logging. This is similar to what the {@link org.apache.tapestry.ioc.services.LoggingDecorator} does for service
+ * interface methods.
+ */
+public class LogWorker implements ComponentClassTransformWorker
+{
+    private final ExceptionTracker exceptionTracker;
+
+    public LogWorker(ExceptionTracker exceptionTracker)
+    {
+        this.exceptionTracker = exceptionTracker;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<TransformMethodSignature> signatures = transformation.findMethodsWithAnnotation(Log.class);
+
+        if (signatures.isEmpty()) return;
+
+        // Re-use the logging advice from LoggingDecorator
+        final MethodAdvice loggingAdvice = new LoggingAdvice(model.getLogger(), exceptionTracker);
+
+        // ... but wrap it for use at the component level.
+        ComponentMethodAdvice advice = new ComponentMethodAdvice()
+        {
+            public void advise(ComponentMethodInvocation invocation)
+            {
+                loggingAdvice.advise(invocation);
+            }
+        };
+
+        for (TransformMethodSignature signature : signatures)
+            transformation.advise(signature, advice);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MetaWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MetaWorker.java
new file mode 100644
index 0000000..a15c195
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MetaWorker.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.internal.KeyValue;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Checks for the presence of a {@link Meta} annotation, and adds the data within to the component model.
+ */
+public class MetaWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        Meta annotation = transformation.getAnnotation(Meta.class);
+
+        if (annotation == null)
+            return;
+
+        for (String meta : annotation.value())
+        {
+            KeyValue kv = TapestryInternalUtils.parseKeyValue(meta);
+
+            model.setMeta(kv.getKey(), kv.getValue());
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinAfterWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinAfterWorker.java
new file mode 100644
index 0000000..8203910
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinAfterWorker.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.MixinAfter;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Looks for the {@link org.apache.tapestry.annotation.MixinAfter} annotatation and sets the {@link
+ * org.apache.tapestry.model.ComponentModel#isMixinAfter() mixinAfter flag} is present.
+ */
+public class MixinAfterWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        if (transformation.getAnnotation(MixinAfter.class) != null)
+            model.setMixinAfter(true);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinWorker.java
new file mode 100644
index 0000000..740efc7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/MixinWorker.java
@@ -0,0 +1,69 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform;

+

+import org.apache.tapestry.annotation.Mixin;

+import org.apache.tapestry.ioc.internal.util.InternalUtils;

+import org.apache.tapestry.model.MutableComponentModel;

+import org.apache.tapestry.services.ClassTransformation;

+import org.apache.tapestry.services.ComponentClassResolver;

+import org.apache.tapestry.services.ComponentClassTransformWorker;

+import org.apache.tapestry.services.TransformConstants;

+

+import java.util.List;

+

+/**

+ * Supports the {@link org.apache.tapestry.annotation.Mixin} annotation, which allows a mixin to be part of the

+ * implementation of a component. The annotation is applied to a field, which will become read-only, and contain a

+ * reference to the mixin instance.

+ */

+public class MixinWorker implements ComponentClassTransformWorker

+{

+    private final ComponentClassResolver resolver;

+

+    public MixinWorker(final ComponentClassResolver resolver)

+    {

+        this.resolver = resolver;

+    }

+

+    public void transform(ClassTransformation transformation, MutableComponentModel model)

+    {

+        List<String> fields = transformation.findFieldsWithAnnotation(Mixin.class);

+

+        for (String fieldName : fields)

+        {

+            Mixin annotation = transformation.getFieldAnnotation(fieldName, Mixin.class);

+

+            String mixinType = annotation.value();

+

+            String fieldType = transformation.getFieldType(fieldName);

+

+            String mixinClassName = InternalUtils.isBlank(mixinType) ? fieldType : resolver

+                    .resolveMixinTypeToClassName(mixinType);

+

+            model.addMixinClassName(mixinClassName);

+

+            transformation.makeReadOnly(fieldName);

+

+            String body = String.format("%s = (%s) %s.getMixinByClassName(\"%s\");", fieldName, fieldType,

+                                        transformation.getResourcesFieldName(), mixinClassName);

+

+            transformation

+                    .extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);

+

+            transformation.claimField(fieldName, annotation);

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnEventWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnEventWorker.java
new file mode 100644
index 0000000..58b604c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/OnEventWorker.java
@@ -0,0 +1,226 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Provides implementations of the {@link org.apache.tapestry.runtime.Component#dispatchComponentEvent(org.apache.tapestry.runtime.ComponentEvent)}
+ * method, based on {@link org.apache.tapestry.annotation.OnEvent} annotations.
+ */
+public class OnEventWorker implements ComponentClassTransformWorker
+{
+    static final String OBJECT_ARRAY_TYPE = "java.lang.Object[]";
+
+    static final String EVENT_CONTEXT_TYPE = EventContext.class.getName();
+
+    static final String LIST_TYPE = List.class.getName();
+
+    private final static int ANY_NUMBER_OF_PARAMETERS = -1;
+
+    public void transform(final ClassTransformation transformation, MutableComponentModel model)
+    {
+        MethodFilter filter = new MethodFilter()
+        {
+            public boolean accept(TransformMethodSignature signature)
+            {
+                return signature.getMethodName().startsWith("on") || transformation.getMethodAnnotation(signature,
+                                                                                                        OnEvent.class) != null;
+            }
+        };
+
+        List<TransformMethodSignature> methods = transformation.findMethods(filter);
+
+        // No methods, no work.
+
+        if (methods.isEmpty()) return;
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        builder.addln("if ($1.isAborted()) return $_;");
+
+        builder.addln("try");
+        builder.begin();
+
+        for (TransformMethodSignature method : methods)
+            addCodeForMethod(builder, method, transformation);
+
+        builder.end(); // try
+
+        // Runtime exceptions pass right through.
+
+        builder.addln("catch (RuntimeException ex) { throw ex; }");
+
+        // Wrap others in a RuntimeException to communicate them up.
+
+        builder.addln("catch (Exception ex) { throw new RuntimeException(ex); } ");
+
+        builder.end();
+
+        transformation.extendMethod(TransformConstants.DISPATCH_COMPONENT_EVENT, builder.toString());
+    }
+
+    private void addCodeForMethod(BodyBuilder builder, TransformMethodSignature method,
+                                  ClassTransformation transformation)
+    {
+        // $1 is the event
+
+        int parameterCount = getParameterCount(method);
+
+        OnEvent annotation = transformation.getMethodAnnotation(method, OnEvent.class);
+
+        String eventType = extractEventType(method, annotation);
+
+        String componentId = extractComponentId(method, annotation);
+
+
+        builder.addln("if ($1.matches(\"%s\", \"%s\", %d))", eventType, componentId, parameterCount);
+        builder.begin();
+
+        // Ensure that we return true, because *some* event handler method was invoked,
+        // even if it chose not to abort the event.
+
+        builder.addln("$_ = true;");
+
+        builder.addln("$1.setMethodDescription(\"%s\");", transformation.getMethodIdentifier(method));
+
+        boolean isNonVoid = !method.getReturnType().equals("void");
+
+        // Store the result, converting primitives to wrappers automatically.
+
+        if (isNonVoid) builder.add("if ($1.storeResult(($w) ");
+
+        builder.add("%s(", method.getMethodName());
+
+        buildMethodParameters(builder, method);
+
+        if (isNonVoid) builder.addln("))) return true;");
+        else builder.addln(");");
+
+        builder.end();
+    }
+
+    private String extractComponentId(TransformMethodSignature method, OnEvent annotation)
+    {
+        if (annotation != null) return annotation.component();
+
+        // Method name started with "on". Extract the component id, if present.
+
+        String name = method.getMethodName();
+
+        int fromx = name.indexOf("From");
+
+        if (fromx < 0) return "";
+
+        return name.substring(fromx + 4);
+    }
+
+    private String extractEventType(TransformMethodSignature method, OnEvent annotation)
+    {
+        if (annotation != null) return annotation.value();
+
+        // Method name started with "on". Extract the event type.
+
+        String name = method.getMethodName();
+
+        int fromx = name.indexOf("From");
+
+        return fromx == -1 ? name.substring(2) : name.substring(2, fromx);
+    }
+
+    private int getParameterCount(TransformMethodSignature method)
+    {
+        String[] types = method.getParameterTypes();
+
+        if (types.length == 0) return 0;
+
+        if (types.length == 1)
+        {
+            String soloType = types[0];
+
+            if (soloType.equals(OBJECT_ARRAY_TYPE) || soloType.equals(EVENT_CONTEXT_TYPE) || soloType.equals(LIST_TYPE))
+                return ANY_NUMBER_OF_PARAMETERS;
+        }
+
+        return types.length;
+    }
+
+    private void buildMethodParameters(BodyBuilder builder, TransformMethodSignature method)
+    {
+        int contextIndex = 0;
+
+        for (int i = 0; i < method.getParameterTypes().length; i++)
+        {
+            if (i > 0) builder.add(", ");
+
+            String type = method.getParameterTypes()[i];
+
+            // Type Object[] is a special case, it gets all of the context parameters in one go.
+
+            if (type.equals(OBJECT_ARRAY_TYPE))
+            {
+                builder.add("$1.getContext()");
+                continue;
+            }
+
+            // Added for TAPESTRY-2177
+
+            if (type.equals(EVENT_CONTEXT_TYPE))
+            {
+                builder.add("$1.getEventContext()");
+                continue;
+            }
+
+            // Added for TAPESTRY-1999
+
+            if (type.equals(LIST_TYPE))
+            {
+                builder.add("%s.asList($1.getContext())", Arrays.class.getName());
+                continue;
+            }
+
+            boolean isPrimitive = TransformUtils.isPrimitive(type);
+            String wrapperType = TransformUtils.getWrapperTypeName(type);
+
+            // Add a cast to the wrapper type up front
+
+            if (isPrimitive) builder.add("(");
+
+            // A cast is always needed (i.e. from java.lang.Object to, say, java.lang.String, etc.).
+            // The wrapper type will be the actual type unless its a primitive, in which case it
+            // really will be the wrapper type.
+
+            builder.add("(%s)", wrapperType);
+
+            // The strings for desired type name will likely repeat a bit; it may be
+            // worth it to inject them as final fields. Could increase the number
+            // of constructor parameters pretty dramatically, however, and will reduce
+            // the readability of the output method bodies.
+
+            builder.add("$1.coerceContext(%d, \"%s\")", contextIndex++, wrapperType);
+
+            // and invoke a method on the cast value to get back to primitive
+            if (isPrimitive) builder.add(").%s()", TransformUtils.getUnwrapperMethodName(type));
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PageLifecycleAnnotationWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PageLifecycleAnnotationWorker.java
new file mode 100644
index 0000000..e2fe04e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PageLifecycleAnnotationWorker.java
@@ -0,0 +1,78 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.internal.util.MethodInvocationBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.MethodFilter;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Similar to {@link ComponentLifecycleMethodWorker} but applies to annotations/methods related to the overall page
+ * lifecycle.
+ */
+public class PageLifecycleAnnotationWorker implements ComponentClassTransformWorker
+{
+    private final Class<? extends Annotation> methodAnnotationClass;
+
+    private final TransformMethodSignature lifecycleMethodSignature;
+
+    private final String methodAlias;
+
+    private final MethodInvocationBuilder invocationBuilder = new MethodInvocationBuilder();
+
+    public PageLifecycleAnnotationWorker(final Class<? extends Annotation> methodAnnotationClass,
+                                         final TransformMethodSignature lifecycleMethodSignature,
+                                         final String methodAlias)
+    {
+        this.methodAnnotationClass = methodAnnotationClass;
+        this.lifecycleMethodSignature = lifecycleMethodSignature;
+        this.methodAlias = methodAlias;
+    }
+
+    public void transform(final ClassTransformation transformation, MutableComponentModel model)
+    {
+        MethodFilter filter = new MethodFilter()
+        {
+            public boolean accept(TransformMethodSignature signature)
+            {
+                if (signature.getMethodName().equals(methodAlias))
+                    return true;
+
+                return transformation.getMethodAnnotation(signature, methodAnnotationClass) != null;
+            }
+        };
+
+        // Did this they easy way, because I doubt there will be more than one signature.
+        // If I expected lots of signatures, I'd build up a BodyBuilder in the loop and extend the
+        // method outside the loop.
+
+        for (TransformMethodSignature signature : transformation.findMethods(filter))
+        {
+            // TODO: Filter out the non-void methods (with a non-fatal warning/error?) For the
+            // moment, we just invoke the method anyway, and ignore the result. Also, MethodInvocationBuilder
+            // is very forgiving (and silent) about unexpected parameters (passing null/0/false).
+
+            String body = invocationBuilder.buildMethodInvocation(signature, transformation);
+
+            transformation.extendMethod(lifecycleMethodSignature, body + ";");
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ParameterWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ParameterWorker.java
new file mode 100644
index 0000000..e6ed188
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ParameterWorker.java
@@ -0,0 +1,310 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.bindings.LiteralBinding;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Responsible for identifying parameters via the {@link org.apache.tapestry.annotation.Parameter} annotation on
+ * component fields. This is one of the most complex of the transformations.
+ */
+public class ParameterWorker implements ComponentClassTransformWorker
+{
+    private static final String BIND_METHOD_NAME = ParameterWorker.class.getName() + ".bind";
+
+    private final BindingSource bindingSource;
+
+    public ParameterWorker(BindingSource bindingSource)
+    {
+        this.bindingSource = bindingSource;
+    }
+
+    public void transform(final ClassTransformation transformation, MutableComponentModel model)
+    {
+        FieldFilter filter = new FieldFilter()
+        {
+            public boolean accept(String fieldName, String fieldType)
+            {
+                Parameter annotation = transformation
+                        .getFieldAnnotation(fieldName, Parameter.class);
+
+                return annotation != null && annotation.principal();
+            }
+        };
+
+        List<String> principleFieldNames = transformation.findFields(filter);
+
+        convertFieldsIntoParameters(transformation, model, principleFieldNames);
+
+        // Now convert the rest.
+
+        List<String> fieldNames = transformation.findFieldsWithAnnotation(Parameter.class);
+
+        convertFieldsIntoParameters(transformation, model, fieldNames);
+    }
+
+    private void convertFieldsIntoParameters(ClassTransformation transformation, MutableComponentModel model,
+                                             List<String> fieldNames)
+    {
+        for (String name : fieldNames)
+            convertFieldIntoParameter(name, transformation, model);
+    }
+
+    private void convertFieldIntoParameter(String name, ClassTransformation transformation, MutableComponentModel model)
+    {
+        Parameter annotation = transformation.getFieldAnnotation(name, Parameter.class);
+
+        String parameterName = getParameterName(name, annotation.name());
+
+        model.addParameter(parameterName, annotation.required(), annotation.defaultPrefix());
+
+        String type = transformation.getFieldType(name);
+
+        boolean cache = annotation.cache();
+
+        String cachedFieldName = transformation.addField(Modifier.PRIVATE, "boolean", name + "_cached");
+
+        String resourcesFieldName = transformation.getResourcesFieldName();
+
+        String invariantFieldName = addParameterSetup(name, annotation.defaultPrefix(), annotation.value(),
+                                                      parameterName, cachedFieldName, cache, type, resourcesFieldName,
+                                                      transformation);
+
+        addReaderMethod(name, cachedFieldName, invariantFieldName, cache, parameterName, type, resourcesFieldName,
+                        transformation);
+
+        addWriterMethod(name, cachedFieldName, cache, parameterName, type, resourcesFieldName, transformation);
+
+        transformation.claimField(name, annotation);
+    }
+
+    /**
+     * Returns the name of a field that stores whether the parameter binding is invariant.
+     */
+    private String addParameterSetup(String fieldName, String defaultPrefix, String defaultBinding,
+                                     String parameterName, String cachedFieldName, boolean cache, String fieldType,
+                                     String resourcesFieldName, ClassTransformation transformation)
+    {
+        String defaultFieldName = transformation.addField(Modifier.PRIVATE, fieldType, fieldName + "_default");
+
+        String invariantFieldName = transformation.addField(Modifier.PRIVATE, "boolean", fieldName + "_invariant");
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        addDefaultBindingSetup(parameterName, defaultPrefix, defaultBinding, resourcesFieldName, transformation,
+                               builder);
+
+        builder.addln("%s = %s.isInvariant(\"%s\");", invariantFieldName, resourcesFieldName, parameterName);
+
+        // Store the current value of the field into the default field. This value will
+        // be used to reset the field after rendering.
+
+        builder.addln("%s = %s;", defaultFieldName, fieldName);
+        builder.end();
+
+        transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
+                .toString());
+
+        // Now, when the component completes rendering, ensure that any variant parameters are
+        // are returned to default value. This isn't necessary when the parameter is not cached,
+        // because (unless the binding is invariant), there's no value to get rid of (and if it is
+        // invariant, there's no need to get rid of it).
+
+        if (cache)
+        {
+            builder.clear();
+
+            builder.addln("if (! %s)", invariantFieldName);
+            builder.begin();
+            builder.addln("%s = %s;", fieldName, defaultFieldName);
+            builder.addln("%s = false;", cachedFieldName);
+            builder.end();
+
+            transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, builder
+                    .toString());
+        }
+
+        return invariantFieldName;
+    }
+
+    private void addDefaultBindingSetup(String parameterName, String defaultPrefix, String defaultBinding,
+                                        String resourcesFieldName, ClassTransformation transformation,
+                                        BodyBuilder builder)
+    {
+        if (InternalUtils.isNonBlank(defaultBinding))
+        {
+            builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
+
+            String bindingFactoryFieldName = transformation.addInjectedField(BindingSource.class, "bindingSource",
+                                                                             bindingSource);
+
+            builder
+                    .addln("  %s.bindParameter(\"%s\", %s.newBinding(\"default %2$s\", %1$s, \"%s\", \"%s\"));",
+                           resourcesFieldName, parameterName, bindingFactoryFieldName, defaultPrefix, defaultBinding);
+
+            return;
+
+        }
+
+        // If no default binding expression provided in the annotation, then look for a default
+        // binding method to provide the binding.
+
+        final String methodName = "default" + InternalUtils.capitalize(parameterName);
+
+        MethodFilter filter = new MethodFilter()
+        {
+            public boolean accept(TransformMethodSignature signature)
+            {
+                return signature.getParameterTypes().length == 0 && signature.getMethodName().equals(methodName);
+            }
+        };
+
+        // This will match exactly 0 or 1 methods, and if it matches, we know the name
+        // of the method.
+
+        List<TransformMethodSignature> signatures = transformation.findMethods(filter);
+
+        if (signatures.isEmpty()) return;
+
+        builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
+        builder.addln("  %s(\"%s\", %s, %s());", BIND_METHOD_NAME, parameterName, resourcesFieldName, methodName);
+    }
+
+    private void addWriterMethod(String fieldName, String cachedFieldName, boolean cache, String parameterName,
+                                 String fieldType, String resourcesFieldName, ClassTransformation transformation)
+    {
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        // Before the component is loaded, updating the property sets the default value
+        // for the parameter. The value is stored in the field, but will be
+        // rolled into default field inside containingPageDidLoad().
+
+        builder.addln("if (! %s.isLoaded())", resourcesFieldName);
+        builder.begin();
+        builder.addln("%s = $1;", fieldName);
+        builder.addln("return;");
+        builder.end();
+
+        // Always start by updating the parameter; this will implicitly check for
+        // read-only or unbound parameters. $1 is the single parameter
+        // to the method.
+
+        builder.addln("if (%s.isBound(\"%s\"))", resourcesFieldName, parameterName);
+        builder.addln("  %s.writeParameter(\"%s\", ($w)$1);", resourcesFieldName, parameterName);
+
+        builder.addln("%s = $1;", fieldName);
+
+        if (cache) builder.addln("%s = %s.isRendering();", cachedFieldName, resourcesFieldName);
+
+        builder.end();
+
+        String methodName = transformation.newMemberName("update_parameter", parameterName);
+
+        TransformMethodSignature signature = new TransformMethodSignature(Modifier.PRIVATE, "void", methodName,
+                                                                          new String[] { fieldType }, null);
+
+        transformation.addMethod(signature, builder.toString());
+
+        transformation.replaceWriteAccess(fieldName, methodName);
+    }
+
+    /**
+     * Adds a private method that will be the replacement for read-access to the field.
+     */
+    private void addReaderMethod(String fieldName, String cachedFieldName, String invariantFieldName, boolean cache,
+                                 String parameterName, String fieldType, String resourcesFieldName,
+                                 ClassTransformation transformation)
+    {
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        // While the component is still loading, or when the value for the component is cached,
+        // or if the value is not bound, then return the current value of the field.
+
+        builder.addln("if (%s || ! %s.isLoaded() || ! %<s.isBound(\"%s\")) return %s;", cachedFieldName,
+                      resourcesFieldName, parameterName, fieldName);
+
+        String cast = TransformUtils.getWrapperTypeName(fieldType);
+
+        // The ($r) cast will convert the result to the method return type; generally
+        // this does nothing. but for primitive types, it will unwrap
+        // the wrapper type back to a primitive.  We pass the desired type name
+        // to readParameter(), since its easier to convert it properly to
+        // a type on that end than in the generated code.
+
+        builder.addln("%s result = ($r) ((%s) %s.readParameter(\"%s\", \"%2$s\"));", fieldType, cast,
+                      resourcesFieldName, parameterName);
+
+        // If the binding is invariant, then it's ok to cache. Othewise, its only
+        // ok to cache if a) the @Parameter says to cache and b) the component
+        // is rendering at the point when field is accessed.
+
+        builder.add("if (%s", invariantFieldName);
+
+        if (cache) builder.add(" || %s.isRendering()", resourcesFieldName);
+
+        builder.addln(")");
+        builder.begin();
+        builder.addln("%s = result;", fieldName);
+        builder.addln("%s = true;", cachedFieldName);
+        builder.end();
+
+        builder.addln("return result;");
+        builder.end();
+
+        String methodName = transformation.newMemberName("read_parameter", parameterName);
+
+        TransformMethodSignature signature = new TransformMethodSignature(Modifier.PRIVATE, fieldType, methodName, null,
+                                                                          null);
+
+        transformation.addMethod(signature, builder.toString());
+
+        transformation.replaceReadAccess(fieldName, methodName);
+    }
+
+    private String getParameterName(String fieldName, String annotatedName)
+    {
+        if (InternalUtils.isNonBlank(annotatedName)) return annotatedName;
+
+        return InternalUtils.stripMemberPrefix(fieldName);
+    }
+
+    public static void bind(String parameterName, InternalComponentResources resources, Object value)
+    {
+        if (value == null) return;
+
+        if (value instanceof Binding)
+        {
+            Binding binding = (Binding) value;
+
+            resources.bindParameter(parameterName, binding);
+            return;
+        }
+
+        resources.bindParameter(parameterName, new LiteralBinding("default " + parameterName, value, null));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PersistWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PersistWorker.java
new file mode 100644
index 0000000..199c9e2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PersistWorker.java
@@ -0,0 +1,122 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+import static java.lang.String.format;
+import java.lang.reflect.Modifier;
+
+/**
+ * Converts fields with the {@link org.apache.tapestry.annotation.Persist} annotation into persistent fields.
+ */
+public class PersistWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (String name : transformation.findFieldsWithAnnotation(Persist.class))
+        {
+            makeFieldPersistent(name, transformation, model);
+        }
+    }
+
+    /**
+     * Making a field persistent: <ul> <li>Need a secondary default field that stores the initial value</li> <li>Store
+     * the active value into the default field when the page finishes loading</li> <li>Roll the active value back to the
+     * default when the page detaches</li> <ii>On changes to the active field, post the change via the {@link
+     * org.apache.tapestry.internal.InternalComponentResources} </li> <li>When the page attaches, pull the persisted
+     * value for the field out of the {@link org.apache.tapestry.services.PersistentFieldBundle}</li> </ul>
+     */
+    private void makeFieldPersistent(String fieldName, ClassTransformation transformation,
+                                     MutableComponentModel model)
+    {
+        String fieldType = transformation.getFieldType(fieldName);
+        Persist annotation = transformation.getFieldAnnotation(fieldName, Persist.class);
+
+        // Record the type of persistence, until needed later.
+
+        String logicalFieldName = model.setFieldPersistenceStrategy(fieldName, annotation.value());
+
+        String defaultFieldName = transformation.addField(Modifier.PRIVATE, fieldType, fieldName
+                + "_default");
+
+        transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, format(
+                "%s = %s;",
+                defaultFieldName,
+                fieldName));
+
+        transformation.extendMethod(
+                TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE,
+                format("%s = %s;", fieldName, defaultFieldName));
+
+        String resourcesFieldName = transformation.getResourcesFieldName();
+
+        String writeMethodName = transformation.newMemberName("write", fieldName);
+
+        BodyBuilder builder = new BodyBuilder();
+
+        builder.begin();
+        builder.addln(
+                "%s.persistFieldChange(\"%s\", ($w) $1);",
+                resourcesFieldName,
+                logicalFieldName);
+        builder.addln("%s = $1;", fieldName);
+        builder.end();
+
+        transformation.addMethod(new TransformMethodSignature(Modifier.PRIVATE, "void", writeMethodName,
+                                                              new String[]
+                                                                      { fieldType }, null), builder.toString());
+
+        transformation.replaceWriteAccess(fieldName, writeMethodName);
+
+        builder.clear();
+        builder.begin();
+
+        // Check to see if there's a recorded change for this component, this field.
+
+        builder.addln("if (%s.hasFieldChange(\"%s\"))", resourcesFieldName, logicalFieldName);
+
+        String wrapperType = TransformUtils.getWrapperTypeName(fieldType);
+
+        // Get the value, cast it to the correct type (or wrapper type)
+        builder.add(
+                "  %s = ((%s) %s.getFieldChange(\"%s\"))",
+                fieldName,
+                wrapperType,
+                resourcesFieldName,
+                logicalFieldName);
+
+        // For primtive types, add in the method call to unwrap the wrapper type to a primitive type
+
+        String unwrapMethodName = TransformUtils.getUnwrapperMethodName(fieldType);
+
+        if (unwrapMethodName == null)
+            builder.addln(";");
+        else
+            builder.addln(".%s();", unwrapMethodName);
+
+        builder.end();
+
+        transformation.extendMethod(
+                TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE,
+                builder.toString());
+
+        transformation.claimField(fieldName, annotation);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PropertyWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PropertyWorker.java
new file mode 100644
index 0000000..b8ce6fe
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/PropertyWorker.java
@@ -0,0 +1,68 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Provides the getter and setter methods. The methods are added as "existing", meaning that field access to them will
+ * be transformed as necessary by other annotations. This worker needs to be scheduled before any worker that might
+ * delete a field.
+ *
+ * @see org.apache.tapestry.annotation.Property
+ */
+public class PropertyWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (String fieldName : transformation.findAllFieldsWithAnnotation(Property.class))
+        {
+            Property annotation = transformation.getFieldAnnotation(fieldName, Property.class);
+
+            String propertyName = InternalUtils.capitalize(InternalUtils.stripMemberPrefix(fieldName));
+
+            String fieldType = transformation.getFieldType(fieldName);
+
+            if (annotation.read())
+            {
+                TransformMethodSignature getter
+                        = new TransformMethodSignature(Modifier.PUBLIC | Modifier.FINAL, fieldType,
+                                                       "get" + propertyName,
+                                                       null, null);
+
+                transformation.addTransformedMethod(getter, "return " + fieldName + ";");
+            }
+
+            if (annotation.write())
+            {
+                TransformMethodSignature setter
+                        = new TransformMethodSignature(Modifier.PUBLIC | Modifier.FINAL, "void", "set" + propertyName,
+                                                       new String[] { fieldType }, null);
+
+                transformation.addTransformedMethod(setter, fieldName + " = $1;");
+            }
+
+            // The field is NOT claimed, because we want annotation for the fields to operate.
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RenderCommandWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RenderCommandWorker.java
new file mode 100644
index 0000000..8d0895a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RenderCommandWorker.java
@@ -0,0 +1,49 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Ensures that all components implement {@link RenderCommand} by delegating to {@link
+ * org.apache.tapestry.internal.InternalComponentResources#queueRender(org.apache.tapestry.runtime.RenderQueue)}.
+ */
+public class RenderCommandWorker implements ComponentClassTransformWorker
+{
+    private final TransformMethodSignature RENDER_SIGNATURE =
+            new TransformMethodSignature(Modifier.PUBLIC, "void", "render", new String[] {
+                    MarkupWriter.class.getName(), RenderQueue.class.getName() }, null);
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        // Subclasses don't need to bother, they'll inherit from super-classes.
+
+        if (model.getParentModel() != null) return;
+
+        transformation.addImplementedInterface(RenderCommand.class);
+
+        String body = String.format("%s.queueRender($2);", transformation.getResourcesFieldName());
+
+        transformation.addMethod(RENDER_SIGNATURE, body);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ResponseEncodingWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ResponseEncodingWorker.java
new file mode 100644
index 0000000..6c28a95
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/ResponseEncodingWorker.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.annotation.ResponseEncoding;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+public class ResponseEncodingWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        ResponseEncoding annotation = transformation.getAnnotation(ResponseEncoding.class);
+
+        if (annotation == null) return;
+
+        model.setMeta(MetaDataConstants.RESPONSE_ENCODING, annotation.value());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RetainWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RetainWorker.java
new file mode 100644
index 0000000..e629be1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/RetainWorker.java
@@ -0,0 +1,42 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform;

+

+import org.apache.tapestry.annotation.Retain;

+import org.apache.tapestry.model.MutableComponentModel;

+import org.apache.tapestry.services.ClassTransformation;

+import org.apache.tapestry.services.ComponentClassTransformWorker;

+

+/**

+ * Identifies fields with the {@link org.apache.tapestry.annotation.Retain} annotation, and "claims" them so that no

+ * special work will occur on them.

+ */

+public final class RetainWorker implements ComponentClassTransformWorker

+{

+    /**

+     * Claims each field with the {@link org.apache.tapestry.annotation.Retain} annotation, claiming it using the

+     * annotation as the tag.

+     */

+    public void transform(ClassTransformation transformation, MutableComponentModel model)

+    {

+        for (String fieldName : transformation.findFieldsWithAnnotation(Retain.class))

+        {

+            Retain annotation = transformation.getFieldAnnotation(fieldName, Retain.class);

+

+            transformation.claimField(fieldName, annotation);

+        }

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SecureWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SecureWorker.java
new file mode 100644
index 0000000..b6e77e0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SecureWorker.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.annotation.Secure;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Recognizes the {@link org.apache.tapestry.annotation.Secure} annotation and sets the {@link
+ * org.apache.tapestry.MetaDataConstants#SECURE_PAGE} meta data to "true".
+ */
+public class SecureWorker implements ComponentClassTransformWorker
+{
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        Secure secure = transformation.getAnnotation(Secure.class);
+
+        if (secure != null)
+            model.setMeta(MetaDataConstants.SECURE_PAGE, "true");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorker.java
new file mode 100644
index 0000000..06f5829
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorker.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Checks for the {@link SupportsInformalParameters} annotation, settting the corresponding flag on the model if
+ * present.
+ */
+public class SupportsInformalParametersWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        if (transformation.getAnnotation(SupportsInformalParameters.class) != null)
+            model.enableSupportsInformalParameters();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
new file mode 100644
index 0000000..2d41e6a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/TransformMessages.java
@@ -0,0 +1,44 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+class TransformMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(TransformMessages.class);
+
+    static String fieldInjectionError(String className, String fieldName, Throwable cause)
+    {
+        return MESSAGES.format("field-injection-error", className, fieldName, cause);
+    }
+
+    static String componentNotAssignableToField(Component component, String fieldName, String fieldType)
+    {
+        return MESSAGES.format("component-not-assignable-to-field", component
+                .getComponentResources().getCompleteId(), fieldName, fieldType);
+    }
+
+    static String cachedMethodMustHaveReturnValue(TransformMethodSignature method) {
+        return MESSAGES.format("cached-no-return-value", method);
+    }
+    
+    static String cachedMethodsHaveNoParameters(TransformMethodSignature method) {
+        return MESSAGES.format("cached-no-parameters", method);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorker.java
new file mode 100644
index 0000000..1564f46
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorker.java
@@ -0,0 +1,66 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import static org.apache.tapestry.services.TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE;
+import static org.apache.tapestry.services.TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * Designed to be just about the last worker in the pipeline. Its job is to add cleanup code that restores transient
+ * fields back to their initial (null) value. Fields that have been previously {@link
+ * org.apache.tapestry.services.ClassTransformation#claimField(String, Object) claimed} are ignored, as are fields that
+ * are final.
+ */
+public final class UnclaimedFieldWorker implements ComponentClassTransformWorker
+{
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> fieldNames = transformation.findUnclaimedFields();
+
+        for (String fieldName : fieldNames)
+        {
+            transformField(fieldName, transformation);
+        }
+    }
+
+    private void transformField(String fieldName, ClassTransformation transformation)
+    {
+        int modifiers = transformation.getFieldModifiers(fieldName);
+
+        if (Modifier.isFinal(modifiers))
+            return;
+
+        String type = transformation.getFieldType(fieldName);
+
+        String defaultFieldName = transformation.addField(Modifier.PRIVATE, type, fieldName
+                + "_default");
+
+        transformation.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, defaultFieldName + " = "
+                + fieldName + ";");
+
+        // At the end of the request, we want to move the default value back over the
+        // active field value. This will most often be null.
+
+        transformation.extendMethod(CONTAINING_PAGE_DID_DETACH_SIGNATURE, fieldName + " = "
+                + defaultFieldName + ";");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/ByteTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/ByteTranslator.java
new file mode 100644
index 0000000..6f2db43
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/ByteTranslator.java
@@ -0,0 +1,44 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+public class ByteTranslator implements Translator<Byte>
+{
+    public String toClient(Byte value)
+    {
+        return value.toString();
+    }
+
+    public Class<Byte> getType()
+    {
+        return Byte.class;
+    }
+
+    public Byte parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+        try
+        {
+            return new Byte(clientValue.trim());
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ValidationException(messages.format("integer-format-exception", clientValue));
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/DoubleTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/DoubleTranslator.java
new file mode 100644
index 0000000..5a055bb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/DoubleTranslator.java
@@ -0,0 +1,52 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+public class DoubleTranslator implements Translator<Double>
+{
+    /**
+     * Parses blank values to null, otherwise parses the client value to a double
+     *
+     * @throws ValidationException if the clientValue can not be parsed
+     */
+    public Double parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+        try
+        {
+            return new Double(clientValue.trim());
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ValidationException(messages.format("number-format-exception", clientValue));
+        }
+    }
+
+    /**
+     * Converts null to the blank string, non-null to a string representation.
+     */
+    public String toClient(Double value)
+    {
+        return value.toString();
+    }
+
+    public Class<Double> getType()
+    {
+        return Double.class;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/FloatTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/FloatTranslator.java
new file mode 100644
index 0000000..65b9cee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/FloatTranslator.java
@@ -0,0 +1,44 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+public class FloatTranslator implements Translator<Float>
+{
+    public Class<Float> getType()
+    {
+        return Float.class;
+    }
+
+    public String toClient(Float value)
+    {
+        return value.toString();
+    }
+
+    public Float parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+        try
+        {
+            return new Float(clientValue.trim());
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ValidationException(messages.format("number-format-exception", clientValue));
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/IntegerTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/IntegerTranslator.java
new file mode 100644
index 0000000..e83f90b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/IntegerTranslator.java
@@ -0,0 +1,57 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+/**
+ * A translator for type integer.
+ */
+public final class IntegerTranslator implements Translator<Integer>
+{
+    public Class<Integer> getType()
+    {
+        return Integer.class;
+    }
+
+    /**
+     * Parses blank values to null, otherwise parses the client value to an integer.
+     *
+     * @throws ValidationException if the clientValue can not be parsed as an integer
+     */
+    public Integer parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+
+        try
+        {
+            return new Integer(clientValue.trim());
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ValidationException(messages.format("integer-format-exception", clientValue));
+        }
+    }
+
+    /**
+     * Converts null to the blank string, non-null to a string representation.
+     */
+    public String toClient(Integer value)
+    {
+        return value.toString();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/LongTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/LongTranslator.java
new file mode 100644
index 0000000..bdac2ac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/LongTranslator.java
@@ -0,0 +1,56 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+/**
+ * A translator for type long.
+ */
+public class LongTranslator implements Translator<Long>
+{
+    public Class<Long> getType()
+    {
+        return Long.class;
+    }
+
+    /**
+     * Parses blank values to null, otherwise parses the client value to a long
+     *
+     * @throws ValidationException if the clientValue can not be parsed
+     */
+    public Long parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+
+        try
+        {
+            return new Long(clientValue.trim());
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ValidationException(messages.format("integer-format-exception", clientValue));
+        }
+    }
+
+    /**
+     * Converts null to the blank string, non-null to a string representation.
+     */
+    public String toClient(Long value)
+    {
+        return value.toString();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/StringTranslator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/StringTranslator.java
new file mode 100644
index 0000000..df8fce7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/translator/StringTranslator.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.translator;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.Messages;
+
+public class StringTranslator implements Translator<String>
+{
+    public Class<String> getType()
+    {
+        return String.class;
+    }
+
+    /**
+     * Returns the client value (or null, if the client value is blank).
+     */
+    public String parseClient(String clientValue, Messages messages) throws ValidationException
+    {
+        return clientValue;
+    }
+
+    /**
+     * Returns the value.
+     */
+    public String toClient(String value)
+    {
+        return value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java
new file mode 100644
index 0000000..f40f5c8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64InputStream.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import org.apache.commons.codec.binary.Base64;

+

+import java.io.ByteArrayInputStream;

+

+/**

+ * An extension of {@link ByteArrayInputStream} that is initialized from a Base64 input stream (rather than from a byte

+ * array).

+ */

+public class Base64InputStream extends ByteArrayInputStream

+{

+    public Base64InputStream(String base64)

+    {

+        super(decode(base64));

+    }

+

+    private static byte[] decode(String base64)

+    {

+        byte[] array = base64.getBytes();

+

+        return Base64.decodeBase64(array);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java
new file mode 100644
index 0000000..247cf3d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectInputStream.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import java.io.BufferedInputStream;

+import java.io.IOException;

+import java.io.ObjectInputStream;

+import java.util.zip.GZIPInputStream;

+

+/**

+ * A convienience for building a {@link ObjectInputStream} around a Base64 encoding (that originated in {@link

+ * Base64ObjectOutputStream}).

+ */

+public class Base64ObjectInputStream extends ObjectInputStream

+{

+    public Base64ObjectInputStream(String base64) throws IOException

+    {

+        super(new BufferedInputStream(new GZIPInputStream(new Base64InputStream(base64))));

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java
new file mode 100644
index 0000000..52fab63
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64ObjectOutputStream.java
@@ -0,0 +1,48 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import java.io.BufferedOutputStream;

+import java.io.IOException;

+import java.io.ObjectOutputStream;

+import java.util.zip.GZIPOutputStream;

+

+/**

+ * Wraps a {@link Base64OutputStream} with a {@link GZIPOutputStream} as an {@link ObjectOutputStream}. This allows an

+ * object (or objects) to be encoded into a Base64 string (accessed via {@link #toBase64()}).

+ *

+ * @see Base64ObjectInputStream

+ */

+public class Base64ObjectOutputStream extends ObjectOutputStream

+{

+    private final Base64OutputStream output;

+

+    private Base64ObjectOutputStream(Base64OutputStream output) throws IOException

+    {

+        super(new BufferedOutputStream(new GZIPOutputStream(output)));

+

+        this.output = output;

+    }

+

+    public Base64ObjectOutputStream() throws IOException

+    {

+        this(new Base64OutputStream());

+    }

+

+    public String toBase64()

+    {

+        return output.toBase64();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
new file mode 100644
index 0000000..a5ad0bb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Base64OutputStream.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import org.apache.commons.codec.binary.Base64;

+

+import java.io.ByteArrayOutputStream;

+

+/**

+ * An extension of {@link ByteArrayOutputStream} that allows the final byte array to be converted to a Base64 string.

+ */

+public final class Base64OutputStream extends ByteArrayOutputStream

+{

+    public String toBase64()

+    {

+        byte[] binary = toByteArray();

+

+        byte[] base64 = Base64.encodeBase64(binary);

+

+        return new String(base64);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Holder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Holder.java
new file mode 100644
index 0000000..0b36c3c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/Holder.java
@@ -0,0 +1,49 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * An object that holds some type of other object. This is useful for communicating information from an inner class
+ * (used as a closure) to the containing method. This is similar to {@link AtomicReference}, except that it is simpler
+ * but <strong>not</strong> thread safe.
+ *
+ * @param <T>
+ */
+public class Holder<T>
+{
+    private T held;
+
+    public void put(T object)
+    {
+        held = object;
+    }
+
+    public T get()
+    {
+        return held;
+    }
+
+    public boolean hasValue()
+    {
+        return held != null;
+    }
+
+    public static <T> Holder<T> create()
+    {
+        return new Holder<T>();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java
new file mode 100644
index 0000000..7606459
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/IntegerRange.java
@@ -0,0 +1,125 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import java.util.Iterator;

+

+/**

+ * Represents a sequence of integer values, either ascending or descending. The sequence is always inclusive (of the

+ * finish value).

+ */

+public final class IntegerRange implements Iterable<Integer>

+{

+    private final int start;

+

+    private final int finish;

+

+    private class RangeIterator implements Iterator<Integer>

+    {

+        private final int increment;

+

+        private int value = start;

+

+        private boolean hasNext = true;

+

+        RangeIterator()

+        {

+            increment = start < finish ? +1 : -1;

+        }

+

+        public boolean hasNext()

+        {

+            return hasNext;

+        }

+

+        public Integer next()

+        {

+            if (!hasNext) throw new IllegalStateException();

+

+            int result = value;

+

+            hasNext = value != finish;

+

+            value += increment;

+

+            return result;

+        }

+

+        public void remove()

+        {

+            throw new UnsupportedOperationException();

+        }

+

+    }

+

+    public IntegerRange(final int start, final int finish)

+    {

+        this.start = start;

+        this.finish = finish;

+    }

+

+    public int getFinish()

+    {

+        return finish;

+    }

+

+    public int getStart()

+    {

+        return start;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("%d..%d", start, finish);

+    }

+

+    /**

+     * The main puprose of a range object is to produce an Iterator. Since IntegerRange is iterable, it is useful with

+     * the Tapestry Loop component, but also with the Java for loop!

+     */

+    public Iterator<Integer> iterator()

+    {

+        return new RangeIterator();

+    }

+

+    @Override

+    public int hashCode()

+    {

+        final int PRIME = 31;

+

+        int result = PRIME + finish;

+

+        result = PRIME * result + start;

+

+        return result;

+    }

+

+    /**

+     * Returns true if the other object is an IntegerRange with the same start and finish values.

+     */

+    @Override

+    public boolean equals(Object obj)

+    {

+        if (this == obj) return true;

+        if (obj == null) return false;

+        if (getClass() != obj.getClass()) return false;

+        final IntegerRange other = (IntegerRange) obj;

+        if (finish != other.finish) return false;

+

+        return start == other.start;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MethodInvocationBuilder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MethodInvocationBuilder.java
new file mode 100644
index 0000000..2b99552
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MethodInvocationBuilder.java
@@ -0,0 +1,96 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.TransformMethodSignature;
+import org.apache.tapestry.services.TransformUtils;
+
+import java.util.Map;
+
+/**
+ * A utility class for building part of a method body to invoke a method. Analyzes the method and matches parameter
+ * types to ParameterBuilders.
+ */
+public final class MethodInvocationBuilder
+{
+    private final Map<String, ParameterBuilder> builders = CollectionFactory.newMap();
+
+    /**
+     * Maps a parameter type to a {@link ParameterBuilder}.
+     */
+    public void addParameter(String parameterType, ParameterBuilder builder)
+    {
+        // TODO: Name conflicts
+
+        builders.put(parameterType, builder);
+    }
+
+    /**
+     * Maps a parameter type to a literal string to be used for the parameter expression.
+     *
+     * @see StringParameterBuilder
+     */
+    public void addParameter(String parameterType, String expression)
+    {
+        addParameter(parameterType, new StringParameterBuilder(expression));
+    }
+
+    /**
+     * Builds the method invocation. Analyzes the type of each parameter to the method, and uses a {@link
+     * ParameterBuilder} to provide the expression. Supplies a default value (usually null) for any parameters that do
+     * not have parameter builders.
+     *
+     * @param signature      of the method to invoke
+     * @param transformation
+     * @return method invocation expression
+     * @see TransformUtils#getDefaultValue(String)
+     */
+    public String buildMethodInvocation(TransformMethodSignature signature,
+                                        ClassTransformation transformation)
+    {
+        StringBuilder builder = new StringBuilder(signature.getMethodName());
+
+        builder.append("(");
+
+        String[] parameterTypes = signature.getParameterTypes();
+
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            if (i > 0) builder.append(", ");
+
+            String type = parameterTypes[i];
+
+            ParameterBuilder parameterBuilder = builders.get(type);
+
+            if (parameterBuilder == null)
+            {
+                // TODO: Log an error
+
+                builder.append(TransformUtils.getDefaultValue(type));
+            }
+            else
+            {
+                builder.append(parameterBuilder.buildParameter(transformation));
+            }
+        }
+
+        builder.append(")");
+
+        return builder.toString();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MultiKey.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MultiKey.java
new file mode 100644
index 0000000..12cf041
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/MultiKey.java
@@ -0,0 +1,86 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import java.util.Arrays;
+
+/**
+ * Combines multiple values to form a single composite key. MultiKey can often be used as an alternative to nested
+ * maps.
+ */
+public final class MultiKey
+{
+    private static final int PRIME = 31;
+
+    private final Object[] values;
+
+    private final int hashCode;
+
+    /**
+     * Creates a new instance from the provided values. It is assumed that the values provided are good map keys
+     * themselves -- immutable, with proper implementations of equals() and hashCode().
+     *
+     * @param values
+     */
+    public MultiKey(Object... values)
+    {
+        this.values = values;
+
+        hashCode = PRIME * Arrays.hashCode(this.values);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final MultiKey other = (MultiKey) obj;
+
+        return Arrays.equals(values, other.values);
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder("MultiKey[");
+
+        boolean first = true;
+
+        for (Object o : values)
+        {
+            if (!first)
+                builder.append(", ");
+
+            builder.append(o);
+
+            first = false;
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/NotificationEventCallback.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/NotificationEventCallback.java
new file mode 100644
index 0000000..2e3f0d7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/NotificationEventCallback.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.ComponentEventCallback;
+
+/**
+ * A {@link org.apache.tapestry.ComponentEventCallback} used for notification events. Event handler methods may return
+ * true (to abort the event) or false (to allow the event to continue bubbling up), but all other values are forbidden.
+ */
+public class NotificationEventCallback implements ComponentEventCallback
+{
+    private final String eventType;
+
+    private final String completeId;
+
+    public NotificationEventCallback(String eventType, String completeId)
+    {
+        this.eventType = eventType;
+        this.completeId = completeId;
+    }
+
+    public boolean handleResult(Object result)
+    {
+        if (result instanceof Boolean) return ((Boolean) result);
+
+        throw new IllegalArgumentException(
+                UtilMessages.noReturnValueAccepted(eventType, completeId, result));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/ParameterBuilder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/ParameterBuilder.java
new file mode 100644
index 0000000..5f7c9c1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/ParameterBuilder.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import org.apache.tapestry.services.ClassTransformation;

+

+/**

+ * Builds single parameter value to pass into a method being invoked by a {@link org.apache.tapestry.internal.util.MethodInvocationBuilder}.

+ */

+public interface ParameterBuilder

+{

+    /**

+     * @param transformation

+     * @return the expression for the parameter

+     */

+    String buildParameter(ClassTransformation transformation);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/PrintOutCollector.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/PrintOutCollector.java
new file mode 100644
index 0000000..1936508
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/PrintOutCollector.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Utility for collecting the output of a {@link java.io.PrintWriter}.
+ */
+public class PrintOutCollector
+{
+    private final StringWriter stringWriter;
+
+    private PrintWriter printWriter;
+
+    public PrintOutCollector()
+    {
+        stringWriter = new StringWriter();
+        printWriter = new PrintWriter(stringWriter);
+    }
+
+    public PrintWriter getPrintWriter()
+    {
+        return printWriter;
+    }
+
+    /**
+     * Closes the {@link PrintWriter} and returns the accumulated text output.
+     */
+    public String getPrintOut()
+    {
+        printWriter.close();
+        return stringWriter.toString();
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/SelectModelRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/SelectModelRenderer.java
new file mode 100644
index 0000000..8226312
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/SelectModelRenderer.java
@@ -0,0 +1,86 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.*;
+
+import java.util.Map;
+
+public class SelectModelRenderer implements SelectModelVisitor
+{
+    private final MarkupWriter writer;
+
+    private final ValueEncoder encoder;
+
+    public SelectModelRenderer(final MarkupWriter writer, ValueEncoder encoder)
+    {
+        this.writer = writer;
+        this.encoder = encoder;
+    }
+
+    public void beginOptionGroup(OptionGroupModel groupModel)
+    {
+        writer.element("optgroup", "label", groupModel.getLabel());
+
+        writeDisabled(groupModel.isDisabled());
+        writeAttributes(groupModel.getAttributes());
+    }
+
+    public void endOptionGroup(OptionGroupModel groupModel)
+    {
+        writer.end(); // select
+    }
+
+    @SuppressWarnings("unchecked")
+    public void option(OptionModel optionModel)
+    {
+        Object optionValue = optionModel.getValue();
+
+        String clientValue = encoder.toClient(optionValue);
+
+        writer.element("option", "value", clientValue);
+
+        if (isOptionSelected(optionModel, clientValue)) writer.attributes("selected", "selected");
+
+        writeDisabled(optionModel.isDisabled());
+        writeAttributes(optionModel.getAttributes());
+
+        writer.write(optionModel.getLabel());
+
+        writer.end();
+    }
+
+    private void writeDisabled(boolean disabled)
+    {
+        if (disabled) writer.attributes("disabled", "disabled");
+    }
+
+    private void writeAttributes(Map<String, String> attributes)
+    {
+        if (attributes == null) return;
+
+        for (Map.Entry<String, String> e : attributes.entrySet())
+            writer.attributes(e.getKey(), e.getValue());
+    }
+
+    /**
+     * If true, then the selected attribute will be written. This implementation always returns false.
+     */
+    protected boolean isOptionSelected(OptionModel optionModel, String clientValue)
+    {
+        return false;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/StringParameterBuilder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/StringParameterBuilder.java
new file mode 100644
index 0000000..071e742
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/StringParameterBuilder.java
@@ -0,0 +1,44 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.util;

+

+import org.apache.tapestry.services.ClassTransformation;

+

+import static java.lang.String.format;

+

+/**

+ * Implementation of {@link org.apache.tapestry.internal.util.ParameterBuilder} that simply provides a static string

+ * value for the parameter expression.

+ */

+public final class StringParameterBuilder implements ParameterBuilder

+{

+    private final String expression;

+

+    public StringParameterBuilder(String expression)

+    {

+        this.expression = expression;

+    }

+

+    public String buildParameter(ClassTransformation transformation)

+    {

+        return expression;

+    }

+

+    @Override

+    public String toString()

+    {

+        return format("StringParameterBuilder[%s]", expression);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/URLChangeTracker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/URLChangeTracker.java
new file mode 100644
index 0000000..c5a14b0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/URLChangeTracker.java
@@ -0,0 +1,199 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Map;
+
+/**
+ * Given a (growing) set of URLs, can periodically check to see if any of the underlying resources has changed. This
+ * class is capable of using either millisecond-level granularity or second-level granularity. Millisecond-level
+ * granularity is used by default. Second-level granularity is provided for compatibility with browsers vis-a-vis
+ * resource caching -- that's how granular they get with their "If-Modified-Since", "Last-Modified" and "Expires"
+ * headers.
+ */
+public class URLChangeTracker
+{
+    private static final long FILE_DOES_NOT_EXIST_TIMESTAMP = -1L;
+
+    private final Map<File, Long> fileToTimestamp = CollectionFactory.newConcurrentMap();
+
+    private final boolean granularitySeconds;
+
+    /**
+     * Creates a new URL change tracker with millisecond-level granularity.
+     */
+    public URLChangeTracker()
+    {
+        this(false);
+    }
+
+    /**
+     * Creates a new URL change tracker, using either millisecond-level granularity or second-level granularity.
+     *
+     * @param granularitySeconds whether or not to use second granularity (as opposed to millisecond granularity)
+     */
+    public URLChangeTracker(boolean granularitySeconds)
+    {
+        this.granularitySeconds = granularitySeconds;
+    }
+
+    /**
+     * Stores a new URL into the tracker, or returns the previous time stamp for a previously added URL. Filters out all
+     * non-file URLs.
+     *
+     * @param url of the resource to add, or null if not known
+     * @return the current timestamp for the URL (possibly rounded off for granularity reasons), or 0 if the URL is
+     *         null
+     */
+    public long add(URL url)
+    {
+        if (url == null) return 0;
+
+        if (!url.getProtocol().equals("file")) return timestampForNonFileURL(url);
+
+        File resourceFile = toFile(url);
+
+        if (fileToTimestamp.containsKey(resourceFile)) return fileToTimestamp.get(resourceFile);
+
+        long timestamp = readTimestamp(resourceFile);
+
+        // A quick and imperfect fix for TAPESTRY-1918.  When a file
+        // is added, add the directory containing the file as well.
+
+        fileToTimestamp.put(resourceFile, timestamp);
+
+        File dir = resourceFile.getParentFile();
+
+        if (!fileToTimestamp.containsKey(dir))
+        {
+            long dirTimestamp = readTimestamp(dir);
+            fileToTimestamp.put(dir, dirTimestamp);
+        }
+
+
+        return timestamp;
+    }
+
+    private long timestampForNonFileURL(URL url)
+    {
+        long timestamp;
+
+        try
+        {
+            timestamp = url.openConnection().getLastModified();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        return applyGranularity(timestamp);
+    }
+
+    private File toFile(URL url)
+    {
+        // http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html
+
+        try
+        {
+            return new File(url.toURI());
+        }
+        catch (URISyntaxException ex)
+        {
+            return new File(url.getPath());
+        }
+    }
+
+    /**
+     * Clears all URL and timestamp data stored in the tracker.
+     */
+    public void clear()
+    {
+        fileToTimestamp.clear();
+    }
+
+    /**
+     * Re-acquires the last updated timestamp for each URL and returns true if any timestamp has changed.
+     */
+    public boolean containsChanges()
+    {
+        boolean result = false;
+
+        // This code would be highly suspect if this method was expected to be invoked
+        // concurrently, but CheckForUpdatesFilter ensures that it will be invoked
+        // synchronously.
+
+        for (Map.Entry<File, Long> entry : fileToTimestamp.entrySet())
+        {
+            long newTimestamp = readTimestamp(entry.getKey());
+            long current = entry.getValue();
+
+            if (current == newTimestamp) continue;
+
+            result = true;
+            entry.setValue(newTimestamp);
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the time that the specified file was last modified, possibly rounded down to the nearest second.
+     */
+    private long readTimestamp(File file)
+    {
+        if (!file.exists()) return FILE_DOES_NOT_EXIST_TIMESTAMP;
+
+        return applyGranularity(file.lastModified());
+    }
+
+    private long applyGranularity(long timestamp)
+    {
+        // For coarse granularity (accurate only to the last second), remove the milliseconds since
+        // the last full second. This is for compatibility with client HTTP requests, which
+        // are only accurate to one second. The extra level of detail creates false positives
+        // for changes, and undermines HTTP response caching in the client.
+
+        if (granularitySeconds) return timestamp - (timestamp % 1000);
+
+        return timestamp;
+    }
+
+    /**
+     * Needed for testing; changes file timestamps so that a change will be detected by {@link #containsChanges()}.
+     */
+    public void forceChange()
+    {
+        for (Map.Entry<File, Long> e : fileToTimestamp.entrySet())
+        {
+            e.setValue(0l);
+        }
+    }
+
+    /**
+     * Needed for testing.
+     */
+    int trackedFileCount()
+    {
+        return fileToTimestamp.size();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java
new file mode 100644
index 0000000..8ba26dc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/internal/util/UtilMessages.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+class UtilMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(UtilMessages.class);
+
+    private UtilMessages()
+    {
+    }
+
+    static String noReturnValueAccepted(String eventType, String componentId, Object returnValue)
+    {
+        return MESSAGES.format("no-return-value-accepted", eventType, componentId, String
+                .valueOf(returnValue));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ComponentModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ComponentModel.java
new file mode 100644
index 0000000..2262b0d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ComponentModel.java
@@ -0,0 +1,147 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.model;
+
+import org.apache.tapestry.annotation.MixinAfter;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.ioc.Resource;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+/**
+ * Defines a component in terms of its capabilities, parameters, sub-components, etc. During <em>runtime</em>, the
+ * component model is immutable. During <em>construction</em> time, when the class is being transformed and loaded, the
+ * model is mutable.
+ *
+ * @see MutableComponentModel
+ */
+public interface ComponentModel
+{
+    /**
+     * Returns the resource corresponding to the class file for this component. This is used to find related resources,
+     * such as the component's template and message catalog.
+     */
+    Resource getBaseResource();
+
+    /**
+     * The FQCN of the component.
+     */
+    String getComponentClassName();
+
+    /**
+     * Returns the ids of all embedded components defined within the component class (via the {@link
+     * org.apache.tapestry.annotation.Component} annotation).
+     */
+    List<String> getEmbeddedComponentIds();
+
+    /**
+     * Returns an embedded component.
+     *
+     * @param componentId the id of the embedded component
+     * @return the embedded component model, or null if no component exists with that id
+     */
+    EmbeddedComponentModel getEmbeddedComponentModel(String componentId);
+
+    /**
+     * Returns the persistent strategy associated with the field.
+     *
+     * @param fieldName
+     * @return the corresponding strategy, or the empty string
+     * @throws IllegalArgumentException if the named field is not marked as persistent
+     */
+    String getFieldPersistenceStrategy(String fieldName);
+
+    /**
+     * Returns object that will be used to log warnings and errors related to this component.
+     */
+    Logger getLogger();
+
+    /**
+     * Returns a list of the class names of mixins that are part of the component's implementation.
+     */
+    List<String> getMixinClassNames();
+
+    /**
+     * Return a single parameter model by parameter name, or null if the parameter is not defined.
+     *
+     * @param parameterName the name of the parameter (case is ignored)
+     */
+    ParameterModel getParameterModel(String parameterName);
+
+    /**
+     * Returns an alphabetically sorted list of the names of all formal parameters. This includes parameters defined by
+     * a base class.
+     */
+
+    List<String> getParameterNames();
+
+    /**
+     * Returns an alphabetically sorted list of the names of all formal parameters defined by this specific class
+     * (parameters inherited from base classes are not identified).
+     */
+    List<String> getDeclaredParameterNames();
+
+    /**
+     * Returns a list of the names of all persistent fields (within this class, or any super-class). The names are
+     * sorted alphabetically.
+     *
+     * @see Persist
+     */
+    List<String> getPersistentFieldNames();
+
+    /**
+     * Returns true if the modeled component is a root class, a component class whose parent class is not a component
+     * class.  We may in the future require that components only extend from Object.
+     *
+     * @return true if a root class, false if a subclass
+     */
+    boolean isRootClass();
+
+    /**
+     * Returns true if the model indicates that informal parameters, additional parameters beyond the formal parameter
+     * defined for the component, are supported. This is false in most cases, but may be set to true for specific
+     * classes (when the {@link SupportsInformalParameters} annotation is present, or inherited from a super-class).
+     *
+     * @return true if this component model supports informal parameters
+     */
+    boolean getSupportsInformalParameters();
+
+    /**
+     * Returns the component model for this component's super-class, if it exists. Remember that only classes in the
+     * correct packages, are considered component classes.
+     *
+     * @return the parent class model, or null if this component's super class is not itself a component class
+     */
+    ComponentModel getParentModel();
+
+    /**
+     * Relevant for component mixins only. Indicates that the mixin behavior should occur <em>after</em> (not before)
+     * the component. Normally, this flag is set by the presence of the {@link MixinAfter} annotation.
+     *
+     * @return true if the mixin should operate after, not before, the component
+     */
+    boolean isMixinAfter();
+
+    /**
+     * Gets a meta value identified by the given key. If the current model does not provide a value for the key, then
+     * the parent component model (if any) is searched.
+     *
+     * @param key identifies the value to be accessed
+     * @return the value for the key (possibly inherited from a parent model), or null
+     */
+    String getMeta(String key);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/EmbeddedComponentModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/EmbeddedComponentModel.java
new file mode 100644
index 0000000..39a0284
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/EmbeddedComponentModel.java
@@ -0,0 +1,63 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.model;

+

+import org.apache.tapestry.annotation.Component;

+import org.apache.tapestry.ioc.Locatable;

+

+import java.util.List;

+

+/**

+ * The model for a component embedded within another component, as defined by the {@link

+ * org.apache.tapestry.annotation.Component} annotation.

+ */

+public interface EmbeddedComponentModel extends Locatable

+{

+    /**

+     * A unique id for the embedded component.

+     */

+    String getId();

+

+    /**

+     * The type of the component, which may be blank.

+     */

+    String getComponentType();

+

+    /**

+     * The class name of the component, as derived from the field to which the {@link Component} annotation is applied.

+     * This value is only used when the componentType property is blank.

+     */

+    String getComponentClassName();

+

+    /**

+     * A sorted list of the names of all bound parameters.

+     */

+    List<String> getParameterNames();

+

+    /**

+     * The value for each parameter, which will be interpreted as a binding expression.

+     */

+    String getParameterValue(String parameterName);

+

+    /**

+     * Returns the fully qualified class names of all mixins added to this component, sorted alphabetically.

+     */

+    List<String> getMixinClassNames();

+

+    /**

+     * If true, then the component should inherit informal parameters from its container.

+     */

+    boolean getInheritInformalParameters();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableComponentModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableComponentModel.java
new file mode 100644
index 0000000..bc4994a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableComponentModel.java
@@ -0,0 +1,87 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.model;
+
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Mutable version of {@link org.apache.tapestry.model.ComponentModel} used during the transformation phase.
+ */
+public interface MutableComponentModel extends ComponentModel
+{
+    /**
+     * Adds a new formal parameter to the model. Each parameter has a unique name (though access to parameters is case
+     * insensitive).
+     *
+     * @param name                 new, unique name for the parameter
+     * @param required             if true, the parameter must be bound
+     * @param defaultBindingPrefix the default binding prefix for this parameter
+     * @throws IllegalArgumentException if a parameter with the given name has already been defined for this model
+     * @see Parameter
+     */
+    void addParameter(String name, boolean required, String defaultBindingPrefix);
+
+    /**
+     * Defines a new embedded component.
+     *
+     * @param id                        the unique id for the embedded component, which must not already exist.
+     * @param type                      the type of the component (posslibly blank)
+     * @param componentClassName        the fully qualified class name (derived from the field), used if the type is
+     *                                  blank
+     * @param inheritInformalParameters if true, then the component will inherit informal parameters provided to its
+     *                                  container
+     * @param location                  where the component is defined @return a mutable model allowing parameters to be
+     *                                  set
+     */
+    MutableEmbeddedComponentModel addEmbeddedComponent(String id, String type, String componentClassName,
+                                                       boolean inheritInformalParameters, Location location);
+
+    /**
+     * Used to define the field persistence strategy for a particular field name. Returns a logical name for the field,
+     * which is guaranteed to be unique (this is necessary for handling the case where a subclass has a persistent field
+     * with the same name as a persistent field from a super-class).
+     *
+     * @param fieldName the name of the field which is to be made persistent
+     * @param strategy  the strategy for persisting the field, from {@link Persist#value()}. This value may be blank, in
+     *                  which case the stategy is inherited from the component, or the component's container.
+     * @return a logical name for the field, to be used with {@link ComponentModel#getFieldPersistenceStrategy(String)},
+     *         and with {@link InternalComponentResources#persistFieldChange(String, Object)}, etc.
+     */
+    String setFieldPersistenceStrategy(String fieldName, String strategy);
+
+    /**
+     * Adds a mixin to the component's implementation.
+     */
+    void addMixinClassName(String mixinClassName);
+
+    /**
+     * Sets the internal flag to indicate that this model (and all models that extend from it) support informal
+     * parameters.
+     */
+    void enableSupportsInformalParameters();
+
+    /**
+     * Changes the value of the mixinAfter flag. The default value is false.
+     */
+    void setMixinAfter(boolean mixinAfter);
+
+    /**
+     * Stores a meta data value under the indicated key.
+     */
+    void setMeta(String key, String value);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableEmbeddedComponentModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableEmbeddedComponentModel.java
new file mode 100644
index 0000000..3f3ff4e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/MutableEmbeddedComponentModel.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.model;

+

+/**

+ * A mutable version of {@link org.apache.tapestry.model.EmbeddedComponentModel} that allows the parameters to be

+ * incrementally stored.

+ */

+public interface MutableEmbeddedComponentModel extends EmbeddedComponentModel

+{

+    void addParameter(String name, String value);

+

+    /**

+     * Adds a mixin to the component in terms of its fully qualified class name.

+     */

+    void addMixin(String mixinClassName);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ParameterModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ParameterModel.java
new file mode 100644
index 0000000..2ed0fb2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/model/ParameterModel.java
@@ -0,0 +1,40 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.model;
+
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * Model for a <em>formal</em> parameter of a component.
+ *
+ * @see Parameter
+ */
+public interface ParameterModel
+{
+    /**
+     * The name of the parameter.
+     */
+    String getName();
+
+    /**
+     * If true, the parameter is required.
+     */
+    boolean isRequired();
+
+    /**
+     * The default binding prefix for the parameter, usually "prop".
+     */
+    String getDefaultBindingPrefix();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Component.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Component.java
new file mode 100644
index 0000000..49109ad
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Component.java
@@ -0,0 +1,91 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.OnEvent;
+
+/**
+ * Interface that defines the lifecycle of a component, within a page, allowing for callbacks into the component for
+ * many different events. This interface is part of the public API for Tapestry, but is <em>not</em> expected to be
+ * directly implemented by component classes; it should only be implemented as part of the component class
+ * transformation process.
+ * <p/>
+ * Most of the methods are related to render phases; see the corresponding annotations and component rendering
+ * documentation to see how they relate to each other.
+ * <p/>
+ * This interface is likely to change without notice.
+ */
+public interface Component extends ComponentResourcesAware, PageLifecycleListener
+{
+
+    /**
+     * Lifecycle method invoked at the end of the {@link org.apache.tapestry.annotation.CleanupRender} render phase.
+     * There is no annotation for this method, it is part of CleanupRender, but is always invoked. Its specific use is
+     * to allow components to clean up cached parameter values.
+     */
+    void postRenderCleanup();
+
+    /**
+     * Invoked before rendering a component (or its template).
+     */
+    void setupRender(MarkupWriter writer, Event event);
+
+    /**
+     * Invoked to allow a component to render its tag (start tag and attributes).
+     */
+    void beginRender(MarkupWriter writer, Event event);
+
+    /**
+     * This phase is only invoked for components with templates.
+     */
+    void beforeRenderTemplate(MarkupWriter writer, Event event);
+
+    /**
+     * Invoked after rendering the template for a component (only for components with a template).
+     */
+    void afterRenderTemplate(MarkupWriter writer, Event event);
+
+    /**
+     * Invoked just before rendering the body of component.
+     */
+    void beforeRenderBody(MarkupWriter writer, Event event);
+
+    /**
+     * Invoked just after rendering the body of the component.
+     */
+    void afterRenderBody(MarkupWriter writer, Event event);
+
+    /**
+     * Generally used to write the close tag matching any open tag written by {@link
+     * #beginRender(org.apache.tapestry.MarkupWriter, Event)}.
+     */
+    void afterRender(MarkupWriter writer, Event event);
+
+    /**
+     * Generally used to perform final cleanup of the component after rendering.
+     */
+    void cleanupRender(MarkupWriter writer, Event event);
+
+    /**
+     * Invoked to handle a component event. Methods with the {@link OnEvent} annotation (or the matching naming
+     * convention) will be invoked until one returns a non-null value.
+     *
+     * @param event
+     * @return true if any handler was found (and invoked), false otherwise
+     * @throws RuntimeException wrapping any checked exceptions that are thrown by individual event handler methods
+     */
+    boolean dispatchComponentEvent(ComponentEvent event);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java
new file mode 100644
index 0000000..0531cf1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEvent.java
@@ -0,0 +1,58 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.ComponentResourcesCommon;
+import org.apache.tapestry.EventContext;
+
+/**
+ * An event that may originate in application logic, or as a result of a client interaction (a GET or POST from the
+ * client).
+ *
+ * @see ComponentResourcesCommon#triggerEvent(String, Object[], org.apache.tapestry.ComponentEventCallback)
+ * @see org.apache.tapestry.ComponentEventCallback
+ */
+public interface ComponentEvent extends Event
+{
+    /**
+     * Returns true if the event matches the provided criteria.
+     *
+     * @param eventType      the type of event (case insensitive match)
+     * @param componentId    component is to match against (case insensitive), or the empty string
+     * @param parameterCount minimum number of context values
+     * @return true if the event matches.
+     */
+    boolean matches(String eventType, String componentId, int parameterCount);
+
+    /**
+     * Coerces a context value to a particular type. The context is an array of objects; typically it is an array of
+     * strings of extra path information encoded into the action URL.
+     *
+     * @param index           the index of the context value
+     * @param desiredTypeName the desired type
+     * @return the coerced value (a wrapper type if the desired type is a primitive)
+     */
+    Object coerceContext(int index, String desiredTypeName);
+
+    /**
+     * Returns the underlying {@link org.apache.tapestry.EventContext} as a (possibly empty) array.
+     */
+    Object[] getContext();
+
+    /**
+     * Returns the underlying event context.
+     */
+    EventContext getEventContext();
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java
new file mode 100644
index 0000000..174fa5a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentEventException.java
@@ -0,0 +1,57 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+/**
+ * A wrapper exception around any exception thrown when invoking a component event handler. In some cases, the
+ * underlying exception may have been a declared exception, and will be wrapped in a RuntimeException.
+ *
+ * @see org.apache.tapestry.ioc.util.ExceptionUtils#findCause(Throwable, Class)
+ */
+public class ComponentEventException extends TapestryException
+{
+    private final String eventType;
+
+    private final EventContext context;
+
+    /**
+     * @param message   exception message
+     * @param eventType type of event that triggered the exception
+     * @param context   context passed with the failed event
+     * @param location  location of the component while failed (may be null)
+     * @param cause     underlying exception
+     */
+    public ComponentEventException(String message, String eventType, EventContext context, Object location,
+                                   Throwable cause)
+    {
+        super(message, location, cause);
+
+        this.eventType = eventType;
+        this.context = context;
+    }
+
+    public String getEventType()
+    {
+        return eventType;
+    }
+
+    public EventContext getContext()
+    {
+        return context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentResourcesAware.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentResourcesAware.java
new file mode 100644
index 0000000..8fe4c09
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/ComponentResourcesAware.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.runtime;

+

+import org.apache.tapestry.ComponentResources;

+

+/**

+ * Interface implemented by components (after they have been transformed at load time). Component classes should not

+ * implement this interface directly.

+ */

+public interface ComponentResourcesAware

+{

+    /**

+     * Returns the resources associated with this component class.

+     */

+    ComponentResources getComponentResources();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Event.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Event.java
new file mode 100644
index 0000000..edd4df3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/Event.java
@@ -0,0 +1,50 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+/**
+ * The core methods related to event handling. Events used in this way exist to gather data from user code, by invoking
+ * user methods and capturing the response. Return values from methods, if non-null, are passed to a {@link
+ * org.apache.tapestry.ComponentEventCallback}. The {@link ComponentEvent} subinterface extends this by providing access
+ * to a context, or set of information related to the event, along with additional data used, at runtime, to match
+ * events to user code methods.
+ */
+public interface Event
+{
+    /**
+     * Returns true if the event has been aborted (meaning that the return value from some event handler method was
+     * accepted, and processing of the event was terminated).
+     *
+     * @return true if no further event handler methods should be invoked
+     */
+    boolean isAborted();
+
+    /**
+     * Invoke to identify, to the event, what component and method is being acted upon (used for some kinds of exception
+     * reporting).
+     *
+     * @param methodDescription describes the location (i.e. file name, method name and line number) of the method
+     */
+    void setMethodDescription(String methodDescription);
+
+    /**
+     * Stores a result for the event. Storing a non-null result value may abort the event (at the discretion of the
+     * {@link org.apache.tapestry.ComponentEventCallback}).
+     *
+     * @param result the result obtained from a method invocations
+     * @return true if the event is now aborted
+     */
+    boolean storeResult(Object result);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java
new file mode 100644
index 0000000..1725bd2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/PageLifecycleListener.java
@@ -0,0 +1,40 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+/**
+ * A set of methods that allow components to know about page-level operations.
+ */
+public interface PageLifecycleListener
+{
+    /**
+     * Invoked when the page finishes loading. This occurs once all components are loaded and all parameters have been
+     * set.
+     */
+    void containingPageDidLoad();
+
+    /**
+     * Invoked when the page is detached, allowing components a chance to clear out any temporary or client specific
+     * state.
+     */
+    void containingPageDidDetach();
+
+    /**
+     * Invoked when a page is first attached to the current request, giving components a chance to initialize for the
+     * current request.
+     */
+
+    void containingPageDidAttach();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderCommand.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderCommand.java
new file mode 100644
index 0000000..0fcb014
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderCommand.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.runtime;

+

+import org.apache.tapestry.MarkupWriter;

+

+/**

+ * A command used during rendering of a page.

+ */

+public interface RenderCommand

+{

+    /**

+     * Invoked on an object to request that it render itself. This involves a mix of invoking methods on the writer, and

+     * queueing up additional commands (often, representing children of the object that was invoked) to perform

+     * additional rendering.

+     * <p/>

+     * In this way, rendering is a tail recursive algorithm, but is not implemented using tail recursion.

+     */

+    void render(MarkupWriter writer, RenderQueue queue);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
new file mode 100644
index 0000000..ee6673a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/RenderQueue.java
@@ -0,0 +1,42 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.ComponentResources;
+
+/**
+ * A stateful object that manages the process of rendering a page. Rending a page in Tapestry is based on a command
+ * queue.
+ */
+public interface RenderQueue
+{
+    /**
+     * Adds the new command to the front of the queue.
+     */
+    void push(RenderCommand command);
+
+    /**
+     * Indicates that a component is starting its render. A stack of active components is used for exception reporting.
+     *
+     * @param resources identifies the component that is rendering
+     */
+    void startComponent(ComponentResources resources);
+
+    /**
+     * Corresponds to {@link #startComponent(String)}, used to denote when the most recently started component finishes
+     * rendering.
+     */
+    void endComponent();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/package.html b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/package.html
new file mode 100644
index 0000000..06a7d84
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/runtime/package.html
@@ -0,0 +1,5 @@
+<html>
+<body>Contains interfaces that are added to component classes at <em>runtime</em>. These
+interfaces are added using Tapestry built-in AOP support.
+</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Ajax.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Ajax.java
new file mode 100644
index 0000000..ec1490f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Ajax.java
@@ -0,0 +1,31 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Marker annotation for services related to processing an Ajax request (rather than a {@linkplain
+ * org.apache.tapestry.services.Traditional traditional request}).
+ *
+ * @see ComponentEventRequestHandler
+ */
+@Target({ ElementType.PARAMETER, ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Ajax
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Alias.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Alias.java
new file mode 100644
index 0000000..f93a244
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Alias.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.ObjectProvider;
+
+/**
+ * The Alias service provides an ObjectProvider that fits into the MasterObjectProvider command chain and disambiguates
+ * injections based on type. {@linkplain org.apache.tapestry.services.AliasContribution Contibutions} to the Alias
+ * service identify the desired service to inject for a particular service interface; this is only necessary when there
+ * is more than one service implementing the same interface.
+ * <p/>
+ * The {@linkplain AliasManager AliasOverrides} service also takes an unordered configuration of {@link
+ * org.apache.tapestry.services.AliasContribution}; such contributions override the "factory" contributions to the Alias
+ * service itself.  This is often used to replace built-in service implementations with ones that are specific to a
+ * particular application.
+ */
+public interface Alias
+{
+    /**
+     * Returns an object provideer that checks the desired type against the service's contributions.
+     */
+    ObjectProvider getObjectProvider();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasContribution.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasContribution.java
new file mode 100644
index 0000000..a44b252
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasContribution.java
@@ -0,0 +1,102 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.util.Formatter;
+
+/**
+ * A contribution into the {@link Alias} or AliasOverride service configuration.
+ */
+public final class AliasContribution<T>
+{
+    private final Class<T> contributionType;
+
+    private final String mode;
+
+    private final T object;
+
+    /**
+     * Simplifies the creation of an AliasContribution around a known type and instance of that type.
+     */
+    public static <X> AliasContribution<X> create(Class<X> contributionType, X object)
+    {
+        return new AliasContribution<X>(contributionType, object);
+    }
+
+    /**
+     * Simplifies the creation of an AliasContribution around a known type, mode, and an instance of that type.
+     */
+    public static <X> AliasContribution<X> create(Class<X> contributionType, String mode, X object)
+    {
+        return new AliasContribution<X>(contributionType, mode, object);
+    }
+
+    /**
+     * Conntributes the object with a blank mode.
+     */
+    public AliasContribution(Class<T> contributionType, T object)
+    {
+        this(contributionType, "", object);
+    }
+
+    public AliasContribution(Class<T> contributionType, String mode, T object)
+    {
+        this.contributionType = notNull(contributionType, "contributionClass");
+        this.mode = notNull(mode, "mode");
+        this.object = notNull(object, "object");
+    }
+
+    /**
+     * Returns the mode of operation for this instance of Tapestry. Most of the time, this will be the empty string,
+     * meaning that the contribution applies to Tapestry is any mode. In other cases, the mode will be "servlet" but may
+     * be other modes via add on modules, such as "portlet" or "offline".
+     */
+    public String getMode()
+    {
+        return mode;
+    }
+
+    public Class<T> getContributionType()
+    {
+        return contributionType;
+    }
+
+    /**
+     * The contributed object, which will be made available.
+     */
+    public T getObject()
+    {
+        return object;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder();
+        Formatter formatter = new Formatter(builder);
+
+        formatter.format("<AliasContribution: %s", contributionType.getName());
+
+        if (InternalUtils.isNonBlank(mode)) formatter.format(" mode:%s", mode);
+
+        formatter.format(" %s>", object);
+
+        return builder.toString();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasManager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasManager.java
new file mode 100644
index 0000000..e821fac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AliasManager.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.util.Map;
+
+/**
+ * A thin wrapper around a set of {@link org.apache.tapestry.services.AliasContribution}s.
+ */
+public interface AliasManager
+{
+    /**
+     * Filters down the contributions based on the mode. Each {@link AliasContribution contribution} will identify a
+     * contribution type and a non-null object that implements the type and may identify a mode. Only contributions
+     * where the mode is blank or the mode matches the provided mode are returned. Mode specific contributions quietly
+     * override non-specific contributions (where the mode is blank).
+     *
+     * @param mode
+     * @return map from contribution type to contribution object
+     */
+    Map<Class, Object> getAliasesForMode(String mode);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateContribution.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateContribution.java
new file mode 100644
index 0000000..66eb12b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateContribution.java
@@ -0,0 +1,59 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+/**
+ * A contribution to the configuration of the {@link ApplicationStateManager}, identifying the strategy and creator for
+ * a particular ASO (identified by the ASO's class).
+ */
+public final class ApplicationStateContribution
+{
+    private final String strategy;
+
+    private final ApplicationStateCreator creator;
+
+    public ApplicationStateContribution(String strategy)
+    {
+        this(strategy, null);
+    }
+
+    public ApplicationStateContribution(String strategy, ApplicationStateCreator creator)
+    {
+        Defense.notBlank(strategy, "strategy");
+
+        this.strategy = strategy;
+        this.creator = creator;
+    }
+
+    /**
+     * The creator for the ASO. If null, the the ASO is created directly from the ASO class, via its public no-arguments
+     * constructor.
+     */
+    public ApplicationStateCreator getCreator()
+    {
+        return creator;
+    }
+
+    /**
+     * The name of the strategy used to control where the ASO is stored.
+     */
+    public String getStrategy()
+    {
+        return strategy;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateCreator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateCreator.java
new file mode 100644
index 0000000..9354284
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateCreator.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used by {@link ApplicationStateManager} and {@link ApplicationStatePersistenceStrategy} to create an application
+ * state object on demand.
+ *
+ * @param <T>
+ */
+public interface ApplicationStateCreator<T>
+{
+    /**
+     * Create a new instance of an application state object.
+     */
+    T create();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateManager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateManager.java
new file mode 100644
index 0000000..5416da0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStateManager.java
@@ -0,0 +1,62 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Responsible for managing <em>application state objects</em>, objects which persist between requests, but are not tied
+ * to any individual page or component. ASOs are also created on demand. ASOs are typically stored in the session, so
+ * that they are specific to a particular client.
+ */
+public interface ApplicationStateManager
+{
+    /**
+     * For a given class, find the ASO for the class, creating it if necessary. The manager has a configuration that
+     * determines how an instance is stored and created as needed. A requested ASO not in the configuration is assumed
+     * to be created via a no-args constructor, and stored in the session.
+     *
+     * @param <T>
+     * @param asoClass identifies the ASO to access or create
+     * @return the ASO instance
+     */
+    <T> T get(Class<T> asoClass);
+
+    /**
+     * For a given class, find the ASO for the class. The manager has a configuration that determines how an instance is
+     * stored.
+     *
+     * @param <T>
+     * @param asoClass identifies the ASO to access or create
+     * @return the ASO instance or null if it does not already exist
+     */
+    <T> T getIfExists(Class<T> asoClass);
+
+    /**
+     * Returns true if the ASO already exists, false if it has not yet been created.
+     *
+     * @param asoClass used to select the ASO
+     * @return true if ASO exists, false if null
+     */
+    <T> boolean exists(Class<T> asoClass);
+
+    /**
+     * Stores a new ASO, replacing the existing ASO (if any). Storing the value null will delete the ASO so that it may
+     * be re-created later.
+     *
+     * @param <T>
+     * @param asoClass the type of ASO
+     * @param aso      the ASO instance
+     */
+    <T> void set(Class<T> asoClass, T aso);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategy.java
new file mode 100644
index 0000000..23b5ef9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategy.java
@@ -0,0 +1,43 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used by {@link ApplicationStateManager} to manage a specific kind of ASO persistence. The stategy is responsible for
+ * managing ASO instances within its domain.
+ *
+ * @see org.apache.tapestry.services.ApplicationStatePersistenceStrategySource
+ */
+public interface ApplicationStatePersistenceStrategy
+{
+    /**
+     * Gets the ASO from the domain. If the ASO does not already exist, it is created and stored, then returned.
+     */
+    <T> T get(Class<T> asoClass, ApplicationStateCreator<T> creator);
+
+    /**
+     * Stores a new ASO, possibly replacing the existing one.
+     *
+     * @param <T>
+     * @param asoClass
+     * @param aso      instance to store, or null to delete existing
+     */
+    <T> void set(Class<T> asoClass, T aso);
+
+    /**
+     * Returns true if the ASO already exists, false if null.
+     */
+    <T> boolean exists(Class<T> asoClass);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategySource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategySource.java
new file mode 100644
index 0000000..5dcc700
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ApplicationStatePersistenceStrategySource.java
@@ -0,0 +1,33 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used to provide access to stategies via a logical name for the stategy, such as "session".
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeApplicationStatePersistenceStrategySource(org.apache.tapestry.ioc.MappedConfiguration,
+ *      Request)
+ */
+public interface ApplicationStatePersistenceStrategySource
+{
+    /**
+     * Returns the named strategy.
+     *
+     * @param name of strategy to access
+     * @return the strategy
+     * @throws RuntimeException if the name does not match a configured strategy
+     */
+    ApplicationStatePersistenceStrategy get(String name);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetFactory.java
new file mode 100644
index 0000000..f0ed355
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.Resource;
+
+/**
+ * Used by {@link AssetSource} to create new {@link Asset}s as needed.
+ *
+ * @see org.apache.tapestry.services.AssetSource
+ */
+public interface AssetFactory
+{
+    /**
+     * Returns the Resource representing the root folder of the domain this factory is responsible for.
+     */
+    Resource getRootResource();
+
+    Asset createAsset(Resource resource);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetSource.java
new file mode 100644
index 0000000..50b1fe2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/AssetSource.java
@@ -0,0 +1,67 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+
+import java.util.Locale;
+
+/**
+ * Used to find or create an {@link Asset} with a given path.
+ * <p/>
+ * Assets are defined with a domain, and the domain is indicated by a prefix.  The two builtin domains are "context:"
+ * (for files inside the web application context) and "classpath:" for files stored on the classpath (typically, inside
+ * a JAR, such as a component library).
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeAssetSource(org.apache.tapestry.ioc.MappedConfiguration,
+ *      AssetFactory, AssetFactory)
+ */
+public interface AssetSource
+{
+    /**
+     * Finds the asset. The path may either be a simple file name or a relative path (relative to the base resource)
+     * <em>or</em> it may have a prefix, such as "context:" or "classpath:", in which case it is treated as a complete
+     * path within the indicated domain. The resulting Resource is then localized (to the provided Locale) and returned
+     * as an Asset.
+     * <p/>
+     * The AssetSource caches its results, so a single Asset instance may be shared among many different components.
+     *
+     * @param baseResource base resource for computing relative paths, or null to search the classpath
+     * @param path         relative to the base resource
+     * @param locale       locale to localize the final resource to, or null for the thread's current locale
+     * @return the asset
+     * @throws RuntimeException if the asset can not be found
+     */
+    Asset getAsset(Resource baseResource, String path, Locale locale);
+
+    /**
+     * Convienience for finding assets on the classpath.
+     *
+     * @param path   path to the base resource, relative to classpath root
+     * @param locale to localize the resource to
+     * @return the asset
+     */
+    Asset getClasspathAsset(String path, Locale locale);
+
+    /**
+     * Obtains a classpath alias in the current locale (as defined by the {@link ThreadLocale} service).
+     *
+     * @param path
+     * @return the asset
+     */
+    Asset getClasspathAsset(String path);
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BaseURLSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BaseURLSource.java
new file mode 100644
index 0000000..cc2198c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BaseURLSource.java
@@ -0,0 +1,38 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used when switching between normal/insecure (HTTP) and secure (HTTPS) mode.  When a switch occurs, it is no longer
+ * possible to use relative URLs, instead absolute URLs must be generated. The default implementation of this is
+ * simple-minded: it just tacks the correct scheme in front of {@link org.apache.tapestry.services.Request#getServerName()}.
+ * In production, behind a firewall, it is often necessary to do a bit more, since <code>getServerName()</code> will
+ * often be the name of the internal server (not visible to the client web browser), and a hard-coded name of a server
+ * that <em>is</em> visible to the web browser is needed.  Further, in testing, non-default ports are often used. In
+ * those cases, an overriding contribution to the {@link org.apache.tapestry.services.Alias} service will allow a custom
+ * implementation to supercede the default version.
+ */
+public interface BaseURLSource
+{
+    /**
+     * Returns the base portion of the URL, before the context path and servlet path are appended. The return value
+     * should <em>not</em> end with a slash; it should end after the host name, or after the port number.  The context
+     * path, servlet path, and path info will be appended to the returned value.
+     *
+     * @param secure whether a secure "https" or insecure "http" base URL should be returned
+     * @return the base URL ready for additional extensions
+     */
+    String getBaseURL(boolean secure);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockContribution.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockContribution.java
new file mode 100644
index 0000000..41d37a2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockContribution.java
@@ -0,0 +1,80 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.corelib.components.Label;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+
+/**
+ * A contribution to the {@link BeanBlockSource} service, defining a page name and block id (within the page) that can
+ * edit or display a particular type of property.
+ */
+public final class BeanBlockContribution
+{
+    private final String dataType;
+
+    private final String pageName;
+
+    private final String blockId;
+
+    private final boolean edit;
+
+    public BeanBlockContribution(String dataType, String pageName, String blockId, boolean edit)
+    {
+        notBlank(dataType, "datatype");
+        notBlank(pageName, "pageName");
+        notBlank(blockId, "blockId");
+
+        this.dataType = dataType;
+        this.pageName = pageName;
+        this.blockId = blockId;
+        this.edit = edit;
+    }
+
+    /**
+     * The type of data for which the indicated block will provide an editor or displayer for.
+     */
+    public String getDataType()
+    {
+        return dataType;
+    }
+
+    /**
+     * The id of the block within the page.
+     */
+    public String getBlockId()
+    {
+        return blockId;
+    }
+
+    /**
+     * If true, then the block provides an editor for the property, consisting of a {@link Label} and some field
+     * component (or set of field components). If false, the block is used to display the value of the property, usually
+     * by applying some kind of formatting to the raw value.
+     */
+    public boolean isEdit()
+    {
+        return edit;
+    }
+
+    /**
+     * The logical name of the page containing the block.
+     */
+    public String getPageName()
+    {
+        return pageName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockOverrideSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockOverrideSource.java
new file mode 100644
index 0000000..0716a63
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockOverrideSource.java
@@ -0,0 +1,52 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Block;
+
+/**
+ * Used to override the default {@link org.apache.tapestry.services.BeanBlockSource} for a particular data type.  The
+ * service accepts the same configuration of {@link org.apache.tapestry.services.BeanBlockContribution}s as the main
+ * service.
+ */
+public interface BeanBlockOverrideSource
+{
+    /**
+     * Returns a block which can be used to render an editor for the given data type, in the form of a field label and
+     * input field.
+     *
+     * @param datatype logical name for the type of data to be displayed
+     * @return the Block
+     * @throws null if no override is available
+     */
+    Block getEditBlock(String datatype);
+
+    /**
+     * Returns a block which can be used to render output for the given data type.
+     *
+     * @param datatype logical name for the type of data to be displayed
+     * @return the Block
+     * @throws null if no override is available
+     */
+    Block getDisplayBlock(String datatype);
+
+    /**
+     * Checks to see if there is a display block for the indicated data type.
+     *
+     * @param datatype to check for
+     * @return true if an override display block is available
+     */
+    boolean hasDisplayBlock(String datatype);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockSource.java
new file mode 100644
index 0000000..7682b29
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanBlockSource.java
@@ -0,0 +1,62 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Block;
+
+/**
+ * A source of {@link Block}s used to display the properties of a bean (used by the {@link
+ * org.apache.tapestry.corelib.components.Grid} component), or to edit the properties of a bean (used by the {@link
+ * org.apache.tapestry.corelib.components.BeanEditForm} component). Contributions to this service (a configuration of
+ * {@link BeanBlockContribution}s) define what properties may be editted.
+ * <p/>
+ * Blocks are accessed in terms of a <strong>data type</strong> a string that identifies the type of data to be editted,
+ * such as "string", "date", "boolean", etc.
+ * <p/>
+ * Tapestry contributes a number of default data types and corresponding edit and display blocks. The {@link
+ * org.apache.tapestry.services.BeanBlockOverrideSource} service allows these to be overridden.
+ *
+ * @see org.apache.tapestry.services.DataTypeAnalyzer
+ * @see org.apache.tapestry.services.TapestryModule#contributeBeanBlockSource(org.apache.tapestry.ioc.Configuration)
+ */
+public interface BeanBlockSource
+{
+    /**
+     * Returns a block which can be used to render an editor for the given data type, in the form of a field label and
+     * input field.
+     *
+     * @param datatype logical name for the type of data to be displayed
+     * @return the Block
+     * @throws RuntimeException if no appropriate block is available
+     */
+    Block getEditBlock(String datatype);
+
+    /**
+     * Returns a block which can be used to render output for the given data type.
+     *
+     * @param datatype logical name for the type of data to be displayed
+     * @return the Block
+     * @throws RuntimeException if no appropriate block is available
+     */
+    Block getDisplayBlock(String datatype);
+
+    /**
+     * Checks to see if there is a display block for the indicated data type.
+     *
+     * @param datatype to check for
+     * @return true if a block is available
+     */
+    boolean hasDisplayBlock(String datatype);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java
new file mode 100644
index 0000000..a9d2a0e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BeanModelSource.java
@@ -0,0 +1,51 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.OrderBefore;
+
+/**
+ * Used by a component to create a default {@link BeanModel} for a particular bean class. Also provides support to the
+ * model by generating validation information for individual fields.
+ * <p/>
+ * BeanModels are the basis for the {@link org.apache.tapestry.corelib.components.BeanEditor} and {@link
+ * org.apache.tapestry.corelib.components.Grid} comopnents.
+ *
+ * @see org.apache.tapestry.services.PropertyConduitSource
+ */
+public interface BeanModelSource
+{
+    /**
+     * Creates a new model used for editing the indicated bean class. The model will represent all read/write properties
+     * of the bean. The order of the properties is defined by the {@link OrderBefore} annotation on the getter or setter
+     * methods. The labels for the properties are derived from the property names, but if the component's message
+     * catalog has keys of the form <code>propertyName-label</code>, then those will be used instead.
+     * <p/>
+     * Models are <em>mutable</em>, so they are not cached, a fresh instance is created each time.
+     *
+     * @param beanClass                class of object to be edited
+     * @param filterReadOnlyProperties if true, then properties that are read-only will be skipped (leaving only
+     *                                 read-write properties, appropriate for {@link org.apache.tapestry.corelib.components.BeanEditForm},
+     *                                 etc.). If false, then both read-only and read-write properties will be included
+     *                                 (appropriate for {@link org.apache.tapestry.corelib.components.Grid} or {@link
+     *                                 org.apache.tapestry.corelib.components.BeanDisplay}).
+     * @param resources                used when resolving resources, especially component messages (used to access
+     *                                 labels)
+     * @return a model
+     */
+    <T> BeanModel<T> create(Class<T> beanClass, boolean filterReadOnlyProperties, ComponentResources resources);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingFactory.java
new file mode 100644
index 0000000..76be41f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingFactory.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Creates a binding of a particular type.  This is usually invoked from the {@link
+ * org.apache.tapestry.services.BindingSource} service.
+ */
+public interface BindingFactory
+{
+    /**
+     * Creates a new binding instance.
+     * <p/>
+     * The binding represents a connection between the container and the component (the component is usually the child
+     * of the component, though in a few cases, it is the component itself). In most cases, the expression is evaluated
+     * in terms of the resources of the <em>container</em> and the component is ignored.
+     *
+     * @param description of the binding, such as, "parameter foo"
+     * @param container   the component, as represented by its resources, for which a binding is to be created.
+     * @param component   the component whose parameter is to be bound by the resulting binding (rarely used)
+     * @param expression
+     * @param location    from which the binding was generate, or null if not known
+     * @return the new binding instance
+     */
+    Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                       String expression, Location location);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingSource.java
new file mode 100644
index 0000000..2f917b4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/BindingSource.java
@@ -0,0 +1,65 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Location;
+
+/**
+ * Used to acquire bindings for component parameters. The BindingSource service strips off the binding prefix to locate
+ * a {@link org.apache.tapestry.services.BindingFactory}.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeBindingSource(org.apache.tapestry.ioc.MappedConfiguration,
+ *      AssetSource, BindingFactory, FieldValidatorSource, TranslatorSource, org.apache.tapestry.ioc.ObjectLocator)
+ */
+public interface BindingSource
+{
+    /**
+     * Examines the expression and strips off the leading prefix. The prefix is used to choose the appropriate {@link
+     * BindingFactory}, which recieves the description, the expression (after the prefix), and the location. If the
+     * prefix doesn't exist, or if there's no prefix, then the factory for the default prefix (often "literal") is used
+     * (and passed the full prefix).
+     * <p/>
+     * The binding represents a connection between the container and the component (the component is usually the child
+     * of the container, though in a few cases, it is the component itself). In most cases, the expression is evaluated
+     * in terms of the resources of the <em>container</em> and the component is ignored.
+     *
+     * @param description   description of the binding, such as "parameter foo"
+     * @param container     typically, the parent of the component
+     * @param component     the component whose parameter is to be bound
+     * @param defaultPrefix the default prefix used when the expression itself does not have a prefix
+     * @param expression    the binding
+     * @param location      location assigned to the binding (or null if not known)
+     * @return a binding
+     */
+    Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                       String defaultPrefix, String expression, Location location);
+
+    /**
+     * A simpler version of {@link #newBinding(String, ComponentResources, ComponentResources, String, String,
+     * Location)} that defaults the values for several parameters. This is used in most cases. The default binding
+     * prefix will be "prop". Most often, this is used to create a new default binding.
+     *
+     * @param description   description of the binding, such as "parameter foo"
+     * @param container     typically, the parent of the component. This value will be used as the container
+     *                      <em>and</em> the component, so whatever type of expression is evaluated, will be evaulated
+     *                      in terms of this component
+     * @param defaultPrefix the default prefix used when the expression itself does not have a prefix
+     * @param expression    the binding
+     * @return a binding
+     */
+    Binding newBinding(String description, ComponentResources container, String defaultPrefix, String expression);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java
new file mode 100644
index 0000000..f8ffaf6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClassTransformation.java
@@ -0,0 +1,379 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import javassist.CtBehavior;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.slf4j.Logger;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+/**
+ * Contains class-specific information used when transforming a raw component class into an executable component class.
+ * An executable class is one that has been transformed to work within Tapestry.  This includes adding interfaces
+ * ({@link org.apache.tapestry.runtime.Component}) but also transforming access to fields, based on annotations and
+ * naming conventions.  Most of the changes are provided by different implementations of {@link
+ * ComponentClassTransformWorker}.
+ * <p/>
+ * Much of this information is somewhat like ordinary reflection, but applies to a class that has not yet been loaded.
+ * <p/>
+ * Transformation is primarily about identifying annotations on fields and on methods and changing the class, adding new
+ * interfaces, fields and methods, and deleting some existing fields.
+ * <p/>
+ * A ClassTransformation contains all the state data specific to a particular class being transformed. A number of
+ * <em>workers</em> will operate upon the ClassTransformation to effect the desired changes before the true class is
+ * loaded into memory.
+ * <p/>
+ * Instances of this class are not designed to be thread safe, access to an instance should be restricted to a single
+ * thread. In fact, the design of this type is to allow stateless singletons in multiple threads to work on
+ * thread-specific data (within the ClassTransformation).
+ * <p/>
+ * The majority of methods concern the <em>declared</em> members (field and methods) of a specific class, rather than
+ * any fields or methods inherited from a base class.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeComponentClassTransformWorker(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      org.apache.tapestry.ioc.ObjectLocator, InjectionProvider, Environment, ComponentClassResolver,
+ *      org.apache.tapestry.internal.services.RequestPageCache, BindingSource)
+ */
+public interface ClassTransformation extends AnnotationProvider
+{
+    /**
+     * Returns the fully qualified class name of the class being transformed.
+     */
+    String getClassName();
+
+    /**
+     * Returns the name of a new member (field or method). Ensures that the resulting name does not conflict with any
+     * existing member (declared by the underlying class, or inherited from a base class).
+     *
+     * @param suggested the suggested value for the member
+     * @return a unique name for the member
+     */
+    String newMemberName(String suggested);
+
+    /**
+     * As with {@link #newMemberName(String)}, but the suggested name is constructed from the prefix and base name. An
+     * underscore will seperate the prefix from the base name.
+     *
+     * @param prefix   for the generated name
+     * @param baseName an name, often of an existing field or method
+     * @return a unique name
+     */
+    String newMemberName(String prefix, String baseName);
+
+    /**
+     * Generates a list of the names of declared instance fields that have the indicated annotation. Non-private and
+     * static fields are ignored. Only the names of private instance fields are returned. Any {@link #claimField(String,
+     * Object) claimed} fields are excluded.
+     */
+    List<String> findFieldsWithAnnotation(Class<? extends Annotation> annotationClass);
+
+    /**
+     * As with {@link #findFieldsWithAnnotation(Class)}, but finds fields even if they are claimed.
+     */
+    List<String> findAllFieldsWithAnnotation(Class<? extends Annotation> annotationClass);
+
+    /**
+     * Finds all methods defined in the class that are marked with the provided annotation.
+     *
+     * @param annotationClass
+     * @return a list of method signature (which may be empty) in ascending order
+     * @see #findMethods(MethodFilter)
+     */
+    List<TransformMethodSignature> findMethodsWithAnnotation(Class<? extends Annotation> annotationClass);
+
+    /**
+     * Finds all methods matched by the provided filter.
+     *
+     * @param filter Passed each method signature, it may include or exclude each potential
+     * @return a list of matching method signatures (which may be empty) in ascending order (by method name), but
+     *         descending order (by parameter count) within overrides of a single method name.
+     */
+    List<TransformMethodSignature> findMethods(MethodFilter filter);
+
+    /**
+     * Finds all unclaimed fields matched by the provided filter. Only considers unclaimed, private, instance fields.
+     *
+     * @param filter passed each field name and field type
+     * @return the names of all matched fields, in ascending order
+     */
+    List<String> findFields(FieldFilter filter);
+
+    /**
+     * Finds an annotation on a declared instance field.
+     *
+     * @param <T>             constrains parameter and return value to Annotation types
+     * @param fieldName       the name of the field, which must exist
+     * @param annotationClass the type of annotation to access
+     * @return the annotation if present, or null otherwise
+     * @throws IllegalArgumentException if the fieldName does not correspond to a declared field
+     */
+    <T extends Annotation> T getFieldAnnotation(String fieldName, Class<T> annotationClass);
+
+    /**
+     * Finds an annotation on a declared method.
+     *
+     * @param <T>             constrains parameter and return value to Annotation types
+     * @param method          the method signature to search
+     * @param annotationClass the type of annotation to access
+     * @return the annotation if present, or null otherwise
+     * @throws IllegalArgumentException if the method signature does not correspond to a declared method
+     */
+    <T extends Annotation> T getMethodAnnotation(TransformMethodSignature method, Class<T> annotationClass);
+
+    /**
+     * Claims a field so as to ensure that only a single annotation is applied to any single field. When a
+     * transformation occurs (driven by a field annotation), the first thing that occurs is to claim the field, on
+     * behalf of the annotation.
+     *
+     * @param fieldName the name of the field that is being claimed
+     * @param tag       a non-null object that represents why the field is being tagged (this is typically a specific
+     *                  annotation on the field)
+     * @throws IllegalArgumentException if the fieldName does not correspond to a declared instance field
+     * @throws IllegalStateException    if the field is already claimed for some other tag
+     */
+    void claimField(String fieldName, Object tag);
+
+    /**
+     * Changes the field to be read only. Any existing code that changes the field will cause a runtime exception.
+     *
+     * @param fieldName name of field to so change
+     */
+    void makeReadOnly(String fieldName);
+
+    /**
+     * Finds any declared <em>instance</em> fields that have not been claimed (via {@link #claimField(String, Object)})
+     * and returns the names of those fields. May return an empty array.
+     */
+    List<String> findUnclaimedFields();
+
+    /**
+     * Obtains the type of a declared instance field.
+     *
+     * @param fieldName
+     * @return the type of the field, as a string
+     * @throws IllegalArgumentException if the fieldName does not correspond to a declared instance field
+     */
+    String getFieldType(String fieldName);
+
+    /**
+     * Returns true if the indicated name is a private instance field.
+     *
+     * @param fieldName
+     * @return true if field exists
+     */
+    boolean isField(String fieldName);
+
+    /**
+     * Defines a new declared field for the class. The suggestedName may be modified to ensure uniqueness.
+     *
+     * @param modifiers     modifiers for the field (typically, {@link java.lang.reflect.Modifier#PRIVATE})
+     * @param type          the type for the field, as a string
+     * @param suggestedName the desired name for the field, which may be modified (for uniqueness) when returned
+     * @return the (uniqued) name for the field
+     */
+    String addField(int modifiers, String type, String suggestedName);
+
+    /**
+     * Defines a new <strong>protected</strong> instance variable whose initial value is provided statically, via a
+     * constructor parameter. The transformation caches the result, so calling this method repeatedly with the same type
+     * and value will return the same field name. Caching extends to the parent transformation, so that a value injected
+     * into a parent class will be available (via the protected instance variable) to subclasses.
+     *
+     * @param type          the type of object to inject
+     * @param suggestedName the suggested name for the new field
+     * @param value         to be injected. This value is retained.
+     * @return the actual name of the injected field
+     */
+    String addInjectedField(Class type, String suggestedName, Object value);
+
+    /**
+     * Converts the field into a read only field whose value is the provided value. This is used when converting an
+     * existing field into a read-only injected value.
+     *
+     * @param fieldName name of field to convert
+     * @param value     the value provided by the field
+     */
+    void injectField(String fieldName, Object value);
+
+    /**
+     * Transforms the class to implement the indicated interface. If the class (or its super class) does not already
+     * implement the interface, then the interface is added, and default implementations of any methods of the interface
+     * are added.
+     * <p/>
+     * TODO: Checking that the names of methods in the interface do not conflict with the names of methods present in
+     * the (unmodified) class.
+     *
+     * @param interfaceClass the interface to be implemented by the class
+     * @throws IllegalArgumentException if the interfaceClass argument does not represent an interface
+     */
+    void addImplementedInterface(Class interfaceClass);
+
+    /**
+     * Extends an existing method. The provided method body is inserted at the end of the existing method (i.e. {@link
+     * javassist.CtBehavior#insertAfter(java.lang.String)}). To access or change the return value, use the
+     * <code>$_</code> pseudo variable.
+     * <p/>
+     * The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method
+     * is added that first invokes the super implementation. Use {@link #addMethod(TransformMethodSignature, String)}
+     * when it is necessary to control when the super-class method is invoked.
+     * <p/>
+     * The extended method is considered <em>new</em>. New methods <em>are not</em>  scanned for {@linkplain
+     * #removeField(String)} removed}, {@linkplain #replaceReadAccess(String, String)} read replaced}, or {@linkplain
+     * #replaceWriteAccess(String, String) write replaced} fields.  Generally that's what you want!
+     *
+     * @param methodSignature the signature of the method to extend
+     * @param methodBody      the body of code
+     * @throws org.apache.tapestry.internal.services.MethodCompileException
+     *          if the provided Javassist method body can not be compiled
+     * @see #extendExistingMethod(TransformMethodSignature, String)
+     */
+    void extendMethod(TransformMethodSignature methodSignature, String methodBody);
+
+    /**
+     * Like {@link #extendMethod(TransformMethodSignature, String)}, but the extension does not mark the method as new,
+     * and field changes <em>will</em> be processed.
+     *
+     * @param methodSignature signature of the method to extend
+     * @param methodBody      the body of code
+     * @throws org.apache.tapestry.internal.services.MethodCompileException
+     *          if the provided method body can not be compiled
+     * @see #prefixMethod(TransformMethodSignature, String)
+     */
+    void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody);
+
+    /**
+     * Inserts code at the beginning of a method body (i.e. {@link CtBehavior#insertBefore(String)}.
+     * <p/>
+     * The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method
+     * is added that first invokes the super implementation. Use {@link #addMethod(TransformMethodSignature, String)}
+     * when it is necessary to control when the super-class method is invoked.
+     * <p/>
+     * <p/>
+     * Like {@link #extendExistingMethod(TransformMethodSignature, String)}, this method is generally used to "wrap" an
+     * existing method adding additional functionality such as caching or transaction support.
+     *
+     * @param methodSignature
+     * @param methodBody
+     * @throws org.apache.tapestry.internal.services.MethodCompileException
+     *          if the provided method body can not be compiled
+     */
+    void prefixMethod(TransformMethodSignature methodSignature, String methodBody);
+
+    /**
+     * Returns the name of a field that provides the {@link org.apache.tapestry.ComponentResources} for the transformed
+     * component. This will be a protected field, accessible to the class and subclasses.
+     *
+     * @return name of field
+     */
+    String getResourcesFieldName();
+
+    /**
+     * Adds a new method to the transformed class. Replaces any existing method declared for the class. When overriding
+     * a super-class method, you should use {@link #extendMethod(TransformMethodSignature, String)}, or you should
+     * remember to invoke the super class implemetation explicitly. Use this method to control when the super-class
+     * implementation is invoked.
+     */
+    void addMethod(TransformMethodSignature signature, String methodBody);
+
+    /**
+     * As with {@link #addMethod(TransformMethodSignature, String)}, but field references inside the method
+     * <em>will</em> be transformed.
+     */
+    void addTransformedMethod(TransformMethodSignature methodSignature, String methodBody);
+
+    /**
+     * Adds a statement to the constructor. The statement is added as is, though a newline is added.
+     *
+     * @param statement the statement to add, which should end with a semicolon
+     */
+    void extendConstructor(String statement);
+
+    /**
+     * Replaces all read-references to the specified field with invocations of the specified method name. Replacements
+     * do not occur in methods added via {@link #addMethod(TransformMethodSignature, String)} or {@link
+     * #extendMethod(TransformMethodSignature, String)}.
+     */
+    void replaceReadAccess(String fieldName, String methodName);
+
+    /**
+     * Replaces all write accesses to the specified field with invocations of the specified method name. The method
+     * should take a single parameter of the same type as the field. Replacements do not occur in methods added via
+     * {@link #addMethod(TransformMethodSignature, String)} or {@link #extendMethod(TransformMethodSignature, String)}.
+     */
+    void replaceWriteAccess(String fieldName, String methodName);
+
+    /**
+     * Removes a field entirely; this is useful for fields that are replaced entirely by computed values.
+     *
+     * @param fieldName the name of the field to remove
+     * @see #replaceReadAccess(String, String)
+     * @see #replaceWriteAccess(String, String)
+     */
+    void removeField(String fieldName);
+
+    /**
+     * Converts a type name into a corresponding class (possibly, a transformed class). Primitive type names are
+     * returned as wrapper types.
+     */
+
+    Class toClass(String type);
+
+    /**
+     * Returns a logger, based on the class name being transformed, to which warnings or errors concerning the class
+     * being transformed may be logged.
+     */
+    Logger getLogger();
+
+    /**
+     * Returns the modifiers for the named field.
+     */
+    int getFieldModifiers(String fieldName);
+
+    /**
+     * Converts a signature to a string used to identify the method; this consists of the {@link
+     * TransformMethodSignature#getMediumDescription()} appended with source file information and line number
+     * information (when available).
+     *
+     * @param signature
+     * @return a string that identifies the class, method name, types of parameters, source file and source line number
+     */
+    String getMethodIdentifier(TransformMethodSignature signature);
+
+    /**
+     * Returns true if this transformation represents a root class (one that extends directly from Object), or false if
+     * this transformation is an extension of another transformed class.
+     *
+     * @return true if root class, false if sub-class
+     */
+    boolean isRootTransformation();
+
+
+    /**
+     * Adds a catch block to the method.  The body should end with a return or a throw. The special Javassist variable
+     * $e is the exception instance.
+     *
+     * @param methodSignature method to be extended.
+     * @param exceptionType   fully qualified class name of exception
+     * @param body            code to execute
+     */
+    void addCatch(TransformMethodSignature methodSignature, String exceptionType, String body);
+
+    /**
+     * Adds method advice for the indicated method.
+     */
+    void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathAssetAliasManager.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathAssetAliasManager.java
new file mode 100644
index 0000000..bdbe1c5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathAssetAliasManager.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+public interface ClasspathAssetAliasManager
+{
+    /**
+     * Takes a resource path to a classpath resource and adds the asset path prefix to the path. May also convert part
+     * of the path to an alias (based on the manager's configuration).
+     *
+     * @param resourcePath resource path on the classpath (with no leading slash)
+     * @return URL ready to send to the client
+     */
+    String toClientURL(String resourcePath);
+
+    /**
+     * Reverses {@link #toClientURL(String)}, stripping off the asset prefix, and re-expanding any aliased folders back
+     * to complete folders.
+     */
+    String toResourcePath(String clientURL);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathProvider.java
new file mode 100644
index 0000000..b56e7d7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ClasspathProvider.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+
+/**
+ * A marker annotation used to select the correct {@link AssetFactory} for injection. The marked interface will provide
+ * assets located on the classpath.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface ClasspathProvider
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java
new file mode 100644
index 0000000..9c91a8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassResolver.java
@@ -0,0 +1,91 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+
+/**
+ * Resolves page names and component types to fully qualified class names. Pages and components may be provided by the
+ * application or inside a <em>mapped package</em>. Page names often appear inside URLs, and component types often
+ * appear in component template (when specifying the type of an embedded component).
+ * <p/>
+ * The service is configured using a collection of {@link LibraryMapping}s. Each mapping maps a prefix, such as "core"
+ * to a root package name, such as "org.apache.tapestry.corelib". The root package is expected to have sub-packages:
+ * "pages", "components", "mixins" and "base" ("base" is for base classes).
+ * <p/>
+ * The resolver performs a search of the classpath (via {@link ClassNameLocator}), to build up a set of case-insensitive
+ * maps from logical page name, component type, or mixin type to fully qualified class name.
+ * <p/>
+ * Certain ambiguities occur if mapped packages overlap, either in terms of the the prefixes or the package names. Keep
+ * things clearly seperate to avoid lookup problems.
+ */
+public interface ComponentClassResolver
+{
+    /**
+     * Converts a logical page name (such as might be encoded into a URL) into a fully qualified class name. The case of
+     * the page name is irrelevant.
+     *
+     * @param logicalPageName logical page name
+     * @return fully qualified class name for the page
+     * @throws IllegalArgumentException if the name does not match a known page class
+     */
+    String resolvePageNameToClassName(String logicalPageName);
+
+    /**
+     * For a particular path, determines if the path is a logical page name. The check is case insensitive.
+     *
+     * @param pageName potential logical page name
+     * @return true if the page name is valid
+     */
+    boolean isPageName(String pageName);
+
+    /**
+     * Converts a fully qualified page class name into a logical class name (often, for inclusion as part of the URI).
+     * This value may later be passed to {@link #resolvePageNameToClassName(String)}.
+     *
+     * @param pageClassName fully qualified name of a page class
+     * @return equivalent logical page name
+     * @throws IllegalArgumentException if the name can not be resolved
+     */
+    String resolvePageClassNameToPageName(String pageClassName);
+
+    /**
+     * Returns the canonical form of a logical page name. The canonical form uses character case matching the underlying
+     * class name.
+     *
+     * @throws IllegalArgumentException if the page name does not match a logical page name
+     */
+    String canonicalizePageName(String pageName);
+
+    /**
+     * Converts a component type (a logical component name such as might be used inside a template or annotation) into a
+     * fully qualified class name. Case is ignored in resolving the name.
+     *
+     * @param componentType a logical component type
+     * @return fully qualified class name
+     * @throws IllegalArgumentException if the component type can not be resolved
+     */
+    String resolveComponentTypeToClassName(String componentType);
+
+    /**
+     * Converts a logical mixin type (as with component types) into a fully qualified class name. Case is ignored when
+     * resolving the name.
+     *
+     * @param mixinType a logical mixin type
+     * @return fully qualified class name
+     * @throws IllegalArgumentException if the mixin type can not be resolved
+     */
+    String resolveMixinTypeToClassName(String mixinType);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassTransformWorker.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassTransformWorker.java
new file mode 100644
index 0000000..d5376d6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentClassTransformWorker.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import org.apache.tapestry.model.MutableComponentModel;

+

+/**

+ * Interface for a set of objects that can perform component class transformations. Implementations should be

+ * multithreaded, ideally they should be stateless (all necessary state can be stored in the {@link

+ * org.apache.tapestry.services.ClassTransformation}).

+ */

+public interface ComponentClassTransformWorker

+{

+    /**

+     * Invoked to perform a transformation on an as-yet unloaded component class, represented by the {@link

+     * ClassTransformation} instance. In some cases, the worker may make changes to the component model -- for example,

+     * a worker that deals with parameters may update the model to reflect those parameters.

+     */

+    void transform(ClassTransformation transformation, MutableComponentModel model);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentDefaultProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentDefaultProvider.java
new file mode 100644
index 0000000..7859300
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentDefaultProvider.java
@@ -0,0 +1,64 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.*;
+
+/**
+ * A service that can be injected into a component to provide common defaults for various types of parameters.
+ */
+public interface ComponentDefaultProvider
+{
+    /**
+     * Computes the default label for the component (which will generally be a {@link Field}).
+     *
+     * @param resources
+     * @return the label, either extracted from the component's container's message catalog, or derived from the
+     *         component's {@link ComponentResourcesCommon#getId()}.
+     */
+    String defaultLabel(ComponentResources resources);
+
+    /**
+     * Checks to see if the container of the component (identified by its resources) contains a property matching the
+     * component's id. If so, a binding for that property is returned. This is usually the default for a {@link Field}'s
+     * value parameter (or equivalent).
+     *
+     * @param parameterName the name of the parameter
+     * @param resources     the resources of the component for which a binding is needed
+     * @return the binding, or null if the container does not have a matching property
+     */
+    Binding defaultBinding(String parameterName, ComponentResources resources);
+
+    /**
+     * Gets or creates a value encoder based on the <em>type</em> of the named parameter.  ValueEncoders are cached
+     * based on type.
+     *
+     * @param parameterName the name of the parameter whose type is used to locate a {@link
+     *                      org.apache.tapestry.services.ValueEncoderFactory}
+     * @param resources     the resources of the component, from which parameter and its type are extracted
+     * @return the value encoder, or null if the type of the parameter is not known
+     */
+    ValueEncoder defaultValueEncoder(String parameterName, ComponentResources resources);
+
+    /**
+     * Provides a translator based on the bound parameter type, if possible.
+     *
+     * @param parameterName
+     * @param resources
+     * @return the translator, or null
+     */
+    Translator defaultTranslator(String parameterName, ComponentResources resources);
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestFilter.java
new file mode 100644
index 0000000..a4912cf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestFilter.java
@@ -0,0 +1,35 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Filter interface for {@link ComponentEventRequestHandler}.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeComponentEventRequestHandler(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      org.apache.tapestry.internal.services.RequestEncodingInitializer, ComponentEventRequestHandler ,
+ *      org.apache.tapestry.ioc.ObjectLocator) }
+ */
+public interface ComponentEventRequestFilter
+{
+    /**
+     * Filter for a component action request.
+     *
+     * @param parameters defining details of the request
+     * @param handler    to delegate to
+     */
+    void handle(ComponentEventRequestParameters parameters, ComponentEventRequestHandler handler) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestHandler.java
new file mode 100644
index 0000000..959a2e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestHandler.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.corelib.components.ActionLink;
+import org.apache.tapestry.corelib.components.Form;
+
+import java.io.IOException;
+
+/**
+ * Handler interface for action requests. Action requests <em>do things</em> such as process a form submission or
+ * otherwise change state. In the majority of cases, after the action, a redirect response is sent to the client which,
+ * in turn, causes a page render.
+ *
+ * @see ActionLink
+ * @see Form
+ * @see ComponentEventRequestFilter
+ */
+public interface ComponentEventRequestHandler
+{
+    /**
+     * Handler for a component action request which will trigger an event on a component and use the return value to
+     * send a response to the client (typically, a redirect to a page render URL).
+     *
+     * @param parameters defining the requst
+     */
+    void handle(ComponentEventRequestParameters parameters) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java
new file mode 100644
index 0000000..bfdcf7e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventRequestParameters.java
@@ -0,0 +1,142 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+/**
+ * Encapsulates all the information that may be provided in a component event request URL.
+ */
+public final class ComponentEventRequestParameters
+{
+    private final String activePageName, containingPageName, nestedComponentId, eventType;
+    private final EventContext pageActivationContext, eventContext;
+
+    public ComponentEventRequestParameters(String activePageName, String containingPageName, String nestedComponentId,
+                                           String eventType, EventContext pageActivationContext,
+                                           EventContext eventContext)
+    {
+        Defense.notBlank(activePageName, "activePageName");
+        Defense.notBlank(containingPageName, "containingPageName");
+        Defense.notNull(nestedComponentId, "nestedComponentId");
+        Defense.notBlank(eventType, "eventType");
+        Defense.notNull(pageActivationContext, "pageActivationContext");
+        Defense.notNull(eventContext, "eventContext");
+
+        this.activePageName = activePageName;
+        this.containingPageName = containingPageName;
+        this.nestedComponentId = nestedComponentId;
+        this.eventType = eventType;
+        this.pageActivationContext = pageActivationContext;
+        this.eventContext = eventContext;
+    }
+
+    // Implements equals() as a convienience for testing.
+
+    public boolean equals(Object o)
+    {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ComponentEventRequestParameters that = (ComponentEventRequestParameters) o;
+
+        if (!activePageName.equals(that.activePageName)) return false;
+        if (!containingPageName.equals(that.containingPageName)) return false;
+        if (!eventType.equals(that.eventType)) return false;
+        if (!nestedComponentId.equals(that.nestedComponentId)) return false;
+
+        if (!isEqual(eventContext, that.eventContext)) return false;
+
+        return isEqual(pageActivationContext, that.pageActivationContext);
+    }
+
+    private boolean isEqual(EventContext left, EventContext right)
+    {
+        if (left == right) return true;
+
+        int count = left.getCount();
+
+        if (count != right.getCount()) return false;
+
+        for (int i = 0; i < count; i++)
+        {
+            if (!left.get(Object.class, i).equals(right.get(Object.class, i)))
+                return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * The name of the active page which rendered the link.  This is usually, but not always, the page which contains
+     * the component.
+     */
+    public String getActivePageName()
+    {
+        return activePageName;
+    }
+
+    /**
+     * The name of the page containing the component that was triggered. Usually this is the same as the active page,
+     * but because of {@link org.apache.tapestry.Block} and similar constructs, a component from other than the active
+     * page may be rendered with the active page.
+     */
+    public String getContainingPageName()
+    {
+        return containingPageName;
+    }
+
+    /**
+     * The path from the containing page down to the component in question. This may be the empty string if the action
+     * request is routed directly to the page rather than a component.
+     */
+    public String getNestedComponentId()
+    {
+        return nestedComponentId;
+    }
+
+    /**
+     * The type of event.  When not specified in the URL, a default type of "action" ({@link
+     * org.apache.tapestry.EventConstants#ACTION}) is provided.
+     */
+    public String getEventType()
+    {
+        return eventType;
+    }
+
+    /**
+     * The activation context for the <em>active page</em>, possibly empty (but not null).
+     *
+     * @see org.apache.tapestry.ComponentResourcesCommon#triggerContextEvent(String, org.apache.tapestry.EventContext,
+     *      org.apache.tapestry.ComponentEventCallback)
+     */
+    public EventContext getPageActivationContext()
+    {
+        return pageActivationContext;
+    }
+
+    /**
+     * The event context information passed in the URL.  Possibly empty (not not null).
+     *
+     * @see org.apache.tapestry.ComponentResourcesCommon#triggerContextEvent(String, org.apache.tapestry.EventContext,
+     *      org.apache.tapestry.ComponentEventCallback)
+     */
+    public EventContext getEventContext()
+    {
+        return eventContext;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java
new file mode 100644
index 0000000..c49699c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java
@@ -0,0 +1,33 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Responsible for handling the return value provided by a component event handler method.
+ *
+ * @param <T>
+ */
+public interface ComponentEventResultProcessor<T>
+{
+    /**
+     * For a given, non-null return value from a component event method, construct and send a response.
+     *
+     * @param value the value returned from a method
+     * @throws RuntimeException if the value can not handled
+     */
+    void processResultValue(T value) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentLayer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentLayer.java
new file mode 100644
index 0000000..a194436
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentLayer.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation used to identify a service from the component layer that conflicts, in terms of service interface,
+ * with a service from elsewhere. In particular, this is used to disambiguate {@link
+ * org.apache.tapestry.ioc.services.ClassFactory} which has one implementation (marked with {@link
+ * org.apache.tapestry.ioc.services.Builtin} and another with this annotation.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface ComponentLayer
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodAdvice.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodAdvice.java
new file mode 100644
index 0000000..9b7abb2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodAdvice.java
@@ -0,0 +1,27 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * An object that receives control around an "advised" method of a component. The advise can query or even replace
+ * method parameters.  After invoking {@link org.apache.tapestry.services.ComponentMethodInvocation#proceed()}, the
+ * advise may query and override thrown exceptions or the return value of the invocation.
+ *
+ * @see ClassTransformation#advise(TransformMethodSignature, ComponentMethodAdvice)
+ */
+public interface ComponentMethodAdvice
+{
+    void advise(ComponentMethodInvocation invocation);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodInvocation.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodInvocation.java
new file mode 100644
index 0000000..14b3c1a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentMethodInvocation.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.Invocation;
+
+/**
+ * Encapsulates the parameters, thrown exceptions, and result of a method invocation, allowing a {@link
+ * org.apache.tapestry.services.ComponentMethodAdvice} to encapsulate the invocation.
+ */
+public interface ComponentMethodInvocation extends Invocation
+{
+    /**
+     * Returns the component resources for the component whose method is being intercepted.
+     */
+    ComponentResources getComponentResources();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java
new file mode 100644
index 0000000..250730c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.runtime.Component;
+
+/**
+ * Used by classes that need to retrieve a component by its complete id, or a page by its logical page name or root
+ * component class. The complete id is the logical name of the containing page, a colon, and the nested component id. It
+ * may also just be the page name (for the root component of a page).
+ */
+public interface ComponentSource
+{
+    /**
+     * Gets a component by its {@linkplain org.apache.tapestry.ComponentResourcesCommon#getCompleteId() complete id}. If
+     * the component id is for a mixin, then the mixin attached to the component will be returned. A mixin's complete id
+     * is its container's complete id, suffixed with "$" and the mixin's id (its simple class name).
+     *
+     * @param completeId complete component id (case insensitive)
+     * @return the component
+     * @throws IllegalArgumentException if the component can not be found
+     * @see org.apache.tapestry.ComponentResourcesCommon#getCompleteId()
+     */
+    Component getComponent(String completeId);
+
+    /**
+     * Returns the page identified by its logical page name. A logical page name is the short form of a page name often
+     * emebedded into URLs.
+     *
+     * @param pageName the logical page name
+     * @return the corresponding page's root component
+     * @throws IllegalArgumentException if the page can not be found
+     */
+    Component getPage(String pageName);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Context.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Context.java
new file mode 100644
index 0000000..ddd32bc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Context.java
@@ -0,0 +1,67 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * An API agnostic version of {@link javax.servlet.ServletContext}, used to bridge the gaps between the Servlet API and
+ * the Portlet API.
+ */
+public interface Context
+{
+    /**
+     * Returns a URL to a resource stored within the context. The path should start with a leading slash.
+     *
+     * @param path to the resource (with a leading slash)
+     * @return the URL for the path, or null if the path does not correspond to a file.
+     */
+    URL getResource(String path);
+
+    /**
+     * Attempts to find the actual file, on the file system, that would be provided by the servlet container for the
+     * given path (which must start with a leading slash). This may return null if no such file exists, or if the
+     * resource in question is packaged inside a WAR.  If packaged inside a WAR, the contents may be accessed via {@link
+     * #getResource(String)}.
+     *
+     * @param path to  the resource (with a leading slash)
+     * @return the underlying File, or null if no such file
+     */
+    File getRealFile(String path);
+
+    /**
+     * Returns an initial parameter value defined by servlet.
+     */
+    String getInitParameter(String name);
+
+    /**
+     * Looks for resources within the web application within the supplied path. The list will be recurively expanded, as
+     * necessary. The path must start with a leading slash, and usually ends with a slash as well.
+     *
+     * @param path to search for (should start with a leading slash)
+     * @return the matches, sorted alphabetically
+     */
+    List<String> getResourcePaths(String path);
+
+    /**
+     * Returns an attribute previously stored into the context with the given name.
+     *
+     * @param name used to retrieve the attribute
+     * @return the attribute, or null if not found
+     */
+    Object getAttribute(String name);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextProvider.java
new file mode 100644
index 0000000..a93eb84
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextProvider.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation to select the correct {@link AssetFactory} for injection. The marked interface will provide assets
+ * located in the web application context.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface ContextProvider
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java
new file mode 100644
index 0000000..222911e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ContextValueEncoder.java
@@ -0,0 +1,43 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used to convert values used in event contexts to client string representations and back.
+ *
+ * @See org.apache.tapestry.ValueEncoder
+ * @see org.apache.tapestry.ioc.services.TypeCoercer
+ */
+public interface ContextValueEncoder
+{
+    /**
+     * Converts a context value into a client-side string (that will utltimately be encoded into a URL).
+     *
+     * @param value to convert (may not be null)
+     * @return string representation of the value
+     * @see org.apache.tapestry.ValueEncoder#toClient(Object)
+     */
+    String toClient(Object value);
+
+    /**
+     * Converts a client value back into a server-side object.
+     *
+     * @param requiredType required type to convert the string to
+     * @param clientValue  value obtained from context passed from client
+     * @return the client value converted or coerced into a server value
+     * @see org.apache.tapestry.ValueEncoder#toValue(String)
+     */
+    <T> T toValue(Class<T> requiredType, String clientValue);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Cookies.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Cookies.java
new file mode 100644
index 0000000..36ee512
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Cookies.java
@@ -0,0 +1,72 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used by other services to obtain cookie values for the current request.
+ */
+public interface Cookies
+{
+    /**
+     * Returns the value of the first cookie whose name matches. Returns null if no such cookie exists. This method is
+     * only aware of cookies that are part of the incoming request; it does not know about additional cookies added
+     * since then (via {@link #writeCookieValue(String, String)}).
+     */
+    String readCookieValue(String name);
+
+    /**
+     * Creates or updates a cookie value. The value is stored using a max age (in seconds) defined by the symbol
+     * <code>org.apache.tapestry.default-cookie-max-age</code>. The factory default for this value is the equivalent of
+     * one week.
+     */
+
+    void writeCookieValue(String name, String value);
+
+    /**
+     * As with {@link #writeCookieValue(String, String)} but an explicit maximum age may be set.
+     *
+     * @param name   the name of the cookie
+     * @param value  the value to be stored in the cookie
+     * @param maxAge the maximum age, in seconds, to store the cookie
+     */
+
+    void writeCookieValue(String name, String value, int maxAge);
+
+    /**
+     * As with {@link #writeCookieValue(String, String)} but an explicit path may be set.
+     */
+    void writeCookieValue(String name, String value, String path);
+
+    /**
+     * As with {@link #writeCookieValue(String, String)} but an explicit path may be set.
+     */
+    void writeDomainCookieValue(String name, String value, String domain);
+
+    /**
+     * As with {@link #writeCookieValue(String, String)} but an explicit path may be set.
+     */
+    void writeDomainCookieValue(String name, String value, String domain, int maxAge);
+
+    /**
+     * As with {@link #writeCookieValue(String, String, String)} but an explicit domain may be set.
+     */
+    void writeCookieValue(String name, String value, String path, String domain);
+
+    /**
+     * Removes a previously written cookie, by writing a new cookie with a maxAge of 0.
+     */
+
+    void removeCookieValue(String name);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Core.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Core.java
new file mode 100644
index 0000000..7981870
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Core.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation for services that are provided by the Tapestry core module.
+ */
+@Target(
+        { PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+public @interface Core
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/DataTypeAnalyzer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/DataTypeAnalyzer.java
new file mode 100644
index 0000000..68b2d0e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/DataTypeAnalyzer.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.corelib.components.BeanEditForm;
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+
+/**
+ * Used by {@link BeanModelSource} to identify the type of data associated with a particular property (represented as a
+ * {@link PropertyAdapter}). The data type is a string used to determine what kind of interface to use for displaying
+ * the value of the property, or what kind of interface to use for editing the value of the property. Common property
+ * types are "text", "enum", "checkbox", but the list is extensible.
+ * <p/>
+ * <p>Different strategies for identifying the data type are encapsulated in the DataTypeAnalyzer service, forming a
+ * chain of command.
+ *
+ * @see Grid
+ * @see BeanEditForm
+ * @see BeanBlockSource
+ * @see org.apache.tapestry.services.TapestryModule#contributeDataTypeAnalyzer(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      DataTypeAnalyzer)
+ */
+public interface DataTypeAnalyzer
+{
+    /**
+     * Identifies the data type, if known, or returns null if not known.
+     */
+    String identifyDataType(PropertyAdapter adapter);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Dispatcher.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Dispatcher.java
new file mode 100644
index 0000000..3207860
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Dispatcher.java
@@ -0,0 +1,36 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * A dispatcher is responsible for recognizing an incoming request. Dispatchers form an ordered chain of command, with
+ * each dispatcher responsible for recognizing requests that it can process.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeMasterDispatcher(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      ClasspathAssetAliasManager, org.apache.tapestry.internal.services.ResourceCache,
+ *      org.apache.tapestry.internal.services.ResourceStreamer, PageRenderRequestHandler, ComponentEventRequestHandler,
+ *      ComponentClassResolver, ContextValueEncoder, String)
+ */
+public interface Dispatcher
+{
+    /**
+     * Analyzes the incoming request and performs an appropriate operation for each.
+     *
+     * @return true if a response was delivered, false if the servlet container should be allowed to handle the request
+     */
+    boolean dispatch(Request request, Response response) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java
new file mode 100644
index 0000000..68efda8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java
@@ -0,0 +1,75 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Provides access to environment services, which are almost always provided to enclosed components by enclosing
+ * components. Environmental services are a form of very late binding.
+ * <p/>
+ * The Environment acts like a collection of stacks. Each stack contains environmental service instances of a given
+ * type. Most often, a stack has zero or one elements, but on occasion, a particular component will push an override
+ * onto the stack for the benefit of the components it encloses.
+ *
+ * @see org.apache.tapestry.annotation.Environmental
+ * @see org.apache.tapestry.services.EnvironmentalShadowBuilder
+ */
+public interface Environment
+{
+    /**
+     * Peeks at the current top of the indicated stack.
+     *
+     * @param <T>  the type of environmental service
+     * @param type class used to select a service
+     * @return the current service of that type, or null if no service of that type has been added
+     */
+    <T> T peek(Class<T> type);
+
+    /**
+     * Peeks at the current top of the indicated stack (which must have a non-null value).
+     *
+     * @param <T>  the type of environmental service
+     * @param type class used to select a service
+     * @return the current service
+     * @throws RuntimeException if no service of that type has been added
+     */
+    <T> T peekRequired(Class<T> type);
+
+    /**
+     * Removes and returns the top environmental service of the selected type.
+     *
+     * @param <T>
+     * @param type
+     * @return
+     * @throws NoSuchElementException if the environmental stack (for the specified type) is empty
+     */
+    <T> T pop(Class<T> type);
+
+    /**
+     * Pushes a new service onto the stack. The old service at the top of the stack is returned (it may be null).
+     *
+     * @param <T>
+     * @param type     the type of service to store
+     * @param instance the service instance
+     * @return the previous top service
+     */
+    <T> T push(Class<T> type, T instance);
+
+    /**
+     * Clears all stacks; used when initializing the Environment before a render.
+     */
+    void clear();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/EnvironmentalShadowBuilder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/EnvironmentalShadowBuilder.java
new file mode 100644
index 0000000..e080cad
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/EnvironmentalShadowBuilder.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
+
+/**
+ * Much like {@link PropertyShadowBuilder}, except that instead of accessing a property of some other service, it
+ * accesses a value from within the {@link Environment} service. This is useful for defining a new service that can be
+ * injected into other services (whereas the {@link Environmental} annotation may only be used within component
+ * classes).
+ */
+public interface EnvironmentalShadowBuilder
+{
+    /**
+     * Returns a proxy that delegates all methods to an object obtained from {@link Environment#peekRequired(Class)}.
+     * Note that at the time this method is invoked, the Environment service may still be virtual, and will often not
+     * yet have been loaded with values, and that's OK, the resolution is deferred to the instant a method is invoked.
+     *
+     * @param <T>
+     * @param serviceType the service type, which is used to obtained the delegate instance
+     * @return a proxy to the service
+     */
+    <T> T build(Class<T> serviceType);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ExceptionReporter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ExceptionReporter.java
new file mode 100644
index 0000000..b037a81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ExceptionReporter.java
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;

+

+/**

+ * Interface implemented by a page used for reporting exceptions.

+ *

+ * @see RequestExceptionHandler

+ */

+public interface ExceptionReporter

+{

+    /**

+     * Used to communicate to the page what exception is to be reported.

+     *

+     * @param exception

+     */

+    void reportException(Throwable exception);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldFilter.java
new file mode 100644
index 0000000..9c1b1e4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldFilter.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used by {@link ClassTransformation#findFields(FieldFilter)} to identify which fields to keep.
+ */
+public interface FieldFilter
+{
+    boolean accept(String fieldName, String fieldType);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorDefaultSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorDefaultSource.java
new file mode 100644
index 0000000..1b81d8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorDefaultSource.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Messages;
+
+import java.util.Locale;
+
+/**
+ * For a particular field, generates the default validation for the field, in accordance with a number of factors and
+ * contributions.
+ */
+public interface FieldValidatorDefaultSource
+{
+    /**
+     * Analyzes the property type and property annotations to determine the default set of validations for the property,
+     * which are wrapped to form a {@link org.apache.tapestry.FieldValidator} for a field.
+     *
+     * @param field               Field component for which a validator is being created
+     * @param overrideId          the id of the component, used to locate related messages for labels and errors
+     * @param overrideMessages    where to search for label and error messages
+     * @param locale              locale used for locating messages
+     * @param propertyType        type of property bound to the editting parameter of the field (typically, the
+     *                            parameter named "value").
+     * @param propertyAnnotations source of annotations for the property being editted
+     * @return a validator reflecting all default validations for the field
+     */
+    FieldValidator createDefaultValidator(Field field, String overrideId, Messages overrideMessages, Locale locale,
+                                          Class propertyType, AnnotationProvider propertyAnnotations);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorSource.java
new file mode 100644
index 0000000..5ec7399
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FieldValidatorSource.java
@@ -0,0 +1,73 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.corelib.components.BeanEditForm;
+import org.apache.tapestry.ioc.Messages;
+
+import java.util.Locale;
+
+/**
+ * Used to create {@link FieldValidator}s for a particular {@link Field} component.
+ */
+public interface FieldValidatorSource
+{
+    /**
+     * Creates the validator. The error message associated with the field validator usually comes from the {@link
+     * ValidationMessagesSource} (using the validator's {@link Validator#getMessageKey() message key}). However, if the
+     * container component of the field defines a message key <code><i>id</i>-<i>validator</i> (where id is the simple
+     * id of the field component, and validator is the validatorType), then that message is used instead. This allows
+     * you to override the message for a particular validation of a particular field.
+     *
+     * @param field           the field for which a validator is to be created
+     * @param validatorType   used to select the {@link Validator} that forms the core of the {@link FieldValidator}
+     * @param constraintValue a value used to configure the validator, or null if the validator is not configurarable
+     * @return the field validator for the field
+     */
+    FieldValidator createValidator(Field field, String validatorType, String constraintValue);
+
+    /**
+     * Full featured version of {@link #createValidator(Field, String, String)} used in situations where the container
+     * of the field is not necesarrilly the place to look for override messages, and the id of the field is not the key
+     * to use when checking. The {@link BeanEditForm} is an example of this.
+     *
+     * @param field            the field for which a validator is to be created
+     * @param validatorType    used to select the {@link Validator} that forms the core of the {@link FieldValidator}
+     * @param constraintValue  a value used to configure the validator, or null if the validator is not configurable
+     * @param overrideId       the base id used when searching for validator message overrides (this would normally be
+     *                         the field component's simple id)
+     * @param overrideMessages the message catalog to search for override messages (this would normally be the catalog
+     *                         for the container of the field component)
+     * @param locale           locale used when retrieving default validation messages from the {@link
+     *                         ValidationMessagesSource}
+     * @return the field validator for the field
+     */
+    FieldValidator createValidator(Field field, String validatorType, String constraintValue,
+                                   String overrideId, Messages overrideMessages, Locale locale);
+
+    /**
+     * Creates a set of validators. The specification is a string used to identify and configure the individual
+     * validators. The specification is a comma-separated list of terms. Each term is a validator type name and an
+     * optional constraint value (seperated by an equals sign).
+     *
+     * @param field
+     * @param specification
+     * @return a composite field validator
+     */
+    FieldValidator createValidators(Field field, String specification);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java
new file mode 100644
index 0000000..ab2898a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java
@@ -0,0 +1,80 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ClientElement;
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.Field;
+
+/**
+ * Services provided by an enclosing Form control component to the various form element components it encloses.
+ * Implements {@link org.apache.tapestry.ClientElement}, to share the id of the enclosing form.
+ *
+ * @see org.apache.tapestry.Field
+ */
+public interface FormSupport extends ClientElement
+{
+    /**
+     * Allocates a unique (within the form) control name for some enclosed component, based on the component's id.
+     *
+     * @param id the component's id
+     * @return a unique string, usually the component's id, but sometime extended with a unique number or string
+     */
+    String allocateControlName(String id);
+
+    /**
+     * Stores an action for execution during a later request.  If the action contains any mutable state, it should be in
+     * its final state before invoking this method and its internal state should not be changed subsequently.
+     */
+    <T> void store(T component, ComponentAction<T> action);
+
+    /**
+     * As with {@link #store(Object, org.apache.tapestry.ComponentAction)}}, but the action is also invoked immediately.
+     * This is useful for defining an action that should occur symmetrically in both the render request and the form
+     * submission's action request.
+     *
+     * @param component component against which to trigger the action
+     * @param action    the action that will be triggered (and passed the component)
+     */
+    <T> void storeAndExecute(T component, ComponentAction<T> action);
+
+    /**
+     * Defers a command until the end of the form submission. The command will be executed after the Form's validate
+     * notification, but before the Form's submit, success or failure notifications. During a form render, runnables are
+     * executed after the body of the form has rendered.
+     *
+     * @param command to be executed
+     */
+    void defer(Runnable command);
+
+    /**
+     * Sets the encoding type for the Form. This should only be set once, and if
+     *
+     * @param encodingType MIME type indicating type of encoding for the form
+     * @throws IllegalStateException if the encoding type has already been set to a value different than the supplied
+     */
+    void setEncodingType(String encodingType);
+
+    /**
+     * Collects field validation information. A Form may turn off client-side validation, in which case these calls will
+     * be ignored.
+     *
+     * @param field          for which validation is being generated
+     * @param validationName name of validation method (see Tapestry.Validation in tapestry.js)
+     * @param message        the error message to display if the field is invalid
+     * @param constraint     additional constraint value, or null for validations that don't require a constraint
+     */
+    void addValidation(Field field, String validationName, String message, Object constraint);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Heartbeat.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Heartbeat.java
new file mode 100644
index 0000000..cf8e0eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Heartbeat.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Allows for deferred execution of logic, useful when trying to get multiple components to coordinate behavior. A
+ * component may add a command to be executed "{@link #end() at the end of the heartbeat}". The classic example of this
+ * is a Label and the field it labels; since we don't know which order the two will render, we can't tell if the field's
+ * id is correct until after both have rendered.
+ * <p/>
+ * The Heartbeat is injected into components via the {@link org.apache.tapestry.annotation.Environmental} annotation.
+ */
+public interface Heartbeat
+{
+    /**
+     * Begins a new Heartbeat. Heartbeats nest. Every call to begin() should be matched by a call to {@link #end()}.
+     */
+    void begin();
+
+    /**
+     * Executes all commands since the most recent {@link #begin()}.
+     */
+    void end();
+
+    /**
+     * Adds a new command to the current Heartbeat. The command will be executed by {@link #end()}.
+     *
+     * @param command command to be executed at the end of the heartbeat
+     */
+    void defer(Runnable command);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestFilter.java
new file mode 100644
index 0000000..4780cfa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestFilter.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+import java.io.IOException;

+

+/**

+ * Filter interface for {@link org.apache.tapestry.services.HttpServletRequestHandler}.

+ */

+public interface HttpServletRequestFilter

+{

+    /**

+     * Filter interface for the HttpServletRequestHandler pipeline. A filter should delegate to the handler. It may

+     * perform operations before or after invoking the handler, and may modify the request and response passed in to the

+     * handler.

+     *

+     * @return true if the request has been handled, false otherwise

+     */

+    boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler)

+            throws IOException;

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestHandler.java
new file mode 100644
index 0000000..b0f5eb6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/HttpServletRequestHandler.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+import java.io.IOException;

+

+/**

+ * Service interface for the HttpServletRequestHandler pipeline service.

+ *

+ * @see org.apache.tapestry.services.HttpServletRequestFilter

+ */

+public interface HttpServletRequestHandler

+{

+    /**

+     * Returns true if the request was handled, false otherwise.

+     */

+    boolean service(HttpServletRequest request, HttpServletResponse response) throws IOException;

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java
new file mode 100644
index 0000000..6d3b6de
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/InjectionProvider.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+
+/**
+ * Provides some form of injection when the value for an {@link org.apache.tapestry.ioc.annotation.Inject} annotation is
+ * present. In this case, the provider is responsible for determining the value to be injected from the field name and
+ * field type.
+ * <p/>
+ * This interface will be used as part of a {@link org.apache.tapestry.ioc.services.ChainBuilder chain of command}.
+ */
+public interface InjectionProvider
+{
+    /**
+     * Peform the injection, if possible. Most often, this will result in a call to {@link
+     * ClassTransformation#injectField(String, Object)}. The caller is responsible for invoking {@link
+     * ClassTransformation#claimField(String, Object)}.
+     *
+     * @param fieldName      the name of the field requesting injection
+     * @param fieldType      the type of the field
+     * @param locator        allows services to be located
+     * @param transformation allows the code for the class to be transformed
+     * @param componentModel defines the relevant aspects of the component
+     * @return true if an injection has been made (terminates the command chain), false to continue down the chain
+     */
+    boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+                             ClassTransformation transformation, MutableComponentModel componentModel);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/LibraryMapping.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/LibraryMapping.java
new file mode 100644
index 0000000..ebe4fd6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/LibraryMapping.java
@@ -0,0 +1,54 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+/**

+ * Used to configure the {@link ComponentClassResolver}, to allow it to map prefixes to library root packages (the

+ * application namespace is a special case of this). In each case, a prefix on the path is mapped to a package. Prefixes

+ * should start and end with characters, such as "core". It is allowed for a prefix to contain a slash, though it is not

+ * recommended.

+ * <p/>

+ * The root package name should have a number of sub-packages: <dl> <dt>pages</dt> <dd>contains named pages</dd>

+ * <dt>components</dt> <dd>contains components</dd> <dt>mixins</dt> <dd>contains component mixins</dd> <dt>base</dt>

+ * <dd>contains base classes</dd> </dl>

+ *

+ * @see org.apache.tapestry.services.TapestryModule#contributeComponentClassResolver(org.apache.tapestry.ioc.Configuration)

+ */

+public final class LibraryMapping

+{

+    private final String pathPrefix, rootPackage;

+

+    public LibraryMapping(String pathPrefix, String rootPackage)

+    {

+        this.pathPrefix = pathPrefix;

+        this.rootPackage = rootPackage;

+    }

+

+    public String getPathPrefix()

+    {

+        return pathPrefix;

+    }

+

+    public String getRootPackage()

+    {

+        return rootPackage;

+    }

+

+    @Override

+    public String toString()

+    {

+        return String.format("LibraryMapping[%s, %s]", pathPrefix, rootPackage);

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRenderer.java
new file mode 100644
index 0000000..45b6525
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRenderer.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+
+/**
+ * An object which will perform rendering of a page (or portion of a page).  This interface exists to be filtered via
+ * {@link org.apache.tapestry.services.MarkupRendererFilter}.
+ * <p/>
+ * The MarkupRenderer service takes an ordered configuration of {@link org.apache.tapestry.services.MarkupRendererFilter}s,
+ * which are used for ordinary page rendering (as opposed to {@linkplain org.apache.tapestry.services.PartialMarkupRenderer
+ * partial page rendering} for Ajax requests). The MarkupRenderer service may be selected using the {@link
+ * org.apache.tapestry.ioc.annotation.Primary} marker annotation.
+ */
+public interface MarkupRenderer
+{
+    /**
+     * Invoked to render some markup.
+     *
+     * @param writer to which markup should be written
+     */
+    void renderMarkup(MarkupWriter writer);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRendererFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRendererFilter.java
new file mode 100644
index 0000000..0bc6d38
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupRendererFilter.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+
+/**
+ * Filter interface for {@link org.apache.tapestry.services.MarkupRenderer}, which allows for code to execute before
+ * and/or after the main rendering process.  Typically, this is to allow for the placement of {@linkplain
+ * org.apache.tapestry.services.Environment environmental services}.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      org.apache.tapestry.Asset, org.apache.tapestry.Asset, ValidationMessagesSource,
+ *      org.apache.tapestry.ioc.services.SymbolSource, AssetSource)
+ */
+public interface MarkupRendererFilter
+{
+    /**
+     * Implementations should perform work before or after passing the writer to the renderer.
+     *
+     * @param writer   to which markup should be written
+     * @param renderer delegate to which the writer should be passed.
+     */
+    void renderMarkup(MarkupWriter writer, MarkupRenderer renderer);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupWriterFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupWriterFactory.java
new file mode 100644
index 0000000..0eb0eff
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MarkupWriterFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import org.apache.tapestry.ContentType;

+import org.apache.tapestry.MarkupWriter;

+

+/**

+ * Source for {@link org.apache.tapestry.MarkupWriter} instances.

+ */

+public interface MarkupWriterFactory

+{

+    /**

+     * Creates a markup writer for a particular content type.

+     *

+     * @param contentType type of content generated by the markup write; used to control the type of {@link

+     *                    org.apache.tapestry.dom.MarkupModel} used with the {@link org.apache.tapestry.dom.Document}

+     *                    the backs the markup writer.

+     */

+    MarkupWriter newMarkupWriter(ContentType contentType);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MetaDataLocator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MetaDataLocator.java
new file mode 100644
index 0000000..d6e967a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MetaDataLocator.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ComponentResources;
+
+/**
+ * Used to lookup meta data concerning a particular component. The primary source of meta data is the meta data defined
+ * for the component, accessed via {@link org.apache.tapestry.model.ComponentModel#getMeta(String)}. This includes meta
+ * data defined by base classes. When meta-data for a particular component can not be found, a search works up the
+ * containment hierarchy (to the component's container, and the container's container, and so on). If <em>that</em>
+ * proves unfruitful, a system of defaults is provided by configuration and matched against the containing page's
+ * logical name.
+ * <p/>
+ * Finally, if no metadata is available, then {@link org.apache.tapestry.ioc.services.SymbolSource#valueForSymbol(String)}
+ * is used to obtain a value.
+ */
+public interface MetaDataLocator
+{
+    /**
+     * Searches for the value for the corresponding key.  The value, if located, will have symbols expanded, and will be
+     * type coerced to the desired type.
+     *
+     * @param key       the key used to locate the meta data (case insensitive)
+     * @param resources the resources of the initial component used in the search
+     * @return the value if found (in the component, the component's container, etc. or via a folder default) or null if
+     *         not found anywhere
+     * @throws RuntimeException if the value for the key is not present as meta data of the component, as an override,
+     *                          or as a symbol
+     */
+    <T> T findMeta(String key, ComponentResources resources, Class<T> expectedType);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MethodFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MethodFilter.java
new file mode 100644
index 0000000..c23f4db
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/MethodFilter.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+/**
+ * Used by {@link ClassTransformation#findMethods(MethodFilter)} to accept or reject each method.
+ */
+public interface MethodFilter
+{
+    /**
+     * Passed each signature in turn, only signatures for which this method returns true will be included in the final
+     * result.
+     */
+    boolean accept(TransformMethodSignature signature);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/NullFieldStrategySource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/NullFieldStrategySource.java
new file mode 100644
index 0000000..f789b36
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/NullFieldStrategySource.java
@@ -0,0 +1,35 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.NullFieldStrategy;
+
+/**
+ * A source for {@link org.apache.tapestry.NullFieldStrategy} instances based on a logical name.
+ *
+ * @see TapestryModule#contributeNullFieldStrategySource(org.apache.tapestry.ioc.MappedConfiguration)
+ */
+public interface NullFieldStrategySource
+{
+    /**
+     * Returns the instance based on the name.  Instances are expected to be stateless and therefore, shareable and
+     * thread safe.
+     *
+     * @param name name of the strategy (case is ignored)
+     * @return the strategy
+     * @throws IllegalArgumentException if the name does not match a configured instance
+     */
+    NullFieldStrategy get(String name);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ObjectRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ObjectRenderer.java
new file mode 100644
index 0000000..e870179
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ObjectRenderer.java
@@ -0,0 +1,32 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+
+/**
+ * A strategy interface used for converting an object into markup that describes that object. This is primarily used in
+ * terms of an {@link org.apache.tapestry.services.ExceptionReporter} page.
+ */
+public interface ObjectRenderer<T>
+{
+    /**
+     * Renders the object out as markup.
+     *
+     * @param object to be rendered
+     * @param writer to which output should be directed
+     */
+    void render(T object, MarkupWriter writer);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java
new file mode 100644
index 0000000..19279d1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java
@@ -0,0 +1,33 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Filter interface for {@link PageRenderRequestHandler}, which allows extra behaviors to be injected into the
+ * processing of a page render request.
+ */
+public interface PageRenderRequestFilter
+{
+    /**
+     * Invoked to activate and render a page. The return value of the event handler method(s) for the activate event may
+     * result in an action response generator being returned.
+     *
+     * @param parameters defines the page name and activation context
+     * @param handler    to delegate the invocation to
+     */
+    void handle(PageRenderRequestParameters parameters, PageRenderRequestHandler handler) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java
new file mode 100644
index 0000000..bf0d9c3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Handles a invocation related to rendering out a pages complete content.
+ *
+ * @see PageRenderRequestFilter
+ */
+public interface PageRenderRequestHandler
+{
+    /**
+     * Invoked to activate and render a page. In certain cases, based on values returned when activating the page, a
+     * {@link org.apache.tapestry.services.ComponentEventResultProcessor} may be used to send an alternate response
+     * (typically, a redirect).
+     *
+     * @param parameters defines the page name and activation context
+     */
+    void handle(PageRenderRequestParameters parameters) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java
new file mode 100644
index 0000000..4a0e332
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestParameters.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+/**
+ * Used with {@link org.apache.tapestry.services.PageRenderRequestHandler} and {@link
+ * org.apache.tapestry.services.PageRenderRequestFilter} to define the logical page name and activation context for the
+ * request.
+ */
+public class PageRenderRequestParameters
+{
+    private final String logicalPageName;
+
+    private final EventContext activationContext;
+
+    public PageRenderRequestParameters(String logicalPageName, EventContext activationContext)
+    {
+        Defense.notNull(logicalPageName, "logicalPageName");
+        Defense.notNull(activationContext, "activationContext");
+
+        this.logicalPageName = logicalPageName;
+        this.activationContext = activationContext;
+    }
+
+    public String getLogicalPageName()
+    {
+        return logicalPageName;
+    }
+
+    public EventContext getActivationContext()
+    {
+        return activationContext;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRenderer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRenderer.java
new file mode 100644
index 0000000..2576300
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRenderer.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry5.json.JSONObject;
+
+/**
+ * Defines an Ajax-oriented partial page render, wherein a render of a portion of a page occurs, and the content is
+ * stored into a key ("content") of a {@link org.apache.tapestry5.json.JSONObject}, which is sent to the client side as
+ * the final response.  Client-side JavaScript receives this reply and uses it to update a portion of the page.
+ * <p/>
+ * <p/>
+ * The PartialMarkupRenderer service takes an ordered configuration of {@link PartialMarkupRendererFilter}s.  It can be
+ * selected using the {@link org.apache.tapestry.ioc.annotation.Primary} marker annotation.
+ */
+public interface PartialMarkupRenderer
+{
+    /**
+     * Implementations should perform work before or after passing the writer to the renderer.
+     *
+     * @param writer to which markup should be written
+     * @param reply  JSONObject which will contain the partial response
+     */
+    void renderMarkup(MarkupWriter writer, JSONObject reply);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRendererFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRendererFilter.java
new file mode 100644
index 0000000..c3ffa5c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PartialMarkupRendererFilter.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry5.json.JSONObject;
+
+/**
+ * A filter (the main interface being {@link PartialMarkupRenderer}) applied when performing a partial page render as
+ * part of an Ajax-oriented request.  This is similar to {@link org.apache.tapestry.services.MarkupRendererFilter} and
+ * filters are often in place so as to contribute {@link org.apache.tapestry.annotation.Environmental} services to the
+ * pages and components that render.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributePartialMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      org.apache.tapestry.Asset, ValidationMessagesSource, org.apache.tapestry.ioc.services.SymbolSource,
+ *      AssetSource)
+ */
+public interface PartialMarkupRendererFilter
+{
+    /**
+     * Implementations should perform work before or after passing the writer to the renderer.
+     *
+     * @param writer   to which markup should be written
+     * @param reply    JSONObject which will contain the partial response
+     * @param renderer delegate to which the writer should be passed
+     */
+    void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldBundle.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldBundle.java
new file mode 100644
index 0000000..073a030
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldBundle.java
@@ -0,0 +1,40 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+/**

+ * Encapsulates persisted property information for an entire page.

+ */

+public interface PersistentFieldBundle

+{

+    /**

+     * Checks to see if a persistent value has been stored for the indicated component and field. TODO: This method can

+     * probably be removed; it doesn't look like its used (instead, we if check getValue() returns null).

+     *

+     * @param componentId the nested id of the component (within the page), may be null or blank for the root component

+     *                    of the page

+     * @param fieldName   the name of the field whose value was persisted

+     * @return true if a change has been stored

+     */

+    boolean containsValue(String componentId, String fieldName);

+

+    /**

+     * @param componentId the nested if of the component (within the page), may be null or blank for the root component

+     *                    of the page

+     * @param fieldName   the name of the field whose value was persisted

+     * @return the persisted value, possibly null

+     */

+    Object getValue(String componentId, String fieldName);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldChange.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldChange.java
new file mode 100644
index 0000000..4b7a6d7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldChange.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+/**

+ * Represents a previously stored change to a persistent field, within the context of a particular page of the

+ * application.

+ */

+public interface PersistentFieldChange

+{

+    /**

+     * Returns the nested id of the component, or the empty string for the page's root component.

+     */

+    String getComponentId();

+

+    /**

+     * Returns the name of the field for which a change was recorded.

+     */

+    String getFieldName();

+

+    /**

+     * Returns the new value for the field (which may be null).

+     */

+    Object getValue();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
new file mode 100644
index 0000000..c83c3c8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentFieldStrategy.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import java.util.Collection;

+

+/**

+ * Defines how changes to fields (within components, within pages) may have their values persisted between requests.

+ * Different implementations store the field values {@linkplain org.apache.tapestry.internal.services.SessionPersistentFieldStrategy

+ * in the session}, {@linkplain org.apache.tapestry.internal.services.ClientPersistentFieldStrategy on the client}, or

+ * elsewhere.

+ */

+public interface PersistentFieldStrategy

+{

+    /**

+     * Posts a change of a persistent property.

+     *

+     * @param pageName    the name of the page containing the component

+     * @param componentId the nested id path of the component (or null for the page's root component)

+     * @param fieldName   the name of the field whose persistent value has changed

+     * @param newValue    the new value for the field, possibly null

+     */

+    void postChange(String pageName, String componentId, String fieldName, Object newValue);

+

+    /**

+     * Finds all persistent changes previously stored for the named page (for the current active session or client).

+     */

+    Collection<PersistentFieldChange> gatherFieldChanges(String pageName);

+

+    /**

+     * Discards any saved changes for the name page. There is no expectation that data already gathered from the

+     * strategy and persumably dumped into component instance fields will be affected, but future field access (within

+     * this request or a later one) will show no data for the indicated page.

+     *

+     * @param pageName logical name of page whose field persistent data should be discarded

+     */

+    void discardChanges(String pageName);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentLocale.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentLocale.java
new file mode 100644
index 0000000..b2686fa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PersistentLocale.java
@@ -0,0 +1,39 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.util.Locale;
+
+/**
+ * Manages the persistent locale stored as a cookie in the browser.
+ */
+public interface PersistentLocale
+{
+    /**
+     * Sets the locale cookie in the browser.
+     */
+    void set(Locale locale);
+
+    /**
+     * Gets the locale cookie in the browser.
+     */
+    Locale get();
+
+    /**
+     * @return true if a locale cookie is set in the browser; false otherwise.
+     */
+    boolean isSet();
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyConduitSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyConduitSource.java
new file mode 100644
index 0000000..8729327
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyConduitSource.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.PropertyConduit;
+
+/**
+ * A source for {@link org.apache.tapestry.PropertyConduit}s, which can be thought of as a compiled property path
+ * expression. PropertyConduits are the basis of the "prop:" binding factory, thus this service defines the expression
+ * format used by the {@link org.apache.tapestry.internal.bindings.PropBindingFactory}.
+ * <p/>
+ * The expression consist of one or more terms, seperated by periods. Each term may be either the name of a JavaBean
+ * property, or the name of a method (a method that takes no parameters). Method names are distinguished from property
+ * names by appending empty parens. Using a method term as the final term will make the expression read-only.
+ * <p/>
+ * Alternately, the seperator between property names may be "?." (i.e., "user?.name").  This allows an "if not null"
+ * connection: if the term is null, then the expression evaluates to null, otherwise, the expression evaluation
+ * continues to the next property.  The helps avoid NullPointerExceptions.
+ */
+public interface PropertyConduitSource
+{
+    /**
+     * Returns property conduit instance for the given expression. PropertyConduitSource caches the conduits it returns,
+     * so despite the name, this method does not always create a <em>new</em> conduit. The cache is cleared if a change
+     * to component classes is observed.
+     *
+     * @param rootClass  the class of the root object to which the expression is applied
+     * @param expression expression to be evaluated on instances of the root class
+     * @return RuntimeException if the expression is invalid (poorly formed, references non-existent properties, etc.)
+     */
+    PropertyConduit create(Class rootClass, String expression);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java
new file mode 100644
index 0000000..43f1121
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyEditContext.java
@@ -0,0 +1,81 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Messages;
+
+/**
+ * Defines a context for editing a property of a bean via {@link org.apache.tapestry.corelib.components.BeanEditor}.
+ * This value is made available to blocks via the {@link org.apache.tapestry.annotation.Environmental} annotation.
+ *
+ * @see org.apache.tapestry.services.BeanBlockSource
+ */
+public interface PropertyEditContext extends AnnotationProvider
+{
+    /**
+     * Returns the current value of the property being edited (the context encapsulates the object containing the
+     * property).
+     */
+    Object getPropertyValue();
+
+    /**
+     * Updates the value of the property being edited (the context encapsulates the object containing the property).
+     *
+     * @param value new value for the property
+     */
+    void setPropertyValue(Object value);
+
+    /**
+     * Returns the user-presentable label, for use with the {@link org.apache.tapestry.corelib.components.Label}
+     * component, or to be integrated into any validation error messages.
+     */
+    String getLabel();
+
+    /**
+     * Returns the translator appropriate for the field (this is based on the property type).
+     *
+     * @see TranslatorDefaultSource
+     */
+    Translator getTranslator();
+
+    /**
+     * Returns the FieldValidator for the field.
+     *
+     * @see org.apache.tapestry.beaneditor.Validate
+     * @see org.apache.tapestry.services.FieldValidatorDefaultSource
+     */
+    FieldValidator getValidator(Field field);
+
+    /**
+     * Returns a string that identifies the property, usually the property name. This is used as the basis for the
+     * client-side client id.
+     */
+    String getPropertyId();
+
+    /**
+     * Returns the type of the property being edited.
+     */
+    Class getPropertyType();
+
+    /**
+     * Returns the message catalog for the container of the {@link org.apache.tapestry.corelib.components.BeanEditForm},
+     * which is the correct place to look for strings used for labels, etc.
+     */
+    Messages getContainerMessages();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyOutputContext.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyOutputContext.java
new file mode 100644
index 0000000..766f99f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/PropertyOutputContext.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.ioc.Messages;
+
+/**
+ * Provides context information needed when displaying a value. This interface is an integral part of the {@link Grid}
+ * and similar output components.    It is made available to components via an {@link
+ * org.apache.tapestry.annotation.Environmental} annotation.
+ */
+public interface PropertyOutputContext
+{
+    /**
+     * Returns the value of the property (the object being displayed is encapsulated by the context).
+     */
+    Object getPropertyValue();
+
+    /**
+     * Returns the message catalog appropriate for use. In practice, this is the message catalog of the container of the
+     * {@link Grid} component. This is used, for example, to locate labels for fields, or to locate string
+     * representations of Enums.
+     */
+    Messages getMessages();
+
+    /**
+     * Returns a string that identifies the property, usually the property name. This is used as the basis for the
+     * client-side client id.
+     */
+    String getPropertyId();
+
+    /**
+     * Returns the name of the property (which may, in fact, be a property expression).
+     */
+    String getPropertyName();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Request.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Request.java
new file mode 100644
index 0000000..077d703
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Request.java
@@ -0,0 +1,155 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Generic version of {@link javax.servlet.http.HttpServletRequest}, used to encapsulate the Servlet API version, and to
+ * help bridge the differences between Servlet API and Porlet API.
+ */
+public interface Request
+{
+    /**
+     * Gets the {@link Session}. If create is false and the session has not be created previously, returns null.
+     *
+     * @param create true to force the creation of the session
+     * @return the session (or null if create is false the session has not been previously created)
+     */
+    Session getSession(boolean create);
+
+    /**
+     * Returns the context path. This always starts with a "/" character and does not end with one, with the exception
+     * of servlets in the root context, which return the empty string.
+     */
+    String getContextPath();
+
+    /**
+     * Returns a list of query parameter names, in alphabetical order.
+     */
+    List<String> getParameterNames();
+
+    /**
+     * Returns the query parameter value for the given name. Returns null if no such parameter is in the request. For a
+     * multi-valued parameter, returns just the first value.
+     */
+    String getParameter(String name);
+
+    /**
+     * Returns the parameter values for the given name. Returns null if no such parameter is in the request.
+     */
+    String[] getParameters(String name);
+
+    /**
+     * Returns the path portion of the request, which starts with a "/" and contains everything up to the start of the
+     * query parameters. It doesn't include the context path.
+     */
+    String getPath();
+
+    /**
+     * Returns the locale of the client as determined from the request headers.
+     */
+    Locale getLocale();
+
+    /**
+     * Returns the names of all headers in the request.
+     */
+    List<String> getHeaderNames();
+
+    /**
+     * Returns the value of the specified request header as a <code>long</code> value that represents a
+     * <code>Date</code> object. Use this method with headers that contain dates, such as
+     * <code>If-Modified-Since</code>.
+     * <p/>
+     * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is case
+     * insensitive.
+     * <p/>
+     * If the request did not have a header of the specified name, this method returns -1. If the header can't be
+     * converted to a date, the method throws an <code>IllegalArgumentException</code>.
+     *
+     * @param name a <code>String</code> specifying the name of the header
+     * @return a <code>long</code> value representing the date specified in the header expressed as the number of
+     *         milliseconds since January 1, 1970 GMT, or -1 if the named header was not included with the reqest
+     * @throws IllegalArgumentException If the header value can't be converted to a date
+     */
+    long getDateHeader(String name);
+
+    /**
+     * Returns the named header as a string, or null if not found.
+     */
+    String getHeader(String name);
+
+    /**
+     * Sets the encoding of the request, which must occur before any parameters for the request are read.
+     *
+     * @param requestEncoding charset used when parsing parameters
+     */
+    void setEncoding(String requestEncoding);
+
+    /**
+     * Returns true if the request originated on the client using XmlHttpRequest (the core of any Ajax behavior). Ajax
+     * action requests may behave quite differently than ordinary, page-based requests.  This implementation currently
+     * depends on the client side setting a header: <strong>X-Requested-With=XMLHttpRequest</strong> (this is what
+     * Prototype does).
+     *
+     * @return true if the request has an XmlHttpRequest origin
+     */
+    boolean isXHR();
+
+    /**
+     * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS.
+     *
+     * @return a boolean indicating if the request was made using a secure channel
+     */
+    public boolean isSecure();
+
+    /**
+     * Returns the host name of the server to which the request was sent. It is the value of the part before ":" in the
+     * <code>Host</code> header, if any, or the resolved server name, or the server IP address.
+     *
+     * @return the name of the server
+     */
+    public String getServerName();
+
+    /**
+     * Checks whether the requested session ID is still valid.
+     *
+     * @return true if the request included a session id that is still active, false if the included session id has
+     *         expired
+     */
+    boolean isRequestedSessionIdValid();
+
+
+    /**
+     * Returns the value of the named attribute as an <code>Object</code>, or <code>null</code> if no attribute of the
+     * given name exists.  Because this method is a wrapper around {@link javax.servlet.ServletRequest#getAttribute(String)},
+     * it is case <em>sensitive</em> (unlike most of Tapestry).
+     *
+     * @param name a <code>String</code> specifying the name of the attribute
+     * @return an <code>Object</code> containing the value of the attribute, or <code>null</code> if the attribute does
+     *         not exist
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Stores an attribute in this request. Attributes are reset between requests (and remember that in Tapestry, there
+     * is usually two requests per operation: the action request that redirects to a render request).
+     *
+     * @param name  a <code>String</code> specifying the name of the attribute
+     * @param value the <code>Object</code> to be stored, or null to remove the attribute
+     */
+    void setAttribute(String name, Object value);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestExceptionHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestExceptionHandler.java
new file mode 100644
index 0000000..861bf64
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestExceptionHandler.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import java.io.IOException;

+

+/**

+ * Service invoked when an uncaught exception occurs. The error handler is responsible for providing a response to the

+ * user to describe the error.

+ */

+public interface RequestExceptionHandler

+{

+    /**

+     * Reponsible for handling the error <em>in some way</em> and providing <em>some response</em> to the client. A

+     * default implementation may render an error response page.

+     *

+     * @param exception uncaught exception to be reported

+     * @throws IOException

+     */

+    void handleRequestException(Throwable exception) throws IOException;

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestFilter.java
new file mode 100644
index 0000000..3192e24
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestFilter.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Filter interface for {@link org.apache.tapestry.services.RequestHandler}. Implementations of this interface may be
+ * contributed into the RequestHandler service configuration.
+ *
+ * @see org.apache.tapestry.services.TapestryModule#contributeRequestHandler(org.apache.tapestry.ioc.OrderedConfiguration,
+ *      Context, RequestExceptionHandler, long, long, org.apache.tapestry.internal.services.LocalizationSetter,
+ *      RequestFilter)
+ */
+public interface RequestFilter
+{
+    /**
+     * Returns true if the request has been handled, false otherwise.
+     */
+    boolean service(Request request, Response response, RequestHandler handler) throws IOException;
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestHandler.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestHandler.java
new file mode 100644
index 0000000..e9fe547
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/RequestHandler.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.io.IOException;
+
+/**
+ * Service interface for the RequestHandler pipeline service. An ordered configuration of filters may be contributed to
+ * the service.
+ *
+ * @see org.apache.tapestry.services.RequestFilter
+ */
+
+public interface RequestHandler
+{
+    /**
+     * Returns true if the request has been handled, false otherwise.
+     */
+    boolean service(Request request, Response response) throws IOException;
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ResourceDigestGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ResourceDigestGenerator.java
new file mode 100644
index 0000000..b49f5d2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ResourceDigestGenerator.java
@@ -0,0 +1,48 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.internal.services.ClasspathAssetFactory;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+
+import java.net.URL;
+
+/**
+ * Responsible for determining which classpath resources require checksums, and for generating checksums for such
+ * resources.
+ *
+ * @see ClasspathResource
+ * @see ClasspathAssetFactory
+ */
+public interface ResourceDigestGenerator
+{
+    /**
+     * Examines the path (typically, the file name extension at the end of the path) to determine if a checksum is
+     * required for the path. The path is {@link Resource} style, without a leading slash.
+     */
+    boolean requiresDigest(String path);
+
+    /**
+     * Reads the content of a URL (presumably, for a resource on the classpath) and generates a digest of its content.
+     * This digest will be incorporated into the URL provided to the client, to verify that the client has been
+     * "granted" access to this resource. This is only used for resources where {@link #requiresDigest(String)} is
+     * true.
+     *
+     * @param url
+     * @return the digest for the resource
+     */
+    String generateDigest(URL url);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java
new file mode 100644
index 0000000..1509dbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java
@@ -0,0 +1,134 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Link;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+/**
+ * API agnostic wrapper for generating a response. Bridges the gaps between the Servlet API and the Portlet API.
+ */
+public interface Response
+{
+    /**
+     * Returns a PrintWriter object to which output may be sent. Invoking flush() on the writer will commit the output.
+     *
+     * @param contentType the MIME content type for the output, typically "text/html"
+     */
+    PrintWriter getPrintWriter(String contentType) throws IOException;
+
+    /**
+     * Returns an OutputStream to which byte-oriented output may be sent. Invoking flush() on the stream will commit the
+     * output.
+     *
+     * @param contentType the MIME content type for the output, often "application/octet-stream" or "text/plain" or one
+     *                    of several others
+     */
+    OutputStream getOutputStream(String contentType) throws IOException;
+
+    /**
+     * Sends a redirect to the client.
+     *
+     * @param URL full or partial (relative) URL to send to the client
+     * @see #encodeRedirectURL(String)
+     */
+    void sendRedirect(String URL) throws IOException;
+
+    /**
+     * Sends a redirect to a link.
+     *
+     * @param link link to redirect to.
+     */
+    void sendRedirect(Link link) throws IOException;
+
+    /**
+     * Sends an error response to the client using the specified status. The server defaults to creating the response to
+     * look like an HTML-formatted server error page containing the specified message, setting the content type to
+     * "text/html", leaving cookies and other headers unmodified. If an error-page declaration has been made for the web
+     * application corresponding to the status code passed in, it will be served back in preference to the suggested msg
+     * parameter.
+     * <p/>
+     * If the response has already been committed, this method throws an IllegalStateException. After using this method,
+     * the response should be considered to be committed and should not be written to.
+     *
+     * @param sc      the error status code
+     * @param message the descriptive message
+     * @throws IOException           If an input or output exception occurs
+     * @throws IllegalStateException If the response was committed
+     */
+    void sendError(int sc, String message) throws IOException;
+
+    /**
+     * Sets the length of the content body in the response; this method sets the HTTP Content-Length header.
+     *
+     * @param length the length of the content
+     */
+    void setContentLength(int length);
+
+    /**
+     * Sets a response header with the given name and date-value. The date is specified in terms of milliseconds since
+     * the epoch. If the header had already been set, the new value overwrites the previous one.
+     *
+     * @param name the name of the header to set
+     * @param date the assigned date value
+     */
+    void setDateHeader(String name, long date);
+
+    /**
+     * Sets a response header with the given name and value. If the header had already been set, the new value
+     * overwrites the previous one.
+     *
+     * @param name  the name of the header to set
+     * @param value the assigned value
+     */
+    void setHeader(String name, String value);
+
+    /**
+     * Sets a response header with the given name and integer value. If the header had already been set, the new value
+     * overwrites the previous one.
+     *
+     * @param name  the name of the header to set
+     * @param value the assigned integer value
+     */
+    void setIntHeader(String name, int value);
+
+    /**
+     * Encodes the URL, ensuring that a session id is included (if a session exists, and as necessary depending on the
+     * client browser's use of cookies).
+     *
+     * @param URL
+     * @return the same URL or a different one with additional information to track the user session
+     */
+    String encodeURL(String URL);
+
+    /**
+     * Encodes the URL for use as a redirect, ensuring that a session id is included (if a session exists, and as
+     * necessary depending on the client browser's use of cookies).
+     *
+     * @param URL
+     * @return the same URL or a different one with additional information to track the user session
+     */
+    String encodeRedirectURL(String URL);
+
+    /**
+     * Returns true if the response has already been sent, either as a redirect or as a stream of content.
+     *
+     * @return true if response already sent
+     */
+    boolean isCommitted();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializer.java
new file mode 100644
index 0000000..34e1639
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializer.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;

+

+import javax.servlet.ServletContext;

+

+/**

+ * Service interface for initializing a servlet application.

+ */

+public interface ServletApplicationInitializer

+{

+    void initializeApplication(ServletContext context);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializerFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializerFilter.java
new file mode 100644
index 0000000..45383cc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ServletApplicationInitializerFilter.java
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;

+

+import javax.servlet.ServletContext;

+

+/**

+ * Filter interface for {@link org.apache.tapestry.services.ServletApplicationInitializer}.

+ *

+ * @see org.apache.tapestry.services.ServletApplicationInitializer

+ */

+public interface ServletApplicationInitializerFilter

+{

+    /**

+     * Peforms one step of initializing the application before passing off to the next step.

+     */

+    void initializeApplication(ServletContext context, ServletApplicationInitializer initializer);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Session.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Session.java
new file mode 100644
index 0000000..b14a476
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Session.java
@@ -0,0 +1,67 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import javax.servlet.http.HttpSession;
+import java.util.List;
+
+/**
+ * Generic version of {@link HttpSession}, used to bridge the gaps between the Servlet API and the Portlet API.
+ */
+public interface Session
+{
+    /**
+     * Returns a list of the names of all attributes stored in the session. The names are returned sorted
+     * alphabetically.
+     */
+    List<String> getAttributeNames();
+
+    /**
+     * Returns a list of the names of all attributes stored in the session whose name has the provided prefix. The names
+     * are returned in alphabetical order.
+     */
+    List<String> getAttributeNames(String prefix);
+
+    /**
+     * Returns the value previously stored in the session.
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Sets the value of an attribute. If the value is null, then the attribute is deleted.
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     * Returns the maximum time interval, in seconds, that the servlet container will keep this session open between
+     * client accesses. After this interval, the servlet container will invalidate the session. The maximum time
+     * interval can be set with the setMaxInactiveInterval method. A negative time indicates the session should never
+     * timeout.
+     */
+    int getMaxInactiveInterval();
+
+    /**
+     * Specifies the time, in seconds, between client requests before the servlet container will invalidate this
+     * session. A negative time indicates the session should never timeout.
+     */
+    void setMaxInactiveInterval(int seconds);
+
+    /**
+     * Invalidates this session then unbinds any objects bound to it.
+     *
+     * @throws IllegalStateException if this method is called on an already invalidated session
+     */
+    void invalidate();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
new file mode 100644
index 0000000..f22a188
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
@@ -0,0 +1,2013 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.corelib.data.BlankOption;
+import org.apache.tapestry.corelib.data.GridPagerPosition;
+import org.apache.tapestry.corelib.data.InsertPosition;
+import org.apache.tapestry.grid.GridDataSource;
+import org.apache.tapestry.internal.*;
+import org.apache.tapestry.internal.beaneditor.PrimitiveFieldConstraintGenerator;
+import org.apache.tapestry.internal.beaneditor.ValidateAnnotationConstraintGenerator;
+import org.apache.tapestry.internal.bindings.*;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.grid.CollectionGridDataSource;
+import org.apache.tapestry.internal.grid.NullDataSource;
+import org.apache.tapestry.internal.renderers.*;
+import org.apache.tapestry.internal.services.*;
+import org.apache.tapestry.internal.transform.*;
+import org.apache.tapestry.internal.translator.*;
+import org.apache.tapestry.internal.util.IntegerRange;
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.*;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry.ioc.util.TimeInterval;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentResourcesAware;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.util.StringToEnumCoercion;
+import org.apache.tapestry.validator.*;
+import org.apache.tapestry5.json.JSONObject;
+import org.apache.tapestry5.services.*;
+import org.slf4j.Logger;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The root module for Tapestry.
+ */
+@SuppressWarnings({ "JavaDoc" })
+@Marker(Core.class)
+@SubModule(InternalModule.class)
+public final class TapestryModule
+{
+    private final PipelineBuilder pipelineBuilder;
+
+    private final ApplicationGlobals applicationGlobals;
+
+    private final PropertyShadowBuilder shadowBuilder;
+
+    private final Environment environment;
+
+    private final StrategyBuilder strategyBuilder;
+
+    private final PropertyAccess propertyAccess;
+
+    private final ComponentInstantiatorSource componentInstantiatorSource;
+
+    private final UpdateListenerHub updateListenerHub;
+
+    private final ChainBuilder chainBuilder;
+
+    private final Request request;
+
+    private final Response response;
+
+    private final ThreadLocale threadLocale;
+
+    private final RequestGlobals requestGlobals;
+
+    private final ActionRenderResponseGenerator actionRenderResponseGenerator;
+
+    private final EnvironmentalShadowBuilder environmentalBuilder;
+
+
+    /**
+     * We inject all sorts of common dependencies (including builders) into the module itself (note: even though some of
+     * these service are defined by the module itself, that's ok because services are always lazy proxies).  This isn't
+     * about efficiency (it may be slightly more efficient, but not in any noticable way), it's about eliminating the
+     * need to keep injecting these dependencies into invividual service builder and contribution methods.
+     */
+    public TapestryModule(PipelineBuilder pipelineBuilder,
+
+                          PropertyShadowBuilder shadowBuilder,
+
+                          RequestGlobals requestGlobals,
+
+                          ApplicationGlobals applicationGlobals,
+
+                          ChainBuilder chainBuilder,
+
+                          Environment environment,
+
+                          StrategyBuilder strategyBuilder,
+
+                          ComponentInstantiatorSource componentInstantiatorSource,
+
+                          PropertyAccess propertyAccess,
+
+                          UpdateListenerHub updateListenerHub,
+
+                          Request request,
+
+                          Response response,
+
+                          ThreadLocale threadLocale,
+
+                          ActionRenderResponseGenerator actionRenderResponseGenerator,
+
+                          EnvironmentalShadowBuilder environmentalBuilder)
+    {
+        this.pipelineBuilder = pipelineBuilder;
+        this.shadowBuilder = shadowBuilder;
+        this.requestGlobals = requestGlobals;
+        this.applicationGlobals = applicationGlobals;
+        this.chainBuilder = chainBuilder;
+        this.environment = environment;
+        this.strategyBuilder = strategyBuilder;
+        this.componentInstantiatorSource = componentInstantiatorSource;
+        this.propertyAccess = propertyAccess;
+        this.updateListenerHub = updateListenerHub;
+        this.request = request;
+        this.response = response;
+        this.threadLocale = threadLocale;
+        this.actionRenderResponseGenerator = actionRenderResponseGenerator;
+        this.environmentalBuilder = environmentalBuilder;
+    }
+
+    public static void bind(ServiceBinder binder)
+    {
+        // Public Services
+
+        binder.bind(ClasspathAssetAliasManager.class, ClasspathAssetAliasManagerImpl.class);
+        binder.bind(PersistentLocale.class, PersistentLocaleImpl.class);
+        binder.bind(ApplicationStateManager.class, ApplicationStateManagerImpl.class);
+        binder.bind(ApplicationStatePersistenceStrategySource.class,
+                    ApplicationStatePersistenceStrategySourceImpl.class);
+        binder.bind(BindingSource.class, BindingSourceImpl.class);
+        binder.bind(FieldValidatorSource.class, FieldValidatorSourceImpl.class);
+        binder.bind(ApplicationGlobals.class, ApplicationGlobalsImpl.class);
+        binder.bind(AssetSource.class, AssetSourceImpl.class);
+        binder.bind(Cookies.class, CookiesImpl.class);
+        binder.bind(Environment.class, EnvironmentImpl.class);
+        binder.bind(FieldValidatorDefaultSource.class, FieldValidatorDefaultSourceImpl.class);
+        binder.bind(RequestGlobals.class, RequestGlobalsImpl.class);
+        binder.bind(ResourceDigestGenerator.class, ResourceDigestGeneratorImpl.class);
+        binder.bind(ValidationConstraintGenerator.class, ValidationConstraintGeneratorImpl.class);
+        binder.bind(EnvironmentalShadowBuilder.class, EnvironmentalShadowBuilderImpl.class);
+        binder.bind(ComponentSource.class, ComponentSourceImpl.class);
+        binder.bind(BeanModelSource.class, BeanModelSourceImpl.class);
+        binder.bind(BeanBlockSource.class, BeanBlockSourceImpl.class);
+        binder.bind(ComponentDefaultProvider.class, ComponentDefaultProviderImpl.class);
+        binder.bind(MarkupWriterFactory.class, MarkupWriterFactoryImpl.class);
+        binder.bind(FieldValidationSupport.class, FieldValidationSupportImpl.class);
+        binder.bind(ObjectRenderer.class, LocationRenderer.class).withId("LocationRenderer");
+        binder.bind(ObjectProvider.class, AssetObjectProvider.class).withId("AssetObjectProvider");
+        binder.bind(RequestExceptionHandler.class, DefaultRequestExceptionHandler.class);
+        binder.bind(ComponentEventResultProcessor.class, ComponentInstanceResultProcessor.class).withId(
+                "ComponentInstanceResultProcessor");
+        binder.bind(NullFieldStrategySource.class, NullFieldStrategySourceImpl.class);
+        binder.bind(HttpServletRequestFilter.class, IgnoredPathsFilter.class).withId("IgnoredPathsFilter");
+        binder.bind(ContextValueEncoder.class, ContextValueEncoderImpl.class);
+        binder.bind(BaseURLSource.class, BaseURLSourceImpl.class);
+        binder.bind(BeanBlockOverrideSource.class, BeanBlockOverrideSourceImpl.class);
+
+        binder.bind(AliasManager.class, AliasManagerImpl.class).withId("AliasOverrides");
+    }
+
+    // ========================================================================
+    //
+    // Service Builder Methods (static)
+    //
+    // ========================================================================
+
+
+    public static Alias build(Logger logger,
+
+                              @Inject @Symbol(InternalConstants.TAPESTRY_ALIAS_MODE_SYMBOL)
+                              String mode,
+
+                              @InjectService("AliasOverrides")
+                              AliasManager overridesManager,
+
+                              Collection<AliasContribution> configuration)
+    {
+        AliasManager manager = new AliasManagerImpl(logger, configuration);
+
+        return new AliasImpl(manager, mode, overridesManager);
+    }
+
+    // ========================================================================
+    //
+    // Service Contribution Methods (static)
+    //
+    // ========================================================================
+
+    /**
+     * Contributes the factory for serveral built-in binding prefixes ("asset", "block", "component", "literal", prop",
+     * "nullfieldstrategy", "message", "validate", "translate", "var").
+     */
+    public static void contributeBindingSource(MappedConfiguration<String, BindingFactory> configuration,
+
+                                               @InjectService("PropBindingFactory")
+                                               BindingFactory propBindingFactory,
+
+                                               ObjectLocator locator)
+    {
+        configuration.add(BindingConstants.LITERAL, new LiteralBindingFactory());
+        configuration.add(BindingConstants.PROP, propBindingFactory);
+
+        configuration.add(BindingConstants.COMPONENT, new ComponentBindingFactory());
+        configuration.add(BindingConstants.MESSAGE, new MessageBindingFactory());
+        configuration.add(BindingConstants.VALIDATE, locator.autobuild(ValidateBindingFactory.class));
+        configuration.add(BindingConstants.TRANSLATE, locator.autobuild(TranslateBindingFactory.class));
+        configuration.add(BindingConstants.BLOCK, new BlockBindingFactory());
+        configuration.add(BindingConstants.ASSET, locator.autobuild(AssetBindingFactory.class));
+        configuration.add(BindingConstants.VAR, new RenderVariableBindingFactory());
+        configuration.add(BindingConstants.NULLFIELDSTRATEGY,
+                          locator.autobuild(NullFieldStrategyBindingFactory.class));
+    }
+
+    public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration,
+
+                                                            @Symbol(SymbolConstants.TAPESTRY_VERSION)
+                                                            String version,
+
+                                                            // @Inject not needed, because this isn't a service builder method
+                                                            @Symbol("tapestry.scriptaculous.path")
+                                                            String scriptaculousPath,
+
+                                                            @Symbol("tapestry.datepicker.path")
+                                                            String datepickerPath)
+    {
+        // TAPESTRY-2159:  All the classpath assets are inside a version numbered folder (i.e., 5.0.12).
+        // For scriptaculous, etc., this version is not the version of the library, but the version
+        // bundled with Tapestry.
+
+        configuration.add("tapestry/" + version, "org/apache/tapestry");
+
+        configuration.add("scriptaculous/" + version, scriptaculousPath);
+
+        configuration.add("datepicker/" + version, datepickerPath);
+    }
+
+    public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
+    {
+        configuration.add(new LibraryMapping("core", "org.apache.tapestry.corelib"));
+    }
+
+    /**
+     * Adds a number of standard component class transform workers: <dl> <dt>Retain </dt> <dd>Allows fields to retain
+     * their values between requests</dd> <dt>Persist </dt> <dd>Allows fields to store their their value persistently
+     * between requests</dd> <dt>Parameter </dt> <dd>Identifies parameters based on the {@link
+     * org.apache.tapestry.annotation.Parameter} annotation</dd> <dt>Component </dt> <dd>Defines embedded components
+     * based on the {@link org.apache.tapestry.annotation.Component} annotation</dd> <dt>Mixin </dt> <dd>Adds a mixin as
+     * part of a component's implementation</dd> <dt>Environment </dt> <dd>Allows fields to contain values extracted
+     * from the {@link org.apache.tapestry.services.Environment} service</dd> <dt>Inject </dt> <dd>Used with the {@link
+     * org.apache.tapestry.ioc.annotation.Inject} annotation, when a value is supplied</dd> <dt>InjectPage</dt> <dd>Adds
+     * code to allow access to other pages via the {@link org.apache.tapestry.annotation.InjectPage} field
+     * annotation</dd> <dt>InjectBlock </dt> <dd>Allows a block from the template to be injected into a field</dd>
+     * <dt>IncludeStylesheet </dt> <dd>Supports the {@link org.apache.tapestry.annotation.IncludeStylesheet}
+     * annotation</dd> <dt>IncludeJavaScriptLibrary </dt> <dd>Supports the {@link org.apache.tapestry.annotation.IncludeJavaScriptLibrary}
+     * annotation</dd> <dt>SupportsInformalParameters </dt> <dd>Checks for the annotation</dd> <dt>Meta </dt> <dd>Checks
+     * for meta data and adds it to the component model</dd> <dt>ApplicationState </dt> <dd>Converts fields that
+     * reference application state objects <dt>UnclaimedField </dt> <dd>Identifies unclaimed fields and resets them to
+     * null/0/false at the end of the request</dd> <dt>RenderCommand </dt> <dd>Ensures all components also implement
+     * {@link org.apache.tapestry.runtime.RenderCommand}</dd> <dt>SetupRender, BeginRender, etc. </dt> <dd>Correspond to
+     * component render phases and annotations</dd> <dt>InvokePostRenderCleanupOnResources </dt> <dd>Makes sure {@link
+     * org.apache.tapestry.internal.InternalComponentResources#postRenderCleanup()} is invoked after a component
+     * finishes rendering</dd> <dt>Secure</dt> <dd>Checks for the {@link org.apache.tapestry.annotation.Secure}
+     * annotation</dd> <dt>ContentType</dt> <dd>Checks for {@link org.apache.tapestry.annotation.ContentType}
+     * annotation</dd> <dt>ResponseEncoding</dt> <dd>Checks for the {@link org.apache.tapestry.annotation.ResponseEncoding}
+     * annotation</dd> <dt>GenerateAccessors</dt> <dd>Generates accessor methods if {@link
+     * org.apache.tapestry.annotation.Property} annotation is present </dd> <dt>Cached</dt> <dd>Checks for the {@link
+     * org.apache.tapestry.annotation.Cached} annotation</dd><dt>Log</dt> <dd>Checks for the {@link
+     * org.apache.tapestry.annotation.Log} annotation</dd></dl>
+     */
+    public static void contributeComponentClassTransformWorker(
+            OrderedConfiguration<ComponentClassTransformWorker> configuration,
+
+            ObjectLocator locator,
+
+            InjectionProvider injectionProvider,
+
+            ComponentClassResolver resolver)
+    {
+        // TODO: Proper scheduling of all of this. Since a given field or method should
+        // only have a single annotation, the order doesn't matter so much, as long as
+        // UnclaimedField is last.
+
+        configuration.add("Cached", locator.autobuild(CachedWorker.class));
+
+        configuration.add("Meta", new MetaWorker());
+
+        configuration.add("Inject", new InjectWorker(locator, injectionProvider));
+
+        configuration.add("Secure", new SecureWorker());
+
+        configuration.add("MixinAfter", new MixinAfterWorker());
+        configuration.add("Component", new ComponentWorker(resolver));
+        configuration.add("Mixin", new MixinWorker(resolver));
+        configuration.add("OnEvent", new OnEventWorker());
+        configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
+        configuration.add("InjectPage", locator.autobuild(InjectPageWorker.class));
+        configuration.add("InjectContainer", new InjectContainerWorker());
+        configuration.add("InjectComponent", new InjectComponentWorker());
+        configuration.add("RenderCommand", new RenderCommandWorker());
+
+        // Default values for parameters are often some form of injection, so make sure
+        // that Parameter fields are processed after injections.
+
+        configuration.add("Parameter", locator.autobuild(ParameterWorker.class), "after:Inject*");
+
+        // Workers for the component rendering state machine methods; this is in typical
+        // execution order.
+
+        add(configuration, TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
+        add(configuration, TransformConstants.BEGIN_RENDER_SIGNATURE, BeginRender.class, false);
+        add(configuration, TransformConstants.BEFORE_RENDER_TEMPLATE_SIGNATURE, BeforeRenderTemplate.class, false);
+        add(configuration, TransformConstants.BEFORE_RENDER_BODY_SIGNATURE, BeforeRenderBody.class, false);
+
+        // These phases operate in reverse order.
+
+        add(configuration, TransformConstants.AFTER_RENDER_BODY_SIGNATURE, AfterRenderBody.class, true);
+        add(configuration, TransformConstants.AFTER_RENDER_TEMPLATE_SIGNATURE, AfterRenderTemplate.class, true);
+        add(configuration, TransformConstants.AFTER_RENDER_SIGNATURE, AfterRender.class, true);
+        add(configuration, TransformConstants.CLEANUP_RENDER_SIGNATURE, CleanupRender.class, true);
+
+        // Ideally, these should be ordered pretty late in the process to make sure there are no
+        // side effects with other workers that do work inside the page lifecycle methods.
+
+        add(configuration, PageLoaded.class, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, "pageLoaded");
+        add(configuration, PageAttached.class, TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, "pageAttached");
+        add(configuration, PageDetached.class, TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, "pageDetached");
+
+        configuration.add("Retain", new RetainWorker());
+        configuration.add("Persist", new PersistWorker());
+
+        configuration.add("IncludeStylesheet", locator.autobuild(IncludeStylesheetWorker.class), "after:SetupRender");
+        configuration.add("IncludeJavaScriptLibrary", locator.autobuild(IncludeJavaScriptLibraryWorker.class),
+                          "after:SetupRender");
+
+        configuration.add("InvokePostRenderCleanupOnResources", new InvokePostRenderCleanupOnResourcesWorker());
+
+        configuration.add("ContentType", new ContentTypeWorker());
+        configuration.add("ResponseEncoding", new ResponseEncodingWorker());
+
+        configuration.add("Property", new PropertyWorker());
+
+        // These must come after Property, since they actually delete fields that may still have the annotation
+        configuration.add("ApplicationState", locator.autobuild(ApplicationStateWorker.class),
+                          "after:Property");
+        configuration.add("Environment", locator.autobuild(EnvironmentalWorker.class), "after:Property");
+
+        configuration.add("Log", locator.autobuild(LogWorker.class));
+
+        // This one is always last. Any additional private fields that aren't annotated will
+        // be converted to clear out at the end of the request.
+
+        configuration.add("UnclaimedField", new UnclaimedFieldWorker(), "after:*");
+    }
+
+    /**
+     * <dl> <dt>Annotation</dt> <dd>Checks for {@link org.apache.tapestry.beaneditor.DataType} annotation</dd>
+     * <dt>Default  (ordered last)</dt> <dd>{@link org.apache.tapestry.internal.services.DefaultDataTypeAnalyzer}
+     * service ({@link #contributeDefaultDataTypeAnalyzer(org.apache.tapestry.ioc.MappedConfiguration)} })</dd> </dl>
+     */
+    public static void contributeDataTypeAnalyzer(OrderedConfiguration<DataTypeAnalyzer> configuration,
+                                                  @InjectService("DefaultDataTypeAnalyzer")
+                                                  DataTypeAnalyzer defaultDataTypeAnalyzer)
+    {
+        configuration.add("Annotation", new AnnotationDataTypeAnalyzer());
+        configuration.add("Default", defaultDataTypeAnalyzer, "after:*");
+    }
+
+    /**
+     * Maps property types to data type names: <ul> <li>String --&gt; text <li>Number --&gt; number <li>Enum --&gt; enum
+     * <li>Boolean --&gt; boolean <li>Date --&gt; date </ul>
+     */
+    public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class, String> configuration)
+    {
+        // This is a special case contributed to avoid exceptions when a property type can't be
+        // matched. DefaultDataTypeAnalyzer converts the empty string to null.
+
+        configuration.add(Object.class, "");
+
+        configuration.add(String.class, "text");
+        configuration.add(Number.class, "number");
+        configuration.add(Enum.class, "enum");
+        configuration.add(Boolean.class, "boolean");
+        configuration.add(Date.class, "date");
+    }
+
+    public static void contributeBeanBlockSource(Configuration<BeanBlockContribution> configuration)
+    {
+        addEditBlock(configuration, "text");
+        addEditBlock(configuration, "number");
+        addEditBlock(configuration, "enum");
+        addEditBlock(configuration, "boolean");
+        addEditBlock(configuration, "date");
+        addEditBlock(configuration, "password");
+
+        // longtext uses a text area, not a text field
+
+        addEditBlock(configuration, "longtext");
+
+        addDisplayBlock(configuration, "enum");
+        addDisplayBlock(configuration, "date");
+
+        // Password and long text have special output needs.
+        addDisplayBlock(configuration, "password");
+        addDisplayBlock(configuration, "longtext");
+
+    }
+
+    private static void addEditBlock(Configuration<BeanBlockContribution> configuration, String dataType)
+    {
+        addEditBlock(configuration, dataType, dataType);
+    }
+
+    private static void addEditBlock(Configuration<BeanBlockContribution> configuration, String dataType,
+                                     String blockId)
+    {
+        configuration.add(new BeanBlockContribution(dataType, "PropertyEditBlocks", blockId, true));
+    }
+
+    private static void addDisplayBlock(Configuration<BeanBlockContribution> configuration, String dataType)
+    {
+        addDisplayBlock(configuration, dataType, dataType);
+    }
+
+    private static void addDisplayBlock(Configuration<BeanBlockContribution> configuration, String dataType,
+                                        String blockId)
+    {
+        configuration.add(new BeanBlockContribution(dataType, "PropertyDisplayBlocks", blockId, false));
+    }
+
+    /**
+     * Contributes the basic set of validators: <ul> <li>required</li> <li>minlength</li> <li>maxlength</li>
+     * <li>min</li> <li>max</li> <li>regexp</li> </ul>
+     */
+    public static void contributeFieldValidatorSource(MappedConfiguration<String, Validator> configuration)
+    {
+        configuration.add("required", new Required());
+        configuration.add("minlength", new MinLength());
+        configuration.add("maxlength", new MaxLength());
+        configuration.add("min", new Min());
+        configuration.add("max", new Max());
+        configuration.add("regexp", new Regexp());
+    }
+
+    /**
+     * Contributes the base set of injection providers: <dl> <dt>Default</dt> <dd>based on {@link
+     * MasterObjectProvider}</dd> <dt>Block</dt> <dd>injects fields of type Block</dd> <dt>ComponentResources</dt>
+     * <dd>give component access to its resources</dd> <dt>CommonResources</dt> <dd>access to properties of resources
+     * (log, messages, etc.)</dd> <dt>Asset</dt> <dd>injection of assets (triggered via {@link Path} annotation), with
+     * the path relative to the component class</dd> <dt>Service</dt> <dd>ordered last, for use when Inject is present
+     * and nothing else works, matches field type against Tapestry IoC services</dd> </dl>
+     */
+    public static void contributeInjectionProvider(OrderedConfiguration<InjectionProvider> configuration,
+
+                                                   MasterObjectProvider masterObjectProvider,
+
+                                                   ObjectLocator locator,
+
+                                                   SymbolSource symbolSource,
+
+                                                   AssetSource assetSource)
+    {
+        configuration.add("Default", new DefaultInjectionProvider(masterObjectProvider, locator));
+
+        configuration.add("ComponentResources", new ComponentResourcesInjectionProvider());
+
+        // This comes after default, to deal with conflicts between injecting a String as the
+        // component id, and injecting a string with @Symbol or @Value.
+
+        configuration.add("CommonResources", new CommonResourcesInjectionProvider(), "after:Default");
+
+        configuration.add("Asset", new AssetInjectionProvider(symbolSource, assetSource), "before:Default");
+
+        configuration.add("Block", new BlockInjectionProvider(), "before:Default");
+
+        // This needs to be the last one, since it matches against services
+        // and might blow up if there is no match.
+        configuration.add("Service", new ServiceInjectionProvider(locator), "after:*");
+    }
+
+    /**
+     * Contributes two object providers: <dl> <dt>Alias</dt> <dd> Searches by type among {@linkplain AliasContribution
+     * contributions} to the {@link Alias} service</dd> <dt>Asset<dt> <dd> Checks for the {@link Path} annotation, and
+     * injects an {@link Asset}</dd> <dt>Service</dt> <dd>Injects based on the {@link Service} annotation, if
+     * present</dd> </dl>
+     */
+    public static void contributeMasterObjectProvider(OrderedConfiguration<ObjectProvider> configuration,
+
+                                                      @InjectService("Alias")
+                                                      final Alias alias,
+
+                                                      @InjectService("AssetObjectProvider")
+                                                      ObjectProvider assetObjectProvider)
+    {
+        // There's a nasty web of dependencies related to Alias; this wrapper class lets us
+        // defer instantiating the Alias service implementation just long enough to defuse those
+        // dependencies.
+
+        ObjectProvider wrapper = new ObjectProvider()
+        {
+            public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+            {
+                return alias.getObjectProvider().provide(objectType, annotationProvider, locator);
+            }
+        };
+
+        configuration.add("Alias", wrapper, "after:Value");
+
+        configuration.add("Asset", assetObjectProvider, "before:Alias");
+
+        configuration.add("Service", new ServiceAnnotationObjectProvider(), "before:Alias");
+    }
+
+
+    public static void contributeHttpServletRequestHandler(OrderedConfiguration<HttpServletRequestFilter> configuration,
+
+                                                           @InjectService("IgnoredPathsFilter")
+                                                           HttpServletRequestFilter ignoredPathsFilter)
+    {
+        configuration.add("IgnoredPaths", ignoredPathsFilter);
+    }
+
+    /**
+     * Continues a number of filters into the RequestHandler service: <dl> <dt>StaticFiles</dt> <dd>Checks to see if the
+     * request is for an actual file, if so, returns true to let the servlet container process the request</dd>
+     * <dt>CheckForUpdates</dt> <dd>Periodically fires events that checks to see if the file system sources for any
+     * cached data has changed (see {@link org.apache.tapestry.internal.services.CheckForUpdatesFilter}).
+     * <dt>ErrorFilter</dt> <dd>Catches request errors and lets the {@link org.apache.tapestry.services.RequestExceptionHandler}
+     * handle them</dd> <dt>Localization</dt> <dd>Determines the locale for the current request from header data or
+     * cookies in the request</dd> <dt>StoreIntoGlobals</dt> <dd>Stores the request and response into the {@link
+     * org.apache.tapestry5.services.RequestGlobals} service (this is repeated at the end of the pipeline, in case any
+     * filter substitutes the request or response). </dl>
+     */
+    public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, Context context,
+
+                                         // @Inject not needed because its a long, not a String
+                                         @Symbol(SymbolConstants.FILE_CHECK_INTERVAL)
+                                         @IntermediateType(TimeInterval.class)
+                                         long checkInterval,
+
+                                         @Symbol(SymbolConstants.FILE_CHECK_UPDATE_TIMEOUT)
+                                         @IntermediateType(TimeInterval.class)
+                                         long updateTimeout,
+
+                                         LocalizationSetter localizationSetter,
+
+                                         ObjectLocator locator)
+    {
+        RequestFilter staticFilesFilter = new StaticFilesFilter(context);
+
+        RequestFilter storeIntoGlobals = new RequestFilter()
+        {
+            public boolean service(Request request, Response response, RequestHandler handler) throws IOException
+            {
+                requestGlobals.storeRequestResponse(request, response);
+
+                return handler.service(request, response);
+            }
+        };
+
+        configuration.add("CheckForUpdates",
+                          new CheckForUpdatesFilter(updateListenerHub, checkInterval, updateTimeout), "before:*");
+
+        configuration.add("StaticFiles", staticFilesFilter);
+
+        configuration.add("ErrorFilter", locator.autobuild(RequestErrorFilter.class));
+
+        configuration.add("StoreIntoGlobals", storeIntoGlobals);
+
+        configuration.add("Localization", new LocalizationFilter(localizationSetter), "after:ErrorFilter");
+    }
+
+    /**
+     * Contributes the basic set of named translators: <ul>  <li>string</li>  <li>byte</li> <li>integer</li>
+     * <li>long</li> <li>float</li> <li>double</li> </ul>
+     */
+    public static void contributeTranslatorSource(MappedConfiguration<String, Translator> configuration)
+    {
+
+        configuration.add("string", new StringTranslator());
+        configuration.add("byte", new ByteTranslator());
+        configuration.add("integer", new IntegerTranslator());
+        configuration.add("long", new LongTranslator());
+        configuration.add("float", new FloatTranslator());
+        configuration.add("double", new DoubleTranslator());
+    }
+
+    /**
+     * Adds coercions: <ul> <li>String to {@link org.apache.tapestry.SelectModel} <li>String to {@link
+     * org.apache.tapestry.corelib.data.InsertPosition} <li>Map to {@link org.apache.tapestry.SelectModel}
+     * <li>Collection to {@link GridDataSource} <li>null to {@link org.apache.tapestry.grid.GridDataSource} <li>String
+     * to {@link org.apache.tapestry.corelib.data.GridPagerPosition} <li>List to {@link org.apache.tapestry.SelectModel}
+     * <li>{@link org.apache.tapestry.runtime.ComponentResourcesAware} (typically, a component) to {@link
+     * org.apache.tapestry.ComponentResources} <li>String to {@link org.apache.tapestry.corelib.data.BlankOption} </ul>
+     */
+    public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
+    {
+        add(configuration, String.class, SelectModel.class, new Coercion<String, SelectModel>()
+        {
+            public SelectModel coerce(String input)
+            {
+                return TapestryInternalUtils.toSelectModel(input);
+            }
+        });
+
+        add(configuration, Map.class, SelectModel.class, new Coercion<Map, SelectModel>()
+        {
+            @SuppressWarnings("unchecked")
+            public SelectModel coerce(Map input)
+            {
+                return TapestryInternalUtils.toSelectModel(input);
+            }
+        });
+
+        add(configuration, Collection.class, GridDataSource.class, new Coercion<Collection, GridDataSource>()
+        {
+            public GridDataSource coerce(Collection input)
+            {
+                return new CollectionGridDataSource(input);
+            }
+        });
+
+        add(configuration, void.class, GridDataSource.class, new Coercion<Void, GridDataSource>()
+        {
+            private final GridDataSource source = new NullDataSource();
+
+            public GridDataSource coerce(Void input)
+            {
+                return source;
+            }
+        });
+
+        add(configuration, String.class, GridPagerPosition.class,
+            StringToEnumCoercion.create(GridPagerPosition.class));
+
+        add(configuration, String.class, InsertPosition.class, StringToEnumCoercion.create(InsertPosition.class));
+
+        add(configuration, String.class, BlankOption.class, StringToEnumCoercion.create(BlankOption.class));
+
+        add(configuration, List.class, SelectModel.class, new Coercion<List, SelectModel>()
+        {
+            @SuppressWarnings("unchecked")
+            public SelectModel coerce(List input)
+            {
+                return TapestryInternalUtils.toSelectModel(input);
+            }
+        });
+
+        add(configuration, String.class, Pattern.class, new Coercion<String, Pattern>()
+        {
+            public Pattern coerce(String input)
+            {
+                return Pattern.compile(input);
+            }
+        });
+
+        add(configuration, ComponentResourcesAware.class, ComponentResources.class,
+            new Coercion<ComponentResourcesAware, ComponentResources>()
+            {
+
+                public ComponentResources coerce(ComponentResourcesAware input)
+                {
+                    return input.getComponentResources();
+                }
+            });
+    }
+
+    /**
+     * Adds built-in constraint generators: <ul> <li>PrimtiveField -- primitive fields are always required
+     * <li>ValidateAnnotation -- adds constraints from a {@link Validate} annotation </ul>
+     */
+    public static void contributeValidationConstraintGenerator(
+            OrderedConfiguration<ValidationConstraintGenerator> configuration)
+    {
+        configuration.add("PrimitiveField", new PrimitiveFieldConstraintGenerator());
+        configuration.add("ValidateAnnotation", new ValidateAnnotationConstraintGenerator());
+    }
+
+    private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType, Class<T> targetType,
+                                   Coercion<S, T> coercion)
+    {
+        CoercionTuple<S, T> tuple = new CoercionTuple<S, T>(sourceType, targetType, coercion);
+
+        configuration.add(tuple);
+    }
+
+    private static void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
+                            Class<? extends Annotation> annotationClass,
+                            TransformMethodSignature lifecycleMethodSignature, String methodAlias)
+    {
+        ComponentClassTransformWorker worker = new PageLifecycleAnnotationWorker(annotationClass,
+                                                                                 lifecycleMethodSignature, methodAlias);
+
+        String name = TapestryInternalUtils.lastTerm(annotationClass.getName());
+
+        configuration.add(name, worker);
+    }
+
+    private static void add(OrderedConfiguration<ComponentClassTransformWorker> configuration,
+                            TransformMethodSignature signature, Class<? extends Annotation> annotationClass,
+                            boolean reverse)
+    {
+        // make the name match the annotation class name.
+
+        String name = annotationClass.getSimpleName();
+
+        configuration.add(name, new ComponentLifecycleMethodWorker(signature, annotationClass, reverse));
+    }
+
+    // ========================================================================
+    //
+    // Service Builder Methods (instance)
+    //
+    // ========================================================================
+
+    public Context buildContext(ApplicationGlobals globals)
+    {
+        return shadowBuilder.build(globals, "context", Context.class);
+    }
+
+    public ComponentClassResolver buildComponentClassResolver(ServiceResources resources)
+    {
+        ComponentClassResolverImpl service = resources.autobuild(ComponentClassResolverImpl.class);
+
+        // Allow the resolver to clean its cache when the source is invalidated
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    @Marker(ClasspathProvider.class)
+    public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache, ClasspathAssetAliasManager aliasManager)
+    {
+        ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceCache, aliasManager);
+
+        resourceCache.addInvalidationListener(factory);
+
+        return factory;
+    }
+
+    @Marker(ContextProvider.class)
+    public AssetFactory buildContextAssetFactory(ApplicationGlobals globals, RequestPathOptimizer optimizer)
+    {
+        return new ContextAssetFactory(request, globals.getContext(), optimizer);
+    }
+
+    /**
+     * Builds the PropBindingFactory as a chain of command. The terminator of the chain is responsible for ordinary
+     * property names (and property paths). Contributions to the service cover additional special cases, such as simple
+     * literal values.
+     *
+     * @param configuration contributions of special factories for some constants, each contributed factory may return a
+     *                      binding if applicable, or null otherwise
+     */
+    public BindingFactory buildPropBindingFactory(List<BindingFactory> configuration,
+                                                  PropertyConduitSource propertyConduitSource)
+    {
+        PropBindingFactory service = new PropBindingFactory(propertyConduitSource);
+
+        configuration.add(service);
+
+        return chainBuilder.build(BindingFactory.class, configuration);
+    }
+
+    /**
+     * Builds the source of {@link Messages} containing validation messages. The contributions are paths to message
+     * bundles (resource paths within the classpath); the default contribution is "org/apache/tapestry/internal/ValidationMessages".
+     */
+    public ValidationMessagesSource buildValidationMessagesSource(Collection<String> configuration,
+
+                                                                  @ClasspathProvider AssetFactory classpathAssetFactory)
+    {
+        ValidationMessagesSourceImpl service = new ValidationMessagesSourceImpl(configuration,
+                                                                                classpathAssetFactory.getRootResource());
+
+        updateListenerHub.addUpdateListener(service);
+
+        return service;
+    }
+
+    public MetaDataLocator buildMetaDataLocator(ServiceResources resources)
+    {
+        MetaDataLocatorImpl service = resources.autobuild(MetaDataLocatorImpl.class);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    public PersistentFieldStrategy buildClientPersistentFieldStrategy(LinkFactory linkFactory,
+                                                                      ServiceResources resources)
+    {
+        ClientPersistentFieldStrategy service = resources.autobuild(ClientPersistentFieldStrategy.class);
+
+        linkFactory.addListener(service);
+
+        return service;
+    }
+
+    /**
+     * Builds a proxy to the current {@link org.apache.tapestry.RenderSupport} inside this thread's {@link
+     * Environment}.
+     */
+    public RenderSupport buildRenderSupport()
+    {
+        return environmentalBuilder.build(RenderSupport.class);
+    }
+
+    /**
+     * Builds a proxy to the current {@link org.apache.tapestry.services.FormSupport} inside this thread's {@link
+     * org.apache.tapestry.services.Environment}.
+     */
+    public FormSupport buildFormSupport()
+    {
+        return environmentalBuilder.build(FormSupport.class);
+    }
+
+    /**
+     * Allows the exact steps in the component class transformation process to be defined.
+     */
+    public ComponentClassTransformWorker buildComponentClassTransformWorker(
+            List<ComponentClassTransformWorker> configuration)
+    {
+        return chainBuilder.build(ComponentClassTransformWorker.class, configuration);
+    }
+
+    /**
+     * Analyzes properties to determine the data types, used to {@linkplain #contributeBeanBlockSource(org.apache.tapestry.ioc.Configuration)}
+     * locale display and edit blocks} for properties.  The default behaviors look for a {@link
+     * org.apache.tapestry.beaneditor.DataType} annotation before deriving the data type from the property type.
+     */
+    @Marker(Primary.class)
+    public DataTypeAnalyzer buildDataTypeAnalyzer(List<DataTypeAnalyzer> configuration)
+    {
+        return chainBuilder.build(DataTypeAnalyzer.class, configuration);
+    }
+
+    /**
+     * A chain of command for providing values for {@link Inject}-ed fields in component classes. The service's
+     * configuration can be extended to allow for different automatic injections (based on some combination of field
+     * type and field name).
+     */
+
+    public InjectionProvider buildInjectionProvider(List<InjectionProvider> configuration)
+    {
+        return chainBuilder.build(InjectionProvider.class, configuration);
+    }
+
+
+    /**
+     * Initializes the application.
+     */
+    @Marker(Primary.class)
+    public ApplicationInitializer buildApplicationInitializer(Logger logger,
+                                                              List<ApplicationInitializerFilter> configuration)
+    {
+        ApplicationInitializer terminator = new ApplicationInitializer()
+        {
+            public void initializeApplication(Context context)
+            {
+                applicationGlobals.storeContext(context);
+            }
+        };
+
+        return pipelineBuilder.build(logger, ApplicationInitializer.class, ApplicationInitializerFilter.class,
+                                     configuration, terminator);
+    }
+
+    public HttpServletRequestHandler buildHttpServletRequestHandler(Logger logger,
+                                                                    List<HttpServletRequestFilter> configuration,
+
+                                                                    @Primary
+                                                                    final RequestHandler handler)
+    {
+        HttpServletRequestHandler terminator = new HttpServletRequestHandler()
+        {
+            public boolean service(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
+                    throws IOException
+            {
+                requestGlobals.storeServletRequestResponse(servletRequest, servletResponse);
+
+                Request request = new RequestImpl(servletRequest);
+                Response response = new ResponseImpl(servletResponse);
+
+                // Transition from the Servlet API-based pipeline, to the Tapestry-based pipeline.
+
+                return handler.service(request, response);
+            }
+        };
+
+        return pipelineBuilder.build(logger, HttpServletRequestHandler.class, HttpServletRequestFilter.class,
+                                     configuration, terminator);
+    }
+
+    @Marker(Primary.class)
+    public RequestHandler buildRequestHandler(Logger logger, List<RequestFilter> configuration,
+
+                                              @Primary
+                                              final Dispatcher masterDispatcher)
+    {
+        RequestHandler terminator = new RequestHandler()
+        {
+            public boolean service(Request request, Response response) throws IOException
+            {
+                requestGlobals.storeRequestResponse(request, response);
+
+                return masterDispatcher.dispatch(request, response);
+            }
+        };
+
+        return pipelineBuilder.build(logger, RequestHandler.class, RequestFilter.class, configuration, terminator);
+    }
+
+    public ServletApplicationInitializer buildServletApplicationInitializer(Logger logger,
+                                                                            List<ServletApplicationInitializerFilter> configuration,
+
+                                                                            @Primary
+                                                                            final ApplicationInitializer initializer)
+    {
+        ServletApplicationInitializer terminator = new ServletApplicationInitializer()
+        {
+            public void initializeApplication(ServletContext context)
+            {
+                applicationGlobals.storeServletContext(context);
+
+                // And now, down the (Web) ApplicationInitializer pipeline ...
+
+                initializer.initializeApplication(new ContextImpl(context));
+            }
+        };
+
+        return pipelineBuilder.build(logger, ServletApplicationInitializer.class,
+                                     ServletApplicationInitializerFilter.class, configuration, terminator);
+    }
+
+    /**
+     * The component event result processor used for normal component requests.
+     */
+    @Marker({ Primary.class, Traditional.class })
+    public ComponentEventResultProcessor buildComponentEventResultProcessor(
+            Map<Class, ComponentEventResultProcessor> configuration)
+    {
+        return constructComponentEventResultProcessor(configuration);
+    }
+
+    /**
+     * The component event result processor used for Ajax-oriented component requests.
+     */
+    @Marker(Ajax.class)
+    public ComponentEventResultProcessor buildAjaxComponentEventResultProcessor(
+            Map<Class, ComponentEventResultProcessor> configuration)
+    {
+        return constructComponentEventResultProcessor(configuration);
+
+    }
+
+    private ComponentEventResultProcessor constructComponentEventResultProcessor(
+            Map<Class, ComponentEventResultProcessor> configuration)
+    {
+        Set<Class> handledTypes = CollectionFactory.newSet(configuration.keySet());
+
+        // A slight hack!
+
+        configuration.put(Object.class, new ObjectComponentEventResultProcessor(handledTypes));
+
+        StrategyRegistry<ComponentEventResultProcessor> registry = StrategyRegistry.newInstance(
+                ComponentEventResultProcessor.class, configuration);
+
+        return strategyBuilder.build(registry);
+    }
+
+    /**
+     * The default data type analyzer is the final analyzer consulted and identifies the type entirely pased on the
+     * property type, working against its own configuration (mapping property type class to data type).
+     */
+    public DataTypeAnalyzer buildDefaultDataTypeAnalyzer(ServiceResources resources)
+    {
+        DefaultDataTypeAnalyzer service = resources.autobuild(DefaultDataTypeAnalyzer.class);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    public TranslatorSource buildTranslatorSource(ServiceResources resources)
+    {
+        TranslatorSourceImpl service = resources.autobuild(TranslatorSourceImpl.class);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    @Marker(Primary.class)
+    public ObjectRenderer buildObjectRenderer(Map<Class, ObjectRenderer> configuration)
+    {
+        StrategyRegistry<ObjectRenderer> registry = StrategyRegistry.newInstance(ObjectRenderer.class, configuration);
+
+        return strategyBuilder.build(registry);
+    }
+
+    public ComponentMessagesSource buildComponentMessagesSource(
+            @ContextProvider
+            AssetFactory contextAssetFactory,
+
+            @Inject
+            @Value("WEB-INF/${tapestry.app-name}.properties")
+            String appCatalog)
+    {
+        ComponentMessagesSourceImpl service = new ComponentMessagesSourceImpl(contextAssetFactory
+                .getRootResource(), appCatalog);
+
+        updateListenerHub.addUpdateListener(service);
+
+        return service;
+    }
+
+    /**
+     * Returns a {@link org.apache.tapestry.ioc.services.ClassFactory} that can be used to create extra classes around
+     * component classes. This ClassFactory will be cleared whenever an underlying component class is discovered to have
+     * changed. Use of this class factory implies that your code will become aware of this (if necessary) to discard any
+     * cached object (alas, this currently involves dipping into the internals side to register for the correct
+     * notifications). Failure to properly clean up can result in really nasty PermGen space memory leaks.
+     */
+    @Marker(ComponentLayer.class)
+    public ClassFactory buildComponentClassFactory()
+    {
+        return shadowBuilder.build(componentInstantiatorSource, "classFactory", ClassFactory.class);
+    }
+
+
+    /**
+     * Ordered contributions to the MasterDispatcher service allow different URL matching strategies to occur.
+     */
+    @Marker(Primary.class)
+    public Dispatcher buildMasterDispatcher(List<Dispatcher> configuration)
+    {
+        return chainBuilder.build(Dispatcher.class, configuration);
+    }
+
+    public PropertyConduitSource buildPropertyConduitSource(@ComponentLayer ClassFactory componentClassFactory)
+    {
+        PropertyConduitSourceImpl service = new PropertyConduitSourceImpl(propertyAccess, componentClassFactory);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    /**
+     * Builds a shadow of the RequestGlobals.request property. Note again that the shadow can be an ordinary singleton,
+     * even though RequestGlobals is perthread.
+     */
+    public Request buildRequest()
+    {
+        return shadowBuilder.build(requestGlobals, "request", Request.class);
+    }
+
+    /**
+     * Builds a shadow of the RequestGlobals.HTTPServletRequest property.  Generally, you should inject the {@link
+     * Request} service instead, as future version of Tapestry may operate beyond just the servlet API.
+     */
+    public HttpServletRequest buildHttpServletRequest()
+    {
+        return shadowBuilder.build(requestGlobals, "HTTPServletRequest", HttpServletRequest.class);
+    }
+
+    /**
+     * Builds a shadow of the RequestGlobals.response property. Note again that the shadow can be an ordinary singleton,
+     * even though RequestGlobals is perthread.
+     */
+    public Response buildResponse()
+    {
+        return shadowBuilder.build(requestGlobals, "response", Response.class);
+    }
+
+
+    /**
+     * The MarkupRenderer service is used to render a full page as markup.  Supports an ordered configuration of {@link
+     * org.apache.tapestry.services.MarkupRendererFilter}s.
+     *
+     * @param pageRenderQueue handles the bulk of the work
+     * @param logger          used to log errors building the pipeline
+     * @param configuration   filters on this service
+     * @return the service
+     * @see #contributeMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration, org.apache.tapestry.Asset,
+     *      org.apache.tapestry.Asset, ValidationMessagesSource, org.apache.tapestry.ioc.services.SymbolSource,
+     *      AssetSource)
+     */
+    public MarkupRenderer buildMarkupRenderer(final PageRenderQueue pageRenderQueue, Logger logger,
+                                              List<MarkupRendererFilter> configuration)
+    {
+        MarkupRenderer terminator = new MarkupRenderer()
+        {
+            public void renderMarkup(MarkupWriter writer)
+            {
+                pageRenderQueue.render(writer);
+            }
+        };
+
+        return pipelineBuilder.build(logger, MarkupRenderer.class, MarkupRendererFilter.class, configuration,
+                                     terminator);
+    }
+
+    /**
+     * A wrapper around {@link org.apache.tapestry.internal.services.PageRenderQueue} used for partial page renders.
+     * Supports an ordered configuration of {@link org.apache.tapestry.services.PartialMarkupRendererFilter}s.
+     *
+     * @param logger        used to log warnings creating the pipeline
+     * @param configuration filters for the service
+     * @param renderQueue   does most of the work
+     * @return the service
+     * @see #contributePartialMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration, org.apache.tapestry.Asset,
+     *      org.apache.tapestry.ioc.services.SymbolSource, AssetSource, ValidationMessagesSource)
+     */
+    public PartialMarkupRenderer buildPartialMarkupRenderer(Logger logger,
+                                                            List<PartialMarkupRendererFilter> configuration,
+                                                            final PageRenderQueue renderQueue)
+    {
+
+        PartialMarkupRenderer terminator = new PartialMarkupRenderer()
+        {
+            public void renderMarkup(MarkupWriter writer, JSONObject reply)
+            {
+                renderQueue.renderPartial(writer, reply);
+            }
+        };
+
+        return pipelineBuilder.build(logger, PartialMarkupRenderer.class, PartialMarkupRendererFilter.class,
+                                     configuration, terminator);
+    }
+
+    public PageRenderRequestHandler buildPageRenderRequestHandler(List<PageRenderRequestFilter> configuration,
+                                                                  Logger logger, ServiceResources resources)
+    {
+        return pipelineBuilder.build(logger, PageRenderRequestHandler.class, PageRenderRequestFilter.class,
+                                     configuration, resources.autobuild(PageRenderRequestHandlerImpl.class));
+    }
+
+
+    /**
+     * Builds the component action request handler for traditional (non-Ajax) requests. These typically result in a
+     * redirect to a Tapestry render URL.
+     *
+     * @see org.apache.tapestry.internal.services.ComponentEventRequestHandlerImpl
+     */
+    @Marker(Traditional.class)
+    public ComponentEventRequestHandler buildComponentEventRequestHandler(
+            List<ComponentEventRequestFilter> configuration, Logger logger, ServiceResources resources)
+    {
+        return pipelineBuilder.build(logger, ComponentEventRequestHandler.class, ComponentEventRequestFilter.class,
+                                     configuration, resources.autobuild(ComponentEventRequestHandlerImpl.class));
+    }
+
+    /**
+     * Builds the action request handler for Ajax requests, based on {@link org.apache.tapestry.internal.services.AjaxComponentEventRequestHandler}.
+     * Filters on the request handler are supported here as well.
+     */
+    @Marker(Ajax.class)
+    public ComponentEventRequestHandler buildAjaxComponentEventRequestHandler(
+            List<ComponentEventRequestFilter> configuration, Logger logger, ServiceResources resources)
+    {
+        return pipelineBuilder.build(logger, ComponentEventRequestHandler.class, ComponentEventRequestFilter.class,
+                                     configuration, resources.autobuild(AjaxComponentEventRequestHandler.class));
+    }
+
+    // ========================================================================
+    //
+    // Service Contribution Methods (instance)
+    //
+    // ========================================================================
+
+    /**
+     * Contributes the default "session" strategy.
+     */
+    public void contributeApplicationStatePersistenceStrategySource(
+            MappedConfiguration<String, ApplicationStatePersistenceStrategy> configuration,
+
+            Request request)
+    {
+        configuration.add("session", new SessionApplicationStatePersistenceStrategy(request));
+    }
+
+    public void contributeAssetSource(MappedConfiguration<String, AssetFactory> configuration,
+                                      @ContextProvider AssetFactory contextAssetFactory,
+
+                                      @ClasspathProvider AssetFactory classpathAssetFactory)
+    {
+        configuration.add("context", contextAssetFactory);
+        configuration.add("classpath", classpathAssetFactory);
+    }
+
+    /**
+     * Contributes handlers for the following types: <dl> <dt>Object</dt> <dd>Failure case, added to provide a more
+     * useful exception message</dd> <dt>{@link Link}</dt> <dd>Sends a redirect to the link (which is typically a page
+     * render link)</dd> <dt>String</dt> <dd>Sends a page render redirect</dd> <dt>Class</dt> <dd>Interpreted as the
+     * class name of a page, sends a page render render redirect (this is more refactoring safe than the page name)</dd>
+     * <dt>{@link Component}</dt> <dd>A page's root component (though a non-root component will work, but will generate
+     * a warning). A direct to the containing page is sent.</dd> <dt>{@link org.apache.tapestry.StreamResponse}</dt>
+     * <dd>The stream response is sent as the actual reply.</dd> <dt>URL</dt> <dd>Sends a redirect to a (presumably)
+     * external URL</dd> </dl>
+     */
+    public void contributeComponentEventResultProcessor(
+
+            @InjectService("ComponentInstanceResultProcessor")
+            ComponentEventResultProcessor componentInstanceProcessor,
+
+            ComponentClassResolver componentClassResolver,
+
+            final RequestPageCache requestPageCache,
+
+            MappedConfiguration<Class, ComponentEventResultProcessor> configuration)
+    {
+        configuration.add(Link.class, new ComponentEventResultProcessor<Link>()
+        {
+            public void processResultValue(Link value) throws IOException
+            {
+                response.sendRedirect(value);
+            }
+        });
+
+        configuration.add(URL.class, new ComponentEventResultProcessor<URL>()
+        {
+            public void processResultValue(URL value) throws IOException
+            {
+                response.sendRedirect(value.toExternalForm());
+            }
+        });
+
+        configuration.add(String.class, new StringResultProcessor(requestPageCache, actionRenderResponseGenerator));
+
+        configuration.add(Class.class, new ClassResultProcessor(componentClassResolver, requestPageCache,
+                                                                actionRenderResponseGenerator));
+
+        configuration.add(Component.class, componentInstanceProcessor);
+
+        configuration.add(StreamResponse.class, new StreamResponseResultProcessor(response));
+    }
+
+
+    /**
+     * Contributes handlers for the following types: <dl> <dt>Object</dt> <dd>Failure case, added to provide more useful
+     * exception message</dd> <dt>{@link RenderCommand}</dt> <dd>Typically, a {@link org.apache.tapestry.Block}</dd>
+     * <dt>{@link Component}</dt> <dd>Renders the component and its body</dd> <dt>{@link
+     * org.apache.tapestry5.json.JSONObject}</dt> <dd>The JSONObject is returned as a text/javascript response</dd>
+     * <dt>{@link org.apache.tapestry.StreamResponse}</dt> <dd>The stream response is sent as the actual response</dd>
+     * </dl>
+     */
+
+    public void contributeAjaxComponentEventResultProcessor(
+            MappedConfiguration<Class, ComponentEventResultProcessor> configuration, ObjectLocator locator)
+    {
+        configuration.add(RenderCommand.class, locator.autobuild(RenderCommandComponentEventResultProcessor.class));
+        configuration.add(Component.class, locator.autobuild(AjaxComponentInstanceEventResultProcessor.class));
+        configuration.add(JSONObject.class, new JSONObjectEventResultProcessor(response));
+        configuration.add(StreamResponse.class, new StreamResponseResultProcessor(response));
+    }
+
+    /**
+     * The MasterDispatcher is a chain-of-command of individual Dispatchers, each handling (like a servlet) a particular
+     * kind of incoming request. <dl> <dt>RootPath</dt> <dd>Renders the start page for the "/" request</dd>
+     * <dt>Asset</dt> <dd>Provides access to classpath assets</dd> <dt>PageRender</dt> <dd>Identifies the {@link
+     * org.apache.tapestry.services.PageRenderRequestParameters} and forwards onto {@link PageRenderRequestHandler}</dd>
+     * <dt>ComponentEvent</dt> <dd>Identifies the {@link ComponentEventRequestParameters} and forwards onto the {@link
+     * ComponentEventRequestHandler}</dd> </dl>
+     */
+    public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
+                                           ObjectLocator locator)
+    {
+        // Looks for the root path and renders the start page. This is maintained for compatibility
+        // with earlier versions of Tapestry 5, it is recommended that an Index page be used instead.
+
+        configuration.add("RootPath",
+                          locator.autobuild(RootPathDispatcher.class),
+                          "before:Asset");
+
+        // This goes first because an asset to be streamed may have an file extension, such as
+        // ".html", that will confuse the later dispatchers.
+
+        configuration.add("Asset",
+                          locator.autobuild(AssetDispatcher.class), "before:ComponentEvent");
+
+
+        configuration.add("ComponentEvent", locator.autobuild(ComponentEventDispatcher.class),
+                          "before:PageRender");
+
+        configuration.add("PageRender",
+                          locator.autobuild(PageRenderDispatcher.class));
+    }
+
+    /**
+     * Contributes a default object renderer for type Object, plus specialized renderers for {@link
+     * org.apache.tapestry.services.Request}, {@link org.apache.tapestry.ioc.Location}, {@link
+     * org.apache.tapestry.ComponentResources}, {@link org.apache.tapestry.EventContext}, List, and Object[].
+     */
+    public void contributeObjectRenderer(MappedConfiguration<Class, ObjectRenderer> configuration,
+
+                                         @InjectService("LocationRenderer")
+                                         ObjectRenderer locationRenderer,
+
+                                         final TypeCoercer typeCoercer,
+
+                                         ObjectLocator locator)
+    {
+        configuration.add(Object.class, new ObjectRenderer()
+        {
+            public void render(Object object, MarkupWriter writer)
+            {
+                writer.write(String.valueOf(object));
+            }
+        });
+
+        configuration.add(Request.class, new RequestRenderer());
+
+        configuration.add(Location.class, locationRenderer);
+
+        ObjectRenderer preformatted = new ObjectRenderer<Object>()
+        {
+            public void render(Object object, MarkupWriter writer)
+            {
+                writer.element("pre");
+                writer.write(typeCoercer.coerce(object, String.class));
+                writer.end();
+            }
+        };
+
+        configuration.add(ClassTransformation.class, preformatted);
+
+        configuration.add(List.class, locator.autobuild(ListRenderer.class));
+        configuration.add(Object[].class, locator.autobuild(ObjectArrayRenderer.class));
+        configuration.add(ComponentResources.class, locator.autobuild(ComponentResourcesRenderer.class));
+        configuration.add(EventContext.class, locator.autobuild(EventContextRenderer.class));
+    }
+
+
+    /**
+     * Adds page render filters, each of which provides an {@link org.apache.tapestry.annotation.Environmental} service.
+     * Filters often provide {@link Environmental} services needed by components as they render. <dl>
+     * <dt>PageRenderSupport</dt>  <dd>Provides {@link org.apache.tapestry.RenderSupport}</dd>
+     * <dt>ClientBehaviorSupport</dt> <dd>Provides {@link org.apache.tapestry.internal.services.ClientBehaviorSupport}</dd>
+     * <dt>Heartbeat</dt> <dd>Provides {@link org.apache.tapestry.services.Heartbeat}</dd>
+     * <dt>DefaultValidationDecorator</dt> <dd>Provides {@link org.apache.tapestry.ValidationDecorator} (as an instance
+     * of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd> </dl>
+     */
+    public void contributeMarkupRenderer(OrderedConfiguration<MarkupRendererFilter> configuration,
+
+                                         @Symbol(SymbolConstants.PRODUCTION_MODE)
+                                         final boolean productionMode,
+
+                                         @Path("${tapestry.default-stylesheet}")
+                                         final Asset stylesheetAsset,
+
+                                         @Path("${tapestry.field-error-marker}")
+                                         final Asset fieldErrorIcon,
+
+                                         final ValidationMessagesSource validationMessagesSource,
+
+                                         final SymbolSource symbolSource,
+
+                                         final AssetSource assetSource)
+    {
+        MarkupRendererFilter pageRenderSupport = new MarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
+            {
+                DocumentLinkerImpl linker = new DocumentLinkerImpl(productionMode);
+
+                RenderSupportImpl support = new RenderSupportImpl(linker, symbolSource, assetSource,
+
+                                                                  // Core scripts added to any page that uses scripting
+
+                                                                  "${tapestry.scriptaculous}/prototype.js",
+                                                                  "${tapestry.scriptaculous}/scriptaculous.js",
+                                                                  "${tapestry.scriptaculous}/effects.js",
+
+                                                                  // Uses functions defined by the prior three
+
+                                                                  "org/apache/tapestry/tapestry.js");
+
+                support.addStylesheetLink(stylesheetAsset, null);
+
+                environment.push(RenderSupport.class, support);
+
+                renderer.renderMarkup(writer);
+
+                support.commit();
+
+                linker.updateDocument(writer.getDocument());
+
+                environment.pop(RenderSupport.class);
+            }
+        };
+
+        MarkupRendererFilter clientBehaviorSupport = new MarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
+            {
+                RenderSupport renderSupport = environment.peekRequired(RenderSupport.class);
+
+                ClientBehaviorSupportImpl clientBehaviorSupport = new ClientBehaviorSupportImpl(renderSupport);
+
+                environment.push(ClientBehaviorSupport.class, clientBehaviorSupport);
+
+                renderer.renderMarkup(writer);
+
+                environment.pop(ClientBehaviorSupport.class);
+
+                clientBehaviorSupport.commit();
+            }
+        };
+
+        MarkupRendererFilter heartbeat = new MarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
+            {
+                Heartbeat heartbeat = new HeartbeatImpl();
+
+                heartbeat.begin();
+
+                environment.push(Heartbeat.class, heartbeat);
+
+                renderer.renderMarkup(writer);
+
+                environment.pop(Heartbeat.class);
+
+                heartbeat.end();
+            }
+        };
+
+        MarkupRendererFilter defaultValidationDecorator = new MarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
+            {
+                Messages messages = validationMessagesSource.getValidationMessages(threadLocale.getLocale());
+
+                ValidationDecorator decorator = new DefaultValidationDecorator(environment, messages, fieldErrorIcon,
+                                                                               writer);
+
+                environment.push(ValidationDecorator.class, decorator);
+
+                renderer.renderMarkup(writer);
+
+                environment.pop(ValidationDecorator.class);
+            }
+        };
+
+
+        configuration.add("RenderSupport", pageRenderSupport);
+        configuration.add("ClientBehaviorSupport", clientBehaviorSupport, "after:RenderSupport");
+        configuration.add("Heartbeat", heartbeat, "after:RenderSupport");
+        configuration.add("DefaultValidationDecorator", defaultValidationDecorator, "after:Heartbeat");
+    }
+
+
+    /**
+     * Contributes {@link PartialMarkupRendererFilter}s used when rendering a partial Ajax response.  This is an analog
+     * to {@link #contributeMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration, org.apache.tapestry.Asset,
+     * org.apache.tapestry.Asset, ValidationMessagesSource, org.apache.tapestry.ioc.services.SymbolSource, AssetSource)}
+     * } and overlaps it to some degree. <dl> <dt>   PageRenderSupport     </dt> <dd>Provides {@link
+     * org.apache.tapestry.RenderSupport}</dd> <dt>ClientBehaviorSupport</dt> <dd>Provides {@link
+     * org.apache.tapestry.internal.services.ClientBehaviorSupport}</dd> <dt>Heartbeat</dt> <dd>Provides {@link
+     * org.apache.tapestry.services.Heartbeat}</dd> <dt>DefaultValidationDecorator</dt> <dd>Provides {@link
+     * org.apache.tapestry.ValidationDecorator} (as an instance of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd>
+     * </dl>
+     */
+    public void contributePartialMarkupRenderer(OrderedConfiguration<PartialMarkupRendererFilter> configuration,
+
+                                                @Path("${tapestry.field-error-marker}")
+                                                final Asset fieldErrorIcon,
+
+                                                final SymbolSource symbolSource,
+
+                                                final AssetSource assetSource,
+
+                                                final ValidationMessagesSource validationMessagesSource)
+    {
+        PartialMarkupRendererFilter pageRenderSupport = new PartialMarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
+            {
+                String uid = Long.toHexString(System.currentTimeMillis());
+
+                String namespace = ":" + uid;
+
+                final StringBuilder buffer = new StringBuilder(1000);
+
+                IdAllocator idAllocator = new IdAllocator(namespace);
+
+                DocumentLinker builder = new DocumentLinker()
+                {
+                    public void addScriptLink(String scriptURL)
+                    {
+                    }
+
+                    public void addStylesheetLink(String styleURL, String media)
+                    {
+                    }
+
+                    public void addScript(String script)
+                    {
+                        buffer.append(script);
+                        buffer.append("\n");
+                    }
+                };
+
+
+                RenderSupportImpl support = new RenderSupportImpl(builder, symbolSource, assetSource,
+                                                                  idAllocator);
+
+                environment.push(RenderSupport.class, support);
+
+                renderer.renderMarkup(writer, reply);
+
+                support.commit();
+
+                environment.pop(RenderSupport.class);
+
+                if (buffer.length() > 0)
+                    reply.put("script", buffer.toString());
+            }
+        };
+
+        PartialMarkupRendererFilter clientBehaviorSupport = new PartialMarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
+            {
+                RenderSupport renderSupport = environment.peekRequired(RenderSupport.class);
+
+                ClientBehaviorSupportImpl support = new ClientBehaviorSupportImpl(renderSupport);
+
+                environment.push(ClientBehaviorSupport.class, support);
+
+                renderer.renderMarkup(writer, reply);
+
+                environment.pop(ClientBehaviorSupport.class);
+
+                support.commit();
+            }
+        };
+
+        PartialMarkupRendererFilter heartbeat = new PartialMarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
+            {
+                Heartbeat heartbeat = new HeartbeatImpl();
+
+                heartbeat.begin();
+
+                environment.push(Heartbeat.class, heartbeat);
+
+                renderer.renderMarkup(writer, reply);
+
+                environment.pop(Heartbeat.class);
+
+                heartbeat.end();
+            }
+        };
+
+        PartialMarkupRendererFilter defaultValidationDecorator = new PartialMarkupRendererFilter()
+        {
+            public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
+            {
+                Messages messages = validationMessagesSource.getValidationMessages(threadLocale.getLocale());
+
+                ValidationDecorator decorator = new DefaultValidationDecorator(environment, messages, fieldErrorIcon,
+                                                                               writer);
+
+                environment.push(ValidationDecorator.class, decorator);
+
+                renderer.renderMarkup(writer, reply);
+
+                environment.pop(ValidationDecorator.class);
+            }
+        };
+
+
+        configuration.add("RenderSupport", pageRenderSupport);
+        configuration.add("ClientBehaviorSupport", clientBehaviorSupport, "after:RenderSupport");
+        configuration.add("Heartbeat", heartbeat, "after:RenderSupport");
+        configuration.add("DefaultValidationDecorator", defaultValidationDecorator, "after:Heartbeat");
+    }
+
+    /**
+     * Contributes several strategies: <dl> <dt>session <dd>Values are stored in the {@link Session} <dt>flash
+     * <dd>Values are stored in the {@link Session}, until the next request (for the page) <dt>client <dd>Values are
+     * encoded into URLs (or hidden form fields) </dl>
+     */
+    public void contributePersistentFieldManager(MappedConfiguration<String, PersistentFieldStrategy> configuration,
+
+                                                 Request request,
+
+                                                 @InjectService("ClientPersistentFieldStrategy")
+                                                 PersistentFieldStrategy clientStrategy)
+    {
+        configuration.add("session", new SessionPersistentFieldStrategy(request));
+        configuration.add(PersistenceConstants.FLASH, new FlashPersistentFieldStrategy(request));
+        configuration.add("client", clientStrategy);
+    }
+
+    public void contributeValidationMessagesSource(Configuration<String> configuration)
+    {
+        configuration.add("org/apache/tapestry/internal/ValidationMessages");
+    }
+
+    public ValueEncoderSource buildValueEncoderSource(Map<Class, ValueEncoderFactory> configuration)
+    {
+        ValueEncoderSourceImpl service = new ValueEncoderSourceImpl(configuration);
+
+        componentInstantiatorSource.addInvalidationListener(service);
+
+        return service;
+    }
+
+    /**
+     * Contributes {@link ValueEncoderFactory}s for types: <ul> <li>Object <li>String <li>Enum </ul>
+     */
+    @SuppressWarnings("unchecked")
+    public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
+                                                    ObjectLocator locator)
+    {
+        configuration.add(Object.class, locator.autobuild(TypeCoercedValueEncoderFactory.class));
+        configuration.add(String.class, GenericValueEncoderFactory.create(new StringValueEncoder()));
+        configuration.add(Enum.class, new EnumValueEncoderFactory());
+    }
+
+
+    /**
+     * Contributes a single filter, "Secure", which checks for non-secure requests that access secure pages.
+     */
+    public void contributePageRenderRequestHandler(OrderedConfiguration<PageRenderRequestFilter> configuration,
+                                                   final RequestSecurityManager securityManager)
+    {
+        PageRenderRequestFilter secureFilter = new PageRenderRequestFilter()
+        {
+            public void handle(PageRenderRequestParameters parameters, PageRenderRequestHandler handler) throws
+                    IOException
+            {
+
+                if (securityManager.checkForInsecureRequest(parameters.getLogicalPageName())) return;
+
+                handler.handle(parameters);
+            }
+        };
+
+        configuration.add("Secure", secureFilter);
+    }
+
+
+    /**
+     * Configures the extensions that will require a digest to be downloaded via the asset dispatcher. Most resources
+     * are "safe", they don't require a digest. For unsafe resources, the digest is incorporated into the URL to ensure
+     * that the client side isn't just "fishing".
+     * <p/>
+     * The extensions must be all lower case.
+     * <p/>
+     * This contributes "class" and "tml" (the template extension).
+     *
+     * @param configuration collection of extensions
+     */
+    public static void contributeResourceDigestGenerator(Configuration<String> configuration)
+    {
+        // Java class files always require a digest.
+        configuration.add("class");
+
+// Likewise, we don't want people fishing for templates.
+        configuration.add(InternalConstants.TEMPLATE_EXTENSION);
+    }
+
+    public static void contributeTemplateParser(MappedConfiguration<String, URL> config)
+    {
+        // Any class inside the internal module would do. Or we could move all these
+        // files to o.a.t.services.
+
+        Class c = UpdateListenerHub.class;
+        config.add("-//W3C//DTD XHTML 1.0 Strict//EN", c.getResource("xhtml1-strict.dtd"));
+        config.add("-//W3C//DTD XHTML 1.0 Transitional//EN", c
+                .getResource("xhtml1-transitional.dtd"));
+        config.add("-//W3C//DTD XHTML 1.0 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
+        config.add("-//W3C//DTD HTML 4.01//EN", c.getResource("xhtml1-strict.dtd"));
+        config.add("-//W3C//DTD HTML 4.01 Transitional//EN", c
+                .getResource("xhtml1-transitional.dtd"));
+        config.add("-//W3C//DTD HTML 4.01 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
+        config.add("-//W3C//ENTITIES Latin 1 for XHTML//EN", c.getResource("xhtml-lat1.ent"));
+        config.add("-//W3C//ENTITIES Symbols for XHTML//EN", c.getResource("xhtml-symbol.ent"));
+        config.add("-//W3C//ENTITIES Special for XHTML//EN", c.getResource("xhtml-special.ent"));
+    }
+
+    /**
+     * Contributes factory defaults that map be overridden.
+     *
+     * @see TapestryModule#contributeClasspathAssetAliasManager(MappedConfiguration, String, String)
+     */
+    public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
+    {
+        // Remember this is request-to-request time, presumably it'll take the developer more than
+        // one second to make a change, save it, and switch back to the browser.
+
+        configuration.add(SymbolConstants.FILE_CHECK_INTERVAL, "1 s");
+        configuration.add(SymbolConstants.FILE_CHECK_UPDATE_TIMEOUT, "50 ms");
+
+        // This should be overridden for particular applications.
+        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,it,zh_CN");
+
+        configuration.add(SymbolConstants.TAPESTRY_VERSION,
+                          VersionUtils.readVersionNumber(
+                                  "META-INF/maven/org.apache.tapestry/tapestry-core/pom.properties"));
+
+        configuration.add("tapestry.default-cookie-max-age", "7 d");
+
+        configuration.add("tapestry.start-page-name", "start");
+
+        configuration.add("tapestry.default-stylesheet", "org/apache/tapestry/default.css");
+        configuration.add("tapestry.field-error-marker", "org/apache/tapestry/field-error-marker.gif");
+
+        configuration.add("tapestry.page-pool.soft-limit", "5");
+        configuration.add("tapestry.page-pool.soft-wait", "10 ms");
+        configuration.add("tapestry.page-pool.hard-limit", "20");
+        configuration.add("tapestry.page-pool.active-window", "10 m");
+
+        configuration.add(SymbolConstants.SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS, "false");
+
+        configuration.add(SymbolConstants.FORCE_ABSOLUTE_URIS, "false");
+
+        configuration.add(SymbolConstants.PRODUCTION_MODE, "true");
+
+        configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "true");
+
+        configuration.add(MetaDataConstants.SECURE_PAGE, "false");
+
+        // This is designed to make it easy to keep synchronized with script.aculo.ous. As we
+        // support a new version, we create a new folder, and update the path entry. We can then
+        // delete the old version folder (or keep it around). This should be more manageable than
+        // overwriting the local copy with updates (it's too easy for files deleted between scriptaculous
+        // releases to be accidentally left lying around). There's also a ClasspathAliasManager
+        // contribution based on the path.
+
+        configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
+        configuration.add("tapestry.scriptaculous.path", "org/apache/tapestry/scriptaculous_1_8");
+
+        // Likewise for WebFX DatePicker, currently version 1.0.6
+
+        configuration.add("tapestry.datepicker.path", "org/apache/tapestry/datepicker_106");
+        configuration.add("tapestry.datepicker", "classpath:${tapestry.datepicker.path}");
+
+        configuration.add(PersistentFieldManagerImpl.META_KEY, PersistentFieldManagerImpl.DEFAULT_STRATEGY);
+
+        configuration.add(MetaDataConstants.RESPONSE_CONTENT_TYPE, "text/html");
+        configuration.add(MetaDataConstants.RESPONSE_ENCODING, "UTF-8");
+    }
+
+
+    /**
+     * Adds content types for "css" and "js" file extensions. <dl> <dt>css</dt> <dd>test/css</dd> <dt>js</dt>
+     * <dd>text/javascript</dd> </dl>
+     */
+    @SuppressWarnings({ "JavaDoc" })
+    public void contributeResourceStreamer(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("css", "text/css");
+        configuration.add("js", "text/javascript");
+    }
+
+    /**
+     * Adds a listener to the {@link org.apache.tapestry.internal.services.ComponentInstantiatorSource} that clears the
+     * {@link PropertyAccess} and {@link TypeCoercer} caches on a class loader invalidation.  In addition, forces the
+     * realization of {@link ComponentClassResolver} at startup.
+     */
+    public void contributeApplicationInitializer(OrderedConfiguration<ApplicationInitializerFilter> configuration,
+                                                 final TypeCoercer typeCoercer,
+                                                 final ComponentClassResolver componentClassResolver)
+    {
+        final InvalidationListener listener = new InvalidationListener()
+        {
+            public void objectWasInvalidated()
+            {
+                propertyAccess.clearCache();
+
+                typeCoercer.clearCache();
+            }
+        };
+
+        ApplicationInitializerFilter clearCaches = new ApplicationInitializerFilter()
+        {
+            public void initializeApplication(Context context, ApplicationInitializer initializer)
+            {
+                // Snuck in here is the logic to clear the PropertyAccess service's cache whenever
+                // the component class loader is invalidated.
+
+                componentInstantiatorSource.addInvalidationListener(listener);
+
+                initializer.initializeApplication(context);
+
+                // We don't care about the result, but this forces a load of the service
+                // at application startup, rather than on first request.
+
+                componentClassResolver.isPageName("ForceLoadAtStartup");
+            }
+        };
+
+        configuration.add("ClearCachesOnInvalidation", clearCaches);
+    }
+
+    public void contributePropBindingFactory(OrderedConfiguration<BindingFactory> configuration)
+    {
+        BindingFactory keywordFactory = new BindingFactory()
+        {
+            private final Map<String, Object> keywords = CollectionFactory.newCaseInsensitiveMap();
+
+            {
+                keywords.put("true", Boolean.TRUE);
+                keywords.put("false", Boolean.FALSE);
+                keywords.put("null", null);
+            }
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                String key = expression.trim();
+
+                if (keywords.containsKey(key)) return new LiteralBinding(description, keywords.get(key), location);
+
+                return null;
+            }
+        };
+
+        BindingFactory thisFactory = new BindingFactory()
+        {
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                if ("this".equalsIgnoreCase(expression.trim()))
+                    return new LiteralBinding(description, container.getComponent(), location);
+
+                return null;
+            }
+        };
+
+        BindingFactory longFactory = new BindingFactory()
+        {
+            private final Pattern pattern = Pattern.compile("^\\s*(-?\\d+)\\s*$");
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                Matcher matcher = pattern.matcher(expression);
+
+                if (matcher.matches())
+                {
+                    String value = matcher.group(1);
+
+                    return new LiteralBinding(description, new Long(value), location);
+                }
+
+                return null;
+            }
+        };
+
+        BindingFactory intRangeFactory = new BindingFactory()
+        {
+            private final Pattern pattern = Pattern
+                    .compile("^\\s*(-?\\d+)\\s*\\.\\.\\s*(-?\\d+)\\s*$");
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                Matcher matcher = pattern.matcher(expression);
+
+                if (matcher.matches())
+                {
+                    int start = Integer.parseInt(matcher.group(1));
+                    int finish = Integer.parseInt(matcher.group(2));
+
+                    IntegerRange range = new IntegerRange(start, finish);
+
+                    return new LiteralBinding(description, range, location);
+                }
+
+                return null;
+            }
+        };
+
+        BindingFactory doubleFactory = new BindingFactory()
+        {
+            // So, either 1234. or 1234.56 or .78
+            private final Pattern pattern = Pattern
+                    .compile("^\\s*(\\-?((\\d+\\.)|(\\d*\\.\\d+)))\\s*$");
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                Matcher matcher = pattern.matcher(expression);
+
+                if (matcher.matches())
+                {
+                    String value = matcher.group(1);
+
+                    return new LiteralBinding(description, new Double(value), location);
+                }
+
+                return null;
+            }
+        };
+
+        BindingFactory stringFactory = new BindingFactory()
+        {
+            // This will match embedded single quotes as-is, no escaping necessary.
+
+            private final Pattern pattern = Pattern.compile("^\\s*'(.*)'\\s*$");
+
+            public Binding newBinding(String description, ComponentResources container, ComponentResources component,
+                                      String expression, Location location)
+            {
+                Matcher matcher = pattern.matcher(expression);
+
+                if (matcher.matches())
+                {
+                    String value = matcher.group(1);
+
+                    return new LiteralBinding(description, value, location);
+                }
+
+                return null;
+            }
+        };
+
+        // To be honest, order probably doesn't matter.
+
+        configuration.add("Keyword", keywordFactory);
+        configuration.add("This", thisFactory);
+        configuration.add("Long", longFactory);
+        configuration.add("IntRange", intRangeFactory);
+        configuration.add("Double", doubleFactory);
+        configuration.add("StringLiteral", stringFactory);
+    }
+
+    /**
+     * Contributes filters: <dl> <dt>Ajax</dt> <dd>Determines if the request is Ajax oriented, and redirects to an
+     * alternative handler if so</dd> <dt>ImmediateRender</dt> <dd>When {@linkplain
+     * org.apache.tapestry.SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS immediate action response rendering}
+     * is enabled, generates the markup response (instead of a page redirect response, which is the normal behavior)
+     * </dd> <dt>Secure</dt> <dd>Sends a redirect if an non-secure request accesses a secure page</dd></dl>
+     */
+    public void contributeComponentEventRequestHandler(OrderedConfiguration<ComponentEventRequestFilter> configuration,
+                                                       final RequestSecurityManager requestSecurityManager,
+                                                       @Ajax ComponentEventRequestHandler ajaxHandler,
+                                                       ObjectLocator locator)
+    {
+        ComponentEventRequestFilter secureFilter = new ComponentEventRequestFilter()
+        {
+            public void handle(ComponentEventRequestParameters parameters, ComponentEventRequestHandler handler)
+                    throws IOException
+            {
+                if (requestSecurityManager.checkForInsecureRequest(parameters.getActivePageName())) return;
+
+                handler.handle(parameters);
+            }
+        };
+
+        configuration.add("Ajax", new AjaxFilter(request, ajaxHandler));
+
+        configuration.add("ImmediateRender", locator.autobuild(ImmediateActionRenderResponseFilter.class));
+
+        configuration.add("Secure", secureFilter, "before:Ajax");
+    }
+
+
+    /**
+     * Contributes strategies accessible via the {@link NullFieldStrategySource} service.
+     * <p/>
+     * <dl> <dt>default</dt> <dd>Does nothing, nulls stay null.</dd> <dt>zero</dt> <dd>Null values are converted to
+     * zero.</dd> </dl>
+     */
+    public static void contributeNullFieldStrategySource(MappedConfiguration<String, NullFieldStrategy> configuration)
+    {
+        configuration.add("default", new DefaultNullFieldStrategy());
+        configuration.add("zero", new ZeroNullFieldStrategy());
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java
new file mode 100644
index 0000000..31d926d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java
@@ -0,0 +1,31 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import java.lang.annotation.*;
+
+
+/**
+ * Marker annotation for a service that should be used for traditional page oriented requests, as opposed to Ajax
+ * requests (that send ad-hoc or {@linkplain PartialMarkupRenderer partial page markup} responses.
+ *
+ * @see ComponentEventRequestHandler
+ */
+@Target({ ElementType.PARAMETER, ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Traditional
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformConstants.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformConstants.java
new file mode 100644
index 0000000..096033d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformConstants.java
@@ -0,0 +1,129 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.ComponentEvent;
+import org.apache.tapestry.runtime.Event;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Constants used by implementations of {@link org.apache.tapestry.services.ComponentClassTransformWorker}.
+ */
+public final class TransformConstants
+{
+    // Shared parameters of a whole bunch of lifecycle methods, representing the different
+    // component render states.
+    private static final String[] RENDER_PHASE_METHOD_PARAMETERS = { MarkupWriter.class.getName(),
+            Event.class.getName() };
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#dispatchComponentEvent(org.apache.tapestry.runtime.ComponentEvent)}.
+     *
+     * @see org.apache.tapestry.annotation.OnEvent
+     */
+    public static final TransformMethodSignature DISPATCH_COMPONENT_EVENT = new TransformMethodSignature(
+            Modifier.PUBLIC, "boolean", "dispatchComponentEvent", new String[] { ComponentEvent.class.getName() },
+            null);
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()}.
+     */
+    public static final TransformMethodSignature CONTAINING_PAGE_DID_LOAD_SIGNATURE = new TransformMethodSignature(
+            "containingPageDidLoad");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#postRenderCleanup()}.
+     */
+    public static final TransformMethodSignature POST_RENDER_CLEANUP_SIGNATURE = new TransformMethodSignature(
+            "postRenderCleanup");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidDetach()}.
+     */
+    public static final TransformMethodSignature CONTAINING_PAGE_DID_DETACH_SIGNATURE = new TransformMethodSignature(
+            "containingPageDidDetach");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidAttach()}.
+     */
+    public static final TransformMethodSignature CONTAINING_PAGE_DID_ATTACH_SIGNATURE = new TransformMethodSignature(
+            "containingPageDidAttach");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#setupRender(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.SetupRender
+     */
+    public static final TransformMethodSignature SETUP_RENDER_SIGNATURE = renderPhaseSignature("setupRender");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#beginRender(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.BeginRender
+     */
+    public static final TransformMethodSignature BEGIN_RENDER_SIGNATURE = renderPhaseSignature("beginRender");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#beforeRenderTemplate(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.BeforeRenderTemplate
+     */
+    public static final TransformMethodSignature BEFORE_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature(
+            "beforeRenderTemplate");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#afterRenderTemplate(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.BeforeRenderTemplate
+     */
+    public static final TransformMethodSignature AFTER_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature(
+            "afterRenderTemplate");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#beforeRenderBody(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.BeforeRenderBody
+     */
+    public static final TransformMethodSignature BEFORE_RENDER_BODY_SIGNATURE = renderPhaseSignature(
+            "beforeRenderBody");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#afterRenderBody(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.AfterRenderBody
+     */
+    public static final TransformMethodSignature AFTER_RENDER_BODY_SIGNATURE = renderPhaseSignature("afterRenderBody");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#afterRender(MarkupWriter, Event)}
+     *
+     * @see org.apache.tapestry.annotation.AfterRender
+     */
+    public static final TransformMethodSignature AFTER_RENDER_SIGNATURE = renderPhaseSignature("afterRender");
+
+    /**
+     * Signature for {@link org.apache.tapestry.runtime.Component#cleanupRender(MarkupWriter, Event)}.
+     *
+     * @see org.apache.tapestry.annotation.CleanupRender
+     */
+    public static final TransformMethodSignature CLEANUP_RENDER_SIGNATURE = renderPhaseSignature("cleanupRender");
+
+    private static TransformMethodSignature renderPhaseSignature(String name)
+    {
+        return new TransformMethodSignature(Modifier.PUBLIC, "void", name, RENDER_PHASE_METHOD_PARAMETERS, null);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformMethodSignature.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformMethodSignature.java
new file mode 100644
index 0000000..cc62b6c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformMethodSignature.java
@@ -0,0 +1,240 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * A representation of a method signature, which consists of its name, modifiers (primarily, visibility), return type,
+ * parameter types, and declared exception types.
+ * <p/>
+ * Types are stored as class names (or primitive names) because the signature is used with {@link ClassTransformation}
+ * (which operates on as-yet unloaded classes).
+ */
+public class TransformMethodSignature implements Comparable<TransformMethodSignature>
+{
+    private int hashCode = -1;
+
+    private final int modifiers;
+
+    private final String returnType, methodName;
+
+    private final String[] parameterTypes, exceptionTypes;
+
+    private static final String[] EMPTY_STRINGS = new String[0];
+
+    /**
+     * Convenience for adding a public void method with no parameters or exception types.
+     */
+
+    public TransformMethodSignature(String name)
+    {
+        this(Modifier.PUBLIC, "void", name, EMPTY_STRINGS, EMPTY_STRINGS);
+    }
+
+    public TransformMethodSignature(int modifiers, String type, String name,
+                                    String[] parameterTypes, String[] exceptionTypes)
+    {
+        this.modifiers = modifiers;
+
+        returnType = notBlank(type, "type");
+        methodName = notBlank(name, "name");
+
+        // TODO: Checks that no element within the two arrays
+        // is null or blank.
+
+        this.parameterTypes = typeNamesOrEmpty(parameterTypes);
+        this.exceptionTypes = typeNamesOrEmpty(exceptionTypes);
+    }
+
+    private String[] typeNamesOrEmpty(String[] types)
+    {
+        return types == null ? EMPTY_STRINGS : types;
+    }
+
+    /**
+     * Returns a non-null array of the names of each declared exception type thrown by the method. Calling code should
+     * not modify the array.
+     */
+    public String[] getExceptionTypes()
+    {
+        return exceptionTypes;
+    }
+
+    /**
+     * Returns the name of the method.
+     */
+    public String getMethodName()
+    {
+        return methodName;
+    }
+
+    /**
+     * Returns the set of modifier flags for this method.
+     *
+     * @see java.lang.reflect.Modifier
+     */
+    public int getModifiers()
+    {
+        return modifiers;
+    }
+
+    /**
+     * Returns an array of the type name for each parameter. Calling code should not modify the array.
+     */
+    public String[] getParameterTypes()
+    {
+        return parameterTypes;
+    }
+
+    /**
+     * Return the type name of the return type of the method.
+     */
+    public String getReturnType()
+    {
+        return returnType;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        if (hashCode == -1)
+        {
+            hashCode = 17 * modifiers;
+            hashCode += 31 * returnType.hashCode();
+            hashCode += 31 * methodName.hashCode();
+
+            for (String parameterType : parameterTypes)
+            {
+                hashCode += 31 * parameterType.hashCode();
+            }
+
+            for (String exceptionType : exceptionTypes)
+            {
+                hashCode += 31 * exceptionType.hashCode();
+            }
+        }
+
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object other)
+    {
+        if (other == null || !(other instanceof TransformMethodSignature)) return false;
+
+        TransformMethodSignature ms = (TransformMethodSignature) other;
+
+        return modifiers == ms.modifiers && returnType.equals(ms.returnType)
+                && methodName.equals(ms.methodName)
+                && matches(parameterTypes, ms.parameterTypes)
+                && matches(exceptionTypes, ms.exceptionTypes);
+    }
+
+    private boolean matches(String[] values, String[] otherValues)
+    {
+        if (values.length != otherValues.length) return false;
+
+        for (int i = 0; i < values.length; i++)
+        {
+            if (!values[i].equals(otherValues[i])) return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the long form description of the signature. This includes modifiers, return type, method name, parameters
+     * and thrown exceptions, formatter approximately as it would appear in Java source (except that parameter names,
+     * which are not known, do no appear).
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder();
+
+        // Package private is simply omitted.
+
+        if (modifiers != 0)
+        {
+            builder.append(Modifier.toString(modifiers));
+            builder.append(' ');
+        }
+
+        builder.append(returnType);
+        builder.append(' ');
+
+        addMethodNameAndParameters(builder);
+
+        for (int i = 0; i < exceptionTypes.length; i++)
+        {
+            if (i == 0)
+                builder.append(" throws ");
+            else
+                builder.append(", ");
+
+            builder.append(exceptionTypes[i]);
+        }
+
+        return builder.toString();
+    }
+
+    private void addMethodNameAndParameters(StringBuilder builder)
+    {
+        builder.append(methodName);
+        builder.append('(');
+
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            if (i > 0) builder.append(", ");
+
+            builder.append(parameterTypes[i]);
+        }
+
+        builder.append(')');
+    }
+
+    /**
+     * Sorting is primarily via method name. For methods with the same name, the second level of sorting is by parameter
+     * count (descending).
+     */
+    public int compareTo(TransformMethodSignature o)
+    {
+        int result = methodName.compareTo(o.methodName);
+
+        // Sort descending
+        if (result == 0) result = o.parameterTypes.length - parameterTypes.length;
+
+        return result;
+    }
+
+    /**
+     * Returns a shortened form of the string representation of the method. It lists just the name of the method and the
+     * types of any parameters, omitting return type, exceptions and modifiers.
+     *
+     * @return
+     */
+    public String getMediumDescription()
+    {
+        StringBuilder builder = new StringBuilder();
+
+        addMethodNameAndParameters(builder);
+
+        return builder.toString();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformUtils.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformUtils.java
new file mode 100644
index 0000000..ea97580
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TransformUtils.java
@@ -0,0 +1,127 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;

+

+import java.util.Map;

+

+/**

+ * Support code for generating code (used when transforming component classes).

+ */

+public final class TransformUtils

+{

+    private static final Map<String, PrimitiveTypeInfo> nameToInfo = newMap();

+

+    private static final Map<Class, PrimitiveTypeInfo> classToInfo = newMap();

+

+    static class PrimitiveTypeInfo

+    {

+        private final Class wrapperType;

+

+        private final String unwrapperMethodName;

+

+        private final String defaultValue;

+

+        public PrimitiveTypeInfo(Class wrapperType, String unwrapperMethodName, String defaultValue)

+        {

+            this.wrapperType = wrapperType;

+            this.unwrapperMethodName = unwrapperMethodName;

+            this.defaultValue = defaultValue;

+        }

+    }

+

+    static

+    {

+        add(boolean.class, Boolean.class, "booleanValue", "false");

+        add(byte.class, Byte.class, "byteValue", "0");

+        add(char.class, Character.class, "charValue", "0");

+        add(short.class, Short.class, "shortValue", "0");

+        add(int.class, Integer.class, "intValue", "0");

+        add(long.class, Long.class, "longValue", "0L");

+        add(float.class, Float.class, "floatValue", "0.0f");

+        add(double.class, Double.class, "doubleValue", "0.0d");

+    }

+

+    private TransformUtils()

+    {

+    }

+

+    private static void add(Class primitiveType, Class wrapperType, String unwrapperMethodName, String defaultValue)

+    {

+        PrimitiveTypeInfo info = new PrimitiveTypeInfo(wrapperType, unwrapperMethodName, defaultValue);

+

+        classToInfo.put(primitiveType, info);

+        nameToInfo.put(primitiveType.getName(), info);

+    }

+

+    /**

+     * Returns true if the specified type is a primitive type.

+     */

+    public static boolean isPrimitive(String type)

+    {

+        return nameToInfo.containsKey(type);

+    }

+

+    /**

+     * Returns the name of wrapper type for a given input type. For primitive types, returns the wrapper type. For other

+     * types, returns the input type name.

+     *

+     * @param type primitive type name, or fully qualified class name

+     */

+    public static String getWrapperTypeName(String type)

+    {

+        PrimitiveTypeInfo info = nameToInfo.get(type);

+

+        return info == null ? type : info.wrapperType.getName();

+    }

+

+    /**

+     * For primitive types, returns the method on the <em>wrapper type</em> that converts back to the primitive.

+     *

+     * @param type the primitive type

+     * @return the method of the corresponding wrapper type, or null if type is not a primitive type

+     */

+    public static String getUnwrapperMethodName(String type)

+    {

+        PrimitiveTypeInfo info = nameToInfo.get(type);

+

+        return info == null ? null : info.unwrapperMethodName;

+    }

+

+    /**

+     * Returns the wrapper type for a given input type. For primitive types, returns the wrapper type. For other types,

+     * returns the type itself.

+     *

+     * @param type primitive or object type

+     */

+    public static Class getWrapperType(Class type)

+    {

+        PrimitiveTypeInfo info = classToInfo.get(type);

+

+        return info == null ? type : info.wrapperType;

+    }

+

+    /**

+     * Returns the default value for a type. This is the string "null" for most types, or a literal value for primtive

+     * types.

+     */

+    public static String getDefaultValue(String type)

+    {

+        PrimitiveTypeInfo info = nameToInfo.get(type);

+

+        return info == null ? "null" : info.defaultValue;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TranslatorSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TranslatorSource.java
new file mode 100644
index 0000000..da0013b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/TranslatorSource.java
@@ -0,0 +1,51 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Translator;
+
+/**
+ * A source for {@link Translator}s, either by name.
+ */
+public interface TranslatorSource
+{
+    /**
+     * Returns the translator with the given logical name.
+     *
+     * @param name name of translator (as configured)
+     * @return the shared translator instance
+     * @throws RuntimeException if no translator is configured for the provided name
+     */
+    Translator get(String name);
+
+    /**
+     * Finds a {@link Translator} that is appropriate to the given type, which is usually obtained via {@link
+     * org.apache.tapestry.Binding#getBindingType()}. Performs an inheritanced-based search for the best match.
+     *
+     * @param valueType the type of value for which a default translator is needed
+     * @return the matching translator, or null if no match can be found
+     */
+    Translator findByType(Class valueType);
+
+    /**
+     * Finds a {@link Translator} that is appropriate to the given type, which is usually obtained via {@link
+     * org.apache.tapestry.Binding#getBindingType()}. Performs an inheritanced-based search for the best match.
+     *
+     * @param valueType the type of value for which a default translator is needed
+     * @return the matching translator
+     * @throws IllegalArgumentException if no known validator matches the provided type
+     */
+    Translator getByType(Class valueType);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationConstraintGenerator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationConstraintGenerator.java
new file mode 100644
index 0000000..d436375
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationConstraintGenerator.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+import java.util.List;
+
+/**
+ * Invoked to generate a list of validation constraint strings for a property. This typically involves scanning the
+ * property for annotations or naming conventions that confer the desired validation. The constraint strings are
+ * ultimately handed to {@link FieldValidatorSource#createValidator(org.apache.tapestry.Field, String, String, String,
+ * org.apache.tapestry.ioc.Messages, java.util.Locale)}.
+ */
+public interface ValidationConstraintGenerator
+{
+    /**
+     * For a given property, identify all the approprite validation constraints. Each returned value is the name of a
+     * validator (i.e., "required") or a validator name and configuration (i.e., "minlength=5"). These contraints are
+     * exactly the individual terms in a {@link FieldValidatorSource#createValidators(org.apache.tapestry.Field, String)
+     * validate specification}. These will ultimately be used to create {@link FieldValidator}s for the field that edits
+     * the property.
+     *
+     * @param propertyType       the type of the property for which constraints are needed
+     * @param annotationProvider provides access to any annotations concerning the property (for implementations that
+     *                           are based on analysis of property annotations)
+     * @return a list of constraints
+     * @see FieldValidatorSource
+     */
+    List<String> buildConstraints(Class propertyType, AnnotationProvider annotationProvider);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationMessagesSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationMessagesSource.java
new file mode 100644
index 0000000..bb28702
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValidationMessagesSource.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.Messages;
+
+import java.util.Locale;
+
+/**
+ * Source for validation messages, within a particular locale.
+ */
+public interface ValidationMessagesSource
+{
+    Messages getValidationMessages(Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderFactory.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderFactory.java
new file mode 100644
index 0000000..ba6ac94
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderFactory.java
@@ -0,0 +1,31 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ValueEncoder;
+
+/**
+ * A source for {@link ValueEncoder} instances of a given type.
+ */
+public interface ValueEncoderFactory<V>
+{
+    /**
+     * For a given type, create an encoder.
+     *
+     * @param type type of object for which an encoder is needed
+     * @return the encoder for the object
+     */
+    ValueEncoder<V> create(Class<V> type);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java
new file mode 100644
index 0000000..82ae67e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/services/ValueEncoderSource.java
@@ -0,0 +1,31 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ValueEncoder;
+
+/**
+ * A source for value encoders based on a property type.
+ */
+public interface ValueEncoderSource
+{
+    /**
+     * Gets or creates a value encoder for the indicated type.  ValueEncoders are cached.
+     *
+     * @param type type of value to be encoded and decoded
+     * @return the value encoder
+     */
+    <T> ValueEncoder<T> getValueEncoder(Class<T> type);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java
new file mode 100644
index 0000000..7f4a670
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/PageTester.java
@@ -0,0 +1,298 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.dom.Node;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.SingleKeySymbolProvider;
+import org.apache.tapestry.internal.TapestryAppInitializer;
+import org.apache.tapestry.internal.services.*;
+import org.apache.tapestry.internal.test.*;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.apache.tapestry5.services.ApplicationGlobals;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * This class is used to run a Tapestry app in an in-process testing environment. You can ask it to render a certain
+ * page and check the DOM object created. You can also ask it to click on a link element in the DOM object to get the
+ * next page. Because no servlet container is required, it is very fast and you can directly debug into your code in
+ * your IDE.
+ */
+public class PageTester implements ComponentInvoker
+{
+    private final Registry registry;
+
+    private final ComponentInvocationMap invocationMap;
+
+    private final TestableRequest request;
+
+    private final StrategyRegistry<ComponentInvoker> invokerRegistry;
+
+    private Locale preferedLanguage;
+
+    private final LocalizationSetter localizationSetter;
+
+    public static final String DEFAULT_CONTEXT_PATH = "src/main/webapp";
+
+    private static final String DEFAULT_SUBMIT_VALUE_ATTRIBUTE = "Submit Query";
+
+    /**
+     * Initializes a PageTester without overriding any services and assuming that the context root is in
+     * src/main/webapp.
+     *
+     * @see #PageTester(String, String, String, Class[])
+     */
+    public PageTester(String appPackage, String appName)
+    {
+        this(appPackage, appName, DEFAULT_CONTEXT_PATH);
+    }
+
+    /**
+     * Initializes a PageTester that acts as a browser and a servlet container to test drive your Tapestry pages.
+     *
+     * @param appPackage    The same value you would specify using the tapestry.app-package context parameter. As this
+     *                      testing environment is not run in a servlet container, you need to specify it.
+     * @param appName       The same value you would specify as the filter name. It is used to form the name of the
+     *                      module builder for your app. If you don't have one, pass an empty string.
+     * @param contextPath   The path to the context root so that Tapestry can find the templates (if they're put
+     *                      there).
+     * @param moduleClasses Classes of additional modules to load
+     */
+    public PageTester(String appPackage, String appName, String contextPath, Class... moduleClasses)
+    {
+        preferedLanguage = Locale.ENGLISH;
+
+        SymbolProvider provider = new SingleKeySymbolProvider(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM, appPackage);
+
+        TapestryAppInitializer initializer = new TapestryAppInitializer(provider, appName, PageTesterModule.TEST_MODE);
+
+        initializer.addModules(PageTesterModule.class);
+        initializer.addModules(moduleClasses);
+        initializer.addModules(provideExtraModuleDefs());
+
+        registry = initializer.getRegistry();
+
+        request = registry.getObject(TestableRequest.class, null);
+
+        localizationSetter = registry.getService("LocalizationSetter", LocalizationSetter.class);
+
+        invocationMap = registry.getObject(ComponentInvocationMap.class, null);
+
+        ApplicationGlobals globals = registry.getObject(ApplicationGlobals.class, null);
+
+        globals.storeContext(new PageTesterContext(contextPath));
+
+        Map<Class, ComponentInvoker> map = newMap();
+        map.put(PageLinkTarget.class, new PageLinkInvoker(registry));
+        map.put(ActionLinkTarget.class, new ActionLinkInvoker(registry, this, invocationMap));
+
+        invokerRegistry = StrategyRegistry.newInstance(ComponentInvoker.class, map);
+    }
+
+    /**
+     * Overridden in subclasses to provide additional module definitions beyond those normally located. This
+     * implementation returns an empty array.
+     */
+    protected ModuleDef[] provideExtraModuleDefs()
+    {
+        return new ModuleDef[0];
+    }
+
+
+    /**
+     * You should call it after use
+     */
+    public void shutdown()
+    {
+        registry.shutdown();
+    }
+
+
+    /**
+     * Returns the Registry that was created for the application.
+     */
+    public Registry getRegistry()
+    {
+        return registry;
+    }
+
+    /**
+     * Allows a service to be retrieved via its service interface.  Use {@link #getRegistry()} for more complicated
+     * queries.
+     *
+     * @param serviceInterface used to select the service
+     */
+    public <T> T getService(Class<T> serviceInterface)
+    {
+        return registry.getService(serviceInterface);
+    }
+
+    /**
+     * Renders a page specified by its name.
+     *
+     * @param pageName The name of the page to be rendered.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document renderPage(String pageName)
+    {
+        return invoke(new ComponentInvocationImpl(new PageLinkTarget(pageName), new String[0], null));
+    }
+
+    /**
+     * Simulates a click on a link.
+     *
+     * @param link The Link object to be "clicked" on.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document clickLink(Element link)
+    {
+        notNull(link, "link");
+
+        ComponentInvocation invocation = getInvocation(link);
+
+        return invoke(invocation);
+    }
+
+    private ComponentInvocation getInvocation(Element element)
+    {
+        ComponentInvocation invocation = invocationMap.get(element);
+
+        if (invocation == null)
+            throw new IllegalArgumentException("No component invocation object is associated with the Element.");
+
+        return invocation;
+    }
+
+    public Document invoke(ComponentInvocation invocation)
+    {
+        // It is critical to clear the map before invoking an invocation (render a page or click a
+        // link).
+        invocationMap.clear();
+
+        setThreadLocale();
+
+        ComponentInvoker invoker = invokerRegistry.getByInstance(invocation.getTarget());
+
+        return invoker.invoke(invocation);
+    }
+
+    private void setThreadLocale()
+    {
+        localizationSetter.setThreadLocale(preferedLanguage);
+    }
+
+    /**
+     * Simulates a submission of the form specified. The caller can specify values for the form fields.
+     *
+     * @param form       the form to be submitted.
+     * @param parameters the query parameter name/value pairs
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document submitForm(Element form, Map<String, String> parameters)
+    {
+        notNull(form, "form");
+
+        request.clear();
+
+        request.loadParameters(parameters);
+
+        addHiddenFormFields(form);
+
+        ComponentInvocation invocation = getInvocation(form);
+
+        return invoke(invocation);
+    }
+
+    /**
+     * Simulates a submission of the form by clicking the specified submit button. The caller can specify values for the
+     * form fields.
+     *
+     * @param submitButton the submit button to be clicked.
+     * @param fieldValues  the field values keyed on field names.
+     * @return The DOM created. Typically you will assert against it.
+     */
+    public Document clickSubmit(Element submitButton, Map<String, String> fieldValues)
+    {
+        notNull(submitButton, "submitButton");
+
+        assertIsSubmit(submitButton);
+
+        Element form = getFormAncestor(submitButton);
+        String value = submitButton.getAttribute("value");
+
+        if (value == null) value = DEFAULT_SUBMIT_VALUE_ATTRIBUTE;
+
+        fieldValues.put(submitButton.getAttribute("name"), value);
+
+        return submitForm(form, fieldValues);
+    }
+
+    private void assertIsSubmit(Element element)
+    {
+        if (element.getName().equals("input"))
+        {
+            String type = element.getAttribute("type");
+
+            if ("submit".equals(type)) return;
+        }
+
+        throw new IllegalArgumentException("The specified element is not a submit button.");
+    }
+
+    private Element getFormAncestor(Element element)
+    {
+        while (true)
+        {
+            if (element == null) throw new IllegalArgumentException("The given element is not contained by a form.");
+
+            if (element.getName().equalsIgnoreCase("form")) return element;
+
+            element = element.getParent();
+        }
+    }
+
+    private void addHiddenFormFields(Element element)
+    {
+        if (isHiddenFormField(element))
+            request.loadParameter(element.getAttribute("name"), element.getAttribute("value"));
+
+        for (Node child : element.getChildren())
+        {
+            if (child instanceof Element)
+            {
+                addHiddenFormFields((Element) child);
+            }
+        }
+    }
+
+    private boolean isHiddenFormField(Element element)
+    {
+        return element.getName().equalsIgnoreCase("input") && "hidden".equalsIgnoreCase(element.getAttribute("type"));
+    }
+
+    public void setPreferedLanguage(Locale preferedLanguage)
+    {
+        this.preferedLanguage = preferedLanguage;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
new file mode 100644
index 0000000..a31ef4b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
@@ -0,0 +1,1062 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotation.Id;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.internal.services.MapMessages;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import static org.apache.tapestry.internal.test.CodeEq.codeEq;
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.EmbeddedComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.model.ParameterModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.*;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import org.easymock.IAnswer;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.*;
+import static java.lang.Thread.sleep;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * Base test case that adds a number of convienience factory and training methods for the public interfaces of
+ * Tapestry.
+ */
+public abstract class TapestryTestCase extends IOCTestCase
+{
+
+    /**
+     * Creates a new markup writer instance (not a markup writer mock). Output can be directed at the writer, which uses
+     * the default (HTML) markup model. The writer's toString() value represents all the collected markup in the
+     * writer.
+     */
+    protected final MarkupWriter createMarkupWriter()
+    {
+        return new MarkupWriterImpl();
+    }
+
+    protected final void train_getAliasesForMode(AliasManager manager, String mode, Map<Class, Object> configuration)
+    {
+        expect(manager.getAliasesForMode(mode)).andReturn(configuration);
+    }
+
+    protected final ApplicationStateCreator mockApplicationStateCreator()
+    {
+        return newMock(ApplicationStateCreator.class);
+    }
+
+    protected final ApplicationStatePersistenceStrategy mockApplicationStatePersistenceStrategy()
+    {
+        return newMock(ApplicationStatePersistenceStrategy.class);
+    }
+
+    protected final ApplicationStatePersistenceStrategySource mockApplicationStatePersistenceStrategySource()
+    {
+        return newMock(ApplicationStatePersistenceStrategySource.class);
+    }
+
+    protected final Asset mockAsset()
+    {
+        return newMock(Asset.class);
+    }
+
+    protected final AssetFactory mockAssetFactory()
+    {
+        return newMock(AssetFactory.class);
+    }
+
+    protected final AssetSource mockAssetSource()
+    {
+        return newMock(AssetSource.class);
+    }
+
+    protected final Binding mockBinding()
+    {
+        return newMock(Binding.class);
+    }
+
+    protected final BindingFactory mockBindingFactory()
+    {
+        return newMock(BindingFactory.class);
+    }
+
+    protected final BindingSource mockBindingSource()
+    {
+        return newMock(BindingSource.class);
+    }
+
+    protected final Block mockBlock()
+    {
+        return newMock(Block.class);
+    }
+
+    protected final ClasspathAssetAliasManager mockClasspathAssetAliasManager()
+    {
+        return newMock(ClasspathAssetAliasManager.class);
+    }
+
+    protected final ClassTransformation mockClassTransformation()
+    {
+        return newMock(ClassTransformation.class);
+    }
+
+    protected final Component mockComponent()
+    {
+        return newMock(Component.class);
+    }
+
+    protected final ComponentClassResolver mockComponentClassResolver()
+    {
+        return newMock(ComponentClassResolver.class);
+    }
+
+    protected final ComponentEventCallback mockComponentEventHandler()
+    {
+        return newMock(ComponentEventCallback.class);
+    }
+
+    protected final ComponentModel mockComponentModel()
+    {
+        return newMock(ComponentModel.class);
+    }
+
+    protected final ComponentResources mockComponentResources()
+    {
+        return newMock(ComponentResources.class);
+    }
+
+    protected final Context mockContext()
+    {
+        return newMock(Context.class);
+    }
+
+    protected final Environment mockEnvironment()
+    {
+        return newMock(Environment.class);
+    }
+
+    protected final Field mockField()
+    {
+        return newMock(Field.class);
+    }
+
+    protected final FieldValidator mockFieldValidator()
+    {
+        return newMock(FieldValidator.class);
+    }
+
+    protected FieldValidatorSource mockFieldValidatorSource()
+    {
+        return newMock(FieldValidatorSource.class);
+    }
+
+    protected final Field mockFieldWithLabel(String label)
+    {
+        Field field = mockField();
+
+        train_getLabel(field, label);
+
+        return field;
+    }
+
+    protected final Heartbeat mockHeartbeat()
+    {
+        return newMock(Heartbeat.class);
+    }
+
+    protected final HttpServletRequest mockHttpServletRequest()
+    {
+        return newMock(HttpServletRequest.class);
+    }
+
+    protected final HttpServletResponse mockHttpServletResponse()
+    {
+        return newMock(HttpServletResponse.class);
+    }
+
+    protected final HttpSession mockHttpSession()
+    {
+        return newMock(HttpSession.class);
+    }
+
+    protected final Inject mockInject()
+    {
+        return newMock(Inject.class);
+    }
+
+    protected final Link mockLink()
+    {
+        return newMock(Link.class);
+    }
+
+    protected final MarkupWriter mockMarkupWriter()
+    {
+        return newMock(MarkupWriter.class);
+    }
+
+    protected final MutableComponentModel mockMutableComponentModel()
+    {
+        return newMock(MutableComponentModel.class);
+    }
+
+    protected final ParameterModel mockParameterModel()
+    {
+        return newMock(ParameterModel.class);
+    }
+
+    protected final Path mockPath()
+    {
+        return newMock(Path.class);
+    }
+
+    protected final PropertyConduit mockPropertyConduit()
+    {
+        return newMock(PropertyConduit.class);
+    }
+
+    protected final PropertyModel mockPropertyModel()
+    {
+        return newMock(PropertyModel.class);
+    }
+
+    protected final Request mockRequest()
+    {
+        return newMock(Request.class);
+    }
+
+    protected final RequestHandler mockRequestHandler()
+    {
+        return newMock(RequestHandler.class);
+    }
+
+    protected final ResourceDigestGenerator mockResourceDigestGenerator()
+    {
+        return newMock(ResourceDigestGenerator.class);
+    }
+
+    protected final Response mockResponse()
+    {
+        return newMock(Response.class);
+    }
+
+    protected final Session mockSession()
+    {
+        return newMock(Session.class);
+    }
+
+    protected final Translator mockTranslator()
+    {
+        return newMock(Translator.class);
+    }
+
+    protected final ValidationConstraintGenerator mockValidationConstraintGenerator()
+    {
+        return newMock(ValidationConstraintGenerator.class);
+    }
+
+    protected final ValidationMessagesSource mockValidationMessagesSource()
+    {
+        return newMock(ValidationMessagesSource.class);
+    }
+
+    protected final ValidationTracker mockValidationTracker()
+    {
+        return newMock(ValidationTracker.class);
+    }
+
+    protected final Validator mockValidator()
+    {
+        return newMock(Validator.class);
+    }
+
+    /**
+     * Writes a change to a file.
+     */
+    protected final void touch(File f) throws Exception
+    {
+        long startModified = f.lastModified();
+
+        while (true)
+        {
+            OutputStream o = new FileOutputStream(f);
+            o.write(0);
+            o.close();
+
+            long newModified = f.lastModified();
+
+            if (newModified != startModified) return;
+
+            // Sleep 1/20 second and try again
+
+            sleep(50);
+        }
+    }
+
+    protected final void train_addField(ClassTransformation transformation, int modifiers, String type,
+                                        String suggestedName, String actualName)
+    {
+        expect(transformation.addField(modifiers, type, suggestedName)).andReturn(actualName);
+    }
+
+    protected final void train_addInjectedField(ClassTransformation ct, Class type, String suggestedName, Object value,
+                                                String fieldName)
+    {
+        expect(ct.addInjectedField(type, suggestedName, value)).andReturn(fieldName);
+    }
+
+    protected final void train_addMethod(ClassTransformation transformation, TransformMethodSignature signature,
+                                         String... body)
+    {
+        transformation.addMethod(eq(signature), codeEq(join(body)));
+    }
+
+    protected final void train_buildConstraints(ValidationConstraintGenerator generator, Class propertyType,
+                                                AnnotationProvider provider, String... constraints)
+    {
+        expect(generator.buildConstraints(propertyType, provider)).andReturn(Arrays.asList(constraints));
+    }
+
+    protected final <T> void train_create(ApplicationStateCreator<T> creator, T aso)
+    {
+        expect(creator.create()).andReturn(aso);
+    }
+
+    protected final void train_createAsset(AssetFactory factory, Resource resource, Asset asset)
+    {
+        expect(factory.createAsset(resource)).andReturn(asset);
+    }
+
+    protected final void train_createValidator(FieldValidatorSource source, Field field, String validatorType,
+                                               String constraintValue, String overrideId, Messages overrideMessages,
+                                               Locale locale, FieldValidator result)
+    {
+        expect(source.createValidator(field, validatorType, constraintValue, overrideId, overrideMessages,
+                                      locale)).andReturn(result);
+    }
+
+    protected final void train_encodeRedirectURL(Response response, String URI, String encoded)
+    {
+        expect(response.encodeRedirectURL(URI)).andReturn(encoded);
+    }
+
+    protected final void train_encodeURL(Response response, String inputURL, String outputURL)
+    {
+        expect(response.encodeURL(inputURL)).andReturn(outputURL);
+    }
+
+    protected final <T> void train_exists(ApplicationStatePersistenceStrategy strategy, Class<T> asoClass,
+                                          boolean exists)
+    {
+        expect(strategy.exists(asoClass)).andReturn(exists);
+    }
+
+    protected final void train_extendConstructor(ClassTransformation transformation, String... body)
+    {
+        transformation.extendConstructor(codeEq(join(body)));
+    }
+
+    protected final void train_extendMethod(ClassTransformation transformation, TransformMethodSignature signature,
+                                            String... body)
+    {
+        transformation.extendMethod(eq(signature), codeEq(join(body)));
+    }
+
+    protected final void train_getAsset(AssetSource source, Resource root, String path, Locale locale, Asset asset)
+    {
+        expect(source.getAsset(root, path, locale)).andReturn(asset);
+    }
+
+    protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
+                                                        Class<? extends Annotation> annotationClass,
+                                                        List<String> fieldNames)
+    {
+        expect(transformation.findFieldsWithAnnotation(annotationClass)).andReturn(fieldNames);
+    }
+
+    protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
+                                                        Class<? extends Annotation> annotationClass,
+                                                        String... fieldNames)
+    {
+        train_findFieldsWithAnnotation(transformation, annotationClass, Arrays.asList(fieldNames));
+    }
+
+    protected final void train_findMethods(ClassTransformation transformation,
+                                           final TransformMethodSignature... signatures)
+    {
+        IAnswer<List<TransformMethodSignature>> answer = new IAnswer<List<TransformMethodSignature>>()
+        {
+            public List<TransformMethodSignature> answer() throws Throwable
+            {
+                // Can't think of a way to do this without duplicating some code out of
+                // InternalClassTransformationImpl
+
+                List<TransformMethodSignature> result = newList();
+                MethodFilter filter = (MethodFilter) EasyMock.getCurrentArguments()[0];
+
+                for (TransformMethodSignature sig : signatures)
+                {
+                    if (filter.accept(sig)) result.add(sig);
+                }
+
+                // We don't have to sort them for testing purposes. Usually there's just going to be
+                // one in there.
+
+                return result;
+            }
+
+        };
+
+        expect(transformation.findMethods(EasyMock.isA(MethodFilter.class))).andAnswer(answer);
+    }
+
+    protected final void train_findMethodsWithAnnotation(ClassTransformation tf,
+                                                         Class<? extends Annotation> annotationType,
+                                                         List<TransformMethodSignature> sigs)
+    {
+        expect(tf.findMethodsWithAnnotation(annotationType)).andReturn(sigs);
+    }
+
+    protected final void train_findUnclaimedFields(ClassTransformation transformation, String... fieldNames)
+    {
+        expect(transformation.findUnclaimedFields()).andReturn(Arrays.asList(fieldNames));
+    }
+
+    protected final void train_generateChecksum(ResourceDigestGenerator generator, URL url, String digest)
+    {
+        expect(generator.generateDigest(url)).andReturn(digest);
+    }
+
+    protected final <T> void train_get(ApplicationStatePersistenceStrategy strategy, Class<T> asoClass,
+                                       ApplicationStateCreator<T> creator, T aso)
+    {
+        expect(strategy.get(asoClass, creator)).andReturn(aso);
+    }
+
+    protected final void train_get(ApplicationStatePersistenceStrategySource source, String strategyName,
+                                   ApplicationStatePersistenceStrategy strategy)
+    {
+        expect(source.get(strategyName)).andReturn(strategy).atLeastOnce();
+    }
+
+    protected final void train_get(Binding binding, Object value)
+    {
+        expect(binding.get()).andReturn(value);
+    }
+
+    protected void train_getAttribute(HttpSession session, String attributeName, Object value)
+    {
+        expect(session.getAttribute(attributeName)).andReturn(value);
+    }
+
+    protected final void train_getAttribute(Session session, String name, Object attribute)
+    {
+        expect(session.getAttribute(name)).andReturn(attribute);
+    }
+
+    protected final void train_getAttributeNames(Session session, String prefix, String... names)
+    {
+        expect(session.getAttributeNames(prefix)).andReturn(Arrays.asList(names));
+    }
+
+    protected final void train_getBaseResource(ComponentModel model, Resource resource)
+    {
+        expect(model.getBaseResource()).andReturn(resource).atLeastOnce();
+    }
+
+    protected final void train_getClassName(ClassTransformation transformation, String className)
+    {
+        expect(transformation.getClassName()).andReturn(className).atLeastOnce();
+    }
+
+    protected final void train_getClasspathAsset(AssetSource source, String path, Asset asset)
+    {
+        expect(source.getClasspathAsset(path)).andReturn(asset);
+    }
+
+    protected final void train_getClasspathAsset(AssetSource source, String path, Locale locale, Asset asset)
+    {
+        expect(source.getClasspathAsset(path, locale)).andReturn(asset);
+    }
+
+    protected final void train_getCompleteId(ComponentResourcesCommon resources, String completeId)
+    {
+        expect(resources.getCompleteId()).andReturn(completeId).atLeastOnce();
+    }
+
+    protected final void train_getComponent(ComponentResources resources, Component component)
+    {
+        expect(resources.getComponent()).andReturn(component).atLeastOnce();
+    }
+
+    protected final void train_getComponentClassName(ComponentModel model, String className)
+    {
+        expect(model.getComponentClassName()).andReturn(className).atLeastOnce();
+    }
+
+    protected final void train_getComponentResources(Component component, ComponentResources resources)
+    {
+        expect(component.getComponentResources()).andReturn(resources).atLeastOnce();
+    }
+
+    protected final void train_getConduit(PropertyModel model, PropertyConduit conduit)
+    {
+        expect(model.getConduit()).andReturn(conduit).atLeastOnce();
+    }
+
+    protected <C, T> void train_getConstraintType(Validator<C, T> validator, Class<C> constraintType)
+    {
+        expect(validator.getConstraintType()).andReturn(constraintType).atLeastOnce();
+    }
+
+    protected final void train_getContainer(ComponentResources resources, Component container)
+    {
+        expect(resources.getContainer()).andReturn(container).atLeastOnce();
+    }
+
+    protected final void train_getContainerMessages(ComponentResources resources, Messages containerMessages)
+    {
+        expect(resources.getContainerMessages()).andReturn(containerMessages).atLeastOnce();
+    }
+
+    protected final void train_getContainerResources(ComponentResources resources,
+                                                     ComponentResources containerResources)
+    {
+        expect(resources.getContainerResources()).andReturn(containerResources).atLeastOnce();
+    }
+
+    protected final void train_getDateHeader(Request request, String name, long value)
+    {
+        expect(request.getDateHeader(name)).andReturn(value).atLeastOnce();
+    }
+
+    protected final <T extends Annotation> void train_getFieldAnnotation(ClassTransformation transformation,
+                                                                         String fieldName, Class<T> annotationClass,
+                                                                         T annotation)
+    {
+        expect(transformation.getFieldAnnotation(fieldName, annotationClass)).andReturn(annotation);
+    }
+
+    protected final void train_getFieldPersistenceStrategy(ComponentModel model, String fieldName, String fieldStrategy)
+    {
+        expect(model.getFieldPersistenceStrategy(fieldName)).andReturn(fieldStrategy).atLeastOnce();
+    }
+
+    protected final void train_getFieldType(ClassTransformation transformation, String fieldName, String type)
+    {
+        expect(transformation.getFieldType(fieldName)).andReturn(type).atLeastOnce();
+
+    }
+
+    protected final void train_getId(ComponentResources resources, String id)
+    {
+        expect(resources.getId()).andReturn(id).atLeastOnce();
+    }
+
+    protected final void train_getLabel(Field field, String label)
+    {
+        expect(field.getLabel()).andReturn(label).atLeastOnce();
+    }
+
+    protected final void train_getLocale(ComponentResourcesCommon resources, Locale locale)
+    {
+        expect(resources.getLocale()).andReturn(locale).atLeastOnce();
+    }
+
+    protected final void train_getLocale(Request request, Locale locale)
+    {
+        expect(request.getLocale()).andReturn(locale).atLeastOnce();
+    }
+
+    protected void train_getMessageKey(Validator validator, String messageKey)
+    {
+        expect(validator.getMessageKey()).andReturn(messageKey).atLeastOnce();
+    }
+
+    protected final void train_getMessages(ComponentResources resources, Messages messages)
+    {
+        expect(resources.getMessages()).andReturn(messages).atLeastOnce();
+    }
+
+    protected final void train_getMeta(ComponentModel model, String key, String value)
+    {
+        expect(model.getMeta(key)).andReturn(value).atLeastOnce();
+    }
+
+    protected final <T extends Annotation> void train_getMethodAnnotation(ClassTransformation ct,
+                                                                          TransformMethodSignature signature,
+                                                                          Class<T> annotationClass, T annotation)
+    {
+        expect(ct.getMethodAnnotation(signature, annotationClass)).andReturn(annotation)
+                .atLeastOnce();
+    }
+
+    protected final void train_getMethodIdentifier(ClassTransformation transformation,
+                                                   TransformMethodSignature signature, String id)
+    {
+        expect(transformation.getMethodIdentifier(signature)).andReturn(id);
+    }
+
+    protected final void train_getOutputStream(HttpServletResponse response, ServletOutputStream stream)
+    {
+        try
+        {
+            expect(response.getOutputStream()).andReturn(stream);
+        }
+        catch (IOException e)
+        {
+            fail(e.getMessage(), e);
+        }
+    }
+
+    protected final void train_getPage(ComponentResources resources, Component page)
+    {
+        expect(resources.getPage()).andReturn(page).atLeastOnce();
+    }
+
+    protected final void train_getParameterModel(ComponentModel model, String parameterName,
+                                                 ParameterModel parameterModel)
+    {
+        expect(model.getParameterModel(parameterName)).andReturn(parameterModel);
+    }
+
+    protected final void train_getParameterNames(ComponentModel model, String... names)
+    {
+        expect(model.getParameterNames()).andReturn(Arrays.asList(names));
+    }
+
+    protected final void train_getParentModel(ComponentModel model, ComponentModel parentModel)
+    {
+        expect(model.getParentModel()).andReturn(parentModel).atLeastOnce();
+    }
+
+    protected final void train_getPath(Request request, String path)
+    {
+        expect(request.getPath()).andReturn(path).atLeastOnce();
+    }
+
+    protected final void train_getPersistentFieldNames(ComponentModel model, String... names)
+    {
+        expect(model.getPersistentFieldNames()).andReturn(Arrays.asList(names)).atLeastOnce();
+    }
+
+    protected final void train_getResourcesFieldName(ClassTransformation transformation, String name)
+    {
+        expect(transformation.getResourcesFieldName()).andReturn(name).atLeastOnce();
+    }
+
+    protected final void train_getRootResource(AssetFactory factory, Resource rootResource)
+    {
+        expect(factory.getRootResource()).andReturn(rootResource);
+    }
+
+    protected final void train_getSession(HttpServletRequest request, boolean create, HttpSession session)
+    {
+        expect(request.getSession(create)).andReturn(session);
+    }
+
+    protected void train_getSession(Request request, boolean create, Session session)
+    {
+        expect(request.getSession(create)).andReturn(session);
+    }
+
+    protected final void train_getSupportsInformalParameters(ComponentModel model, boolean supports)
+    {
+        expect(model.getSupportsInformalParameters()).andReturn(supports).atLeastOnce();
+    }
+
+    protected final void train_getValidationMessages(ValidationMessagesSource messagesSource, Locale locale,
+                                                     Messages messages)
+    {
+        expect(messagesSource.getValidationMessages(locale)).andReturn(messages).atLeastOnce();
+    }
+
+    protected final void train_getValueType(Validator validator, Class valueType)
+    {
+        expect(validator.getValueType()).andReturn(valueType).atLeastOnce();
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final void train_handleResult(ComponentEventCallback handler, Object result,
+                                            boolean abort)
+    {
+        expect(handler.handleResult(result)).andReturn(abort);
+    }
+
+    protected final void train_inError(ValidationTracker tracker, Field field, boolean inError)
+    {
+        expect(tracker.inError(field)).andReturn(inError);
+    }
+
+    protected final void train_isRequired(Validator validator, boolean isRequired)
+    {
+        expect(validator.isRequired()).andReturn(isRequired).atLeastOnce();
+    }
+
+    protected final void train_isInvariant(Binding binding, boolean isInvariant)
+    {
+        expect(binding.isInvariant()).andReturn(isInvariant);
+    }
+
+    protected final void train_isRequired(ParameterModel model, boolean isRequired)
+    {
+        expect(model.isRequired()).andReturn(isRequired);
+    }
+
+    protected final void train_isRootClass(MutableComponentModel model, boolean isRootClass)
+    {
+        expect(model.isRootClass()).andReturn(isRootClass);
+    }
+
+    protected final void train_name(Parameter parameter, String name)
+    {
+        expect(parameter.name()).andReturn(name).atLeastOnce();
+    }
+
+    protected final void train_newBinding(BindingFactory factory, String description, ComponentResources container,
+                                          ComponentResources component, String expression, Location l, Binding binding)
+    {
+        expect(factory.newBinding(description, container, component, expression, l)).andReturn(binding);
+    }
+
+    protected void train_newBinding(BindingSource bindingSource, String description,
+                                    ComponentResources componentResources, String defaultBindingPrefix,
+                                    String expression, Binding binding)
+    {
+        expect(bindingSource.newBinding(description, componentResources, defaultBindingPrefix, expression)).andReturn(
+                binding);
+    }
+
+    protected final void train_newMemberName(ClassTransformation transformation, String suggested, String name)
+    {
+        expect(transformation.newMemberName(suggested)).andReturn(name);
+    }
+
+    protected final void train_newMemberName(ClassTransformation transformation, String prefix, String baseName,
+                                             String name)
+    {
+        expect(transformation.newMemberName(prefix, baseName)).andReturn(name);
+    }
+
+    protected final <T> void train_peek(Environment env, Class<T> type, T value)
+    {
+        expect(env.peek(type)).andReturn(value);
+    }
+
+    protected final <T> void train_peekRequired(Environment env, Class<T> type, T value)
+    {
+        expect(env.peekRequired(type)).andReturn(value);
+    }
+
+    protected final void train_provideInjection(InjectionProvider provider, String fieldName, Class fieldType,
+                                                ObjectLocator locator, ClassTransformation transformation,
+                                                MutableComponentModel model, boolean result)
+    {
+        expect(provider.provideInjection(fieldName, fieldType, locator, transformation, model))
+                .andReturn(result);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final void train_renderInformalParameters(ComponentResources resources, final MarkupWriter writer,
+                                                        final Object... informals)
+    {
+        resources.renderInformalParameters(writer);
+        IAnswer answer = new IAnswer()
+        {
+            public Object answer() throws Throwable
+            {
+                writer.attributes(informals);
+
+                return null;
+            }
+        };
+
+        getMocksControl().andAnswer(answer);
+    }
+
+    protected final void train_requiresDigest(ResourceDigestGenerator generator, String path, boolean requiresDigest)
+    {
+        expect(generator.requiresDigest(path)).andReturn(requiresDigest);
+    }
+
+    protected final void train_service(RequestHandler handler, Request request, Response response, boolean result)
+            throws IOException
+    {
+        expect(handler.service(request, response)).andReturn(result);
+    }
+
+    protected final void train_setContentLength(HttpServletResponse response, int length)
+    {
+        response.setContentLength(length);
+    }
+
+    protected final void train_setContentType(HttpServletResponse response, String contentType)
+    {
+        response.setContentType(contentType);
+    }
+
+    protected final void train_setDateHeader(HttpServletResponse response, String headerName, long date)
+    {
+        response.setDateHeader(headerName, date);
+    }
+
+    protected final void train_toClass(ClassTransformation transformation, String type, Class classForType)
+    {
+        expect(transformation.toClass(type)).andReturn(classForType);
+    }
+
+    protected final void train_toClientURL(Asset asset, String URL)
+    {
+        expect(asset.toClientURL()).andReturn(URL).atLeastOnce();
+    }
+
+    protected final void train_toClientURL(ClasspathAssetAliasManager manager, String resourcePath, String clientURL)
+    {
+        expect(manager.toClientURL(resourcePath)).andReturn(clientURL);
+    }
+
+    protected final void train_toRedirectURI(Link link, String URI)
+    {
+        expect(link.toRedirectURI()).andReturn(URI).atLeastOnce();
+    }
+
+    protected final void train_toResourcePath(ClasspathAssetAliasManager manager, String clientURL, String resourcePath)
+    {
+        expect(manager.toResourcePath(clientURL)).andReturn(resourcePath).atLeastOnce();
+    }
+
+    protected final void train_value(Id annotation, String value)
+    {
+        expect(annotation.value()).andReturn(value).atLeastOnce();
+    }
+
+    protected final void train_value(Path annotation, String value)
+    {
+        expect(annotation.value()).andReturn(value).atLeastOnce();
+    }
+
+    protected final void train_create(BeanModelSource source, Class beanClass, boolean filterReadOnly,
+                                      ComponentResources containerResources, BeanModel model)
+    {
+        expect(source.create(beanClass, filterReadOnly, containerResources)).andReturn(model);
+    }
+
+    protected final void train_getBoundType(ComponentResources resources, String parameterName, Class type)
+    {
+        expect(resources.getBoundType(parameterName)).andReturn(type);
+    }
+
+    protected final BeanModel mockBeanModel()
+    {
+        return newMock(BeanModel.class);
+    }
+
+    protected final BeanModelSource mockBeanModelSource()
+    {
+        return newMock(BeanModelSource.class);
+    }
+
+    public final void train_getLocation(Locatable locatable, Location location)
+    {
+        expect(locatable.getLocation()).andReturn(location).atLeastOnce();
+    }
+
+    protected final void train_getParameter(Request request, String elementName, String value)
+    {
+        expect(request.getParameter(elementName)).andReturn(value).atLeastOnce();
+    }
+
+    protected final void train_getPageName(ComponentResourcesCommon resources, String pageName)
+    {
+        expect(resources.getPageName()).andReturn(pageName).atLeastOnce();
+    }
+
+    protected final FormSupport mockFormSupport()
+    {
+        return newMock(FormSupport.class);
+    }
+
+    /**
+     * Provides access to component messages, suitable for testing. Reads the associated .properties file for the class
+     * (NOT any localization of it). Only the messages directly in the .properties file is available.
+     *
+     * @param componentClass component class whose messages are needed *
+     * @return the Messages instance
+     */
+    protected final Messages messagesFor(Class componentClass) throws IOException
+    {
+        String file = componentClass.getSimpleName() + ".properties";
+
+        Properties properties = new Properties();
+
+        InputStream is = null;
+
+        try
+        {
+            is = componentClass.getResourceAsStream(file);
+
+            if (is == null) throw new RuntimeException(
+                    String.format("Class %s does not have a message catalog.", componentClass.getName()));
+
+            properties.load(is);
+        }
+        finally
+        {
+            InternalUtils.close(is);
+        }
+
+        Map<String, String> map = CollectionFactory.newCaseInsensitiveMap();
+
+        for (Object key : properties.keySet())
+        {
+
+            String skey = (String) key;
+
+            map.put(skey, properties.getProperty(skey));
+        }
+
+        return new MapMessages(Locale.ENGLISH, map);
+    }
+
+    protected final FieldValidationSupport mockFieldValidationSupport()
+    {
+        return newMock(FieldValidationSupport.class);
+    }
+
+    protected final RenderSupport mockRenderSupport()
+    {
+        return newMock(RenderSupport.class);
+    }
+
+    protected final void train_getInheritInformalParameters(EmbeddedComponentModel model, boolean inherits)
+    {
+        expect(model.getInheritInformalParameters()).andReturn(inherits).atLeastOnce();
+    }
+
+    protected final ApplicationStateManager mockApplicationStateManager()
+    {
+        return newMock(ApplicationStateManager.class);
+    }
+
+    protected final <T> void train_get(ApplicationStateManager manager, Class<T> asoClass, T aso)
+    {
+        expect(manager.get(asoClass)).andReturn(aso);
+    }
+
+    protected final void train_getInput(ValidationTracker tracker, Field field, String input)
+    {
+        expect(tracker.getInput(field)).andReturn(input);
+    }
+
+    protected final void train_isXHR(Request request, boolean isXHR)
+    {
+        expect(request.isXHR()).andReturn(isXHR).atLeastOnce();
+    }
+
+    protected void train_getPathInfo(HttpServletRequest request, String pathInfo)
+    {
+        expect(request.getPathInfo()).andReturn(pathInfo).atLeastOnce();
+    }
+
+    protected final void train_service(HttpServletRequestHandler handler, HttpServletRequest request,
+                                       HttpServletResponse response, boolean result) throws IOException
+    {
+        expect(handler.service(request, response)).andReturn(result);
+    }
+
+    protected final void train_getServletPath(HttpServletRequest request, String path)
+    {
+        expect(request.getServletPath()).andReturn(path).atLeastOnce();
+    }
+
+    protected final HttpServletRequestHandler mockHttpServletRequestHandler()
+    {
+        return newMock(HttpServletRequestHandler.class);
+    }
+
+    protected final NullFieldStrategy mockNullFieldStrategy()
+    {
+        return newMock(NullFieldStrategy.class);
+    }
+
+    protected final ValueEncoderSource mockValueEncoderSource()
+    {
+        return newMock(ValueEncoderSource.class);
+    }
+
+    protected final ValueEncoder mockValueEncoder()
+    {
+        return newMock(ValueEncoder.class);
+    }
+
+    protected final void train_toClient(ValueEncoder valueEncoder, Object value, String encoded)
+    {
+        expect(valueEncoder.toClient(value)).andReturn(encoded);
+    }
+
+    protected final void train_getValueEncoder(ValueEncoderSource source, Class type, ValueEncoder valueEncoder)
+    {
+        expect(source.getValueEncoder(type)).andReturn(valueEncoder).atLeastOnce();
+    }
+
+    protected final void train_toValue(ValueEncoder valueEncoder, String clientValue, Object value)
+    {
+        expect(valueEncoder.toValue(clientValue)).andReturn(value);
+    }
+
+    protected <T> void train_findMeta(MetaDataLocator locator, String key,
+                                      ComponentResources resources, Class<T> expectedType, T value)
+    {
+        expect(locator.findMeta(key, resources, expectedType)).andReturn(value).atLeastOnce();
+    }
+
+    protected MetaDataLocator mockMetaDataLocator()
+    {
+        return newMock(MetaDataLocator.class);
+    }
+
+    protected final void train_isSecure(Request request, boolean isSecure)
+    {
+        expect(request.isSecure()).andReturn(isSecure).atLeastOnce();
+    }
+
+    protected final void train_getBaseURL(BaseURLSource baseURLSource, boolean secure, String baseURL)
+    {
+        expect(baseURLSource.getBaseURL(secure)).andReturn(baseURL);
+    }
+
+    protected final BaseURLSource mockBaseURLSource()
+    {
+        return newMock(BaseURLSource.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/AbstractSelectModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/AbstractSelectModel.java
new file mode 100644
index 0000000..151236b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/AbstractSelectModel.java
@@ -0,0 +1,58 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.OptionGroupModel;
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.SelectModelVisitor;
+
+import java.util.List;
+
+/**
+ * Base class for {@link SelectModel} implementations, whose primary job is to provide the {@link
+ * #visit(SelectModelVisitor)} method.
+ */
+public abstract class AbstractSelectModel implements SelectModel
+{
+    public final void visit(SelectModelVisitor visitor)
+    {
+        List<OptionGroupModel> groups = getOptionGroups();
+
+        if (groups != null)
+        {
+            for (OptionGroupModel groupModel : groups)
+            {
+                visitor.beginOptionGroup(groupModel);
+
+                visitOptions(groupModel.getOptions(), visitor);
+
+                visitor.endOptionGroup(groupModel);
+            }
+        }
+
+        visitOptions(getOptions(), visitor);
+    }
+
+    private void visitOptions(List<OptionModel> options, SelectModelVisitor vistor)
+    {
+        if (options != null)
+        {
+            for (OptionModel optionModel : options)
+                vistor.option(optionModel);
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoder.java
new file mode 100644
index 0000000..c4fb9fd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoder.java
@@ -0,0 +1,214 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.PrimaryKeyEncoder;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A default, extensible version of {@link PrimaryKeyEncoder} that is based on loading known values into an internal
+ * map. When there's a reasonable number (hundreds, perhaps thousands) of items to choose from, and those items are fast
+ * and cheap to read and instantiate, this implementation is a good bet. For very large result sets, you'll need to
+ * create your own implementation of {@link PrimaryKeyEncoder}.
+ *
+ * @param <K> the key type (which must be serializable)
+ * @param <V> the value type
+ */
+public class DefaultPrimaryKeyEncoder<K extends Serializable, V> implements PrimaryKeyEncoder<K, V>
+{
+    private final Map<K, V> keyToValue = new LinkedHashMap<K, V>();
+
+    private final Map<V, K> valueToKey = CollectionFactory.newMap();
+
+    private Set<K> deletedKeys;
+
+    private K currentKey;
+
+    /**
+     * Adds a new key/value pair to the encoder.
+     */
+    public final void add(K key, V value)
+    {
+        Defense.notNull(key, "key");
+        Defense.notNull(value, "value");
+
+        V existing = keyToValue.get(key);
+        if (existing != null) throw new IllegalArgumentException(PublicUtilMessages.duplicateKey(key, value, existing));
+
+        keyToValue.put(key, value);
+
+        // TODO: Ensure that the value is unique?
+
+        valueToKey.put(value, key);
+    }
+
+    /**
+     * Returns the values previously {@link #add(Serializable, Object) added to the encoder}, <em>in the order in which
+     * they were added</em>. Values that are deleted are not returned.
+     *
+     * @return ordered list of values
+     */
+    public final List<V> getValues()
+    {
+        return valuesNotInKeySet(deletedKeys);
+    }
+
+    /**
+     * Returns a list of all the values <em>except</em> those values whose keys are in the provided set. The set may be
+     * null, in which case all values are returned.
+     *
+     * @param keySet set of keys identifying values to exclude, or null to exclude no values
+     * @return values (not in the set) in order origionally added
+     */
+    protected final List<V> valuesNotInKeySet(Set<K> keySet)
+    {
+        if (keySet == null || keySet.isEmpty()) return getAllValues();
+
+        List<V> result = CollectionFactory.newList();
+
+        for (Map.Entry<K, V> entry : keyToValue.entrySet())
+        {
+
+            if (keySet.contains(entry.getKey())) continue;
+
+            result.add(entry.getValue());
+        }
+
+        return result;
+    }
+
+    public final List<V> getAllValues()
+    {
+        List<V> result = CollectionFactory.newList();
+
+        for (Map.Entry<K, V> entry : keyToValue.entrySet())
+        {
+            result.add(entry.getValue());
+        }
+
+        return result;
+    }
+
+    /**
+     * For a previously {@link #add(Serializable, Object) added key/value pair}, returns the key corresponding to the
+     * given value.
+     */
+    public final K toKey(V value)
+    {
+        Defense.notNull(value, "value");
+
+        currentKey = valueToKey.get(value);
+
+        if (currentKey == null) throw new IllegalArgumentException(PublicUtilMessages.missingValue(value, valueToKey
+                .keySet()));
+
+        return currentKey;
+    }
+
+    public final V toValue(K key)
+    {
+        V result = keyToValue.get(key);
+
+        if (result == null)
+        {
+            result = provideMissingObject(key);
+
+            currentKey = key;
+        }
+        else
+        {
+            currentKey = key;
+        }
+
+        return result;
+    }
+
+    /**
+     * Invoked by {@link #toValue(Serializable)} whenever a key can not be converted to a value using the internal
+     * cache. This is an opportunity to record the fact that an error occured (they key was not valuable, possibly
+     * because it points to a deleted entity object) and provide a temporary object. This method may return null, but in
+     * a typical application, that will likely case NullPointerExceptions further down the processing chain.
+     * <p/>
+     * This implementation returns null, and is intended to be overriden in subclasses.
+     *
+     * @param key key for which a value is required
+     * @return a substitute value, or null
+     */
+    protected V provideMissingObject(K key)
+    {
+        return null;
+    }
+
+    public final boolean isDeleted()
+    {
+        return inKeySet(deletedKeys);
+    }
+
+    public final void setDeleted(boolean value)
+    {
+        deletedKeys = modifyKeySet(deletedKeys, value);
+    }
+
+    /**
+     * Returns true if the current key is in the provided set.
+     *
+     * @param keySet the set of keys to check, or null
+     * @return true if the key is in the set, false if it is missing (or if keySet is null)
+     */
+    protected final boolean inKeySet(Set<K> keySet)
+    {
+        return keySet != null && keySet.contains(currentKey);
+    }
+
+    /**
+     * Modifies a keySet to add or remove the current key. If necessary, a new Set is created.
+     * <p/>
+     * Useage: <code> private Set<K> myFlagKeys;
+     * <p/>
+     * public boolean void setMyFlag(boolean value) { myFlagKeys = modifySet(myFlagKeys, value); } </code>
+     *
+     * @param keySet the set of keys, or null
+     * @param value  true to add the current key, false to remove
+     * @return the provided key set, or a new one
+     */
+    protected final Set<K> modifyKeySet(Set<K> keySet, boolean value)
+    {
+        if (keySet == null)
+        {
+            if (!value) return null;
+
+            keySet = CollectionFactory.newSet();
+        }
+
+        if (value) keySet.add(currentKey);
+        else keySet.remove(currentKey);
+
+        return keySet;
+    }
+
+    /**
+     * Does nothing. Subclasses may override as necessary.
+     */
+    public void prepareForKeys(List<K> keys)
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumSelectModel.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumSelectModel.java
new file mode 100644
index 0000000..3ca3ae8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumSelectModel.java
@@ -0,0 +1,76 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.OptionGroupModel;
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.internal.OptionModelImpl;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * A basic select model for a particular Enum type. The labels for each Enum are drawn from the Enum instance name and
+ * the provides message catalog: <ul> <li>As key <em>ClassName</em>.<em>name</em> if present. The class name excludes
+ * the package portion. Ex: "ElementType.LOCAL_VARIABLE" <li>As key <em>name</em> if present, i.e., "LOCAL_VARIABLE".
+ * <li>As a user-presentable version of the name, i.e., "Local Variable". </ul>
+ */
+public final class EnumSelectModel extends AbstractSelectModel implements Serializable
+{
+    private static final long serialVersionUID = -3590412082766899684L;
+
+    private final List<OptionModel> options = CollectionFactory.newList();
+
+    public <T extends Enum> EnumSelectModel(Class<T> enumClass, Messages messages)
+    {
+        this(enumClass, messages, enumClass.getEnumConstants());
+    }
+
+    public <T extends Enum> EnumSelectModel(Class<T> enumClass, Messages messages, T[] values)
+    {
+        notNull(enumClass, "enumClass");
+        notNull(messages, "messages");
+
+        String prefix = enumClass.getSimpleName();
+
+        for (T value : values)
+        {
+            String label = TapestryInternalUtils.getLabelForEnum(messages, prefix, value);
+
+            options.add(new OptionModelImpl(label, value));
+        }
+    }
+
+    /**
+     * Returns null.
+     */
+    public List<OptionGroupModel> getOptionGroups()
+    {
+        return null;
+    }
+
+    /**
+     * Returns the option groupos created in the constructor.
+     */
+    public List<OptionModel> getOptions()
+    {
+        return options;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java
new file mode 100644
index 0000000..c2f44a0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/EnumValueEncoder.java
@@ -0,0 +1,50 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.ValueEncoder;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+/**
+ * A value encoder that can be used for aribrary Enum types. The enum name is stored as the client side value.
+ */
+public class EnumValueEncoder<E extends Enum<E>> implements ValueEncoder<E>
+{
+    private final Class<E> enumType;
+
+    public EnumValueEncoder(final Class<E> enumType)
+    {
+        notNull(enumType, "enumType");
+
+        this.enumType = enumType;
+    }
+
+    public String toClient(E value)
+    {
+        if (value == null) return null;
+
+        return value.name();
+    }
+
+    @SuppressWarnings("unchecked")
+    public E toValue(String clientValue)
+    {
+        if (InternalUtils.isBlank(clientValue)) return null;
+
+        return Enum.valueOf(enumType, clientValue);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/PublicUtilMessages.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/PublicUtilMessages.java
new file mode 100644
index 0000000..0af3806
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/PublicUtilMessages.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+import java.util.Collection;
+
+final class PublicUtilMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(PublicUtilMessages.class);
+
+    static String duplicateKey(Object key, Object newValue, Object existingValue)
+    {
+        return MESSAGES.format("duplicate-key", key, newValue, existingValue);
+    }
+
+    static <V> String missingValue(V value, Collection<V> values)
+    {
+        return MESSAGES.format("missing-value", value, InternalUtils.joinSorted(values));
+    }
+
+    static String missingEnumValue(String value, Class enumClass, Collection<String> values)
+    {
+        return MESSAGES.format("missing-enum-value", value, enumClass.getName(), InternalUtils.joinSorted(values));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java
new file mode 100644
index 0000000..af8187c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java
@@ -0,0 +1,71 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.Coercion;
+
+import java.util.Map;
+
+/**
+ * A {@link org.apache.tapestry.ioc.services.Coercion} for converting strings into an instance of a particular
+ * enumerated type. The {@link Enum#name() name} is used as the key to identify the enum instance, in a case-insensitive
+ * fashion.
+ *
+ * @param <T> the type of enumeration
+ */
+public final class StringToEnumCoercion<T extends Enum> implements Coercion<String, T>
+{
+    private final Class<T> enumClass;
+
+    private final Map<String, T> stringToEnum = CollectionFactory.newCaseInsensitiveMap();
+
+    public StringToEnumCoercion(Class<T> enumClass)
+    {
+        this(enumClass, enumClass.getEnumConstants());
+    }
+
+    public StringToEnumCoercion(Class<T> enumClass, T... values)
+    {
+        this.enumClass = enumClass;
+
+        for (T value : values)
+            stringToEnum.put(value.name(), value);
+    }
+
+    public T coerce(String input)
+    {
+        if (InternalUtils.isBlank(input))
+            return null;
+
+        T result = stringToEnum.get(input);
+
+        if (result == null)
+            throw new RuntimeException(PublicUtilMessages.missingEnumValue(
+                    input,
+                    enumClass,
+                    stringToEnum.keySet()));
+
+        return result;
+    }
+
+
+    public static <T extends Enum> StringToEnumCoercion<T> create(Class<T> enumClass)
+    {
+        return new StringToEnumCoercion<T>(enumClass);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/TextStreamResponse.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/TextStreamResponse.java
new file mode 100644
index 0000000..bb688a1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/util/TextStreamResponse.java
@@ -0,0 +1,54 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.StreamResponse;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.services.Response;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class TextStreamResponse implements StreamResponse
+{
+    private final String contentType, text;
+
+    public TextStreamResponse(String contentType, String text)
+    {
+        notBlank(contentType, "contentType");
+        notNull(text, "text");
+
+        this.contentType = contentType;
+        this.text = text;
+    }
+
+    public String getContentType()
+    {
+        return contentType;
+    }
+
+    public InputStream getStream() throws IOException
+    {
+        return new ByteArrayInputStream(text.getBytes());
+    }
+
+    public void prepareResponse(Response response)
+    {
+        // No-op by default.
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/AbstractValidator.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/AbstractValidator.java
new file mode 100644
index 0000000..c431024
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/AbstractValidator.java
@@ -0,0 +1,56 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Validator;
+
+/**
+ * Base class for constructing a {@link org.apache.tapestry.Validator}.
+ */
+public abstract class AbstractValidator<C, T> implements Validator<C, T>
+{
+    private final Class<C> constraintType;
+
+    private final Class<T> valueType;
+
+    private final String messageKey;
+
+    protected AbstractValidator(Class<C> constraintType, Class<T> valueType, String messageKey)
+    {
+        this.constraintType = constraintType;
+        this.valueType = valueType;
+        this.messageKey = messageKey;
+    }
+
+    public final Class<C> getConstraintType()
+    {
+        return constraintType;
+    }
+
+    public final Class<T> getValueType()
+    {
+        return valueType;
+    }
+
+    public String getMessageKey()
+    {
+        return messageKey;
+    }
+
+    public boolean isRequired()
+    {
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Max.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Max.java
new file mode 100644
index 0000000..93ca9d2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Max.java
@@ -0,0 +1,51 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * Enforces a maximum integer value.
+ */
+public class Max extends AbstractValidator<Long, Number>
+{
+    public Max()
+    {
+        super(Long.class, Number.class, "max-integer");
+    }
+
+    public void validate(Field field, Long constraintValue, MessageFormatter formatter, Number value)
+            throws ValidationException
+    {
+        if (value.longValue() > constraintValue)
+            throw new ValidationException(buildMessage(formatter, field, constraintValue));
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field, Long constraintValue)
+    {
+        return formatter.format(constraintValue, field.getLabel());
+    }
+
+    public void render(Field field, Long constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        formSupport.addValidation(field, "max", buildMessage(formatter, field, constraintValue), constraintValue);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MaxLength.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MaxLength.java
new file mode 100644
index 0000000..6ce1db8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MaxLength.java
@@ -0,0 +1,50 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+public final class MaxLength extends AbstractValidator<Integer, String>
+{
+    public MaxLength()
+    {
+        super(Integer.class, String.class, "maximum-string-length");
+    }
+
+    public void validate(Field field, Integer constraintValue, MessageFormatter formatter, String value)
+            throws ValidationException
+    {
+        if (value.length() > constraintValue)
+            throw new ValidationException(buildMessage(formatter, field, constraintValue));
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field, Integer constraintValue)
+    {
+        return formatter.format(constraintValue, field.getLabel());
+    }
+
+    public void render(Field field, Integer constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        // TODO: write a maxlength attribute into the element?  But that's only for
+        // textfield, not for textarea.
+
+        formSupport.addValidation(field, "maxlength", buildMessage(formatter, field, constraintValue), constraintValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Min.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Min.java
new file mode 100644
index 0000000..2a429be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Min.java
@@ -0,0 +1,48 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+/* A vaidator that enforces that a number is greater than some minimum integer value. */
+public class Min extends AbstractValidator<Long, Number>
+{
+    public Min()
+    {
+        super(Long.class, Number.class, "min-integer");
+    }
+
+    public void validate(Field field, Long constraintValue, MessageFormatter formatter, Number value)
+            throws ValidationException
+    {
+        if (value.longValue() < constraintValue)
+            throw new ValidationException(buildMessage(formatter, field, constraintValue));
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field, Long constraintValue)
+    {
+        return formatter.format(constraintValue, field.getLabel());
+    }
+
+    public void render(Field field, Long constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        formSupport.addValidation(field, "min", buildMessage(formatter, field, constraintValue), constraintValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MinLength.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MinLength.java
new file mode 100644
index 0000000..9013709
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/MinLength.java
@@ -0,0 +1,50 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * Validates that a string value has a minimum length.
+ */
+public final class MinLength extends AbstractValidator<Integer, String>
+{
+    public MinLength()
+    {
+        super(Integer.class, String.class, "minimum-string-length");
+    }
+
+    public void validate(Field field, Integer constraintValue, MessageFormatter formatter, String value)
+            throws ValidationException
+    {
+        if (value.length() < constraintValue)
+            throw new ValidationException(buildMessage(formatter, field, constraintValue));
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field, Integer constraintValue)
+    {
+        return formatter.format(constraintValue, field.getLabel());
+    }
+
+    public void render(Field field, Integer constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        formSupport.addValidation(field, "minlength", buildMessage(formatter, field, constraintValue), constraintValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Regexp.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Regexp.java
new file mode 100644
index 0000000..3444220
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Regexp.java
@@ -0,0 +1,53 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.services.FormSupport;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Regexp extends AbstractValidator<Pattern, String>
+{
+    public Regexp()
+    {
+        super(Pattern.class, String.class, "regexp");
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field, Pattern constraintValue)
+    {
+        return formatter.format(constraintValue.toString(), field.getLabel());
+    }
+
+    public void render(Field field, Pattern constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        formSupport.addValidation(field, "regexp", buildMessage(formatter, field, constraintValue),
+                                  constraintValue.pattern());
+    }
+
+    public void validate(Field field, Pattern constraintValue, MessageFormatter formatter, String value)
+            throws ValidationException
+    {
+        Matcher matcher = constraintValue.matcher(value);
+
+        if (!matcher.matches()) throw new ValidationException(buildMessage(formatter, field, constraintValue));
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Required.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Required.java
new file mode 100644
index 0000000..5d82050
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry/validator/Required.java
@@ -0,0 +1,59 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * A validator that enforces that the value is not null and not the empty string. This validator is not configurable.
+ */
+public final class Required extends AbstractValidator<Void, Object>
+{
+    public Required()
+    {
+        super(null, Object.class, "required");
+    }
+
+    public void validate(Field field, Void constraintValue, MessageFormatter formatter, Object value)
+            throws ValidationException
+    {
+        if (value == null || InternalUtils.isBlank(value.toString()))
+            throw new ValidationException(buildMessage(formatter, field));
+    }
+
+    private String buildMessage(MessageFormatter formatter, Field field)
+    {
+        return formatter.format(field.getLabel());
+    }
+
+    /**
+     * The exception to the rule.
+     */
+    public boolean isRequired()
+    {
+        return true;
+    }
+
+    public void render(Field field, Void constraintValue, MessageFormatter formatter, MarkupWriter writer,
+                       FormSupport formSupport)
+    {
+        formSupport.addValidation(field, "required", buildMessage(formatter, field), null);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java
new file mode 100644
index 0000000..1ee99bd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONArray.java
@@ -0,0 +1,433 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.json;
+
+/*
+ Copyright (c) 2002 JSON.org
+
+ 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 shall be used for Good, not Evil.
+
+ 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.
+ */
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+/**
+ * A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in square brackets with
+ * commas separating the values. The internal form is an object having <code>get</code> and <code>opt</code> methods for
+ * accessing the values by index, and <code>put</code> methods for adding or replacing values. The values can be any of
+ * these types: <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
+ * <code>String</code>, or the <code>JSONObject.NULL object</code>.
+ * <p/>
+ * The constructor can convert a JSON text into a Java object. The <code>toString</code> method converts to JSON text.
+ * <p/>
+ * A <code>get</code> method returns a value if one can be found, and throws an exception if one cannot be found. An
+ * <code>opt</code> method returns a default value instead of throwing an exception, and so is useful for obtaining
+ * optional values.
+ * <p/>
+ * The generic <code>get()</code> and <code>opt()</code> methods return an object which you can cast or query for type.
+ * There are also typed <code>get</code> and <code>opt</code> methods that do type checking and type coersion for you.
+ * <p/>
+ * The texts produced by the <code>toString</code> methods strictly conform to JSON syntax rules. The constructors are
+ * more forgiving in the texts they will accept: <ul> <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear
+ * just before the closing bracket.</li> <li>The <code>null</code> value will be inserted when there is
+ * <code>,</code>&nbsp;<small>(comma)</small> elision.</li> <li>Strings may be quoted with
+ * <code>'</code>&nbsp;<small>(single quote)</small>.</li> <li>Strings do not need to be quoted at all if they do not
+ * begin with a quote or single quote, and if they do not contain leading or trailing spaces, and if they do not contain
+ * any of these characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they are not
+ * the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li> <li>Values can be separated by
+ * <code>;</code> <small>(semicolon)</small> as well as by <code>,</code> <small>(comma)</small>.</li> <li>Numbers may
+ * have the <code>0-</code> <small>(octal)</small> or <code>0x-</code> <small>(hex)</small> prefix.</li> <li>Comments
+ * written in the slashshlash, slashstar, and hash conventions will be ignored.</li> </ul>
+ *
+ * @author JSON.org
+ * @version 2
+ */
+public final class JSONArray
+{
+
+    /**
+     * The arrayList where the JSONArray's properties are kept.
+     */
+    private final List<Object> list = CollectionFactory.newList();
+
+    /**
+     * Construct an empty JSONArray.
+     */
+    public JSONArray()
+    {
+    }
+
+    public JSONArray(String text)
+    {
+        JSONTokener tokener = new JSONTokener(text);
+
+        parse(tokener);
+    }
+
+    /**
+     * Construct a JSONArray from a JSONTokener.
+     *
+     * @param tokenizer A JSONTokener
+     * @throws RuntimeException If there is a syntax error.
+     */
+    JSONArray(JSONTokener tokenizer)
+    {
+        assert tokenizer != null;
+
+        parse(tokenizer);
+    }
+
+    private void parse(JSONTokener tokenizer)
+    {
+        if (tokenizer.nextClean() != '[')
+        {
+            throw tokenizer
+                    .syntaxError("A JSONArray text must start with '['");
+        }
+
+        if (tokenizer.nextClean() == ']')
+        {
+            return;
+        }
+
+        tokenizer.back();
+
+        while (true)
+        {
+            if (tokenizer.nextClean() == ',')
+            {
+                tokenizer.back();
+                list.add(null);
+            }
+            else
+            {
+                tokenizer.back();
+                list.add(tokenizer.nextValue());
+            }
+
+            switch (tokenizer.nextClean())
+            {
+                case ';':
+                case ',':
+                    if (tokenizer.nextClean() == ']')
+                    {
+                        return;
+                    }
+                    tokenizer.back();
+                    break;
+
+                case ']':
+                    return;
+
+                default:
+                    throw tokenizer.syntaxError("Expected a ',' or ']'");
+            }
+        }
+    }
+
+    /**
+     * Get the object value associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return An object value.
+     * @throws RuntimeException If there is no value for the index.
+     */
+    public Object get(int index)
+    {
+        return list.get(index);
+    }
+
+    /**
+     * Get the boolean value associated with an index. The string values "true" and "false" are converted to boolean.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return The truth.
+     * @throws RuntimeException If there is no value for the index or if the value is not convertable to boolean.
+     */
+    public boolean getBoolean(int index)
+    {
+        Object value = get(index);
+
+        if (value instanceof Boolean)
+        {
+            return (Boolean) value;
+        }
+
+        if (value instanceof String)
+        {
+            String asString = (String) value;
+
+            if (asString.equalsIgnoreCase("false")) return false;
+
+            if (asString.equalsIgnoreCase("true")) return true;
+        }
+
+        throw new RuntimeException("JSONArray[" + index + "] is not a Boolean.");
+    }
+
+    /**
+     * Get the double value associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return The value.
+     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number.
+     */
+    public double getDouble(int index)
+    {
+        Object value = get(index);
+
+        try
+        {
+            if (value instanceof Number) return ((Number) value).doubleValue();
+
+            return Double.valueOf((String) value);
+        }
+        catch (Exception e)
+        {
+            throw new IllegalArgumentException("JSONArray[" + index + "] is not a number.");
+        }
+    }
+
+    /**
+     * Get the int value associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return The value.
+     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number. if the
+     *                                  value cannot be converted to a number.
+     */
+    public int getInt(int index)
+    {
+        Object o = get(index);
+        return o instanceof Number ? ((Number) o).intValue() : (int) getDouble(index);
+    }
+
+    /**
+     * Get the JSONArray associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return A JSONArray value.
+     * @throws RuntimeException If there is no value for the index. or if the value is not a JSONArray
+     */
+    public JSONArray getJSONArray(int index)
+    {
+        Object o = get(index);
+        if (o instanceof JSONArray)
+        {
+            return (JSONArray) o;
+        }
+
+        throw new RuntimeException("JSONArray[" + index + "] is not a JSONArray.");
+    }
+
+    /**
+     * Get the JSONObject associated with an index.
+     *
+     * @param index subscript
+     * @return A JSONObject value.
+     * @throws RuntimeException If there is no value for the index or if the value is not a JSONObject
+     */
+    public JSONObject getJSONObject(int index)
+    {
+        Object o = get(index);
+        if (o instanceof JSONObject)
+        {
+            return (JSONObject) o;
+        }
+
+        throw new RuntimeException("JSONArray[" + index + "] is not a JSONObject.");
+    }
+
+    /**
+     * Get the long value associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return The value.
+     * @throws IllegalArgumentException If the key is not found or if the value cannot be converted to a number.
+     */
+    public long getLong(int index)
+    {
+        Object o = get(index);
+        return o instanceof Number ? ((Number) o).longValue() : (long) getDouble(index);
+    }
+
+    /**
+     * Get the string associated with an index.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return A string value.
+     * @throws RuntimeException If there is no value for the index.
+     */
+    public String getString(int index)
+    {
+        return get(index).toString();
+    }
+
+    /**
+     * Determine if the value is null.
+     *
+     * @param index The index must be between 0 and length() - 1.
+     * @return true if the value at the index is null, or if there is no value.
+     */
+    public boolean isNull(int index)
+    {
+        return get(index) == JSONObject.NULL;
+    }
+
+    /**
+     * Make a string from the contents of this JSONArray. The <code>separator</code> string is inserted between each
+     * element. Warning: This method assumes that the data structure is acyclical.
+     *
+     * @param separator A string that will be inserted between the elements.
+     * @return a string.
+     * @throws RuntimeException If the array contains an invalid number.
+     */
+    public String join(String separator)
+    {
+        int len = length();
+        StringBuilder buffer = new StringBuilder();
+
+        for (int i = 0; i < len; i += 1)
+        {
+            if (i > 0) buffer.append(separator);
+
+            buffer.append(JSONObject.valueToString(list.get(i)));
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Get the number of elements in the JSONArray, included nulls.
+     *
+     * @return The length (or size).
+     */
+    public int length()
+    {
+        return list.size();
+    }
+
+    /**
+     * Append an object value. This increases the array's length by one.
+     *
+     * @param value An object value. The value should be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or
+     *              String, or the JSONObject.NULL object.
+     * @return
+     */
+    public JSONArray put(Object value)
+    {
+        assert value != null;
+
+        JSONObject.testValidity(value);
+
+        list.add(value);
+
+        return this;
+    }
+
+    /**
+     * Put or replace an object value in the JSONArray. If the index is greater than the length of the JSONArray, then
+     * null elements will be added as necessary to pad it out.
+     *
+     * @param index The subscript.
+     * @param value The value to put into the array. The value should be a Boolean, Double, Integer, JSONArray,
+     *              JSONObject, Long, or String, or the JSONObject.NULL object.
+     * @return
+     * @throws RuntimeException If the index is negative or if the the value is an invalid number.
+     */
+    public JSONArray put(int index, Object value)
+    {
+        assert value != null;
+
+        if (index < 0)
+        {
+            throw new RuntimeException("JSONArray[" + index + "] not found.");
+        }
+
+        JSONObject.testValidity(value);
+
+        if (index < length())
+        {
+            list.set(index, value);
+        }
+        else
+        {
+            while (index != length()) list.add(JSONObject.NULL);
+
+            list.add(value);
+
+        }
+
+        return this;
+    }
+
+    /**
+     * Make a JSON text of this JSONArray. For compactness, no unnecessary whitespace is added. If it is not possible to
+     * produce a syntactically correct JSON text then null will be returned instead. This could occur if the array
+     * contains an invalid number.
+     * <p/>
+     * Warning: This method assumes that the data structure is acyclical.
+     *
+     * @return a printable, displayable, transmittable representation of the array.
+     */
+    @Override
+    public String toString()
+    {
+        try
+        {
+            return '[' + join(",") + ']';
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    Object[] toArray()
+    {
+        return list.toArray();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null) return false;
+
+        if (!(obj instanceof JSONArray)) return false;
+
+        JSONArray other = (JSONArray) obj;
+
+        return list.equals(other.list);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java
new file mode 100644
index 0000000..a3fcf6b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONObject.java
@@ -0,0 +1,854 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.json;
+
+/*
+ Copyright (c) 2002 JSON.org
+
+ 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 shall be used for Good, not Evil.
+
+ 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.
+ */
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A JSONObject is an unordered collection of name/value pairs. Its external form is a string wrapped in curly braces
+ * with colons between the names and values, and commas between the values and names. The internal form is an object
+ * having <code>get</code> and <code>opt</code> methods for accessing the values by name, and <code>put</code> methods
+ * for adding or replacing values by name. The values can be any of these types: <code>Boolean</code>,
+ * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>, <code>String</code>, or the
+ * <code>JSONObject.NULL</code> object. A JSONObject constructor can be used to convert an external form JSON text into
+ * an internal form whose values can be retrieved with the <code>get</code> and <code>opt</code> methods, or to convert
+ * values into a JSON text using the <code>put</code> and <code>toString</code> methods. A <code>get</code> method
+ * returns a value if one can be found, and throws an exception if one cannot be found. An <code>opt</code> method
+ * returns a default value instead of throwing an exception, and so is useful for obtaining optional values.
+ * <p/>
+ * The generic <code>get()</code> and <code>opt()</code> methods return an object, which you can cast or query for type.
+ * There are also typed <code>get</code> and <code>opt</code> methods that do type checking and type coersion for you.
+ * <p/>
+ * The <code>put</code> methods adds values to an object. For example,
+ * <p/>
+ * <pre>
+ * myString = new JSONObject().put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
+ * </pre>
+ * <p/>
+ * produces the string <code>{"JSON": "Hello, World"}</code>.
+ * <p/>
+ * The texts produced by the <code>toString</code> methods strictly conform to the JSON sysntax rules. The constructors
+ * are more forgiving in the texts they will accept: <ul> <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may
+ * appear just before the closing brace.</li> <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
+ * quote)</small>.</li> <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
+ * and if they do not contain leading or trailing spaces, and if they do not contain any of these characters: <code>{ }
+ * [ ] / \ : , = ; #</code> and if they do not look like numbers and if they are not the reserved words
+ * <code>true</code>, <code>false</code>, or <code>null</code>.</li> <li>Keys can be followed by <code>=</code> or
+ * <code>=></code> as well as by <code>:</code>.</li> <li>Values can be followed by <code>;</code>
+ * <small>(semicolon)</small> as well as by <code>,</code> <small>(comma)</small>.</li> <li>Numbers may have the
+ * <code>0-</code> <small>(octal)</small> or <code>0x-</code> <small>(hex)</small> prefix.</li> <li>Comments written in
+ * the slashshlash, slashstar, and hash conventions will be ignored.</li> </ul> <hr/>
+ * <p/>
+ * This class, and the other related classes, have been heavily modified from the original source, to fit Tapestry
+ * standards and to make use of JDK 1.5 features such as generics. Further, since the interest of Tapestry is primarily
+ * constructing JSON (and not parsing it), many of the non-essential methods have been removed (since the original code
+ * came with no tests).
+ *
+ * @author JSON.org
+ * @version 2
+ */
+@SuppressWarnings({ "CloneDoesntCallSuperClone" })
+public final class JSONObject
+{
+
+    /**
+     * JSONObject.NULL is equivalent to the value that JavaScript calls null, whilst Java's null is equivalent to the
+     * value that JavaScript calls undefined.
+     */
+    private static final class Null
+    {
+
+        /**
+         * There is only intended to be a single instance of the NULL object, so the clone method returns itself.
+         *
+         * @return NULL.
+         */
+        @Override
+        protected final Object clone()
+        {
+            return this;
+        }
+
+        /**
+         * A Null object is equal to the null value and to itself.
+         *
+         * @param object An object to test for nullness.
+         * @return true if the object parameter is the JSONObject.NULL object or null.
+         */
+        @Override
+        public boolean equals(Object object)
+        {
+            return object == null || object == this;
+        }
+
+        /**
+         * Get the "null" string value.
+         *
+         * @return The string "null".
+         */
+        @Override
+        public String toString()
+        {
+            return "null";
+        }
+    }
+
+    /**
+     * The map where the JSONObject's properties are kept.
+     */
+    private final Map<String, Object> properties = CollectionFactory.newMap();
+
+    /**
+     * It is sometimes more convenient and less ambiguous to have a <code>NULL</code> object than to use Java's
+     * <code>null</code> value. <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
+     * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
+     */
+    public static final Object NULL = new Null();
+
+    /**
+     * Construct an empty JSONObject.
+     */
+    public JSONObject()
+    {
+    }
+
+    /**
+     * Construct a JSONObject from a subset of another JSONObject. An array of strings is used to identify the keys that
+     * should be copied. Missing keys are ignored.
+     *
+     * @param source        A JSONObject.
+     * @param propertyNames The strings to copy.
+     * @throws RuntimeException If a value is a non-finite number.
+     */
+    public JSONObject(JSONObject source, String... propertyNames)
+    {
+        for (String name : propertyNames)
+        {
+            Object value = source.opt(name);
+
+            if (value != null) put(name, value);
+        }
+    }
+
+    /**
+     * Construct a JSONObject from a JSONTokener.
+     *
+     * @param x A JSONTokener object containing the source string. @ If there is a syntax error in the source string.
+     */
+    JSONObject(JSONTokener x)
+    {
+        String key;
+
+        if (x.nextClean() != '{')
+        {
+            throw x.syntaxError("A JSONObject text must begin with '{'");
+        }
+
+        while (true)
+        {
+            char c = x.nextClean();
+            switch (c)
+            {
+                case 0:
+                    throw x.syntaxError("A JSONObject text must end with '}'");
+                case '}':
+                    return;
+                default:
+                    x.back();
+                    key = x.nextValue().toString();
+            }
+
+            /*
+             * The key is followed by ':'. We will also tolerate '=' or '=>'.
+             */
+
+            c = x.nextClean();
+            if (c == '=')
+            {
+                if (x.next() != '>')
+                {
+                    x.back();
+                }
+            }
+            else if (c != ':')
+            {
+                throw x.syntaxError("Expected a ':' after a key");
+            }
+            put(key, x.nextValue());
+
+            /*
+             * Pairs are separated by ','. We will also tolerate ';'.
+             */
+
+            switch (x.nextClean())
+            {
+                case ';':
+                case ',':
+                    if (x.nextClean() == '}')
+                    {
+                        return;
+                    }
+                    x.back();
+                    break;
+                case '}':
+                    return;
+                default:
+                    throw x.syntaxError("Expected a ',' or '}'");
+            }
+        }
+    }
+
+    /**
+     * Construct a JSONObject from a string. This is the most commonly used JSONObject constructor.
+     *
+     * @param string A string beginning with <code>{</code>&nbsp;<small>(left brace)</small> and ending with
+     *               <code>}</code>&nbsp;<small>(right brace)</small>.
+     * @throws RuntimeException If there is a syntax error in the source string.
+     */
+    public JSONObject(String string)
+    {
+        this(new JSONTokener(string));
+    }
+
+    /**
+     * Accumulate values under a key. It is similar to the put method except that if there is already an object stored
+     * under the key then a JSONArray is stored under the key to hold all of the accumulated values. If there is already
+     * a JSONArray, then the new value is appended to it. In contrast, the put method replaces the previous value.
+     *
+     * @param key   A key string.
+     * @param value An object to be accumulated under the key.
+     * @return this.
+     * @throws {@link RuntimeException} If the value is an invalid number or if the key is null.
+     */
+    public JSONObject accumulate(String key, Object value)
+    {
+        testValidity(value);
+
+        Object existing = opt(key);
+
+        if (existing == null)
+        {
+            // Note that the original implementation of this method contradicited the method
+            // documentation.
+            put(key, value);
+            return this;
+        }
+
+        if (existing instanceof JSONArray)
+        {
+            ((JSONArray) existing).put(value);
+            return this;
+        }
+
+        // Replace the existing value, of any type, with an array that includes both the
+        // existing and the new value.
+
+        put(key, new JSONArray().put(existing).put(value));
+
+        return this;
+    }
+
+    /**
+     * Append values to the array under a key. If the key does not exist in the JSONObject, then the key is put in the
+     * JSONObject with its value being a JSONArray containing the value parameter. If the key was already associated
+     * with a JSONArray, then the value parameter is appended to it.
+     *
+     * @param key   A key string.
+     * @param value An object to be accumulated under the key.
+     * @return this. @ If the key is null or if the current value associated with the key is not a JSONArray.
+     */
+    public JSONObject append(String key, Object value)
+    {
+        testValidity(value);
+        Object o = opt(key);
+        if (o == null)
+        {
+            put(key, new JSONArray().put(value));
+        }
+        else if (o instanceof JSONArray)
+        {
+            put(key, ((JSONArray) o).put(value));
+        }
+        else
+        {
+            throw new RuntimeException("JSONObject[" + quote(key) + "] is not a JSONArray.");
+        }
+
+        return this;
+    }
+
+    /**
+     * Produce a string from a double. The string "null" will be returned if the number is not finite.
+     *
+     * @param d A double.
+     * @return A String.
+     */
+    static String doubleToString(double d)
+    {
+        if (Double.isInfinite(d) || Double.isNaN(d))
+        {
+            return "null";
+        }
+
+        // Shave off trailing zeros and decimal point, if possible.
+
+        String s = Double.toString(d);
+        if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0)
+        {
+            while (s.endsWith("0"))
+            {
+                s = s.substring(0, s.length() - 1);
+            }
+            if (s.endsWith("."))
+            {
+                s = s.substring(0, s.length() - 1);
+            }
+        }
+        return s;
+    }
+
+    /**
+     * Get the value object associated with a key.
+     *
+     * @param key A key string.
+     * @return The object associated with the key. @ if the key is not found.
+     * @see #opt(String)
+     */
+    public Object get(String key)
+    {
+        Object o = opt(key);
+        if (o == null)
+        {
+            throw new RuntimeException("JSONObject[" + quote(key) + "] not found.");
+        }
+
+        return o;
+    }
+
+    /**
+     * Get the boolean value associated with a key.
+     *
+     * @param key A key string.
+     * @return The truth.
+     * @throws RuntimeException if the value is not a Boolean or the String "true" or "false".
+     */
+    public boolean getBoolean(String key)
+    {
+        Object o = get(key);
+
+        if (o instanceof Boolean) return o.equals(Boolean.TRUE);
+
+        if (o instanceof String)
+        {
+            String value = (String) o;
+
+            if (value.equalsIgnoreCase("true")) return true;
+
+            if (value.equalsIgnoreCase("false")) return false;
+        }
+
+        throw new RuntimeException("JSONObject[" + quote(key) + "] is not a Boolean.");
+    }
+
+    /**
+     * Get the double value associated with a key.
+     *
+     * @param key A key string.
+     * @return The numeric value. @ if the key is not found or if the value is not a Number object and cannot be
+     *         converted to a number.
+     */
+    public double getDouble(String key)
+    {
+        Object value = get(key);
+
+        try
+        {
+            if (value instanceof Number) return ((Number) value).doubleValue();
+
+            // This is a bit sloppy for the case where value is not a string.
+
+            return Double.valueOf((String) value);
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("JSONObject[" + quote(key) + "] is not a number.");
+        }
+    }
+
+    /**
+     * Get the int value associated with a key. If the number value is too large for an int, it will be clipped.
+     *
+     * @param key A key string.
+     * @return The integer value. @ if the key is not found or if the value cannot be converted to an integer.
+     */
+    public int getInt(String key)
+    {
+        Object value = get(key);
+
+        if (value instanceof Number) return ((Number) value).intValue();
+
+        // Very inefficient way to do this!
+        return (int) getDouble(key);
+    }
+
+    /**
+     * Get the JSONArray value associated with a key.
+     *
+     * @param key A key string.
+     * @return A JSONArray which is the value.
+     * @throws RuntimeException if the key is not found or if the value is not a JSONArray.
+     */
+    public JSONArray getJSONArray(String key)
+    {
+        Object o = get(key);
+        if (o instanceof JSONArray)
+        {
+            return (JSONArray) o;
+        }
+
+        throw new RuntimeException("JSONObject[" + quote(key) + "] is not a JSONArray.");
+    }
+
+    /**
+     * Get the JSONObject value associated with a key.
+     *
+     * @param key A key string.
+     * @return A JSONObject which is the value.
+     * @throws RuntimeException if the key is not found or if the value is not a JSONObject.
+     */
+    public JSONObject getJSONObject(String key)
+    {
+        Object o = get(key);
+        if (o instanceof JSONObject)
+        {
+            return (JSONObject) o;
+        }
+
+        throw new RuntimeException("JSONObject[" + quote(key) + "] is not a JSONObject.");
+    }
+
+    /**
+     * Get the long value associated with a key. If the number value is too long for a long, it will be clipped.
+     *
+     * @param key A key string.
+     * @return The long value. @ if the key is not found or if the value cannot be converted to a long.
+     */
+    public long getLong(String key)
+    {
+        Object o = get(key);
+        return o instanceof Number ? ((Number) o).longValue() : (long) getDouble(key);
+    }
+
+    /**
+     * Get the string associated with a key.
+     *
+     * @param key A key string.
+     * @return A string which is the value.
+     * @throws RuntimeException if the key is not found.
+     */
+    public String getString(String key)
+    {
+        return get(key).toString();
+    }
+
+    /**
+     * Determine if the JSONObject contains a specific key.
+     *
+     * @param key A key string.
+     * @return true if the key exists in the JSONObject.
+     */
+    public boolean has(String key)
+    {
+        return properties.containsKey(key);
+    }
+
+    /**
+     * Determine if the value associated with the key is null or if there is no value.
+     *
+     * @param key A key string.
+     * @return true if there is no value associated with the key or if the value is the JSONObject.NULL object.
+     */
+    public boolean isNull(String key)
+    {
+        return JSONObject.NULL.equals(opt(key));
+    }
+
+    /**
+     * Get an enumeration of the keys of the JSONObject. Caution: the set should not be modified.
+     *
+     * @return An iterator of the keys.
+     */
+    public Set<String> keys()
+    {
+        return properties.keySet();
+    }
+
+    /**
+     * Get the number of keys stored in the JSONObject.
+     *
+     * @return The number of keys in the JSONObject.
+     */
+    public int length()
+    {
+        return properties.size();
+    }
+
+    /**
+     * Produce a JSONArray containing the names of the elements of this JSONObject.
+     *
+     * @return A JSONArray containing the key strings, or null if the JSONObject is empty.
+     */
+    public JSONArray names()
+    {
+        JSONArray ja = new JSONArray();
+
+        for (String key : keys())
+        {
+            ja.put(key);
+        }
+
+        return ja.length() == 0 ? null : ja;
+    }
+
+    /**
+     * Produce a string from a Number.
+     *
+     * @param n A Number
+     * @return A String. @ If n is a non-finite number.
+     */
+    static String numberToString(Number n)
+    {
+        assert n != null;
+
+        testValidity(n);
+
+        // Shave off trailing zeros and decimal point, if possible.
+
+        String s = n.toString();
+        if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0)
+        {
+            while (s.endsWith("0"))
+            {
+                s = s.substring(0, s.length() - 1);
+            }
+            if (s.endsWith("."))
+            {
+                s = s.substring(0, s.length() - 1);
+            }
+        }
+        return s;
+    }
+
+    /**
+     * Get an optional value associated with a key.
+     *
+     * @param key A key string.
+     * @return An object which is the value, or null if there is no value.
+     * @see #get(String)
+     */
+    public Object opt(String key)
+    {
+        return properties.get(key);
+    }
+
+    /**
+     * Put a key/value pair in the JSONObject. If the value is null, then the key will be removed from the JSONObject if
+     * it is present.
+     *
+     * @param key   A key string.
+     * @param value An object which is the value. It should be of one of these types: Boolean, Double, Integer,
+     *              JSONArray, JSONObject, Long, String, or the JSONObject.NULL object.
+     * @return this.
+     * @throws RuntimeException If the value is non-finite number or if the key is null.
+     */
+    public JSONObject put(String key, Object value)
+    {
+        assert key != null;
+
+        if (value != null)
+        {
+            testValidity(value);
+            properties.put(key, value);
+        }
+        else
+        {
+            remove(key);
+        }
+
+        return this;
+    }
+
+    /**
+     * Produce a string in double quotes with backslash sequences in all the right places. A backslash will be inserted
+     * within </, allowing JSON text to be delivered in HTML. In JSON text, a string cannot contain a control character
+     * or an unescaped quote or backslash.
+     *
+     * @param string A String
+     * @return A String correctly formatted for insertion in a JSON text.
+     */
+    public static String quote(String string)
+    {
+        if (string == null || string.length() == 0)
+        {
+            return "\"\"";
+        }
+
+        char b;
+        char c = 0;
+        int i;
+        int len = string.length();
+        StringBuilder buffer = new StringBuilder(len + 4);
+        String t;
+
+        buffer.append('"');
+        for (i = 0; i < len; i += 1)
+        {
+            b = c;
+            c = string.charAt(i);
+            switch (c)
+            {
+                case '\\':
+                case '"':
+                    buffer.append('\\');
+                    buffer.append(c);
+                    break;
+                case '/':
+                    if (b == '<')
+                    {
+                        buffer.append('\\');
+                    }
+                    buffer.append(c);
+                    break;
+                case '\b':
+                    buffer.append("\\b");
+                    break;
+                case '\t':
+                    buffer.append("\\t");
+                    break;
+                case '\n':
+                    buffer.append("\\n");
+                    break;
+                case '\f':
+                    buffer.append("\\f");
+                    break;
+                case '\r':
+                    buffer.append("\\r");
+                    break;
+                default:
+                    if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100'))
+                    {
+                        t = "000" + Integer.toHexString(c);
+                        buffer.append("\\u").append(t.substring(t.length() - 4));
+                    }
+                    else
+                    {
+                        buffer.append(c);
+                    }
+            }
+        }
+        buffer.append('"');
+        return buffer.toString();
+    }
+
+    /**
+     * Remove a name and its value, if present.
+     *
+     * @param key The name to be removed.
+     * @return The value that was associated with the name, or null if there was no value.
+     */
+    public Object remove(String key)
+    {
+        return properties.remove(key);
+    }
+
+    private static final Class[] ALLOWED = new Class[] { String.class, Boolean.class, Number.class, JSONObject.class,
+            JSONArray.class, Null.class };
+
+    /**
+     * Throw an exception if the object is an NaN or infinite number, or not a type which may be stored.
+     *
+     * @param value The object to test. @ If o is a non-finite number.
+     */
+    @SuppressWarnings("unchecked")
+    static void testValidity(Object value)
+    {
+        if (value == null) return;
+
+        boolean found = false;
+        Class actual = value.getClass();
+
+        for (Class allowed : ALLOWED)
+        {
+            if (allowed.isAssignableFrom(actual))
+            {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found) throw new RuntimeException(String
+                .format(
+                "JSONObject properties may be String, Boolean, Number, JSONObject or JSONArray. Type %s is not allowed.",
+                actual.getName()));
+
+        if (value instanceof Double)
+        {
+            Double asDouble = (Double) value;
+
+            if (asDouble.isInfinite() || asDouble.isNaN())
+            {
+                throw new RuntimeException("JSON does not allow non-finite numbers.");
+            }
+
+            return;
+        }
+
+        if (value instanceof Float)
+        {
+            Float asFloat = (Float) value;
+
+            if (asFloat.isInfinite() || asFloat.isNaN())
+            {
+                throw new RuntimeException("JSON does not allow non-finite numbers.");
+            }
+
+        }
+
+    }
+
+    /**
+     * Make a JSON text of this JSONObject. For compactness, no whitespace is added. If this would not result in a
+     * syntactically correct JSON text, then null will be returned instead.
+     * <p/>
+     * Warning: This method assumes that the data structure is acyclical.
+     *
+     * @return a printable, displayable, portable, transmittable representation of the object, beginning with
+     *         <code>{</code>&nbsp;<small>(left brace)</small> and ending with <code>}</code>&nbsp;<small>(right
+     *         brace)</small>.
+     */
+    @Override
+    public String toString()
+    {
+        boolean comma = false;
+
+        StringBuilder buffer = new StringBuilder("{");
+
+        for (String key : keys())
+        {
+            if (comma) buffer.append(',');
+
+            buffer.append(quote(key));
+            buffer.append(':');
+            buffer.append(valueToString(properties.get(key)));
+
+            comma = true;
+        }
+
+        buffer.append('}');
+
+        return buffer.toString();
+    }
+
+    /**
+     * Make a JSON text of an Object value. If the object has an value.toJSONString() method, then that method will be
+     * used to produce the JSON text. The method is required to produce a strictly conforming text. If the object does
+     * not contain a toJSONString method (which is the most common case), then a text will be produced by the rules.
+     * <p/>
+     * Warning: This method assumes that the data structure is acyclical.
+     *
+     * @param value The value to be serialized.
+     * @return a printable, displayable, transmittable representation of the object, beginning with
+     *         <code>{</code>&nbsp;<small>(left brace)</small> and ending with <code>}</code>&nbsp;<small>(right
+     *         brace)</small>. @ If the value is or contains an invalid number.
+     */
+    static String valueToString(Object value)
+    {
+        if (value == null || value.equals(null))
+        {
+            return "null";
+        }
+
+        if (value instanceof JSONString)
+        {
+            try
+            {
+                String json = ((JSONString) value).toJSONString();
+
+                return quote(json);
+            }
+            catch (Exception e)
+            {
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        if (value instanceof Number)
+        {
+            return numberToString((Number) value);
+        }
+
+        if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray)
+        {
+            return value
+                    .toString();
+        }
+        return quote(value.toString());
+    }
+
+    /**
+     * Returns true if the other object is a JSONObject and its set of properties matches this object's properties.
+     * <p/>
+     * '
+     */
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null) return false;
+
+        if (!(obj instanceof JSONObject)) return false;
+
+        JSONObject other = (JSONObject) obj;
+
+        return properties.equals(other.properties);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java
new file mode 100644
index 0000000..f2e12b5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONString.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.json;
+
+/**
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class can change the
+ * behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
+ * <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will be used instead of the
+ * default behavior of using the Object's <code>toString()</code> method and quoting the result.
+ */
+public interface JSONString
+{
+    /**
+     * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
+     *
+     * @return A strictly syntactically correct JSON text.
+     */
+    public String toJSONString();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONTokener.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONTokener.java
new file mode 100644
index 0000000..c7aacb0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/json/JSONTokener.java
@@ -0,0 +1,528 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.json;
+
+/*
+ Copyright (c) 2002 JSON.org
+
+ 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 shall be used for Good, not Evil.
+
+ 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.
+ */
+
+/**
+ * A JSONTokener takes a source string and extracts characters and tokens from it. It is used by the JSONObject and
+ * JSONArray constructors to parse JSON source strings.
+ *
+ * @author JSON.org
+ * @version 2
+ */
+class JSONTokener
+{
+
+    /**
+     * The index of the next character.
+     */
+    private int index;
+
+    /**
+     * The source string being tokenized.
+     */
+    private final String source;
+
+    /**
+     * Construct a JSONTokener from a string.
+     *
+     * @param source A source string, in JSON format.
+     */
+    public JSONTokener(String source)
+    {
+        assert source != null;
+
+        index = 0;
+        this.source = source;
+    }
+
+    /**
+     * Back up one character. This provides a sort of lookahead capability, so that you can test for a digit or letter
+     * before attempting to parse the next number or identifier.
+     */
+    public void back()
+    {
+        if (index > 0)
+        {
+            index -= 1;
+        }
+    }
+
+    /**
+     * Get the hex value of a character (base16).
+     *
+     * @param c A character between '0' and '9' or between 'A' and 'F' or between 'a' and 'f'.
+     * @return An int between 0 and 15, or -1 if c was not a hex digit.
+     */
+    static int dehexchar(char c)
+    {
+        if (c >= '0' && c <= '9')
+        {
+            return c - '0';
+        }
+        if (c >= 'A' && c <= 'F')
+        {
+            return c - ('A' - 10);
+        }
+        if (c >= 'a' && c <= 'f')
+        {
+            return c - ('a' - 10);
+        }
+        return -1;
+    }
+
+    /**
+     * Determine if the source string still contains characters that next() can consume.
+     *
+     * @return true if not yet at the end of the source.
+     */
+    public boolean more()
+    {
+        return index < source.length();
+    }
+
+    /**
+     * Get the next character in the source string.
+     *
+     * @return The next character, or 0 if past the end of the source string.
+     */
+    public char next()
+    {
+        if (more())
+        {
+            return source.charAt(index++);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Consume the next character, and check that it matches a specified character.
+     *
+     * @param c The character to match.
+     * @return The character.
+     * @throws RuntimeException if the character does not match.
+     */
+    public char next(char c)
+    {
+        char n = next();
+        if (n != c)
+        {
+            throw syntaxError("Expected '" + c + "' and instead saw '" + n + "'");
+        }
+        return n;
+    }
+
+    /**
+     * Get the next n characters.
+     *
+     * @param n The number of characters to take.
+     * @return A string of n characters.
+     * @throws RuntimeException Substring bounds error if there are not n characters remaining in the source string.
+     */
+    public String next(int n)
+    {
+        int i = index;
+        int j = i + n;
+        if (j >= source.length())
+        {
+            throw syntaxError("Substring bounds error");
+        }
+        index += n;
+        return source.substring(i, j);
+    }
+
+    /**
+     * Get the next char in the string, skipping whitespace and comments (slashslash, slashstar, and hash).
+     *
+     * @return A character, or 0 if there are no more characters.
+     * @throws RuntimeException
+     */
+    public char nextClean()
+    {
+        for (; ;)
+        {
+            char c = next();
+            if (c == '/')
+            {
+                switch (next())
+                {
+                    case '/':
+                        do
+                        {
+                            c = next();
+                        } while (c != '\n' && c != '\r' && c != 0);
+
+                        break;
+                    case '*':
+
+                        while (true)
+                        {
+                            c = next();
+                            if (c == 0)
+                            {
+                                throw syntaxError("Unclosed comment");
+                            }
+                            if (c == '*')
+                            {
+                                if (next() == '/')
+                                {
+                                    break;
+                                }
+                                back();
+                            }
+                        }
+                        break;
+
+                    default:
+                        back();
+                        return '/';
+                }
+            }
+            else if (c == '#')
+            {
+                do
+                {
+                    c = next();
+                } while (c != '\n' && c != '\r' && c != 0);
+            }
+            else if (c == 0 || c > ' ')
+            {
+                return c;
+            }
+        }
+    }
+
+    /**
+     * Return the characters up to the next close quote character. Backslash processing is done. The formal JSON format
+     * does not allow strings in single quotes, but an implementation is allowed to accept them.
+     *
+     * @param quote The quoting character, either <code>"</code>&nbsp;<small>(double quote)</small> or
+     *              <code>'</code>&nbsp;<small>(single quote)</small>.
+     * @return A String.
+     * @throws RuntimeException Unterminated string.
+     */
+    public String nextString(char quote)
+    {
+        StringBuilder builder = new StringBuilder();
+
+        while (true)
+        {
+            char c = next();
+            switch (c)
+            {
+                case 0:
+                case '\n':
+                case '\r':
+                    throw syntaxError("Unterminated string");
+                case '\\':
+                    c = next();
+                    switch (c)
+                    {
+                        case 'b':
+                            builder.append('\b');
+                            break;
+                        case 't':
+                            builder.append('\t');
+                            break;
+                        case 'n':
+                            builder.append('\n');
+                            break;
+                        case 'f':
+                            builder.append('\f');
+                            break;
+                        case 'r':
+                            builder.append('\r');
+                            break;
+                        case 'u':
+                            builder.append((char) Integer.parseInt(next(4), 16));
+                            break;
+                        case 'x':
+                            builder.append((char) Integer.parseInt(next(2), 16));
+                            break;
+                        default:
+                            builder.append(c);
+                    }
+                    break;
+                default:
+                    if (c == quote)
+                    {
+                        return builder.toString();
+                    }
+                    builder.append(c);
+            }
+        }
+    }
+
+    /**
+     * Get the text up but not including the specified character or the end of line, whichever comes first.
+     *
+     * @param d A delimiter character.
+     * @return A string.
+     */
+    public String nextTo(char d)
+    {
+        StringBuffer sb = new StringBuffer();
+        for (; ;)
+        {
+            char c = next();
+            if (c == d || c == 0 || c == '\n' || c == '\r')
+            {
+                if (c != 0)
+                {
+                    back();
+                }
+                return sb.toString().trim();
+            }
+            sb.append(c);
+        }
+    }
+
+    /**
+     * Get the text up but not including one of the specified delimeter characters or the end of line, whichever comes
+     * first.
+     *
+     * @param delimiters A set of delimiter characters.
+     * @return A string, trimmed.
+     */
+    public String nextTo(String delimiters)
+    {
+        char c;
+        StringBuffer sb = new StringBuffer();
+        for (; ;)
+        {
+            c = next();
+            if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r')
+            {
+                if (c != 0)
+                {
+                    back();
+                }
+                return sb.toString().trim();
+            }
+            sb.append(c);
+        }
+    }
+
+    /**
+     * Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the
+     * JSONObject.NULL object.
+     *
+     * @return An object.
+     * @throws RuntimeException If syntax error.
+     */
+    public Object nextValue()
+    {
+        char c = nextClean();
+        String s;
+
+        switch (c)
+        {
+            case '"':
+            case '\'':
+                return nextString(c);
+            case '{':
+                back();
+                return new JSONObject(this);
+            case '[':
+                back();
+                return new JSONArray(this);
+        }
+
+        /*
+         * Handle unquoted text. This could be the values true, false, or null, or it can be a
+         * number. An implementation (such as this one) is allowed to also accept non-standard
+         * forms. Accumulate characters until we reach the end of the text or a formatting
+         * character.
+         */
+
+        StringBuffer sb = new StringBuffer();
+        char b = c;
+        while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0)
+        {
+            sb.append(c);
+            c = next();
+        }
+        back();
+
+        /*
+         * If it is true, false, or null, return the proper value.
+         */
+
+        s = sb.toString().trim();
+        if (s.equals(""))
+        {
+            throw syntaxError("Missing value");
+        }
+        if (s.equalsIgnoreCase("true"))
+        {
+            return Boolean.TRUE;
+        }
+        if (s.equalsIgnoreCase("false"))
+        {
+            return Boolean.FALSE;
+        }
+        if (s.equalsIgnoreCase("null"))
+        {
+            return JSONObject.NULL;
+        }
+
+        /*
+         * If it might be a number, try converting it. We support the 0- and 0x- conventions. If a
+         * number cannot be produced, then the value will just be a string. Note that the 0-, 0x-,
+         * plus, and implied string conventions are non-standard. A JSON parser is free to accept
+         * non-JSON forms as long as it accepts all correct JSON forms.
+         */
+
+        if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+')
+        {
+            if (b == '0')
+            {
+                if (s.length() > 2 && (s.charAt(1) == 'x' || s.charAt(1) == 'X'))
+                {
+                    try
+                    {
+                        return Integer.parseInt(s.substring(2), 16);
+                    }
+                    catch (Exception e)
+                    {
+                        /* Ignore the error */
+                    }
+                }
+                else
+                {
+                    try
+                    {
+                        return Integer.parseInt(s, 8);
+                    }
+                    catch (Exception e)
+                    {
+                        /* Ignore the error */
+                    }
+                }
+            }
+            try
+            {
+                return new Integer(s);
+            }
+            catch (Exception e)
+            {
+                try
+                {
+                    return new Long(s);
+                }
+                catch (Exception f)
+                {
+                    try
+                    {
+                        return new Double(s);
+                    }
+                    catch (Exception g)
+                    {
+                        return s;
+                    }
+                }
+            }
+        }
+        return s;
+    }
+
+    /**
+     * Skip characters until the next character is the requested character. If the requested character is not found, no
+     * characters are skipped.
+     *
+     * @param to A character to skip to.
+     * @return The requested character, or zero if the requested character is not found.
+     */
+    public char skipTo(char to)
+    {
+        char c;
+        int index = this.index;
+        do
+        {
+            c = next();
+            if (c == 0)
+            {
+                this.index = index;
+                return c;
+            }
+        } while (c != to);
+        back();
+        return c;
+    }
+
+    /**
+     * Skip characters until past the requested string. If it is not found, we are left at the end of the source.
+     *
+     * @param to A string to skip past.
+     */
+    public boolean skipPast(String to)
+    {
+        index = source.indexOf(to, index);
+        if (index < 0)
+        {
+            index = source.length();
+            return false;
+        }
+        index += to.length();
+        return true;
+
+    }
+
+    /**
+     * Make a JSONException to signal a syntax error.
+     *
+     * @param message The error message.
+     * @return A JSONException object, suitable for throwing
+     */
+    RuntimeException syntaxError(String message)
+    {
+        return new RuntimeException(message + toString());
+    }
+
+    /**
+     * Make a printable string of this JSONTokener.
+     *
+     * @return " at character [myIndex] of [mySource]"
+     */
+    @Override
+    public String toString()
+    {
+        return " at character " + index + " of " + source;
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationGlobals.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationGlobals.java
new file mode 100644
index 0000000..c8ede1f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationGlobals.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services;
+
+import org.apache.tapestry.services.Context;
+
+import javax.servlet.ServletContext;
+
+/**
+ * Stores global information about the application and its environment.
+ */
+public interface ApplicationGlobals
+{
+    void storeServletContext(ServletContext context);
+
+    ServletContext getServletContext();
+
+    void storeContext(Context context);
+
+    Context getContext();
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializer.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializer.java
new file mode 100644
index 0000000..5b21e2c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializer.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry5.services;

+

+import org.apache.tapestry.services.Context;

+

+/**

+ * Service interface for initializing Tapestry for the application.

+ *

+ * @see ApplicationInitializerFilter

+ */

+public interface ApplicationInitializer

+{

+    void initializeApplication(Context context);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializerFilter.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializerFilter.java
new file mode 100644
index 0000000..db616f6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ApplicationInitializerFilter.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry5.services;

+

+import org.apache.tapestry.services.Context;

+

+/**

+ * Filter interface for {@link ApplicationInitializer}.

+ */

+public interface ApplicationInitializerFilter

+{

+    void initializeApplication(Context context, ApplicationInitializer initializer);

+}

diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMessagesSource.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMessagesSource.java
new file mode 100644
index 0000000..0319472
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentMessagesSource.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.services;
+
+import org.apache.tapestry.internal.event.InvalidationEventHub;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.model.ComponentModel;
+
+import java.util.Locale;
+
+/**
+ * Used to connect a Tapestry component to its message catalog.
+ */
+public interface ComponentMessagesSource extends InvalidationEventHub
+{
+    /**
+     * Used to obtain a {@link Messages} instance for a particular component, within a particular locale. If the
+     * component extends from another component, then its localized properties will merge with its parent's properties
+     * (with the subclass overriding the super class on any conflicts).
+     *
+     * @param componentModel
+     * @param locale
+     * @return the message catalog for the component, in the indicated locale
+     */
+    Messages getMessages(ComponentModel componentModel, Locale locale);
+}
diff --git a/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/RequestGlobals.java b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/RequestGlobals.java
new file mode 100644
index 0000000..3a02c4a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/java/org/apache/tapestry5/services/RequestGlobals.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry5.services;

+

+import org.apache.tapestry.services.Request;

+import org.apache.tapestry.services.Response;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+/**

+ * Service used to store the current request objects, both the Servlet API versions, and the Tapestry generic versions.

+ * The service has a per-thread scope.

+ */

+public interface RequestGlobals

+{

+    /**

+     * Stores the servlet API request and response objects, for access via the properties.

+     */

+    void storeServletRequestResponse(HttpServletRequest request, HttpServletResponse response);

+

+    /**

+     * The Servlet API Request. This is exposed as service HTTPServletRequest.

+     */

+    HttpServletRequest getHTTPServletRequest();

+

+    HttpServletResponse getHTTPServletResponse();

+

+    void storeRequestResponse(Request request, Response response);

+

+    /**

+     * The current request. This is exposed as service Request.

+     */

+    Request getRequest();

+

+    /**

+     * The current response. This is exposed as service Response.

+     */

+    Response getResponse();

+}

diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif
new file mode 100644
index 0000000..e1cafab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/ajax-loader.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/base/BaseStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/base/BaseStrings.properties
new file mode 100644
index 0000000..5c48f3b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/base/BaseStrings.properties
@@ -0,0 +1,15 @@
+# Copyright 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+null-value-in-path=Property '%s' contains a null value in the path.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanDisplay.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanDisplay.tml
new file mode 100644
index 0000000..9bc608b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanDisplay.tml
@@ -0,0 +1,17 @@
+<div class="t-beandisplay" xml:space="default"
+     xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+    <div class="t-beandisplay-row" t:type="loop" t:source="model.propertyNames"
+         t:volatile="true" t:value="propertyName">
+
+        <div class="${labelClass}">${propertyModel.label}:</div>
+
+        <div class="${valueClass}">
+            <t:propertydisplay model="propertyModel" overrides="overrides" object="object"/>
+        </div>
+
+    </div>
+
+</div>
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
new file mode 100644
index 0000000..3e8403a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+submit-label=Create/Update
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.tml
new file mode 100644
index 0000000..6c7a12a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.tml
@@ -0,0 +1,15 @@
+<form t:id="form"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:errors/>
+
+    <div class="t-beaneditor">
+
+        <t:beaneditor t:id="editor" object="object" remove="inherit:remove"
+                      reorder="inherit:reorder" model="model" overrides="this"/>
+
+        <div class="t-beaneditor-row">
+            <input type="submit" class="t-beaneditor-submit" value="${submitLabel}"/>
+        </div>
+    </div>
+
+</form>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.tml
new file mode 100644
index 0000000..9b6b4a7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.tml
@@ -0,0 +1,6 @@
+<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="default"
+     class="t-beaneditor-row" t:type="loop" t:source="model.propertyNames"
+     t:volatile="true" t:value="propertyName">
+    <t:propertyEditor property="propertyName" object="object"
+                      model="model" overrides="overrides"/>
+</div>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/DateField.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/DateField.properties
new file mode 100644
index 0000000..ee0b89c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/DateField.properties
@@ -0,0 +1,34 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+sym-a=EEE
+sym-upa=EEEE
+sym-b=MMM
+sym-upb=MMMM
+sym-d=dd
+sym-e=d
+sym-uph=HH
+symp-upi=KK
+sym-j=DDD
+sym-k=HH
+sym-l-hh
+sym-m=MM
+sym-upm=mm
+sym-p=aa
+sym-ups=ss
+sym-y=yy
+sym-upy=yyyy
+
+unknown-symbol=Unknown or unsupported symbol '%%%s' (in format '%s').
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors.properties
new file mode 100644
index 0000000..1a73dd2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors.properties
@@ -0,0 +1,15 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+default-banner=You must correct the following errors before you may continue.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_it.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_it.properties
new file mode 100644
index 0000000..8d88b4d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_it.properties
@@ -0,0 +1,15 @@
+# Copyright 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+default-banner=Per poter proseguire è necessario correggere gli errori seguenti.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_zh_CN.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_zh_CN.properties
new file mode 100644
index 0000000..0348e3e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Errors_zh_CN.properties
@@ -0,0 +1,15 @@
+# Copyright 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+default-banner = \u5728\u4F60\u7EE7\u7EED\u4E4B\u524D\uFF0C\u5FC5\u987B\u7EA0\u6B63\u5982\u4E0B\u9519\u8BEF.
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/ExceptionDisplay.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/ExceptionDisplay.tml
new file mode 100644
index 0000000..0d3efe9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/ExceptionDisplay.tml
@@ -0,0 +1,34 @@
+<div xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" class="t-exception-report">
+    <ul>
+        <t:loop source="stack" value="info">
+            <li>
+                <span class="t-exception-class-name">${info.className}</span>
+
+                <t:if test="info.message">
+                    <div class="t-exception-message">${info.message}</div>
+                </t:if>
+
+                <t:if test="showPropertyList">
+                    <dl>
+                        <t:loop source="info.propertyNames" value="propertyName">
+                            <dt>${propertyName}</dt>
+                            <dd>
+                                <t:renderobject object="propertyValue"/>
+                            </dd>
+                        </t:loop>
+                        <t:if test="info.stackTrace">
+                            <dt>Stack trace</dt>
+                            <dd>
+                                <ul class="t-stack-trace">
+                                    <t:loop source="info.stackTrace" value="frame">
+                                        <li class="${frameClass}">${frame}</li>
+                                    </t:loop>
+                                </ul>
+                            </dd>
+                        </t:if>
+                    </dl>
+                </t:if>
+            </li>
+        </t:loop>
+    </ul>
+</div>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Grid.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Grid.tml
new file mode 100644
index 0000000..e2f1247
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Grid.tml
@@ -0,0 +1,20 @@
+<div class="t-data-grid" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <div t:id="pagerTop"/>
+
+    <table t:id="table">
+        <thead t:id="columns"/>
+        <tbody>
+            <tr t:id="rows"/>
+        </tbody>
+    </table>
+
+    <div t:id="pagerBottom"/>
+
+    <t:block>
+        <div t:id="pager"/>
+    </t:block>
+
+    <t:block id="empty">There is no data to display.</t:block>
+
+</div>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.properties
new file mode 100644
index 0000000..139840c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.properties
@@ -0,0 +1,17 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ascending=[Asc]
+descending=[Desc]
+sortable=[Sortable]
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml
new file mode 100644
index 0000000..b82bcf8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridColumns.tml
@@ -0,0 +1,16 @@
+<thead xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="default">
+    <tr>
+        <th t:type="Loop" source="columnNames" value="columnName" volatile="true" class="prop:headerClass"
+            index="columnIndex">
+            <t:delegate to="blockForColumn"/>
+            <t:block id="standardHeader">
+                <a t:id="sort">${columnModel.label}</a>
+                <t:if test="columnModel.sortable">
+                    <a t:id="sort2">
+                        <img src="${icon}" id="${columnModel.id}:sort" class="t-sort-icon" alt="${iconLabel}"/>
+                    </a>
+                </t:if>
+            </t:block>
+        </th>
+    </tr>
+</thead>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridPager.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridPager.properties
new file mode 100644
index 0000000..9215dbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridPager.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+goto-page=Go to page %d
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridRows.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridRows.tml
new file mode 100644
index 0000000..6800b18
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/GridRows.tml
@@ -0,0 +1,7 @@
+<tr class="${rowClass}" xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:loop source="propertyNames" value="propertyName" volatile="inherit:volatile">
+        <td class="${cellClass}">
+            <t:gridcell model="columnModel" object="row" overrides="componentResources.containerResources"/>
+        </td>
+    </t:loop>
+</tr>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.properties
new file mode 100644
index 0000000..88eddd8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.properties
@@ -0,0 +1,21 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+available-label=Available
+selected-label=Selected
+
+select-label=Select >
+deselect-label=< Deselect
+up-label=Move Up
+down-label=Move Down
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.tml
new file mode 100644
index 0000000..ce3720a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/Palette.tml
@@ -0,0 +1,27 @@
+<div class="t-palette" xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <div class="t-palette-available">
+        <div class="t-palette-title">${message:available-label}</div>
+        <t:delegate to="availableRenderer"/>
+    </div>
+    <div class="t-palette-controls">
+        <button id="${clientId}:select" disabled="disabled">
+            <img src="${select}" alt="${message:select-label}"/>
+        </button>
+        <button id="${clientId}:deselect" disabled="disabled">
+            <img src="${deselect}" alt="${message:deselect-label}"/>
+        </button>
+        <t:if test="reorder">
+            <button id="${clientId}:up" disabled="disabled">
+                <img src="${moveUp}" alt="${message:up-label}"/>
+            </button>
+            <button id="${clientId}:down" disabled="disabled">
+                <img src="${moveDown}" alt="${message:down-label}"/>
+            </button>
+        </t:if>
+    </div>
+    <div class="t-palette-selected">
+        <div class="t-palette-title">${message:selected-label}</div>
+        <t:delegate to="selectedRenderer"/>
+    </div>
+    <div class="t-palette-spacer"/>
+</div>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
new file mode 100644
index 0000000..74b425a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/PropertyEditor.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+block-error=Unable to locate a block to edit property '%s' (with data type '%s') of object %s: %s
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.gif b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.gif
new file mode 100644
index 0000000..8526cf5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.js
new file mode 100644
index 0000000..6ca96ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/datefield.js
@@ -0,0 +1,142 @@
+Tapestry.DateField = Class.create();
+
+Tapestry.DateField.prototype = {
+
+    // Initializes a DateField from a JSON specification.
+
+    initialize : function(spec)
+    {
+        this.field = $(spec.field);
+        this.trigger = $(spec.field + ":trigger");
+
+        this.trigger.observe("click", this.triggerClicked.bind(this));
+
+        this.popup = null;
+    },
+
+    triggerClicked : function()
+    {
+        if (this.field.disabled) return;
+
+        if (this.popup == null)
+        {
+            this.createPopup();
+
+        }
+        else
+        {
+            if (this.popup.visible())
+            {
+                this.hidePopup();
+                return;
+            }
+        }
+
+
+        var value = $F(this.field);
+
+        if (value == "")
+        {
+            this.datePicker.setDate(null);
+        }
+        else
+        {
+
+            // TODO: This is limited and americanized (not localized) to MM/DD/YYYY
+            var re = /^\s*(\d+)\/(\d+)\/(\d{2,4})\s*$/;
+            var matches = re.exec(value);
+
+
+            // If the RE is bad, raise the date picker anyway, showing
+            // the last valid date, or showing no date.
+
+            if (matches != null)
+            {
+
+                var month = Number(matches[1]);
+                var day = Number(matches[2])
+                var year = Number(matches[3]);
+
+            // For two digits, guestamate which century they want.
+
+                if (year < 100)
+                {
+                    if (year >= 60) year += 1900
+                    else year += 2000;
+                }
+
+                var date = new Date(value);
+
+                date.setMonth(month - 1);
+                date.setDate(day);
+                date.setFullYear(year);
+
+                this.datePicker.setDate(date);
+            }
+        }
+
+        this.positionPopup();
+
+        this.revealPopup();
+    },
+
+    createPopup : function()
+    {
+        this.datePicker = new DatePicker();
+
+        this.popup = $(this.datePicker.create());
+
+        this.field.insert({ after : this.popup });
+
+        this.popup.absolutize().hide();
+
+        this.datePicker.onselect = function()
+        {
+            this.field.value = this.formatDate(this.datePicker.getDate());
+
+            this.hidePopup();
+
+            new Effect.Highlight(this.field);
+
+        }.bind(this);
+    },
+
+    formatDate : function(date)
+    {
+        if (date == null) return "";
+
+        // TODO: This needs to localize; currently its Americanized (MM/DD/YYYY).
+        return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
+    },
+
+    positionPopup : function()
+    {
+        this.popup.clonePosition(this.field, { offsetTop: this.field.getHeight() + 2 }).setStyle({ width: "", height: "" });
+    },
+
+    /** Duration used when fading the popup in or out. */
+
+    FADE_DURATION : .20,
+
+    hidePopup : function()
+    {
+
+        new Effect.Fade(this.popup, { duration: this.FADE_DURATION });
+    },
+
+    revealPopup : function()
+    {
+
+        // Only show one DateField popup at a time.
+
+        if (Tapestry.DateField.activeDateField != undefined &&
+            Tapestry.DateField.activeDateField != this)
+        {
+            Tapestry.DateField.activeDateField.hidePopup();
+        }
+
+        new Effect.Appear(this.popup, { duration: this.FADE_DURATION });
+
+        Tapestry.DateField.activeDateField = this;
+    }
+};
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/deselect.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/deselect.png
new file mode 100644
index 0000000..97473a6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/deselect.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_down.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_down.png
new file mode 100644
index 0000000..1f5c72a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_down.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_up.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_up.png
new file mode 100644
index 0000000..05a447b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/move_up.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
new file mode 100644
index 0000000..4204a93
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/palette.js
@@ -0,0 +1,250 @@
+Tapestry.Palette = Class.create();
+
+Tapestry.Palette.prototype = {
+
+    // id: of main select element
+    // reorder: true to enable extra controls for changing selection order
+    // naturalOrder: array of values, the proper order for the elements (needed when de-selecting items)
+    initialize : function(id, reorder, naturalOrder)
+    {
+        this.reorder = reorder;
+    // The SELECT elements
+
+        this.avail = $(id + ":avail");
+        this.selected = $(id);
+
+        this.hidden = $(id + ":values");
+
+	  // The BUTTON elements
+        this.select = $(id + ":select");
+        this.deselect = $(id + ":deselect");
+
+        if (this.reorder)
+        {
+            this.up = $(id + ":up");
+            this.down = $(id + ":down");
+        }
+
+        this.valueToOrderIndex = {};
+
+        naturalOrder.each(function (value, i)
+        {
+            this.valueToOrderIndex[value] = i;
+        }.bind(this));
+
+        this.bindEvents();
+    },
+
+    bindEvents : function()
+    {
+        var updateButtons = this.updateButtons.bindAsEventListener(this);
+        this.avail.observe("change", updateButtons);
+        this.selected.observe("change", updateButtons);
+
+        var selectClicked = this.selectClicked.bindAsEventListener(this);
+        this.select.observe("click", selectClicked);
+        this.avail.observe("dblclick", selectClicked);
+
+        var deselectClicked = this.deselectClicked.bindAsEventListener(this);
+        this.deselect.observe("click", deselectClicked);
+        this.selected.observe("dblclick", deselectClicked);
+
+        if (this.reorder)
+        {
+            this.up.observe("click", this.moveUpClicked.bindAsEventListener(this));
+            this.down.observe("click", this.moveDownClicked.bindAsEventListener(this));
+        }
+    },
+
+    updateButtons: function()
+    {
+        this.select.disabled = this.avail.selectedIndex < 0;
+
+        var nothingSelected = this.selected.selectedIndex < 0;
+
+        this.deselect.disabled = nothingSelected;
+
+        if (this.reorder)
+        {
+            this.up.disabled = nothingSelected || this.allSelectionsAtTop();
+            this.down.disabled = nothingSelected || this.allSelectionsAtBottom();
+        }
+    },
+
+    indexOfLastSelection : function(select)
+    {
+        if (select.selectedIndex < 0) return -1;
+
+        for (var i = select.options.length - 1; i >= select.selectedIndex; i--)
+        {
+            if (select.options[i].selected) return i;
+        }
+
+        return -1;
+    },
+
+    allSelectionsAtTop: function()
+    {
+        var last = this.indexOfLastSelection(this.selected);
+        var options = $A(this.selected.options);
+
+        return ! options.slice(0, last).any(function (o)
+        {
+            return ! o.selected;
+        });
+    },
+
+    allSelectionsAtBottom : function()
+    {
+        var options = $A(this.selected.options);
+
+    // Make sure that all elements from the (first) selectedIndex to the end are also selected.
+        return options.slice(this.selected.selectedIndex).all(function(o)
+        {
+            return o.selected;
+        });
+    },
+
+    selectClicked : function(event)
+    {
+        this.transferOptions(this.avail, this.selected, this.reorder);
+    },
+
+    deselectClicked : function(event)
+    {
+        this.transferOptions(this.selected, this.avail, false);
+    },
+
+    transferOptions : function (from, to, atEnd)
+    {
+        // from: SELECT to move option(s) from (those that are selected)
+        // to: SELECT to add option(s) to
+        // atEnd : if true, add at end, otherwise by natural sort order
+        var toOptions = $A(to.options);
+
+        toOptions.each(function(option)
+        {
+            option.selected = false;
+        });
+
+        var movers = this.removeSelectedOptions(from);
+        this.moveOptions(movers, to, atEnd);
+
+    },
+
+    updateHidden : function()
+    {
+        // Every value in the selected list (whether enabled or not) is combined to form the value.
+        var values = $A(this.selected).map(function(o)
+        {
+            return o.value;
+        });
+
+        this.hidden.value = values.toJSON();
+    },
+
+    moveUpClicked : function(event)
+    {
+        var pos = this.selected.selectedIndex - 1;
+        var movers = this.removeSelectedOptions(this.selected);
+
+        var before = pos < 0 ? this.selected.options[0] : this.selected.options[pos];
+
+        this.reorderSelected(movers, before);
+
+        Event.stop(event);
+    },
+
+    removeSelectedOptions : function(select)
+    {
+        var movers = [];
+        var options = select.options;
+
+        for (var i = select.selectedIndex; i < select.length; i++)
+        {
+            var option = options[i];
+            if (option.selected)
+            {
+                select.remove(i--);
+                movers.push(option);
+            }
+        }
+
+        return movers;
+    },
+
+    moveOptions : function(movers, to, atEnd)
+    {
+
+        movers.each(function(option)
+        {
+            this.moveOption(option, to, atEnd);
+        }.bind(this));
+
+        this.updateHidden();
+        this.updateButtons();
+    },
+
+    moveOption : function(option, to, atEnd)
+    {
+        var before = null;
+
+        if (!atEnd)
+        {
+            var optionOrder = this.valueToOrderIndex[option.value];
+            var candidate = $A(to.options).find(function (o)
+            {
+                return this.valueToOrderIndex[o.value] > optionOrder;
+            }.bind(this));
+            if (candidate) before = candidate;
+        }
+
+        try
+        {
+            to.add(option, before);
+        }
+        catch (ex)
+        {
+            //probably IE complaining about type mismatch for before argument;
+            if (before == null)
+            {
+                //just add to the end...
+                to.add(option);
+            }
+            else
+            {
+                //use option index property...
+                to.add(option, before.index);
+            }
+        }
+    },
+
+    moveDownClicked : function(event)
+    {
+        var lastSelected = $A(this.selected.options).reverse(true).find(function (option)
+        {
+            return option.selected;
+        });
+        var lastPos = lastSelected.index;
+        var before = this.selected.options[lastPos + 2];
+
+    // TODO: needs to be "reorder options"
+        this.reorderSelected(this.removeSelectedOptions(this.selected), before);
+
+        Event.stop(event);
+    },
+
+    reorderSelected : function(movers, before)
+    {
+        movers.each(function(option)
+        {
+            this.selected.add(option, before);
+        }.bind(this));
+
+        this.updateHidden();
+        this.updateButtons();
+    }
+};
+
+
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/select.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/select.png
new file mode 100644
index 0000000..78c78a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/select.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-asc.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-asc.png
new file mode 100644
index 0000000..8a539c5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-asc.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-desc.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-desc.png
new file mode 100644
index 0000000..b150dbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sort-desc.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sortable.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sortable.png
new file mode 100644
index 0000000..1e301ee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/sortable.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/internal/InternalStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/internal/InternalStrings.properties
new file mode 100644
index 0000000..f808a70
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/internal/InternalStrings.properties
@@ -0,0 +1,19 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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-action-not-serializable=Error serializing component action for component %s: %s
+enclose-errors-in-form=The Errors component must be enclosed by a Form component.
+failure-instantitating-object=Exception instantiating instance of %s (for component '%s'): %s
+conflicting-encoding-type=Encoding type of form has already been set to '%s' and may not be changed to '%s'.
+to-client-should-return-string=Return value from 'parseClient' event handler method must be a string.
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ExceptionReport.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ExceptionReport.tml
new file mode 100644
index 0000000..18102b8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ExceptionReport.tml
@@ -0,0 +1,60 @@
+<html xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Application Exception</title>
+    </head>
+    <body>
+        <h1 class="t-exception-report">An unexpected application exception has occurred.</h1>
+
+        <t:if test="productionMode">
+            <p>${rootException.message}</p>
+            <t:parameter name="else">
+                <t:exceptiondisplay exception="rootException"/>
+
+                <div class="t-env-data">
+
+                    <h2>Tapestry Framework</h2>
+                    <dl>
+                        <dt>Version</dt>
+                        <dd>${tapestryVersion}</dd>
+                    </dl>
+
+                    <h2>Request</h2>
+                    <t:renderobject object="request"/>
+
+                    <t:if test="hasSession">
+                        <h2>Session</h2>
+                        <dl>
+                            <t:loop source="session.attributeNames" value="attributeName">
+                                <dt>${attributeName}</dt>
+                                <dd>
+                                    <t:renderobject object="attributeValue"/>
+                                </dd>
+                            </t:loop>
+                        </dl>
+                    </t:if>
+
+                    <h2>System Properties</h2>
+                    <dl>
+                        <t:loop source="systemProperties" value="propertyName">
+                            <dt>${propertyName}</dt>
+                            <dd>
+                                <t:if test="simpleProperty">
+                                    ${propertyValue}
+                                    <t:parameter name="else">
+                                        <ul>
+                                            <li t:type="loop" source="complexPropertyValue" value="var:path">
+                                                ${var:path}
+                                            </li>
+                                        </ul>
+                                    </t:parameter>
+                                </t:if>
+                            </dd>
+                        </t:loop>
+                    </dl>
+
+                </div>
+            </t:parameter>
+        </t:if>
+    </body>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.tml
new file mode 100644
index 0000000..e4867c0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyDisplayBlocks.tml
@@ -0,0 +1,19 @@
+<t:container xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:block id="enum">
+        ${convertedEnumValue}
+    </t:block>
+
+    <t:block id="date">
+        <t:output value="context.propertyValue" format="dateFormat"/>
+    </t:block>
+
+    <t:block id="password">
+        <t:delegate to="passwordRenderer"/>
+    </t:block>
+
+    <t:block id="longtext">
+        <t:textoutput value="context.propertyValue"/>
+    </t:block>
+
+</t:container>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyEditBlocks.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyEditBlocks.tml
new file mode 100644
index 0000000..a061c1e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/PropertyEditBlocks.tml
@@ -0,0 +1,39 @@
+<div xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:block id="text">
+        <t:label for="textField"/>
+        <input t:id="textField"/>
+    </t:block>
+
+    <t:block id="number">
+        <t:label for="numberField"/>
+        <input t:id="numberField" class="t-number"/>
+    </t:block>
+
+
+    <t:block id="enum">
+        <t:label for="select"/>
+        <input t:id="select"/>
+    </t:block>
+
+    <t:block id="boolean">
+        <t:label for="checkboxField"/>
+        <input t:id="checkboxField"/>
+    </t:block>
+
+    <t:block id="date">
+        <t:label for="dateField"/>
+        <input t:id="dateField"/>
+    </t:block>
+
+    <t:block id="password">
+        <t:label for="passwordField"/>
+        <input t:id="passwordField"/>
+    </t:block>
+
+    <t:block id="longtext">
+        <t:label for="textarea"/>
+        <textarea t:id="textarea"/>
+    </t:block>
+
+</div>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml
new file mode 100644
index 0000000..cc5042b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml
@@ -0,0 +1,72 @@
+<html xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Tapestry IoC Services Status</title>
+        <style>
+            TR.defined {
+            color: #666666;
+            font-style: italic;
+            }
+
+            TR.virtual
+            {
+            color: blue;
+            }
+
+            TR.real
+            {
+            color: green;
+            }
+
+
+        </style>
+    </head>
+    <body>
+
+        <h1>Tapestry IoC Services Status</h1>
+
+        <p>${activity.size()} services defined in the IoC Registry.</p>
+
+        <t:grid rowsperpage="100" model="model" pagerposition="top" rowClass="row.status"
+                source="activity" row="row">
+
+            <t:parameter name="serviceInterfaceCell">
+                ${row.serviceInterface}
+            </t:parameter>
+
+        </t:grid>
+
+        <p>
+            Explanation of status:
+            <dl>
+                <dt>Builtin</dt>
+                <dd>
+                    A fundamental service that exists even before the Registry is
+                    created.
+                </dd>
+
+                <dt>Defined</dt>
+                <dd>
+                    The service is defined, but has not yet been referenced.
+                </dd>
+
+                <dt>Virtual</dt>
+                <dd>
+                    The service has been referenced (usually for injection into
+                    another service) but has not yet been
+                    <em>realized</em>
+                    into an instantiated service. Realization occurs with the
+                    first method invocation on the proxy.
+                </dd>
+
+                <dt>Real</dt>
+                <dd>
+                    The service has been realized: instantiated, dependencies
+                    injected, decorated with interceptors and is fully in
+                    operation.
+                </dd>
+
+            </dl>
+        </p>
+
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/css/datepicker.css b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/css/datepicker.css
new file mode 100644
index 0000000..b91084d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/css/datepicker.css
@@ -0,0 +1,143 @@
+.datePicker {

+    border: 1px solid WindowText;

+    background: Window;

+    width: 170px;

+    padding: 0px;

+    cursor: default;

+    -moz-user-focus: normal;

+}

+

+.datePicker td {

+    font: smallcaption;

+    font: small-caption;

+    text-align: center;

+    color: WindowText;

+    cursor: default;

+    font-weight: normal !important;

+    -moz-user-select: none;

+    padding: 0;

+}

+

+.datePicker td.red {

+    color: red;

+}

+

+.datePicker .header {

+    background: ActiveCaption;

+    padding: 3px;

+    border-bottom: 1px solid WindowText;

+}

+

+.datePicker .headerTable {

+    width: 100%;

+}

+

+.datePicker .footer {

+    padding: 3px;

+}

+

+.datePicker .footerTable {

+    width: 100%;

+}

+

+.datePicker .grid {

+    padding: 3px;

+}

+

+.datePicker .gridTable {

+    width: 100%;

+}

+

+.datePicker .gridTable td {

+    width: 14.3%;

+}

+

+.datePicker .gridTable .daysRow td {

+    font-weight: bold !important;

+    border-bottom: 1px solid ThreeDDarkShadow;

+}

+

+.datePicker .grid .gridTable .upperLine {

+    width: 100%;

+    height: 2px;

+    overflow: hidden;

+    background: transparent;

+}

+

+.datePicker td.today {

+    font-weight: bold !important;

+}

+

+.datePicker td.selected {

+    background: Highlight;

+    color: HighlightText !important;

+}

+

+.datePicker td.labelContainer {

+    width: 100%;

+}

+

+.datePicker td .topLabel {

+    color: CaptionText;

+    display: block;

+    font-weight: bold !important;

+    width: 100%;

+    text-decoration: none;

+

+}

+

+.datePicker td.filler {

+    width: 100%;

+}

+

+.datePicker button {

+    border-width: 1px;

+    font: Caption;

+    font-weight: normal !important;

+    display: block;

+}

+

+.datePicker .previousButton {

+    background: buttonface url( "../images/arrow.left.png" ) no-repeat center center;

+}

+

+.datePicker .nextButton {

+    background: buttonface url( "../images/arrow.right.png" ) no-repeat center center;

+}

+

+.datePicker .previousButton,

+    .datePicker .nextButton {

+    width: 14px;

+    height: 14px;

+}

+

+.datePicker .todayButton,

+    .datePicker .noneButton {

+    width: 50px;

+}

+

+.datePicker .labelPopup {

+    position: absolute;

+    min-width: 130px;

+    background: Window;

+    border: 1px solid WindowText;

+    padding: 1px;

+}

+

+.datePicker .labelPopup a {

+    width: 100%;

+    display: block;

+    color: WindowText;

+    text-decoration: none;

+    white-space: nowrap;

+}

+

+.datePicker .labelPopup a:hover {

+    background: Highlight;

+    color: HighlightText;

+}

+

+.datePicker .labelPopup a.selected {

+    font-weight: bold;

+}

+

diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.left.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.left.png
new file mode 100644
index 0000000..93085aa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.left.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.right.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.right.png
new file mode 100644
index 0000000..79abee5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/images/arrow.right.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/js/datepicker.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/js/datepicker.js
new file mode 100644
index 0000000..6e7b645
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/datepicker_106/js/datepicker.js
@@ -0,0 +1,691 @@
+/*----------------------------------------------------------------------------\

+|                              Date Picker 1.06                               |

+|-----------------------------------------------------------------------------|

+|                         Created by Erik Arvidsson                           |

+|                  (http://webfx.eae.net/contact.html#erik)                   |

+|                      For WebFX (http://webfx.eae.net/)                      |

+|-----------------------------------------------------------------------------|

+|                            A DOM based Date Picker                          |

+|-----------------------------------------------------------------------------|

+|       Copyright (c) 1999, 2002, 2002, 2003, 2004, 2006 Erik Arvidsson       |

+|-----------------------------------------------------------------------------|

+| Licensed under the Apache License, Version 2.0 (the "License"); you may not |

+| use this file except in compliance with the License.  You may obtain a copy |

+| of the License at http://www.apache.org/licenses/LICENSE-2.0                |

+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |

+| Unless  required  by  applicable law or  agreed  to  in  writing,  software |

+| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |

+| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |

+| License  for the  specific language  governing permissions  and limitations |

+| under the License.                                                          |

+|-----------------------------------------------------------------------------|

+| Dependencies: datepicker.css      Date picker style declarations            |

+|-----------------------------------------------------------------------------|

+| 2002-02-10 | Changed _update method to only update the text nodes instead   |

+|            | rewriting the entire table. Also added support for mouse wheel |

+|            | in IE6.                                                        |

+| 2002-01-14 | Cleaned up for 1.0 public version                              |

+| 2002-01-15 | Replace all innerHTML calls with DOM1 methods                  |

+| 2002-01-18 | Minor IE6 bug that occured when dragging the mouse             |

+| 2002-01-19 | Added a popup that is shown when the user clicks on the month. |

+|            | This allows navigation to 6 adjacent months.                   |

+| 2002-04-10 | Fixed a bug that occured in the popup when a date was selected |

+|            | that caused surroundung months to "overflow"                   |

+|            | This had the effect that one could get two October months      |

+|            | listed.                                                        |

+| 2002-09-06 | I had missed one place were window was used instead of         |

+|            | doc.parentWindow                                               |

+| 2003-08-28 | Added support for ensurin no date overflow when changing       |

+|            | months.                                                        |

+| 2004-01-10 | Adding type on the buttons to ensure they are not submit       |

+|            | buttons. Minor CSS change for CSS2                             |

+| 2006-05-28 | Changed license to Apache Software License 2.0.                |

+|-----------------------------------------------------------------------------|

+| Created 2001-10-?? | All changes are in the log above. | Updated 2006-05-28 |

+\----------------------------------------------------------------------------*/

+

+// The DatePicker constructor

+// oDate : Date Optional argument representing the date to select

+// Note: some minor modifications for Tapestry, to work well as a popup.

+function DatePicker(oDate)

+{

+    // check arguments

+    if (arguments.length == 0)

+    {

+        this._selectedDate = new Date;

+        this._none = false;

+    }

+    else

+    {

+        this._selectedDate = oDate || new Date();

+        this._none = oDate == null;

+    }

+

+    this._matrix = [[],[],[],[],[],[],[]];

+    this._showNone = true;

+    this._showToday = true;

+    this._firstWeekDay = 0;	// start week with monday according to standards

+    this._redWeekDay = 6;	// sunday is the default red day.

+

+    this._dontChangeNone = false;

+}

+

+// two static fields describing the name of the months abd days

+DatePicker.months = [

+    "January", "February", "March", "April",

+    "May", "June", "July", "August",

+    "September", "October", "November", "December"];

+DatePicker.days = ["m", "t", "w", "t", "f", "s", "s"];

+

+

+// Function invoked whenever the selected date changes, whether by

+// navigation or when the user selects a date.

+DatePicker.prototype.onchange = function ()

+{

+};

+

+// onselect is more specified than onchange, and    is triggered only when the user makes a specific selection

+// using the calendar (rather than navigating to a new month). For Tapestry,

+// this will dismiss the popup.

+DatePicker.prototype.onselect = function()

+{

+}

+

+

+// create the nodes inside the date picker

+DatePicker.prototype.create = function (doc)

+{

+    if (doc == null) doc = document;

+

+    this._document = doc;

+

+	// create elements

+    this._el = doc.createElement("div");

+    this._el.className = "datePicker";

+

+	// header

+    var div = doc.createElement("div");

+    div.className = "header";

+    this._el.appendChild(div);

+

+    var headerTable = doc.createElement("table");

+    headerTable.className = "headerTable";

+    headerTable.cellSpacing = 0;

+    div.appendChild(headerTable);

+

+    var tBody = doc.createElement("tbody");

+    headerTable.appendChild(tBody);

+

+    var tr = doc.createElement("tr");

+    tBody.appendChild(tr);

+

+    var td = doc.createElement("td");

+    this._previousMonth = doc.createElement("button");

+    this._previousMonth.className = "previousButton";

+    this._previousMonth.setAttribute("type", "button");

+    td.appendChild(this._previousMonth);

+    tr.appendChild(td);

+

+    td = doc.createElement("td");

+    td.className = "labelContainer";

+    tr.appendChild(td);

+

+    this._topLabel = doc.createElement("a");

+    this._topLabel.className = "topLabel";

+    this._topLabel.href = "#";

+    this._topLabel.appendChild(doc.createTextNode(String.fromCharCode(160)));

+    td.appendChild(this._topLabel);

+

+    this._labelPopup = doc.createElement("div");

+    this._labelPopup.className = "labelPopup";

+	// no insertion

+

+    td = doc.createElement("td");

+    this._nextMonth = doc.createElement("button");

+    this._nextMonth.className = "nextButton";

+    this._nextMonth.setAttribute("type", "button");

+    td.appendChild(this._nextMonth);

+    tr.appendChild(td);

+

+	// grid

+    div = doc.createElement("div");

+    div.className = "grid";

+    this._el.appendChild(div);

+    this._table = div;

+

+	// footer

+    div = doc.createElement("div");

+    div.className = "footer";

+    this._el.appendChild(div);

+

+    var footerTable = doc.createElement("table");

+    footerTable.className = "footerTable";

+    footerTable.cellSpacing = 0;

+    div.appendChild(footerTable);

+

+    tBody = doc.createElement("tbody");

+    footerTable.appendChild(tBody);

+

+    tr = doc.createElement("tr");

+    tBody.appendChild(tr);

+

+    td = doc.createElement("td");

+    this._todayButton = doc.createElement("button");

+    this._todayButton.className = "todayButton";

+    this._todayButton.setAttribute("type", "button");

+    this._todayButton.appendChild(doc.createTextNode("Today"));

+    td.appendChild(this._todayButton);

+    tr.appendChild(td);

+

+    td = doc.createElement("td");

+    td.className = "filler";

+    td.appendChild(doc.createTextNode(String.fromCharCode(160)));

+    tr.appendChild(td);

+

+    td = doc.createElement("td");

+    this._noneButton = doc.createElement("button");

+    this._noneButton.className = "noneButton";

+    this._noneButton.setAttribute("type", "button");

+    this._noneButton.appendChild(doc.createTextNode("None"));

+    td.appendChild(this._noneButton);

+    tr.appendChild(td);

+

+

+    this._createTable(doc);

+

+    this._updateTable();

+    this._setTopLabel();

+

+    if (!this._showNone)

+        this._noneButton.style.visibility = "hidden";

+    if (!this._showToday)

+        this._todayButton.style.visibility = "hidden";

+

+	// IE55+ extension

+    this._previousMonth.hideFocus = true;

+    this._nextMonth.hideFocus = true;

+    this._todayButton.hideFocus = true;

+    this._noneButton.hideFocus = true;

+	// end IE55+ extension

+

+    // hook up events

+    var dp = this;

+	// buttons

+    this._previousMonth.onclick = function ()

+    {

+        dp._dontChangeNone = true;

+        dp.goToPreviousMonth();

+        dp._dontChangeNone = false;

+    };

+    this._nextMonth.onclick = function ()

+    {

+        dp._dontChangeNone = true;

+        dp.goToNextMonth();

+        dp._dontChangeNone = false;

+    };

+    this._todayButton.onclick = function ()

+    {

+        dp.goToToday();

+    };

+    this._noneButton.onclick = function ()

+    {

+        dp.setDate(null, true);

+    };

+

+    this._el.onselectstart = function ()

+    {

+        return false;

+    };

+

+    this._table.onclick = function (e)

+    {

+        // find event

+        if (e == null) e = doc.parentWindow.event;

+

+		// find td

+        var el = e.target != null ? e.target : e.srcElement;

+        while (el.nodeType != 1)

+            el = el.parentNode;

+        while (el != null && el.tagName && el.tagName.toLowerCase() != "td")

+            el = el.parentNode;

+

+		// if no td found, return

+        if (el == null || el.tagName == null || el.tagName.toLowerCase() != "td")

+            return;

+

+        var d = new Date(dp._selectedDate);

+        var n = Number(el.firstChild.data);

+        if (isNaN(n) || n <= 0 || n == null)

+            return;

+

+        d.setDate(n);

+        dp.setDate(d, true);

+    };

+

+	// show popup

+    this._topLabel.onclick = function (e)

+    {

+        dp._showLabelPopup();

+        return false;

+    };

+

+    this._el.onkeydown = function (e)

+    {

+        if (e == null) e = doc.parentWindow.event;

+        var kc = e.keyCode != null ? e.keyCode : e.charCode;

+

+        if (kc < 37 || kc > 40) return true;

+

+        var d = new Date(dp._selectedDate).valueOf();

+        if (kc == 37) // left

+            d -= 24 * 60 * 60 * 1000;

+        else if (kc == 39) // right

+            d += 24 * 60 * 60 * 1000;

+        else if (kc == 38) // up

+            d -= 7 * 24 * 60 * 60 * 1000;

+        else if (kc == 40) // down

+            d += 7 * 24 * 60 * 60 * 1000;

+

+        dp.setDate(new Date(d), false);

+        return false;

+    }

+

+	// ie6 extension

+    this._el.onmousewheel = function (e)

+    {

+        if (e == null) e = doc.parentWindow.event;

+        var n = - e.wheelDelta / 120;

+        var d = new Date(dp._selectedDate);

+        var m = d.getMonth() + n;

+        d.setMonth(m);

+

+

+        dp._dontChangeNone = true;

+        dp.setDate(d, false);

+        dp._dontChangeNone = false;

+

+        return false;

+    }

+

+    return this._el;

+};

+

+DatePicker.prototype.setDate = function (oDate, isSelection)

+{

+

+    this._hideLabelPopup();

+

+	// if null then set None

+    if (oDate == null)

+    {

+        if (!this._none)

+        {

+            this._none = true;

+            this._setTopLabel();

+            this._updateTable();

+

+            if (typeof this.onchange == "function")

+                this.onchange();

+        }

+

+        if (isSelection)

+            this.onselect();

+

+        return;

+    }

+

+	// if string or number create a Date object

+    if (typeof oDate == "string" || typeof oDate == "number")

+    {

+        oDate = new Date(oDate);

+    }

+

+

+	// do not update if not really changed

+    if (this._selectedDate.getDate() != oDate.getDate() ||

+        this._selectedDate.getMonth() != oDate.getMonth() ||

+        this._selectedDate.getFullYear() != oDate.getFullYear() ||

+        this._none)

+    {

+

+        if (!this._dontChangeNone)

+            this._none = false;

+

+        this._selectedDate = new Date(oDate);

+

+        this._setTopLabel();

+        this._updateTable();

+

+        if (typeof this.onchange == "function")

+            this.onchange();

+

+        if (isSelection)

+            this.onselect();

+    }

+

+    if (!this._dontChangeNone)

+        this._none = false;

+

+}

+

+

+DatePicker.prototype.getDate = function ()

+{

+    if (this._none) return null;

+    return new Date(this._selectedDate);	// create a new instance

+}

+

+// creates the table elements and inserts them into the date picker

+DatePicker.prototype._createTable = function (doc)

+{

+    var str, i;

+    var rows = 6;

+    var cols = 7;

+    var currentWeek = 0;

+

+    var table = doc.createElement("table");

+    table.className = "gridTable";

+    table.cellSpacing = 0;

+

+    var tBody = doc.createElement("tbody");

+    table.appendChild(tBody);

+

+	// days row

+    var tr = doc.createElement("tr");

+    tr.className = "daysRow";

+

+    var td, tn;

+    var nbsp = String.fromCharCode(160);

+    for (i = 0; i < cols; i++)

+    {

+        td = doc.createElement("td");

+        td.appendChild(doc.createTextNode(nbsp));

+        tr.appendChild(td);

+    }

+    tBody.appendChild(tr);

+

+	// upper line

+    tr = doc.createElement("tr");

+    td = doc.createElement("td");

+    td.className = "upperLine";

+    td.colSpan = 7;

+    tr.appendChild(td);

+    tBody.appendChild(tr);

+

+	// rest

+    for (i = 0; i < rows; i++)

+    {

+        tr = doc.createElement("tr");

+        for (var j = 0; j < cols; j++)

+        {

+            td = doc.createElement("td");

+            td.appendChild(doc.createTextNode(nbsp));

+            tr.appendChild(td);

+        }

+        tBody.appendChild(tr);

+    }

+    str += "</table>";

+

+    if (this._table != null)

+        this._table.appendChild(table)

+};

+// this method updates all the text nodes inside the table as well

+// as all the classNames on the tds

+DatePicker.prototype._updateTable = function ()

+{

+    // if no element no need to continue

+    if (this._table == null) return;

+

+    var i;

+    var str = "";

+    var rows = 6;

+    var cols = 7;

+    var currentWeek = 0;

+

+    var cells = new Array(rows);

+    this._matrix = new Array(rows)

+    for (i = 0; i < rows; i++)

+    {

+        cells[i] = new Array(cols);

+        this._matrix[i] = new Array(cols);

+    }

+

+	// Set the tmpDate to this month

+    var tmpDate = new Date(this._selectedDate.getFullYear(),

+            this._selectedDate.getMonth(), 1);

+    var today = new Date();

+	// go thorugh all days this month and store the text

+    // and the class name in the cells matrix

+    for (i = 1; i < 32; i++)

+    {

+        tmpDate.setDate(i);

+		// convert to ISO, Monday is 0 and 6 is Sunday

+        var weekDay = ( tmpDate.getDay() + 6 ) % 7;

+        var colIndex = ( weekDay - this._firstWeekDay + 7 ) % 7;

+        if (tmpDate.getMonth() == this._selectedDate.getMonth())

+        {

+

+            var isToday = tmpDate.getDate() == today.getDate() &&

+                          tmpDate.getMonth() == today.getMonth() &&

+                          tmpDate.getFullYear() == today.getFullYear();

+

+            cells[currentWeek][colIndex] = { text: "", className: "" };

+

+            if (this._selectedDate.getDate() == tmpDate.getDate() && !this._none)

+                cells[currentWeek][colIndex].className += "selected ";

+            if (isToday)

+                cells[currentWeek][colIndex].className += "today ";

+            if (( tmpDate.getDay() + 6 ) % 7 == this._redWeekDay) // ISO

+                cells[currentWeek][colIndex].className += "red";

+

+            cells[currentWeek][colIndex].text =

+            this._matrix[currentWeek][colIndex] = tmpDate.getDate();

+

+            if (colIndex == 6)

+                currentWeek++;

+        }

+    }

+

+	// fix day letter order if not standard

+    var weekDays = DatePicker.days;

+    if (this._firstWeekDay != 0)

+    {

+        weekDays = new Array(7);

+        for (i = 0; i < 7; i++)

+            weekDays[i] = DatePicker.days[ (i + this._firstWeekDay) % 7];

+    }

+

+	// update text in days row

+    var tds = this._table.firstChild.tBodies[0].rows[0].cells;

+    for (i = 0; i < cols; i++)

+        tds[i].firstChild.data = weekDays[i];

+

+	// update the text nodes and class names

+    var trs = this._table.firstChild.tBodies[0].rows;

+    var tmpCell;

+    var nbsp = String.fromCharCode(160);

+    for (var y = 0; y < rows; y++)

+    {

+        for (var x = 0; x < cols; x++)

+        {

+            tmpCell = trs[y + 2].cells[x];

+            if (typeof cells[y][x] != "undefined")

+            {

+                tmpCell.className = cells[y][x].className;

+                tmpCell.firstChild.data = cells[y][x].text;

+            }

+            else

+            {

+                tmpCell.className = "";

+                tmpCell.firstChild.data = nbsp;

+            }

+        }

+    }

+}

+

+// sets the label showing the year and selected month

+DatePicker.prototype._setTopLabel = function ()

+{

+    var str = this._selectedDate.getFullYear() + " " + DatePicker.months[ this._selectedDate.getMonth() ];

+    if (this._topLabel != null)

+        this._topLabel.lastChild.data = str;

+}

+

+DatePicker.prototype.goToNextMonth = function ()

+{

+    var d = new Date(this._selectedDate);

+    d.setDate(Math.min(d.getDate(), DatePicker.getDaysPerMonth(d.getMonth() + 1,

+            d.getFullYear()))); // no need to catch dec -> jan for the year

+    d.setMonth(d.getMonth() + 1);

+    this.setDate(d);

+}

+

+DatePicker.prototype.goToPreviousMonth = function ()

+{

+    var d = new Date(this._selectedDate);

+    d.setDate(Math.min(d.getDate(), DatePicker.getDaysPerMonth(d.getMonth() - 1,

+            d.getFullYear()))); // no need to catch jan -> dec for the year

+    d.setMonth(d.getMonth() - 1);

+    this.setDate(d);

+}

+

+DatePicker.prototype.goToToday = function ()

+{

+    if (this._none)

+        // change the selectedDate to force update if none was true

+        this._selectedDate = new Date(this._selectedDate + 10000000000);

+    this._none = false;

+    this.setDate(new Date(), true);

+}

+

+DatePicker.prototype.setShowToday = function (bShowToday)

+{

+    if (typeof bShowToday == "string")

+        bShowToday = !/false|0|no/i.test(bShowToday);

+

+    if (this._todayButton != null)

+        this._todayButton.style.visibility = bShowToday ? "visible" : "hidden";

+    this._showToday = bShowToday;

+}

+

+DatePicker.prototype.getShowToday = function ()

+{

+    return this._showToday;

+}

+

+DatePicker.prototype.setShowNone = function (bShowNone)

+{

+    if (typeof bShowNone == "string")

+        bShowNone = !/false|0|no/i.test(bShowNone);

+

+    if (this._noneButton != null)

+        this._noneButton.style.visibility = bShowNone ? "visible" : "hidden";

+    this._showNone = bShowNone;

+}

+

+DatePicker.prototype.getShowNone = function ()

+{

+    return this._showNone;

+}

+

+// 0 is monday and 6 is sunday as in the ISO standard

+DatePicker.prototype.setFirstWeekDay = function (nFirstWeekDay)

+{

+    if (this._firstWeekDay != nFirstWeekDay)

+    {

+        this._firstWeekDay = nFirstWeekDay;

+        this._updateTable();

+    }

+}

+

+DatePicker.prototype.getFirstWeekDay = function ()

+{

+    return this._firstWeekDay;

+}

+

+// 0 is monday and 6 is sunday as in the ISO standard

+DatePicker.prototype.setRedWeekDay = function (nRedWeekDay)

+{

+    if (this._redWeekDay != nRedWeekDay)

+    {

+        this._redWeekDay = nRedWeekDay;

+        this._updateTable();

+    }

+}

+

+DatePicker.prototype.getRedWeekDay = function ()

+{

+    return this._redWeekDay;

+}

+

+

+DatePicker.prototype._showLabelPopup = function ()

+{

+

+    /*

+     this._labelPopup document.createElement( "DIV" );

+     div.className = "month-popup";

+     div.noWrap = true;

+     el.unselectable = div.unselectable = "on";

+     el.onselectstart = div.onselectstart = function () { return false; };

+     */

+

+    var dateContext = function (dp, d)

+    {

+        return function (e)

+        {

+            dp._dontChangeNone = true;

+            dp._hideLabelPopup();

+            dp.setDate(d);

+            dp._dontChangeNone = false;

+            return false;

+        };

+    };

+

+    var dp = this;

+

+	// clear all old elements in the popup

+    while (this._labelPopup.hasChildNodes())

+        this._labelPopup.removeChild(this._labelPopup.firstChild);

+

+    var a, tmp, tmp2;

+    for (var i = -3; i < 4; i++)

+    {

+        tmp = new Date(this._selectedDate);

+        tmp2 = new Date(this._selectedDate);	// need another tmp to catch year change when checking leap

+        tmp2.setDate(1);

+        tmp2.setMonth(tmp2.getMonth() + i);

+        tmp.setDate(Math.min(tmp.getDate(), DatePicker.getDaysPerMonth(tmp.getMonth() + i,

+                tmp2.getFullYear())));

+        tmp.setMonth(tmp.getMonth() + i);

+

+        a = this._document.createElement("a");

+        a.href = "javascript:void 0;";

+        a.onclick = dateContext(dp, tmp);

+        a.appendChild(this._document.createTextNode(tmp.getFullYear() + " " +

+                                                    DatePicker.months[ tmp.getMonth() ]));

+        if (i == 0)

+            a.className = "selected";

+        this._labelPopup.appendChild(a);

+    }

+

+    this._topLabel.parentNode.insertBefore(this._labelPopup, this._topLabel.parentNode.firstChild);

+};

+

+DatePicker.prototype._hideLabelPopup = function ()

+{

+    if (this._labelPopup.parentNode)

+        this._labelPopup.parentNode.removeChild(this._labelPopup);

+};

+

+DatePicker._daysPerMonth = [31,28,31,30,31,30,31,31,30,31,30,31];

+DatePicker.getDaysPerMonth = function (nMonth, nYear)

+{

+    nMonth = (nMonth + 12) % 12;

+    var res = DatePicker._daysPerMonth[nMonth];

+    if (nMonth == 1)

+    {

+        res += nYear % 4 == 0 && !(nYear % 400 == 0) ? 1 : 0;

+    }

+    return res;

+};
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/default.css b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/default.css
new file mode 100644
index 0000000..172d558
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/default.css
@@ -0,0 +1,416 @@
+/* Tapestry styles all start with "t-" */
+DIV.t-error {
+    border: 1px solid red;
+    padding: 0px;
+    margin: 4px 0px;
+}
+
+DIV.t-error DIV {
+    padding: 2px;
+    display: block;
+    margin: 0px;
+    background-color: red;
+    color: white;
+    font-weight: bold;
+}
+
+DIV.t-error UL {
+    margin: 2px 0px;
+    background-color: white;
+    color: red;
+}
+
+DIV.t-error LI {
+    margin-left: 20px;
+}
+
+HTML>BODY DIV.t-error LI {
+    margin-left: -20px;
+}
+
+.t-invisible {
+    display: none;
+}
+
+LABEL.t-error {
+    color: red;
+}
+
+INPUT.t-error, TEXTAREA.t-error {
+    border-color: red;
+    font-style: italic;
+    color: red;
+}
+
+IMG.t-error-icon {
+    margin-left: 4px;
+}
+
+IMG.t-sort-icon {
+    margin-left: 4px;
+}
+
+DIV.t-exception-message {
+    font-style: italic;
+    font-size: 12pt;
+    border: thin dotted silver;
+    margin: 5px 0px;
+    padding: 3px;
+}
+
+DIV.t-exception-report, DIV.t-env-data {
+    font-family: "Trebuchet MS", Arial, sans-serif;
+}
+
+DIV.t-exception-report LI {
+    margin-left: -40px;
+}
+
+DIV.t-exception-report DT, DIV.t-env-data DT {
+    color: green;
+    padding-left: 2px;
+    background-color: #FFFFCF;
+}
+
+DIV.t-exception-report LI {
+    list-style: none;
+}
+
+SPAN.t-exception-class-name {
+    display: block;
+    margin-top: 15px;
+    font-size: 12pt;
+    background-color: #E1E1E1;
+    color: blue;
+    padding: 2px 3px;
+    font-weight: bold;
+}
+
+UL.t-stack-trace LI {
+    font-family: Monaco, Times, monospace;
+    font-size: 10pt;
+    margin-left: -25px;
+    list-style: square;
+}
+
+LI.t-usercode-frame {
+    font-weight: bold;
+    color: blue;
+}
+
+H1.t-exception-report {
+    font-family: "Trebuchet MS", Arial, sans-serif;
+    color: red;
+}
+
+DIV.t-exception-report DT:after {
+    content: ":";
+}
+
+DIV.t-exception-report DD, DIV.t-env-data DD {
+    margin-left: 10px;
+}
+
+TABLE.t-data-table {
+    border-collapse: collapse;
+    margin: 0px;
+    padding: 2px;
+}
+
+TABLE.t-data-table TH {
+    background-color: black;
+    color: white;
+}
+
+TABLE.t-data-table TD {
+    border: 1px solid silver;
+    margin: 0px;
+}
+
+DIV.t-beaneditor, DIV.t-beandisplay {
+    display: block;
+    background: #ffc;
+    border: 2px outset brown;
+    padding: 2px;
+    font-family: "Trebuchet MS", Arial, sans-serif;
+}
+
+DIV.t-beandisplay {
+    background: #CCBE99;
+    border: 2px outset black;
+    width: auto;
+}
+
+DIV.t-beaneditor-row {
+    padding: 4px 0px 2px 0px;
+}
+
+DIV.t-beaneditor-row LABEL:after {
+    content: ":";
+}
+
+DIV.t-beandisplay-row {
+    clear: both;
+}
+
+DIV.t-beaneditor-row LABEL, DIV.t-beandisplay DIV.t-beandisplay-label {
+    width: 250px;
+    display: block;
+    float: left;
+    text-align: right;
+    clear: left;
+    padding-right: 3px;
+    vertical-align: middle;
+}
+
+INPUT.t-number {
+    text-align: right;
+}
+
+DIV.t-beandisplay DIV.t-beandisplay-label {
+    padding-right: 5px;
+}
+
+TABLE.t-data-grid THEAD TR {
+    color: white;
+    background-color: #809FFF;
+}
+
+TABLE.t-data-grid THEAD TR TH {
+    text-align: left;
+    padding: 3px;
+    white-space: nowrap;
+    border-right: 1px solid silver;
+    border-bottom: 1px solid silver;
+}
+
+TABLE.t-data-grid {
+    border-collapse: collapse;
+    border-left: 1px solid silver;
+}
+
+TABLE.t-data-grid TBODY TR TD {
+    border-right: 1px solid silver;
+    border-bottom: 1px solid silver;
+    padding: 2px;
+}
+
+DIV.t-data-grid {
+    font-family: "Trebuchet MS", Arial, sans-serif;
+}
+
+DIV.t-data-grid-pager {
+    margin: 8px 0px;
+}
+
+DIV.t-data-grid-pager A, DIV.t-data-grid-pager SPAN.current {
+    text-decoration: none;
+    color: black;
+    padding: 2px 5px;
+    font-size: medium;
+    border: 1px solid silver;
+    margin-right: 5px;
+}
+
+DIV.t-data-grid-pager A:hover {
+    border: 1px solid black;
+}
+
+DIV.t-data-grid-pager SPAN.current {
+    color: white;
+    background-color: #809FFF;
+}
+
+TABLE.t-data-grid TR TH A {
+    color: white;
+}
+
+IMG {
+    border: none;
+}
+
+DIV.t-env-data-section {
+    padding-left: 5px;
+}
+
+DIV.t-env-data DD, DIV.t-exception-report DD {
+    margin-left: 25px;
+    margin-bottom: 10px;
+}
+
+DIV.t-env-data LI {
+    margin-left: -25px;
+}
+
+DIV.t-env-data-section {
+    font-size: 12pt;
+    background-color: #E1E1E1;
+    color: blue;
+    padding: 2px 3px;
+    font-weight: bold;
+}
+
+TABLE.t-location-outer {
+    padding: 5px;
+    border-collapse: collapse;
+    border: 1px solid black;
+    width: 100%;
+}
+
+TD.t-location-line {
+    width: 40px;
+    text-align: right;
+    padding: 0px;
+    background-color: #E1E1E1;
+    padding-right: 3px;
+    border-right: 1px solid black;
+}
+
+TD.t-location-content {
+    border-top: 1px solid silver;
+    border-right: 1px solid black;
+    white-space: pre;
+}
+
+TD.t-location-current {
+    background-color: #FFFFCF;
+}
+
+TD.t-location-content-first {
+    border-top: 1px solid black;
+}
+
+DIV.t-palette {
+    display: inline;
+}
+
+DIV.t-palette SELECT {
+    margin-bottom: 2px;
+    width: 200px;
+}
+
+DIV.t-palette-title {
+    color: white;
+    background-color: #809FFF;
+    text-align: center;
+    font-weight: bold;
+    margin-bottom: 3px;
+    display: block;
+}
+
+DIV.t-palette-available {
+    float: left;
+}
+
+DIV.t-palette-controls {
+    margin: 5px 5px;
+    float: left;
+    text-align: center;
+}
+
+DIV.t-palette-controls BUTTON {
+    display: block;
+    margin-bottom: 3px;
+}
+
+DIV.t-palette-controls BUTTON[disabled] IMG {
+    filter: alpha( opacity = 25 );
+    -moz-opacity: .25;
+}
+
+DIV.t-palette-selected {
+    float: left;
+    clear: right;
+}
+
+DIV.t-palette-spacer {
+    clear: left;
+}
+
+IMG.t-calendar-trigger {
+    padding-left: 3px;
+    cursor: pointer;
+}
+
+DIV.t-autocomplete-menu UL {
+    border: 2px outset #cc9933;
+    background-color: #cc9933;
+    padding: 4px 6px;
+    overflow: auto;
+}
+
+DIV.t-autocomplete-menu LI {
+    color: white;
+    list-style-type: none;
+    padding: 0px;
+    margin: 0px;
+    border-bottom: 1px solid black;
+    cursor: pointer;
+}
+
+DIV.t-autocomplete-menu LI.selected {
+    color: black;
+    font-weight: bold;
+}
+
+DIV.t-error-popup SPAN {
+    background: transparent url( 'error-bevel-left.gif' ) no-repeat;
+    display: block;
+    line-height: 28px;
+    margin-left: 0px;
+    padding: 0px 5px 10px 22px;
+}
+
+HTML>BODY DIV.t-error-popup SPAN {
+    background: transparent url( 'error-bevel-left.png' ) no-repeat;
+}
+
+DIV.t-error-popup {
+    background: transparent url( 'error-bevel-right.gif' ) no-repeat scroll top right;
+    cursor: pointer;
+    color: #FFF;
+    display: block;
+    float: left;
+    font: normal 12px arial, sans-serif;
+    height: 39px;
+    margin-right: 6px;
+    padding-right: 29px;
+    text-decoration: none;
+}
+
+HTML>BODY DIV.t-error-popup {
+    background: transparent url( 'error-bevel-right.png' ) no-repeat scroll top right;
+}
+
+UL.t-data-list LI {
+    list-style-type: square;
+}
+
+/* The console is used to show debugging messages. */
+DIV.t-console {
+    position: absolute;
+    z-index: 1;
+    top: 2px;
+    left: 2px;
+}
+
+DIV.t-console DIV {
+    font-weight: bold;
+    cursor: pointer;
+    padding: 0px 2px;
+}
+
+DIV.t-console DIV.t-err {
+    background-color: red;
+    color: white;
+}
+
+DIV.t-console DIV.t-warn {
+    background-color: yellow;
+    color: black;
+}
+
+DIV.t-console DIV.t-debug {
+    background-color: silver;
+    color: black;
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/deselect.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/deselect.png
new file mode 100644
index 0000000..083612d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/deselect.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/dom/DomStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/dom/DomStrings.properties
new file mode 100644
index 0000000..bfa901e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/dom/DomStrings.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+no-root-element=No root element has been defined.
+namespace-uri-not-mapped-to-prefix=Namespace prefix for URI '%s' is not defined.
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.gif b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.gif
new file mode 100644
index 0000000..16d83d4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.png
new file mode 100644
index 0000000..5a2d39d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-left.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.gif b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.gif
new file mode 100644
index 0000000..31d6266
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.png b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.png
new file mode 100644
index 0000000..69fd960
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/error-bevel-right.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/field-error-marker.gif b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/field-error-marker.gif
new file mode 100644
index 0000000..130b7e2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/field-error-marker.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties
new file mode 100644
index 0000000..a79aa2f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/InternalStrings.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+bad-key-value=Key/value pair '%s' is not properly formatted (it does not contain an equals sign).
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages.properties
new file mode 100644
index 0000000..fada18c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages.properties
@@ -0,0 +1,35 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# We try to keep these consistent, with the constraint value (if applicable)
+# as the first parameter, and the field's label as the second parameter. Occasionally
+# we must use specific indexing when that's not the best order.
+
+required=You must provide a value for %s.
+minimum-string-length=You must provide at least %d characters for %s.
+maximum-string-length=You may provide at most %d characters for %s.
+min-integer=%2$s requires a value of at least %1$d. 
+max-integer=%2$s requires a value no larger than %1$d.
+# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
+# this.
+regexp=%2$s does not match pattern '%1$s'.
+
+# This is where the translator messages go.
+
+integer-format-exception=The input value '%s' is not parseable as an integer value.
+number-format-exception=The input value '%s' is not parseable as a numeric value.
+
+# The label/alt text for the icon that is displayed next to each field.
+
+icon-label=[Error]
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_it.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_it.properties
new file mode 100644
index 0000000..ad71b65
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_it.properties
@@ -0,0 +1,35 @@
+# Copyright 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# We try to keep these consistent, with the constraint value (if applicable)
+# as the first parameter, and the field's label as the second parameter. Occasionally
+# we must use specific indexing when that's not the best order.
+
+required=Il valore di %s deve essere immesso.
+minimum-string-length=Il campo %2$s richiede almeno %1$d caratteri.
+maximum-string-length=Il campo %2$s può contenere al massimo %1$d caratteri.
+min-integer=%2$s deve essere maggiore di %1$d. 
+max-integer=%2$s deve essere minore di %1$d.
+# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
+# this.
+regexp=%2$s non soddisfa la regola '%1$s'.
+
+# This is where the translator messages go.
+
+integer-format-exception=Il valore di '%s' deve essere un numero intero.
+number-format-exception=Il valore di '%s' deve essere un numero.
+
+# The label/alt text for the icon that is displayed next to each field.
+
+icon-label=[Errore]
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_zh_CN.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_zh_CN.properties
new file mode 100644
index 0000000..b76ffbf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/ValidationMessages_zh_CN.properties
@@ -0,0 +1,34 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 label/alt text for the icon that is displayed next to each field.
+icon-label = [\u9519\u8BEF]
+
+# This is where the translator messages go.
+integer-format-exception = '%s'\u7684\u5185\u5BB9\u5FC5\u987B\u662F\u6574\u6570\u3002
+
+max-integer = %2$s\u7684\u6570\u503C\u4E0D\u80FD\u5927\u4E8E%1$d\u3002
+
+maximum-string-length = %2$s\u7684\u5185\u5BB9\u4E0D\u80FD\u8D85\u8FC7%1$d\u5B57\u7B26\u3002
+
+min-integer = %2$s\u7684\u6570\u503C\u4E0D\u80FD\u5C0F\u4E8E%1$d\u3002
+
+minimum-string-length = %2$s\u7684\u5185\u5BB9\u4E0D\u80FD\u5C11\u4E8E%1$s\u5B57\u7B26\u3002
+
+number-format-exception = \u8F93\u5165\u7684'%s'\u4E0D\u662F\u6570\u5B57.
+
+# We try to keep these consistent, with the constraint value (if applicable)
+# as the first parameter, and the field's label as the second parameter. Occasionally
+# we must use specific indexing when that's not the best order.
+required = \u8BF7\u8F93\u5165%s\u7684\u5185\u5BB9\u3002
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties
new file mode 100644
index 0000000..ca88199
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/beaneditor/BeanEditorStrings.properties
@@ -0,0 +1,17 @@
+# Copyright 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+duplicate-property-name=Bean editor model for %s already contains a property model for property '%s'.
+unknown-property=Bean editor model for %s does not contain a property named '%s'.  Available properties: %s.
+unknown-property-id=Bean editor model for %s does not contain a property with id '%s'.  Available property ids: %s.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/bindings/BindingsStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/bindings/BindingsStrings.properties
new file mode 100644
index 0000000..0db561b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/bindings/BindingsStrings.properties
@@ -0,0 +1,16 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+binding-is-read-only=Binding %s is read-only.

+validate-binding-for-fields-only=Component '%s' is not a field (it does not implement the Field interface) and may not be used with the validate: binding prefix.

diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/model/ModelStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/model/ModelStrings.properties
new file mode 100644
index 0000000..2480d1b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/model/ModelStrings.properties
@@ -0,0 +1,19 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+duplicate-parameter=Parameter '%s' of component %s is already defined.

+duplicate-parameter-value=A value for parameter '%s' of embedded component %s (of component class %s) has already been provided.

+duplicate-component-id=Embedded component '%s' has already been defined for component class %s.

+duplicate-mixin=Mixin %s (for component %s) has already been defined.

+missing-persistent-field=No field persistence strategy has been defined for field '%s'.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
new file mode 100644
index 0000000..4f27591
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
@@ -0,0 +1,94 @@
+# Copyright 2006, 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+duplicate-contribution=Contribution %s (for type %s) conflicts with existing contribution %s and has been ignored.
+markup-writer-no-current-element=This markup writer does not have a current element. \
+  The current element is established with the first call to element() and is \
+  maintained across subsequent calls. 
+no-constructor-found=Unable to find an applicable constructor for class %s.
+missing-declared-field=Class %s does not contain a field named '%s'.
+error-adding-method=Error adding method %s to class %s: %s 
+field-already-claimed=Field %s of class %s is already claimed by %s and can not be claimed by %s.
+no-declared-method=Class %s does not declare method '%s'.
+class-not-transformed=Class %s was not transformed for use as a component; this can happen if it is an interface, or was not in a package subject to component transformation.
+new-parser-error=Failure obtaining a SAX parser for resource %s: %s
+missing-template-resource=Template resource %s does not exist.
+template-parse-error=Failure parsing template %s: %s
+content-inside-body-not-allowed=Content inside a Tapestry body element is not allowed (at %s). The content has been ignored.
+may-not-nest-elements-inside-body=Element '%s' is nested within a Tapestry body element, which is not allowed.
+method-compile-error=Error compiling method %s (%s): %s
+render-queue-error=Render queue error in %s: %s
+read-only-field=Field %s.%s is read-only.
+non-private-fields=Class %s contains field(s) (%s) that are not private. \
+  You should change these fields to private, and add accessor methods if needed.  
+mixins-invalid-without-id-or-type=You may not specify mixins for element <%s> because it does not represent a component (which requires either an id attribute or a type attribute).
+comp-type-conflict=Embedded component '%s' provides a type attribute in the template ('%s') as well as in the component class ('%s'). \
+  You should not provide a type attribute in the template when defining an embedded component within the component class.
+no-type-for-embedded-component=Embedded component '%s' has no type. You should specify a type in the component template, \
+  or define the component inside class %s using the @Component annotation on a private instance variable.
+embedded-components-not-in-template=Embedded component(s) %s are defined within component class %s, but are not present in the component template.
+binding-source-failure=Could not convert '%s' into a component parameter binding: %s
+page-name-unresolved=Unable to resolve class name %s to a logical page name.
+context-index-out-of-range=Method %s has more parameters than there are context values for this component event.
+exception-in-method-parameter=Exception in method %s, parameter #%d: %s
+component-event-is-aborted=Can not store result from invoking method %s, because an event result value has already been obtained from some other event handler method.
+unknown-persistent-field-strategy='%s' is not a defined persistent strategy.  Defined strategies: %s.
+could-not-resolve-page-name=Unable to resolve '%s' to a page class name.  Available page names: %s.
+could-not-canonicalize-page-name=Unable to resolve '%s' to a known page name. Available page names: %s.
+could-not-resolve-component-type=Unable to resolve '%s' to a component class name.  Available component types: %s.
+could-not-resolve-mixin-type=Unable to resolve '%s' to a mixin class name.  Available mixin types: %s.
+parameter-name-must-be-unique=Parameter names are required to be unique.  Parameter '%s' already has the value '%s'.
+page-is-dirty=Page %s is dirty, and will be discarded (rather than returned to the page pool).
+component-instance-is-not-a-page=Component %s was returned from an event handler method, but is not a page component. The page containing the component will render the client response.
+failure-reading-messages=Unable to read message catalog from %s: %s
+unknown-asset-prefix=Unknown prefix for asset path '%s'.
+asset-does-not-exist=Unable to locate asset '%s' (the file does not exist).
+wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests. 
+unknown-validator-type=Unknown validator type '%s'.  Configured validators are %s.
+validator-specification-parse-error=Unexpected character '%s' at position %d of input string: %s
+unknown-translator-type=Unknown translator type '%s'.  Configured translators are %s.
+missing-from-environment=No object of type %s is available from the Environment.  Available types are %s.
+invalid-component-event-result=A component event handler method returned the value %s. Return type %s can not be handled.  Configured return types are %s.
+undefined-tapestry-attribute=Element <%s> does not support an attribute named '%s'. The only allowed attribute name is '%s'.
+attribute-not-allowed=Element <%s> does not support any attributes.
+parameter-element-name-required=The name attribute of the <parameter> element must be specified.
+missing-application-state-persistence-strategy=No application state persistence strategy is available with name '%s'. Available strategies: %s.
+method-is-void=Method '%s' returns void (in class %s, within property expression '%s').
+method-not-found=No public method '%s' in class %s (within property expression '%s').
+no-such-property=Class %s does not contain a property named '%s' (within property expression '%s').  Available properties: %s.
+write-only-property=Property '%s' of class %s (within property expression '%s') is not readable (it has no read accessor method).
+request-exception=Processing of request failed with uncaught exception: %s
+component-recursion=The template for component %s is recursive (contains another direct or indirect reference to component %<s). \
+  This is not supported (components may not contain themselves).
+client-state-must-be-serializable=State persisted on the client must be serializable, but %s does not implement the Serializable interface.
+corrupt-client-state=Serialized client state was corrupted. \
+  This may indicate that too much state is being stored, which can cause the encoded string to be truncated by the client web browser.
+unclosed-attribute-expression=Attribute expression '%s' is missing a closing brace.
+no-display-for-data-type=There is no defined way to display data of type '%s'. Make a contribution to the BeanBlockSource service for this type.
+no-edit-for-data-type=There is no defined way to edit data of type '%s'.  Make a contribution to the BeanBlockSource service for this type.
+missing-validator-constraint=Validator '%s' requires a validation constraint (of type %s) but none was provided.
+resource-access-forbidden=URI %s may not be accessed remotely.
+no-markup-from-page-render=Page %s did not generate any markup when rendered. This could be because its template file could not be located, or because a \
+  render phase method in the page prevented rendering.
+base-class-in-wrong-package=Base class %s (super class of %s) is not in a controlled package and is therefore not valid. You should try moving the class to package %s.
+invalid-component-id=Component id '%s' is not valid; component ids must be valid Java identifiers: start with a letter, and consist of letters, numbers and underscores.
+invalid-block-id=Block id '%s' is not valid; block ids must be valid Java identifiers: start with a letter, and consist of letters, numbers and underscores. 
+page-pool-exausted=The page pool for page '%s' (in locale %s) has been exausted: there are %d instances currently being used and no more can be created. \
+  Try increasing the hard limit (symbol tapestry.page-pool.hard-limit) to allow additional instances to be created, \
+  or increasing the soft wait (symbol tapestry.page-pool.soft-wait) to trade away some throughput for more efficient use of page instances.
+unknown-null-field-strategy-name=Unrecognized name '%s' locating a null field strategy.  Available strategies: %s.
+no-translator-for-type=No translator is defined for type %s.  Registered types: %s.
+parameter-binding-must-not-be-empty=Parameter '%s' must have a non-empty binding.
+no-such-method=Class %s does not contain a method named '%s()'.
+context-value-may-not-be-null=Context values (which are added to the request URL) may not be null or blank.
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd
new file mode 100644
index 0000000..5c732dd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/tapestry_5_0_0.xsd
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
+           targetNamespace="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <xs:element name="body">
+        <xs:annotation>
+            <xs:documentation>
+                Defines the position within the template that the body of the component (the portion of the container's
+                template
+                enclosed by the component) will be rendered. This is optional, and only applies to components that wish
+                to render
+                their body within their template.
+            </xs:documentation>
+        </xs:annotation>
+    </xs:element>
+    <xs:element name="container">
+        <xs:annotation>
+            <xs:documentation>
+                May be used as the root element of a template, but is not part of the template itself. Useful when
+                a component exists to emit a series of related elements that are not inside a containing element.
+            </xs:documentation>
+        </xs:annotation>
+    </xs:element>
+    <xs:element name="parameter">
+        <xs:annotation>
+            <xs:documentation>
+                A structured parameter passed to a component as a single object of type Block. The receiving component
+                can get the Block to render. A parameter should always be enclosed by a component element
+                (either an explicit comp element, or an ordinary element instrumented with a Tapestry type or id).
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="name" type="xs:string" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The name of the parameter to be bound to the Block.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="block">
+        <xs:annotation>
+            <xs:documentation>
+                A block is simply a container of other elements. Blocks do not render themselves or their bodies in the
+                normal flow; they
+                only get rendered when specifially directed to.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="id" type="xs:ID">
+                <xs:annotation>
+                    <xs:documentation>
+                        An optional identifier that is used to reference the block from inside the Java class.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-lat1.ent b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-lat1.ent
new file mode 100644
index 0000000..ffee223
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-lat1.ent
@@ -0,0 +1,196 @@
+<!-- Portions (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+    <!ENTITY % HTMLlat1 PUBLIC
+       "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
+    %HTMLlat1;
+-->
+
+<!ENTITY nbsp   "&#160;"> <!-- no-break space = non-breaking space,
+                                  U+00A0 ISOnum -->
+<!ENTITY iexcl  "&#161;"> <!-- inverted exclamation mark, U+00A1 ISOnum -->
+<!ENTITY cent   "&#162;"> <!-- cent sign, U+00A2 ISOnum -->
+<!ENTITY pound  "&#163;"> <!-- pound sign, U+00A3 ISOnum -->
+<!ENTITY curren "&#164;"> <!-- currency sign, U+00A4 ISOnum -->
+<!ENTITY yen    "&#165;"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->
+<!ENTITY brvbar "&#166;"> <!-- broken bar = broken vertical bar,
+                                  U+00A6 ISOnum -->
+<!ENTITY sect   "&#167;"> <!-- section sign, U+00A7 ISOnum -->
+<!ENTITY uml    "&#168;"> <!-- diaeresis = spacing diaeresis,
+                                  U+00A8 ISOdia -->
+<!ENTITY copy   "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
+<!ENTITY ordf   "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
+<!ENTITY laquo  "&#171;"> <!-- left-pointing double angle quotation mark
+                                  = left pointing guillemet, U+00AB ISOnum -->
+<!ENTITY not    "&#172;"> <!-- not sign = angled dash,
+                                  U+00AC ISOnum -->
+<!ENTITY shy    "&#173;"> <!-- soft hyphen = discretionary hyphen,
+                                  U+00AD ISOnum -->
+<!ENTITY reg    "&#174;"> <!-- registered sign = registered trade mark sign,
+                                  U+00AE ISOnum -->
+<!ENTITY macr   "&#175;"> <!-- macron = spacing macron = overline
+                                  = APL overbar, U+00AF ISOdia -->
+<!ENTITY deg    "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
+<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
+                                  U+00B1 ISOnum -->
+<!ENTITY sup2   "&#178;"> <!-- superscript two = superscript digit two
+                                  = squared, U+00B2 ISOnum -->
+<!ENTITY sup3   "&#179;"> <!-- superscript three = superscript digit three
+                                  = cubed, U+00B3 ISOnum -->
+<!ENTITY acute  "&#180;"> <!-- acute accent = spacing acute,
+                                  U+00B4 ISOdia -->
+<!ENTITY micro  "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
+<!ENTITY para   "&#182;"> <!-- pilcrow sign = paragraph sign,
+                                  U+00B6 ISOnum -->
+<!ENTITY middot "&#183;"> <!-- middle dot = Georgian comma
+                                  = Greek middle dot, U+00B7 ISOnum -->
+<!ENTITY cedil  "&#184;"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->
+<!ENTITY sup1   "&#185;"> <!-- superscript one = superscript digit one,
+                                  U+00B9 ISOnum -->
+<!ENTITY ordm   "&#186;"> <!-- masculine ordinal indicator,
+                                  U+00BA ISOnum -->
+<!ENTITY raquo  "&#187;"> <!-- right-pointing double angle quotation mark
+                                  = right pointing guillemet, U+00BB ISOnum -->
+<!ENTITY frac14 "&#188;"> <!-- vulgar fraction one quarter
+                                  = fraction one quarter, U+00BC ISOnum -->
+<!ENTITY frac12 "&#189;"> <!-- vulgar fraction one half
+                                  = fraction one half, U+00BD ISOnum -->
+<!ENTITY frac34 "&#190;"> <!-- vulgar fraction three quarters
+                                  = fraction three quarters, U+00BE ISOnum -->
+<!ENTITY iquest "&#191;"> <!-- inverted question mark
+                                  = turned question mark, U+00BF ISOnum -->
+<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
+                                  = latin capital letter A grave,
+                                  U+00C0 ISOlat1 -->
+<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
+                                  U+00C1 ISOlat1 -->
+<!ENTITY Acirc  "&#194;"> <!-- latin capital letter A with circumflex,
+                                  U+00C2 ISOlat1 -->
+<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
+                                  U+00C3 ISOlat1 -->
+<!ENTITY Auml   "&#196;"> <!-- latin capital letter A with diaeresis,
+                                  U+00C4 ISOlat1 -->
+<!ENTITY Aring  "&#197;"> <!-- latin capital letter A with ring above
+                                  = latin capital letter A ring,
+                                  U+00C5 ISOlat1 -->
+<!ENTITY AElig  "&#198;"> <!-- latin capital letter AE
+                                  = latin capital ligature AE,
+                                  U+00C6 ISOlat1 -->
+<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
+                                  U+00C7 ISOlat1 -->
+<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
+                                  U+00C8 ISOlat1 -->
+<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
+                                  U+00C9 ISOlat1 -->
+<!ENTITY Ecirc  "&#202;"> <!-- latin capital letter E with circumflex,
+                                  U+00CA ISOlat1 -->
+<!ENTITY Euml   "&#203;"> <!-- latin capital letter E with diaeresis,
+                                  U+00CB ISOlat1 -->
+<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
+                                  U+00CC ISOlat1 -->
+<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
+                                  U+00CD ISOlat1 -->
+<!ENTITY Icirc  "&#206;"> <!-- latin capital letter I with circumflex,
+                                  U+00CE ISOlat1 -->
+<!ENTITY Iuml   "&#207;"> <!-- latin capital letter I with diaeresis,
+                                  U+00CF ISOlat1 -->
+<!ENTITY ETH    "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
+<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
+                                  U+00D1 ISOlat1 -->
+<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
+                                  U+00D2 ISOlat1 -->
+<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
+                                  U+00D3 ISOlat1 -->
+<!ENTITY Ocirc  "&#212;"> <!-- latin capital letter O with circumflex,
+                                  U+00D4 ISOlat1 -->
+<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
+                                  U+00D5 ISOlat1 -->
+<!ENTITY Ouml   "&#214;"> <!-- latin capital letter O with diaeresis,
+                                  U+00D6 ISOlat1 -->
+<!ENTITY times  "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
+<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
+                                  = latin capital letter O slash,
+                                  U+00D8 ISOlat1 -->
+<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
+                                  U+00D9 ISOlat1 -->
+<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
+                                  U+00DA ISOlat1 -->
+<!ENTITY Ucirc  "&#219;"> <!-- latin capital letter U with circumflex,
+                                  U+00DB ISOlat1 -->
+<!ENTITY Uuml   "&#220;"> <!-- latin capital letter U with diaeresis,
+                                  U+00DC ISOlat1 -->
+<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
+                                  U+00DD ISOlat1 -->
+<!ENTITY THORN  "&#222;"> <!-- latin capital letter THORN,
+                                  U+00DE ISOlat1 -->
+<!ENTITY szlig  "&#223;"> <!-- latin small letter sharp s = ess-zed,
+                                  U+00DF ISOlat1 -->
+<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
+                                  = latin small letter a grave,
+                                  U+00E0 ISOlat1 -->
+<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
+                                  U+00E1 ISOlat1 -->
+<!ENTITY acirc  "&#226;"> <!-- latin small letter a with circumflex,
+                                  U+00E2 ISOlat1 -->
+<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
+                                  U+00E3 ISOlat1 -->
+<!ENTITY auml   "&#228;"> <!-- latin small letter a with diaeresis,
+                                  U+00E4 ISOlat1 -->
+<!ENTITY aring  "&#229;"> <!-- latin small letter a with ring above
+                                  = latin small letter a ring,
+                                  U+00E5 ISOlat1 -->
+<!ENTITY aelig  "&#230;"> <!-- latin small letter ae
+                                  = latin small ligature ae, U+00E6 ISOlat1 -->
+<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
+                                  U+00E7 ISOlat1 -->
+<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
+                                  U+00E8 ISOlat1 -->
+<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
+                                  U+00E9 ISOlat1 -->
+<!ENTITY ecirc  "&#234;"> <!-- latin small letter e with circumflex,
+                                  U+00EA ISOlat1 -->
+<!ENTITY euml   "&#235;"> <!-- latin small letter e with diaeresis,
+                                  U+00EB ISOlat1 -->
+<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
+                                  U+00EC ISOlat1 -->
+<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
+                                  U+00ED ISOlat1 -->
+<!ENTITY icirc  "&#238;"> <!-- latin small letter i with circumflex,
+                                  U+00EE ISOlat1 -->
+<!ENTITY iuml   "&#239;"> <!-- latin small letter i with diaeresis,
+                                  U+00EF ISOlat1 -->
+<!ENTITY eth    "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
+<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
+                                  U+00F1 ISOlat1 -->
+<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
+                                  U+00F2 ISOlat1 -->
+<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
+                                  U+00F3 ISOlat1 -->
+<!ENTITY ocirc  "&#244;"> <!-- latin small letter o with circumflex,
+                                  U+00F4 ISOlat1 -->
+<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
+                                  U+00F5 ISOlat1 -->
+<!ENTITY ouml   "&#246;"> <!-- latin small letter o with diaeresis,
+                                  U+00F6 ISOlat1 -->
+<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
+<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
+                                  = latin small letter o slash,
+                                  U+00F8 ISOlat1 -->
+<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
+                                  U+00F9 ISOlat1 -->
+<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
+                                  U+00FA ISOlat1 -->
+<!ENTITY ucirc  "&#251;"> <!-- latin small letter u with circumflex,
+                                  U+00FB ISOlat1 -->
+<!ENTITY uuml   "&#252;"> <!-- latin small letter u with diaeresis,
+                                  U+00FC ISOlat1 -->
+<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
+                                  U+00FD ISOlat1 -->
+<!ENTITY thorn  "&#254;"> <!-- latin small letter thorn,
+                                  U+00FE ISOlat1 -->
+<!ENTITY yuml   "&#255;"> <!-- latin small letter y with diaeresis,
+                                  U+00FF ISOlat1 -->
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-special.ent b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-special.ent
new file mode 100644
index 0000000..ca358b2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-special.ent
@@ -0,0 +1,80 @@
+<!-- Special characters for XHTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLspecial PUBLIC
+        "-//W3C//ENTITIES Special for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
+     %HTMLspecial;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- C0 Controls and Basic Latin -->
+<!ENTITY quot    "&#34;"> <!--  quotation mark, U+0022 ISOnum -->
+<!ENTITY amp     "&#38;#38;"> <!--  ampersand, U+0026 ISOnum -->
+<!ENTITY lt      "&#38;#60;"> <!--  less-than sign, U+003C ISOnum -->
+<!ENTITY gt      "&#62;"> <!--  greater-than sign, U+003E ISOnum -->
+<!ENTITY apos	 "&#39;"> <!--  apostrophe = APL quote, U+0027 ISOnum -->
+
+<!-- Latin Extended-A -->
+<!ENTITY OElig   "&#338;"> <!--  latin capital ligature OE,
+                                    U+0152 ISOlat2 -->
+<!ENTITY oelig   "&#339;"> <!--  latin small ligature oe, U+0153 ISOlat2 -->
+<!-- ligature is a misnomer, this is a separate character in some languages -->
+<!ENTITY Scaron  "&#352;"> <!--  latin capital letter S with caron,
+                                    U+0160 ISOlat2 -->
+<!ENTITY scaron  "&#353;"> <!--  latin small letter s with caron,
+                                    U+0161 ISOlat2 -->
+<!ENTITY Yuml    "&#376;"> <!--  latin capital letter Y with diaeresis,
+                                    U+0178 ISOlat2 -->
+
+<!-- Spacing Modifier Letters -->
+<!ENTITY circ    "&#710;"> <!--  modifier letter circumflex accent,
+                                    U+02C6 ISOpub -->
+<!ENTITY tilde   "&#732;"> <!--  small tilde, U+02DC ISOdia -->
+
+<!-- General Punctuation -->
+<!ENTITY ensp    "&#8194;"> <!-- en space, U+2002 ISOpub -->
+<!ENTITY emsp    "&#8195;"> <!-- em space, U+2003 ISOpub -->
+<!ENTITY thinsp  "&#8201;"> <!-- thin space, U+2009 ISOpub -->
+<!ENTITY zwnj    "&#8204;"> <!-- zero width non-joiner,
+                                    U+200C NEW RFC 2070 -->
+<!ENTITY zwj     "&#8205;"> <!-- zero width joiner, U+200D NEW RFC 2070 -->
+<!ENTITY lrm     "&#8206;"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->
+<!ENTITY rlm     "&#8207;"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->
+<!ENTITY ndash   "&#8211;"> <!-- en dash, U+2013 ISOpub -->
+<!ENTITY mdash   "&#8212;"> <!-- em dash, U+2014 ISOpub -->
+<!ENTITY lsquo   "&#8216;"> <!-- left single quotation mark,
+                                    U+2018 ISOnum -->
+<!ENTITY rsquo   "&#8217;"> <!-- right single quotation mark,
+                                    U+2019 ISOnum -->
+<!ENTITY sbquo   "&#8218;"> <!-- single low-9 quotation mark, U+201A NEW -->
+<!ENTITY ldquo   "&#8220;"> <!-- left double quotation mark,
+                                    U+201C ISOnum -->
+<!ENTITY rdquo   "&#8221;"> <!-- right double quotation mark,
+                                    U+201D ISOnum -->
+<!ENTITY bdquo   "&#8222;"> <!-- double low-9 quotation mark, U+201E NEW -->
+<!ENTITY dagger  "&#8224;"> <!-- dagger, U+2020 ISOpub -->
+<!ENTITY Dagger  "&#8225;"> <!-- double dagger, U+2021 ISOpub -->
+<!ENTITY permil  "&#8240;"> <!-- per mille sign, U+2030 ISOtech -->
+<!ENTITY lsaquo  "&#8249;"> <!-- single left-pointing angle quotation mark,
+                                    U+2039 ISO proposed -->
+<!-- lsaquo is proposed but not yet ISO standardized -->
+<!ENTITY rsaquo  "&#8250;"> <!-- single right-pointing angle quotation mark,
+                                    U+203A ISO proposed -->
+<!-- rsaquo is proposed but not yet ISO standardized -->
+
+<!-- Currency Symbols -->
+<!ENTITY euro   "&#8364;"> <!--  euro sign, U+20AC NEW -->
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-symbol.ent b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-symbol.ent
new file mode 100644
index 0000000..63c2abf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml-symbol.ent
@@ -0,0 +1,237 @@
+<!-- Mathematical, Greek and Symbolic characters for XHTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLsymbol PUBLIC
+        "-//W3C//ENTITIES Symbols for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
+     %HTMLsymbol;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- Latin Extended-B -->
+<!ENTITY fnof     "&#402;"> <!-- latin small letter f with hook = function
+                                    = florin, U+0192 ISOtech -->
+
+<!-- Greek -->
+<!ENTITY Alpha    "&#913;"> <!-- greek capital letter alpha, U+0391 -->
+<!ENTITY Beta     "&#914;"> <!-- greek capital letter beta, U+0392 -->
+<!ENTITY Gamma    "&#915;"> <!-- greek capital letter gamma,
+                                    U+0393 ISOgrk3 -->
+<!ENTITY Delta    "&#916;"> <!-- greek capital letter delta,
+                                    U+0394 ISOgrk3 -->
+<!ENTITY Epsilon  "&#917;"> <!-- greek capital letter epsilon, U+0395 -->
+<!ENTITY Zeta     "&#918;"> <!-- greek capital letter zeta, U+0396 -->
+<!ENTITY Eta      "&#919;"> <!-- greek capital letter eta, U+0397 -->
+<!ENTITY Theta    "&#920;"> <!-- greek capital letter theta,
+                                    U+0398 ISOgrk3 -->
+<!ENTITY Iota     "&#921;"> <!-- greek capital letter iota, U+0399 -->
+<!ENTITY Kappa    "&#922;"> <!-- greek capital letter kappa, U+039A -->
+<!ENTITY Lambda   "&#923;"> <!-- greek capital letter lamda,
+                                    U+039B ISOgrk3 -->
+<!ENTITY Mu       "&#924;"> <!-- greek capital letter mu, U+039C -->
+<!ENTITY Nu       "&#925;"> <!-- greek capital letter nu, U+039D -->
+<!ENTITY Xi       "&#926;"> <!-- greek capital letter xi, U+039E ISOgrk3 -->
+<!ENTITY Omicron  "&#927;"> <!-- greek capital letter omicron, U+039F -->
+<!ENTITY Pi       "&#928;"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->
+<!ENTITY Rho      "&#929;"> <!-- greek capital letter rho, U+03A1 -->
+<!-- there is no Sigmaf, and no U+03A2 character either -->
+<!ENTITY Sigma    "&#931;"> <!-- greek capital letter sigma,
+                                    U+03A3 ISOgrk3 -->
+<!ENTITY Tau      "&#932;"> <!-- greek capital letter tau, U+03A4 -->
+<!ENTITY Upsilon  "&#933;"> <!-- greek capital letter upsilon,
+                                    U+03A5 ISOgrk3 -->
+<!ENTITY Phi      "&#934;"> <!-- greek capital letter phi,
+                                    U+03A6 ISOgrk3 -->
+<!ENTITY Chi      "&#935;"> <!-- greek capital letter chi, U+03A7 -->
+<!ENTITY Psi      "&#936;"> <!-- greek capital letter psi,
+                                    U+03A8 ISOgrk3 -->
+<!ENTITY Omega    "&#937;"> <!-- greek capital letter omega,
+                                    U+03A9 ISOgrk3 -->
+
+<!ENTITY alpha    "&#945;"> <!-- greek small letter alpha,
+                                    U+03B1 ISOgrk3 -->
+<!ENTITY beta     "&#946;"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->
+<!ENTITY gamma    "&#947;"> <!-- greek small letter gamma,
+                                    U+03B3 ISOgrk3 -->
+<!ENTITY delta    "&#948;"> <!-- greek small letter delta,
+                                    U+03B4 ISOgrk3 -->
+<!ENTITY epsilon  "&#949;"> <!-- greek small letter epsilon,
+                                    U+03B5 ISOgrk3 -->
+<!ENTITY zeta     "&#950;"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->
+<!ENTITY eta      "&#951;"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->
+<!ENTITY theta    "&#952;"> <!-- greek small letter theta,
+                                    U+03B8 ISOgrk3 -->
+<!ENTITY iota     "&#953;"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->
+<!ENTITY kappa    "&#954;"> <!-- greek small letter kappa,
+                                    U+03BA ISOgrk3 -->
+<!ENTITY lambda   "&#955;"> <!-- greek small letter lamda,
+                                    U+03BB ISOgrk3 -->
+<!ENTITY mu       "&#956;"> <!-- greek small letter mu, U+03BC ISOgrk3 -->
+<!ENTITY nu       "&#957;"> <!-- greek small letter nu, U+03BD ISOgrk3 -->
+<!ENTITY xi       "&#958;"> <!-- greek small letter xi, U+03BE ISOgrk3 -->
+<!ENTITY omicron  "&#959;"> <!-- greek small letter omicron, U+03BF NEW -->
+<!ENTITY pi       "&#960;"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->
+<!ENTITY rho      "&#961;"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->
+<!ENTITY sigmaf   "&#962;"> <!-- greek small letter final sigma,
+                                    U+03C2 ISOgrk3 -->
+<!ENTITY sigma    "&#963;"> <!-- greek small letter sigma,
+                                    U+03C3 ISOgrk3 -->
+<!ENTITY tau      "&#964;"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->
+<!ENTITY upsilon  "&#965;"> <!-- greek small letter upsilon,
+                                    U+03C5 ISOgrk3 -->
+<!ENTITY phi      "&#966;"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->
+<!ENTITY chi      "&#967;"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->
+<!ENTITY psi      "&#968;"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->
+<!ENTITY omega    "&#969;"> <!-- greek small letter omega,
+                                    U+03C9 ISOgrk3 -->
+<!ENTITY thetasym "&#977;"> <!-- greek theta symbol,
+                                    U+03D1 NEW -->
+<!ENTITY upsih    "&#978;"> <!-- greek upsilon with hook symbol,
+                                    U+03D2 NEW -->
+<!ENTITY piv      "&#982;"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->
+
+<!-- General Punctuation -->
+<!ENTITY bull     "&#8226;"> <!-- bullet = black small circle,
+                                     U+2022 ISOpub  -->
+<!-- bullet is NOT the same as bullet operator, U+2219 -->
+<!ENTITY hellip   "&#8230;"> <!-- horizontal ellipsis = three dot leader,
+                                     U+2026 ISOpub  -->
+<!ENTITY prime    "&#8242;"> <!-- prime = minutes = feet, U+2032 ISOtech -->
+<!ENTITY Prime    "&#8243;"> <!-- double prime = seconds = inches,
+                                     U+2033 ISOtech -->
+<!ENTITY oline    "&#8254;"> <!-- overline = spacing overscore,
+                                     U+203E NEW -->
+<!ENTITY frasl    "&#8260;"> <!-- fraction slash, U+2044 NEW -->
+
+<!-- Letterlike Symbols -->
+<!ENTITY weierp   "&#8472;"> <!-- script capital P = power set
+                                     = Weierstrass p, U+2118 ISOamso -->
+<!ENTITY image    "&#8465;"> <!-- black-letter capital I = imaginary part,
+                                     U+2111 ISOamso -->
+<!ENTITY real     "&#8476;"> <!-- black-letter capital R = real part symbol,
+                                     U+211C ISOamso -->
+<!ENTITY trade    "&#8482;"> <!-- trade mark sign, U+2122 ISOnum -->
+<!ENTITY alefsym  "&#8501;"> <!-- alef symbol = first transfinite cardinal,
+                                     U+2135 NEW -->
+<!-- alef symbol is NOT the same as hebrew letter alef,
+     U+05D0 although the same glyph could be used to depict both characters -->
+
+<!-- Arrows -->
+<!ENTITY larr     "&#8592;"> <!-- leftwards arrow, U+2190 ISOnum -->
+<!ENTITY uarr     "&#8593;"> <!-- upwards arrow, U+2191 ISOnum-->
+<!ENTITY rarr     "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
+<!ENTITY darr     "&#8595;"> <!-- downwards arrow, U+2193 ISOnum -->
+<!ENTITY harr     "&#8596;"> <!-- left right arrow, U+2194 ISOamsa -->
+<!ENTITY crarr    "&#8629;"> <!-- downwards arrow with corner leftwards
+                                     = carriage return, U+21B5 NEW -->
+<!ENTITY lArr     "&#8656;"> <!-- leftwards double arrow, U+21D0 ISOtech -->
+<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow
+    but also does not have any other character for that function. So lArr can
+    be used for 'is implied by' as ISOtech suggests -->
+<!ENTITY uArr     "&#8657;"> <!-- upwards double arrow, U+21D1 ISOamsa -->
+<!ENTITY rArr     "&#8658;"> <!-- rightwards double arrow,
+                                     U+21D2 ISOtech -->
+<!-- Unicode does not say this is the 'implies' character but does not have 
+     another character with this function so rArr can be used for 'implies'
+     as ISOtech suggests -->
+<!ENTITY dArr     "&#8659;"> <!-- downwards double arrow, U+21D3 ISOamsa -->
+<!ENTITY hArr     "&#8660;"> <!-- left right double arrow,
+                                     U+21D4 ISOamsa -->
+
+<!-- Mathematical Operators -->
+<!ENTITY forall   "&#8704;"> <!-- for all, U+2200 ISOtech -->
+<!ENTITY part     "&#8706;"> <!-- partial differential, U+2202 ISOtech  -->
+<!ENTITY exist    "&#8707;"> <!-- there exists, U+2203 ISOtech -->
+<!ENTITY empty    "&#8709;"> <!-- empty set = null set, U+2205 ISOamso -->
+<!ENTITY nabla    "&#8711;"> <!-- nabla = backward difference,
+                                     U+2207 ISOtech -->
+<!ENTITY isin     "&#8712;"> <!-- element of, U+2208 ISOtech -->
+<!ENTITY notin    "&#8713;"> <!-- not an element of, U+2209 ISOtech -->
+<!ENTITY ni       "&#8715;"> <!-- contains as member, U+220B ISOtech -->
+<!ENTITY prod     "&#8719;"> <!-- n-ary product = product sign,
+                                     U+220F ISOamsb -->
+<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
+     the same glyph might be used for both -->
+<!ENTITY sum      "&#8721;"> <!-- n-ary summation, U+2211 ISOamsb -->
+<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
+     though the same glyph might be used for both -->
+<!ENTITY minus    "&#8722;"> <!-- minus sign, U+2212 ISOtech -->
+<!ENTITY lowast   "&#8727;"> <!-- asterisk operator, U+2217 ISOtech -->
+<!ENTITY radic    "&#8730;"> <!-- square root = radical sign,
+                                     U+221A ISOtech -->
+<!ENTITY prop     "&#8733;"> <!-- proportional to, U+221D ISOtech -->
+<!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->
+<!ENTITY ang      "&#8736;"> <!-- angle, U+2220 ISOamso -->
+<!ENTITY and      "&#8743;"> <!-- logical and = wedge, U+2227 ISOtech -->
+<!ENTITY or       "&#8744;"> <!-- logical or = vee, U+2228 ISOtech -->
+<!ENTITY cap      "&#8745;"> <!-- intersection = cap, U+2229 ISOtech -->
+<!ENTITY cup      "&#8746;"> <!-- union = cup, U+222A ISOtech -->
+<!ENTITY int      "&#8747;"> <!-- integral, U+222B ISOtech -->
+<!ENTITY there4   "&#8756;"> <!-- therefore, U+2234 ISOtech -->
+<!ENTITY sim      "&#8764;"> <!-- tilde operator = varies with = similar to,
+                                     U+223C ISOtech -->
+<!-- tilde operator is NOT the same character as the tilde, U+007E,
+     although the same glyph might be used to represent both  -->
+<!ENTITY cong     "&#8773;"> <!-- approximately equal to, U+2245 ISOtech -->
+<!ENTITY asymp    "&#8776;"> <!-- almost equal to = asymptotic to,
+                                     U+2248 ISOamsr -->
+<!ENTITY ne       "&#8800;"> <!-- not equal to, U+2260 ISOtech -->
+<!ENTITY equiv    "&#8801;"> <!-- identical to, U+2261 ISOtech -->
+<!ENTITY le       "&#8804;"> <!-- less-than or equal to, U+2264 ISOtech -->
+<!ENTITY ge       "&#8805;"> <!-- greater-than or equal to,
+                                     U+2265 ISOtech -->
+<!ENTITY sub      "&#8834;"> <!-- subset of, U+2282 ISOtech -->
+<!ENTITY sup      "&#8835;"> <!-- superset of, U+2283 ISOtech -->
+<!ENTITY nsub     "&#8836;"> <!-- not a subset of, U+2284 ISOamsn -->
+<!ENTITY sube     "&#8838;"> <!-- subset of or equal to, U+2286 ISOtech -->
+<!ENTITY supe     "&#8839;"> <!-- superset of or equal to,
+                                     U+2287 ISOtech -->
+<!ENTITY oplus    "&#8853;"> <!-- circled plus = direct sum,
+                                     U+2295 ISOamsb -->
+<!ENTITY otimes   "&#8855;"> <!-- circled times = vector product,
+                                     U+2297 ISOamsb -->
+<!ENTITY perp     "&#8869;"> <!-- up tack = orthogonal to = perpendicular,
+                                     U+22A5 ISOtech -->
+<!ENTITY sdot     "&#8901;"> <!-- dot operator, U+22C5 ISOamsb -->
+<!-- dot operator is NOT the same character as U+00B7 middle dot -->
+
+<!-- Miscellaneous Technical -->
+<!ENTITY lceil    "&#8968;"> <!-- left ceiling = APL upstile,
+                                     U+2308 ISOamsc  -->
+<!ENTITY rceil    "&#8969;"> <!-- right ceiling, U+2309 ISOamsc  -->
+<!ENTITY lfloor   "&#8970;"> <!-- left floor = APL downstile,
+                                     U+230A ISOamsc  -->
+<!ENTITY rfloor   "&#8971;"> <!-- right floor, U+230B ISOamsc  -->
+<!ENTITY lang     "&#9001;"> <!-- left-pointing angle bracket = bra,
+                                     U+2329 ISOtech -->
+<!-- lang is NOT the same character as U+003C 'less than sign' 
+     or U+2039 'single left-pointing angle quotation mark' -->
+<!ENTITY rang     "&#9002;"> <!-- right-pointing angle bracket = ket,
+                                     U+232A ISOtech -->
+<!-- rang is NOT the same character as U+003E 'greater than sign' 
+     or U+203A 'single right-pointing angle quotation mark' -->
+
+<!-- Geometric Shapes -->
+<!ENTITY loz      "&#9674;"> <!-- lozenge, U+25CA ISOpub -->
+
+<!-- Miscellaneous Symbols -->
+<!ENTITY spades   "&#9824;"> <!-- black spade suit, U+2660 ISOpub -->
+<!-- black here seems to mean filled as opposed to hollow -->
+<!ENTITY clubs    "&#9827;"> <!-- black club suit = shamrock,
+                                     U+2663 ISOpub -->
+<!ENTITY hearts   "&#9829;"> <!-- black heart suit = valentine,
+                                     U+2665 ISOpub -->
+<!ENTITY diams    "&#9830;"> <!-- black diamond suit, U+2666 ISOpub -->
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-frameset.dtd b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-frameset.dtd
new file mode 100644
index 0000000..d128f2e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-frameset.dtd
@@ -0,0 +1,1235 @@
+<!--
+   Extensible HTML version 1.0 Frameset DTD
+
+   This is the same as HTML 4 Frameset except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
+
+   $Revision: 1.2 $
+   $Date: 2002/08/01 18:37:55 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % FrameTarget "NMTOKEN">
+    <!-- render in this frame -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % MultiLengths "CDATA">
+    <!-- comma-separated list of MultiLength -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!-- used for object, applet, img, input and iframe -->
+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">
+
+<!-- a color using sRGB: #RRGGBB as Hex values -->
+<!ENTITY % Color "CDATA">
+
+<!-- There are also 16 widely known color names with their sRGB values:
+
+    Black  = #000000    Green  = #008000
+    Silver = #C0C0C0    Lime   = #00FF00
+    Gray   = #808080    Olive  = #808000
+    White  = #FFFFFF    Yellow = #FFFF00
+    Maroon = #800000    Navy   = #000080
+    Red    = #FF0000    Blue   = #0000FF
+    Purple = #800080    Teal   = #008080
+    Fuchsia= #FF00FF    Aqua   = #00FFFF
+-->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!-- text alignment for p, div, h1-h6. The default is
+     align="left" for ltr headings, "right" for rtl -->
+
+<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.extra
+   "object | applet | img | map | iframe">
+	
+<!ENTITY % special.basic
+	"br | span | bdo">
+
+<!ENTITY % special
+   "%special.basic; | %special.extra;">
+
+<!ENTITY % fontstyle.extra "big | small | font | basefont">
+
+<!ENTITY % fontstyle.basic "tt | i | b | u
+                      | s | strike ">
+
+<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;">
+
+<!ENTITY % phrase.extra "sub | sup">
+<!ENTITY % phrase.basic "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym">
+
+<!ENTITY % phrase "%phrase.basic; | %phrase.extra;">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl | menu | dir">
+<!ENTITY % blocktext "pre | hr | blockquote | address | center">
+
+<!ENTITY % block
+    "p | %heading; | div | %lists; | %blocktext; | isindex | fieldset | table">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding img, object, applet, big, small,
+     sub, sup, font, or basefont -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; |
+	   %inline.forms; | %misc.inline;)*">
+
+
+<!-- form uses %Flow; excluding form -->
+
+<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form, form controls, iframe -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+      table | br | span | bdo | object | applet | img | map |
+      %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, frameset)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  id          ID             #IMPLIED
+  href        %URI;          #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  language    CDATA          #IMPLIED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Flow;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--======================= Frames =======================================-->
+
+<!-- only one noframes element permitted per document -->
+
+<!ELEMENT frameset (frameset|frame|noframes)*>
+<!ATTLIST frameset
+  %coreattrs;
+  rows        %MultiLengths; #IMPLIED
+  cols        %MultiLengths; #IMPLIED
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  >
+
+<!-- reserved frame names start with "_" otherwise starts with letter -->
+
+<!-- tiled window within frameset -->
+
+<!ELEMENT frame EMPTY>
+<!ATTLIST frame
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  noresize    (noresize)     #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  >
+
+<!-- inline subwindow -->
+
+<!ELEMENT iframe %Flow;>
+<!ATTLIST iframe
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  align       %ImgAlign;     #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!-- alternate content container for non frame-based rendering -->
+
+<!ELEMENT noframes (body)>
+<!ATTLIST noframes
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Flow;>
+<!ATTLIST body
+  %attrs;
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  background  %URI;          #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  text        %Color;        #IMPLIED
+  link        %Color;        #IMPLIED
+  vlink       %Color;        #IMPLIED
+  alink       %Color;        #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list bullet styles -->
+
+<!ENTITY % ULStyle "(disc|square|circle)">
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  type        %ULStyle;     #IMPLIED
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- Ordered list numbering style
+
+    1   arabic numbers      1, 2, 3, ...
+    a   lower alpha         a, b, c, ...
+    A   upper alpha         A, B, C, ...
+    i   lower roman         i, ii, iii, ...
+    I   upper roman         I, II, III, ...
+
+    The style is applied to the sequence number which by default
+    is reset to 1 for the first list item in an ordered list.
+-->
+<!ENTITY % OLStyle "CDATA">
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  type        %OLStyle;      #IMPLIED
+  compact     (compact)      #IMPLIED
+  start       %Number;       #IMPLIED
+  >
+
+<!-- single column list (DEPRECATED) --> 
+<!ELEMENT menu (li)+>
+<!ATTLIST menu
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- multiple column list (DEPRECATED) --> 
+<!ELEMENT dir (li)+>
+<!ATTLIST dir
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->
+<!ENTITY % LIStyle "CDATA">
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  type        %LIStyle;      #IMPLIED
+  value       %Number;       #IMPLIED
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  compact     (compact)      #IMPLIED
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  align       (left|center|right) #IMPLIED
+  noshade     (noshade)      #IMPLIED
+  size        %Pixels;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding 
+        "img|object|applet|big|small|sub|sup|font|basefont" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  width       %Number;      #IMPLIED
+  xml:space   (preserve)    #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Flow;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Text alignment ===================================-->
+
+<!-- center content -->
+<!ELEMENT center %Flow;>
+<!ATTLIST center
+  %attrs;
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  clear       (left|all|right|none) "none"
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!ELEMENT u %Inline;>   <!-- underline -->
+<!ATTLIST u %attrs;>
+
+<!ELEMENT s %Inline;>   <!-- strike-through -->
+<!ATTLIST s %attrs;>
+
+<!ELEMENT strike %Inline;>   <!-- strike-through -->
+<!ATTLIST strike %attrs;>
+
+<!ELEMENT basefont EMPTY>  <!-- base font size -->
+<!ATTLIST basefont
+  id          ID             #IMPLIED
+  size        CDATA          #REQUIRED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!ELEMENT font %Inline;> <!-- local change to font -->
+<!ATTLIST font
+  %coreattrs;
+  %i18n;
+  size        CDATA          #IMPLIED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form |%inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #REQUIRED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Java applet ==================================-->
+<!--
+  One of code or object attributes must be present.
+  Place param elements before other content.
+-->
+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST applet
+  %coreattrs;
+  codebase    %URI;          #IMPLIED
+  archive     CDATA          #IMPLIED
+  code        CDATA          #IMPLIED
+  object      CDATA          #IMPLIED
+  alt         %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  width       %Length;       #REQUIRED
+  height      %Length;       #REQUIRED
+  align       %ImgAlign;     #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  name        NMTOKEN        #IMPLIED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--================ Forms ===============================================-->
+
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  name        NMTOKEN        #IMPLIED
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ENTITY % LAlign "(top|bottom|left|right)">
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  align       %LAlign;       #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form, form controls, iframe
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!-- single-line text input control (DEPRECATED) -->
+<!ELEMENT isindex EMPTY>
+<!ATTLIST isindex
+  %coreattrs;
+  %i18n;
+  prompt      %Text;         #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal placement of table relative to document -->
+<!ENTITY % TAlign "(left|center|right)">
+
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=":"
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  align       %TAlign;       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!ENTITY % CAlign "(top|bottom|left|right)">
+
+<!ATTLIST caption
+  %attrs;
+  align       %CAlign;       #IMPLIED
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Pixels;       #IMPLIED
+  height      %Pixels;       #IMPLIED
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Pixels;       #IMPLIED
+  height      %Pixels;       #IMPLIED
+  >
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-strict.dtd b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-strict.dtd
new file mode 100644
index 0000000..2927b9e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-strict.dtd
@@ -0,0 +1,978 @@
+<!--
+   Extensible HTML version 1.0 Strict DTD
+
+   This is the same as HTML 4 Strict except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+
+   $Revision: 1.1 $
+   $Date: 2002/08/01 13:56:03 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.pre
+   "br | span | bdo | map">
+
+
+<!ENTITY % special
+   "%special.pre; | object | img ">
+
+<!ENTITY % fontstyle "tt | i | b | big | small ">
+
+<!ENTITY % phrase "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym | sub | sup ">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl">
+<!ENTITY % blocktext "pre | hr | blockquote | address">
+
+<!ENTITY % block
+     "p | %heading; | div | %lists; | %blocktext; | fieldset | table">
+
+<!ENTITY % Block "(%block; | form | %misc;)*">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding big, small, sup or sup -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline;
+      | %inline.forms;)*">
+
+<!-- form uses %Block; excluding form -->
+
+<!ENTITY % form.content "(%block; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form and form controls -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+    table | %special; | %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, body)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  href        %URI;          #REQUIRED
+  id          ID             #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Block;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Block;>
+<!ATTLIST body
+  %attrs;
+  onload          %Script;   #IMPLIED
+  onunload        %Script;   #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+   %attrs;
+   >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+   %attrs;
+   >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+   %attrs;
+   >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+   %attrs;
+   >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+   %attrs;
+   >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+   %attrs;
+   >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  >
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  >
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address %Inline;>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding "img|object|big|small|sub|sup" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  xml:space (preserve) #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Block;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+   Note that in this DTD there is no name attribute. That
+   is only available in the transitional and frameset DTD.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  >
+
+<!--================ Forms ===============================================-->
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form and form controls
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=':'
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  >
+
+<!ATTLIST caption
+  %attrs;
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  >
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-transitional.dtd b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-transitional.dtd
new file mode 100644
index 0000000..628f27a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/xhtml1-transitional.dtd
@@ -0,0 +1,1201 @@
+<!--
+   Extensible HTML version 1.0 Transitional DTD
+
+   This is the same as HTML 4 Transitional except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
+
+   $Revision: 1.2 $
+   $Date: 2002/08/01 18:37:55 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % FrameTarget "NMTOKEN">
+    <!-- render in this frame -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!-- used for object, applet, img, input and iframe -->
+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">
+
+<!-- a color using sRGB: #RRGGBB as Hex values -->
+<!ENTITY % Color "CDATA">
+
+<!-- There are also 16 widely known color names with their sRGB values:
+
+    Black  = #000000    Green  = #008000
+    Silver = #C0C0C0    Lime   = #00FF00
+    Gray   = #808080    Olive  = #808000
+    White  = #FFFFFF    Yellow = #FFFF00
+    Maroon = #800000    Navy   = #000080
+    Red    = #FF0000    Blue   = #0000FF
+    Purple = #800080    Teal   = #008080
+    Fuchsia= #FF00FF    Aqua   = #00FFFF
+-->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!-- text alignment for p, div, h1-h6. The default is
+     align="left" for ltr headings, "right" for rtl -->
+
+<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.extra
+   "object | applet | img | map | iframe">
+	
+<!ENTITY % special.basic
+	"br | span | bdo">
+
+<!ENTITY % special
+   "%special.basic; | %special.extra;">
+
+<!ENTITY % fontstyle.extra "big | small | font | basefont">
+
+<!ENTITY % fontstyle.basic "tt | i | b | u
+                      | s | strike ">
+
+<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;">
+
+<!ENTITY % phrase.extra "sub | sup">
+<!ENTITY % phrase.basic "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym">
+
+<!ENTITY % phrase "%phrase.basic; | %phrase.extra;">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl | menu | dir">
+<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes">
+
+<!ENTITY % block
+    "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding img, object, applet, big, small,
+     font, or basefont -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; |
+	   %inline.forms; | %misc.inline;)*">
+
+<!-- form uses %Flow; excluding form -->
+
+<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form, form controls, iframe -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+      table | br | span | bdo | object | applet | img | map |
+      %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, body)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  id          ID             #IMPLIED
+  href        %URI;          #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  language    CDATA          #IMPLIED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Flow;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--======================= Frames =======================================-->
+
+<!-- inline subwindow -->
+
+<!ELEMENT iframe %Flow;>
+<!ATTLIST iframe
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  align       %ImgAlign;     #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!-- alternate content container for non frame-based rendering -->
+
+<!ELEMENT noframes %Flow;>
+<!ATTLIST noframes
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Flow;>
+<!ATTLIST body
+  %attrs;
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  background  %URI;          #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  text        %Color;        #IMPLIED
+  link        %Color;        #IMPLIED
+  vlink       %Color;        #IMPLIED
+  alink       %Color;        #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list bullet styles -->
+
+<!ENTITY % ULStyle "(disc|square|circle)">
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  type        %ULStyle;     #IMPLIED
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- Ordered list numbering style
+
+    1   arabic numbers      1, 2, 3, ...
+    a   lower alpha         a, b, c, ...
+    A   upper alpha         A, B, C, ...
+    i   lower roman         i, ii, iii, ...
+    I   upper roman         I, II, III, ...
+
+    The style is applied to the sequence number which by default
+    is reset to 1 for the first list item in an ordered list.
+-->
+<!ENTITY % OLStyle "CDATA">
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  type        %OLStyle;      #IMPLIED
+  compact     (compact)      #IMPLIED
+  start       %Number;       #IMPLIED
+  >
+
+<!-- single column list (DEPRECATED) --> 
+<!ELEMENT menu (li)+>
+<!ATTLIST menu
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- multiple column list (DEPRECATED) --> 
+<!ELEMENT dir (li)+>
+<!ATTLIST dir
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->
+<!ENTITY % LIStyle "CDATA">
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  type        %LIStyle;      #IMPLIED
+  value       %Number;       #IMPLIED
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  compact     (compact)      #IMPLIED
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  align       (left|center|right) #IMPLIED
+  noshade     (noshade)      #IMPLIED
+  size        %Pixels;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding 
+        "img|object|applet|big|small|sub|sup|font|basefont" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  width       %Number;      #IMPLIED
+  xml:space   (preserve)    #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Flow;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Text alignment ===================================-->
+
+<!-- center content -->
+<!ELEMENT center %Flow;>
+<!ATTLIST center
+  %attrs;
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  clear       (left|all|right|none) "none"
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!ELEMENT u %Inline;>   <!-- underline -->
+<!ATTLIST u %attrs;>
+
+<!ELEMENT s %Inline;>   <!-- strike-through -->
+<!ATTLIST s %attrs;>
+
+<!ELEMENT strike %Inline;>   <!-- strike-through -->
+<!ATTLIST strike %attrs;>
+
+<!ELEMENT basefont EMPTY>  <!-- base font size -->
+<!ATTLIST basefont
+  id          ID             #IMPLIED
+  size        CDATA          #REQUIRED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!ELEMENT font %Inline;> <!-- local change to font -->
+<!ATTLIST font
+  %coreattrs;
+  %i18n;
+  size        CDATA          #IMPLIED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #REQUIRED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Java applet ==================================-->
+<!--
+  One of code or object attributes must be present.
+  Place param elements before other content.
+-->
+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST applet
+  %coreattrs;
+  codebase    %URI;          #IMPLIED
+  archive     CDATA          #IMPLIED
+  code        CDATA          #IMPLIED
+  object      CDATA          #IMPLIED
+  alt         %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  width       %Length;       #REQUIRED
+  height      %Length;       #REQUIRED
+  align       %ImgAlign;     #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  name        NMTOKEN        #IMPLIED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Length;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        CDATA          #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--================ Forms ===============================================-->
+
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  name        NMTOKEN        #IMPLIED
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ENTITY % LAlign "(top|bottom|left|right)">
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  align       %LAlign;       #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form, form controls, iframe
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!-- single-line text input control (DEPRECATED) -->
+<!ELEMENT isindex EMPTY>
+<!ATTLIST isindex
+  %coreattrs;
+  %i18n;
+  prompt      %Text;         #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal placement of table relative to document -->
+<!ENTITY % TAlign "(left|center|right)">
+
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=':'
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  align       %TAlign;       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!ENTITY % CAlign "(top|bottom|left|right)">
+
+<!ATTLIST caption
+  %attrs;
+  align       %CAlign;       #IMPLIED
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Length;       #IMPLIED
+  height      %Length;       #IMPLIED
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Length;       #IMPLIED
+  height      %Length;       #IMPLIED
+  >
+
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
new file mode 100644
index 0000000..a57e609
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties
@@ -0,0 +1,36 @@
+# Copyright 2006, 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+missing-parameters=Parameter(s) '%s' are required for %s, but have not been bound.
+no-such-component=Component %s does not contain an embedded component with id '%s'. Available components: %s.
+get-parameter-failure=Failure reading parameter '%s' of component %s: %s
+write-parameter-failure=Failure writing parameter '%s' of component %s: %s
+missing-mixin-for-parameter=Component %s does not contain a mixin named '%s' (setting parameter '%s').
+unknown-mixin=Component %s does not contain a mixin of type %s.
+detach-failure=Listener %s failed during page detach: %s
+wrong-phase-result-type=The return value from a render phase event method was not compatible the expected return type of %s. \
+  You should change the method to return the correct type. 
+block-not-found=Template for component %s does not contain a block with identifier '%s'.
+unbalanced-elements=Component %s has rendered unbalanced elements; \
+  either it has started an element with MarkupWriter.element() and not followed up with MarkupWriter.end(), or \
+  it has invoked MarkupWriter.end() without first invoking MarkupWriter.element().
+page-is-dirty=Page %s was stored into the page pool in a dirty state. This should never happen, \
+  and may indicate that a reference to the page (or component within the page) was retained past the end of a request.
+duplicate-child-component=Component %s already contains a child component with id '%s'. \
+  Embedded component ids must be unique (excluding case, which is ignored).
+duplicate-block=Component %s already contains a block with id '%s'. \
+  Block ids must be unique (excluding case, which is ignored).
+field-persist-failure=Error persisting field %s:%s: %s
+missing-render-variable=Component %s does not contain a stored render variable with name '%s'.  Stored render variables: %s.
+render-variable-set-when-not-rendering=Component %s is not rendering, so render variable '%s' may not be updated.
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
new file mode 100644
index 0000000..c5f0109
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/transform/TransformStrings.properties
@@ -0,0 +1,18 @@
+# Copyright 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+field-injection-error=Error obtaining injected value for field %s.%s: %s
+component-not-assignable-to-field=Component %s is not assignable to field %s (of type %s).
+cached-no-return-value=@Cached may only be used with methods that return values: %s
+cached-no-parameters=@Cached cannot be used with methods that accept parameters: %s
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties
new file mode 100644
index 0000000..6e5f136
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/internal/util/UtilStrings.properties
@@ -0,0 +1,16 @@
+# Copyright 2006, 2008 The Apache Software Foundation

+#

+# Licensed under the Apache License, Version 2.0 (the "License");

+# you may not use this file except in compliance with the License.

+# You may obtain a copy of the License at

+#

+#     http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing, software

+# distributed under the License is distributed on an "AS IS" BASIS,

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

+# See the License for the specific language governing permissions and

+# limitations under the License.

+

+no-return-value-accepted=Event '%s' from %s received an event handler method return value of %s. \

+  This type of event does not support return values from event handler methods.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/builder.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/builder.js
new file mode 100644
index 0000000..2b80bd7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/builder.js
@@ -0,0 +1,162 @@
+// script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Builder = {
+    NODEMAP: {
+        AREA: 'map',
+        CAPTION: 'table',
+        COL: 'table',
+        COLGROUP: 'table',
+        LEGEND: 'fieldset',
+        OPTGROUP: 'select',
+        OPTION: 'select',
+        PARAM: 'object',
+        TBODY: 'table',
+        TD: 'table',
+        TFOOT: 'table',
+        TH: 'table',
+        THEAD: 'table',
+        TR: 'table'
+    },
+    // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+    //       due to a Firefox bug
+    node: function(elementName)
+    {
+        elementName = elementName.toUpperCase();
+    
+    // try innerHTML approach
+        var parentTag = this.NODEMAP[elementName] || 'div';
+        var parentElement = document.createElement(parentTag);
+        try
+        { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+            parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+        }
+        catch(e)
+        {
+        }
+        var element = parentElement.firstChild || null;
+      
+    // see if browser added wrapping tags
+        if (element && (element.tagName.toUpperCase() != elementName))
+            element = element.getElementsByTagName(elementName)[0];
+    
+    // fallback to createElement approach
+        if (!element) element = document.createElement(elementName);
+    
+    // abort if nothing could be created
+        if (!element) return;
+
+    // attributes (or text)
+        if (arguments[1])
+            if (this._isStringOrNumber(arguments[1]) ||
+                (arguments[1] instanceof Array) ||
+                arguments[1].tagName)
+            {
+                this._children(element, arguments[1]);
+            }
+            else
+            {
+                var attrs = this._attributes(arguments[1]);
+                if (attrs.length)
+                {
+                    try
+                    { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+                        parentElement.innerHTML = "<" + elementName + " " +
+                                                  attrs + "></" + elementName + ">";
+                    }
+                    catch(e)
+                    {
+                    }
+                    element = parentElement.firstChild || null;
+            // workaround firefox 1.0.X bug
+                    if (!element)
+                    {
+                        element = document.createElement(elementName);
+                        for (attr in arguments[1])
+                            element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+                    }
+                    if (element.tagName.toUpperCase() != elementName)
+                        element = parentElement.getElementsByTagName(elementName)[0];
+                }
+            }
+
+    // text, or array of children
+        if (arguments[2])
+            this._children(element, arguments[2]);
+
+        return element;
+    },
+    _text: function(text)
+    {
+        return document.createTextNode(text);
+    },
+
+    ATTR_MAP: {
+        'className': 'class',
+        'htmlFor': 'for'
+    },
+
+    _attributes: function(attributes)
+    {
+        var attrs = [];
+        for (attribute in attributes)
+            attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
+                       '="' + attributes[attribute].toString().escapeHTML().gsub(/"/, '&quot;') + '"');
+        return attrs.join(" ");
+    },
+    _children: function(element, children)
+    {
+        if (children.tagName)
+        {
+            element.appendChild(children);
+            return;
+        }
+        if (typeof children == 'object')
+        { // array can hold nodes and text
+            children.flatten().each(function(e)
+            {
+                if (typeof e == 'object')
+                    element.appendChild(e)
+                else
+                    if (Builder._isStringOrNumber(e))
+                        element.appendChild(Builder._text(e));
+            });
+        }
+        else
+            if (Builder._isStringOrNumber(children))
+                element.appendChild(Builder._text(children));
+    },
+    _isStringOrNumber: function(param)
+    {
+        return(typeof param == 'string' || typeof param == 'number');
+    },
+    build: function(html)
+    {
+        var element = this.node('div');
+        $(element).update(html.strip());
+        return element.down();
+    },
+    dump: function(scope)
+    {
+        if (typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
+
+        var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+                    "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+                    "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX " +
+                    "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P " +
+                    "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD " +
+                    "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+
+        tags.each(function(tag)
+        {
+            scope[tag] = function()
+            {
+                return Builder.node.apply(Builder, [tag].concat($A(arguments)));
+            }
+        });
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/controls.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/controls.js
new file mode 100644
index 0000000..14c3d30
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/controls.js
@@ -0,0 +1,1099 @@
+// script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+//  Richard Livsey
+//  Rahul Bhargava
+//  Rob Wills
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// Autocompleter.Base handles all the autocompletion functionality 
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least, 
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method 
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most 
+// useful when one of the tokens is \n (a newline), as it 
+// allows smart autocompletion after linebreaks.
+
+if (typeof Effect == 'undefined')
+    throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = { }
+Autocompleter.Base = Class.create({
+    baseInitialize: function(element, update, options)
+    {
+        element = $(element)
+        this.element = element;
+        this.update = $(update);
+        this.hasFocus = false;
+        this.changed = false;
+        this.active = false;
+        this.index = 0;
+        this.entryCount = 0;
+        this.oldElementValue = this.element.value;
+
+        if (this.setOptions)
+            this.setOptions(options);
+        else
+            this.options = options || { };
+
+        this.options.paramName = this.options.paramName || this.element.name;
+        this.options.tokens = this.options.tokens || [];
+        this.options.frequency = this.options.frequency || 0.4;
+        this.options.minChars = this.options.minChars || 1;
+        this.options.onShow = this.options.onShow ||
+                              function(element, update)
+                              {
+                                  if (!update.style.position || update.style.position == 'absolute')
+                                  {
+                                      update.style.position = 'absolute';
+                                      Position.clone(element, update, {
+                                          setHeight: false,
+                                          offsetTop: element.offsetHeight
+                                      });
+                                  }
+                                  Effect.Appear(update, {duration:0.15});
+                              };
+        this.options.onHide = this.options.onHide ||
+                              function(element, update)
+                              {
+                                  new Effect.Fade(update, {duration:0.15})
+                              };
+
+        if (typeof(this.options.tokens) == 'string')
+            this.options.tokens = new Array(this.options.tokens);
+    // Force carriage returns as token delimiters anyway
+        if (!this.options.tokens.include('\n'))
+            this.options.tokens.push('\n');
+
+        this.observer = null;
+
+        this.element.setAttribute('autocomplete', 'off');
+
+        Element.hide(this.update);
+
+        Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
+        Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
+    },
+
+    show: function()
+    {
+        if (Element.getStyle(this.update, 'display') == 'none') this.options.onShow(this.element, this.update);
+        if (!this.iefix &&
+            (Prototype.Browser.IE) &&
+            (Element.getStyle(this.update, 'position') == 'absolute'))
+        {
+            new Insertion.After(this.update,
+                    '<iframe id="' + this.update.id + '_iefix" ' +
+                    'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+                    'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+            this.iefix = $(this.update.id + '_iefix');
+        }
+        if (this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+    },
+
+    fixIEOverlapping: function()
+    {
+        Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+        this.iefix.style.zIndex = 1;
+        this.update.style.zIndex = 2;
+        Element.show(this.iefix);
+    },
+
+    hide: function()
+    {
+        this.stopIndicator();
+        if (Element.getStyle(this.update, 'display') != 'none') this.options.onHide(this.element, this.update);
+        if (this.iefix) Element.hide(this.iefix);
+    },
+
+    startIndicator: function()
+    {
+        if (this.options.indicator) Element.show(this.options.indicator);
+    },
+
+    stopIndicator: function()
+    {
+        if (this.options.indicator) Element.hide(this.options.indicator);
+    },
+
+    onKeyPress: function(event)
+    {
+        if (this.active)
+            switch (event.keyCode)
+                    {
+                case Event.KEY_TAB:
+                case Event.KEY_RETURN:
+                    this.selectEntry();
+                    Event.stop(event);
+                case Event.KEY_ESC:
+                    this.hide();
+                    this.active = false;
+                    Event.stop(event);
+                    return;
+                case Event.KEY_LEFT:
+                case Event.KEY_RIGHT:
+                    return;
+                case Event.KEY_UP:
+                    this.markPrevious();
+                    this.render();
+                    if (Prototype.Browser.WebKit) Event.stop(event);
+                    return;
+                case Event.KEY_DOWN:
+                    this.markNext();
+                    this.render();
+                    if (Prototype.Browser.WebKit) Event.stop(event);
+                    return;
+            }
+        else
+            if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN ||
+                (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
+
+        this.changed = true;
+        this.hasFocus = true;
+
+        if (this.observer) clearTimeout(this.observer);
+        this.observer =
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency * 1000);
+    },
+
+    activate: function()
+    {
+        this.changed = false;
+        this.hasFocus = true;
+        this.getUpdatedChoices();
+    },
+
+    onHover: function(event)
+    {
+        var element = Event.findElement(event, 'LI');
+        if (this.index != element.autocompleteIndex)
+        {
+            this.index = element.autocompleteIndex;
+            this.render();
+        }
+        Event.stop(event);
+    },
+
+    onClick: function(event)
+    {
+        var element = Event.findElement(event, 'LI');
+        this.index = element.autocompleteIndex;
+        this.selectEntry();
+        this.hide();
+    },
+
+    onBlur: function(event)
+    {
+        // needed to make click events working
+        setTimeout(this.hide.bind(this), 250);
+        this.hasFocus = false;
+        this.active = false;
+    },
+
+    render: function()
+    {
+        if (this.entryCount > 0)
+        {
+            for (var i = 0; i < this.entryCount; i++)
+                this.index == i ?
+                Element.addClassName(this.getEntry(i), "selected") :
+                Element.removeClassName(this.getEntry(i), "selected");
+            if (this.hasFocus)
+            {
+                this.show();
+                this.active = true;
+            }
+        }
+        else
+        {
+            this.active = false;
+            this.hide();
+        }
+    },
+
+    markPrevious: function()
+    {
+        if (this.index > 0) this.index--
+        else this.index = this.entryCount - 1;
+        this.getEntry(this.index).scrollIntoView(true);
+    },
+
+    markNext: function()
+    {
+        if (this.index < this.entryCount - 1) this.index++
+        else this.index = 0;
+        this.getEntry(this.index).scrollIntoView(false);
+    },
+
+    getEntry: function(index)
+    {
+        return this.update.firstChild.childNodes[index];
+    },
+
+    getCurrentEntry: function()
+    {
+        return this.getEntry(this.index);
+    },
+
+    selectEntry: function()
+    {
+        this.active = false;
+        this.updateElement(this.getCurrentEntry());
+    },
+
+    updateElement: function(selectedElement)
+    {
+        if (this.options.updateElement)
+        {
+            this.options.updateElement(selectedElement);
+            return;
+        }
+        var value = '';
+        if (this.options.select)
+        {
+            var nodes = $(selectedElement).select('.' + this.options.select) || [];
+            if (nodes.length > 0) value = Element.collectTextNodes(nodes[0], this.options.select);
+        }
+        else
+            value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+
+        var bounds = this.getTokenBounds();
+        if (bounds[0] != -1)
+        {
+            var newValue = this.element.value.substr(0, bounds[0]);
+            var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
+            if (whitespace)
+                newValue += whitespace[0];
+            this.element.value = newValue + value + this.element.value.substr(bounds[1]);
+        }
+        else
+        {
+            this.element.value = value;
+        }
+        this.oldElementValue = this.element.value;
+        this.element.focus();
+
+        if (this.options.afterUpdateElement)
+            this.options.afterUpdateElement(this.element, selectedElement);
+    },
+
+    updateChoices: function(choices)
+    {
+        if (!this.changed && this.hasFocus)
+        {
+            this.update.innerHTML = choices;
+            Element.cleanWhitespace(this.update);
+            Element.cleanWhitespace(this.update.down());
+
+            if (this.update.firstChild && this.update.down().childNodes)
+            {
+                this.entryCount =
+                this.update.down().childNodes.length;
+                for (var i = 0; i < this.entryCount; i++)
+                {
+                    var entry = this.getEntry(i);
+                    entry.autocompleteIndex = i;
+                    this.addObservers(entry);
+                }
+            }
+            else
+            {
+                this.entryCount = 0;
+            }
+
+            this.stopIndicator();
+            this.index = 0;
+
+            if (this.entryCount == 1 && this.options.autoSelect)
+            {
+                this.selectEntry();
+                this.hide();
+            }
+            else
+            {
+                this.render();
+            }
+        }
+    },
+
+    addObservers: function(element)
+    {
+        Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+        Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+    },
+
+    onObserverEvent: function()
+    {
+        this.changed = false;
+        this.tokenBounds = null;
+        if (this.getToken().length >= this.options.minChars)
+        {
+            this.getUpdatedChoices();
+        }
+        else
+        {
+            this.active = false;
+            this.hide();
+        }
+        this.oldElementValue = this.element.value;
+    },
+
+    getToken: function()
+    {
+        var bounds = this.getTokenBounds();
+        return this.element.value.substring(bounds[0], bounds[1]).strip();
+    },
+
+    getTokenBounds: function()
+    {
+        if (null != this.tokenBounds) return this.tokenBounds;
+        var value = this.element.value;
+        if (value.strip().empty()) return [-1, 0];
+        var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
+        var offset = (diff == this.oldElementValue.length ? 1 : 0);
+        var prevTokenPos = -1, nextTokenPos = value.length;
+        var tp;
+        for (var index = 0, l = this.options.tokens.length; index < l; ++index)
+        {
+            tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
+            if (tp > prevTokenPos) prevTokenPos = tp;
+            tp = value.indexOf(this.options.tokens[index], diff + offset);
+            if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
+        }
+        return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
+    }
+});
+
+Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS)
+{
+    var boundary = Math.min(newS.length, oldS.length);
+    for (var index = 0; index < boundary; ++index)
+        if (newS[index] != oldS[index])
+            return index;
+    return boundary;
+};
+
+Ajax.Autocompleter = Class.create(Autocompleter.Base, {
+    initialize: function(element, update, url, options)
+    {
+        this.baseInitialize(element, update, options);
+        this.options.asynchronous = true;
+        this.options.onComplete = this.onComplete.bind(this);
+        this.options.defaultParams = this.options.parameters || null;
+        this.url = url;
+    },
+
+    getUpdatedChoices: function()
+    {
+        this.startIndicator();
+
+        var entry = encodeURIComponent(this.options.paramName) + '=' +
+                    encodeURIComponent(this.getToken());
+
+        this.options.parameters = this.options.callback ?
+                                  this.options.callback(this.element, entry) : entry;
+
+        if (this.options.defaultParams)
+            this.options.parameters += '&' + this.options.defaultParams;
+
+        new Ajax.Request(this.url, this.options);
+    },
+
+    onComplete: function(request)
+    {
+        this.updateChoices(request.responseText);
+    }
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+//                    text only at the beginning of strings in the 
+//                    autocomplete array. Defaults to true, which will
+//                    match text at the beginning of any *word* in the
+//                    strings in the autocomplete array. If you want to
+//                    search anywhere in the string, additionally set
+//                    the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+//                   a partial match (unlike minChars, which defines
+//                   how many characters are required to do any match
+//                   at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+//                 Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector' 
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create(Autocompleter.Base, {
+    initialize: function(element, update, array, options)
+    {
+        this.baseInitialize(element, update, options);
+        this.options.array = array;
+    },
+
+    getUpdatedChoices: function()
+    {
+        this.updateChoices(this.options.selector(this));
+    },
+
+    setOptions: function(options)
+    {
+        this.options = Object.extend({
+            choices: 10,
+            partialSearch: true,
+            partialChars: 2,
+            ignoreCase: true,
+            fullSearch: false,
+            selector: function(instance)
+            {
+                var ret = []; // Beginning matches
+                var partial = []; // Inside matches
+                var entry = instance.getToken();
+                var count = 0;
+
+                for (var i = 0; i < instance.options.array.length &&
+                                ret.length < instance.options.choices; i++)
+                {
+
+                    var elem = instance.options.array[i];
+                    var foundPos = instance.options.ignoreCase ?
+                                   elem.toLowerCase().indexOf(entry.toLowerCase()) :
+                                   elem.indexOf(entry);
+
+                    while (foundPos != -1)
+                    {
+                        if (foundPos == 0 && elem.length != entry.length)
+                        {
+                            ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+                                     elem.substr(entry.length) + "</li>");
+                            break;
+                        }
+                        else if (entry.length >= instance.options.partialChars &&
+                                 instance.options.partialSearch && foundPos != -1)
+                        {
+                            if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos - 1, 1)))
+                            {
+                                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+                                             elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+                                        foundPos + entry.length) + "</li>");
+                                break;
+                            }
+                        }
+
+                        foundPos = instance.options.ignoreCase ?
+                                   elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
+                                   elem.indexOf(entry, foundPos + 1);
+
+                    }
+                }
+                if (partial.length)
+                    ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+                return "<ul>" + ret.join('') + "</ul>";
+            }
+        }, options || { });
+    }
+});
+
+// AJAX in-place editor and collection editor
+// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field)
+{
+    setTimeout(function()
+    {
+        Field.activate(field);
+    }, 1);
+}
+
+Ajax.InPlaceEditor = Class.create({
+    initialize: function(element, url, options)
+    {
+        this.url = url;
+        this.element = element = $(element);
+        this.prepareOptions();
+        this._controls = { };
+        arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
+        Object.extend(this.options, options || { });
+        if (!this.options.formId && this.element.id)
+        {
+            this.options.formId = this.element.id + '-inplaceeditor';
+            if ($(this.options.formId))
+                this.options.formId = '';
+        }
+        if (this.options.externalControl)
+            this.options.externalControl = $(this.options.externalControl);
+        if (!this.options.externalControl)
+            this.options.externalControlOnly = false;
+        this._originalBackground = this.element.getStyle('background-color') || 'transparent';
+        this.element.title = this.options.clickToEditText;
+        this._boundCancelHandler = this.handleFormCancellation.bind(this);
+        this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
+        this._boundFailureHandler = this.handleAJAXFailure.bind(this);
+        this._boundSubmitHandler = this.handleFormSubmission.bind(this);
+        this._boundWrapperHandler = this.wrapUp.bind(this);
+        this.registerListeners();
+    },
+    checkForEscapeOrReturn: function(e)
+    {
+        if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
+        if (Event.KEY_ESC == e.keyCode)
+            this.handleFormCancellation(e);
+        else if (Event.KEY_RETURN == e.keyCode)
+            this.handleFormSubmission(e);
+    },
+    createControl: function(mode, handler, extraClasses)
+    {
+        var control = this.options[mode + 'Control'];
+        var text = this.options[mode + 'Text'];
+        if ('button' == control)
+        {
+            var btn = document.createElement('input');
+            btn.type = 'submit';
+            btn.value = text;
+            btn.className = 'editor_' + mode + '_button';
+            if ('cancel' == mode)
+                btn.onclick = this._boundCancelHandler;
+            this._form.appendChild(btn);
+            this._controls[mode] = btn;
+        }
+        else if ('link' == control)
+        {
+            var link = document.createElement('a');
+            link.href = '#';
+            link.appendChild(document.createTextNode(text));
+            link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
+            link.className = 'editor_' + mode + '_link';
+            if (extraClasses)
+                link.className += ' ' + extraClasses;
+            this._form.appendChild(link);
+            this._controls[mode] = link;
+        }
+    },
+    createEditField: function()
+    {
+        var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
+        var fld;
+        if (1 >= this.options.rows && !/\r|\n/.test(this.getText()))
+        {
+            fld = document.createElement('input');
+            fld.type = 'text';
+            var size = this.options.size || this.options.cols || 0;
+            if (0 < size) fld.size = size;
+        }
+        else
+        {
+            fld = document.createElement('textarea');
+            fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
+            fld.cols = this.options.cols || 40;
+        }
+        fld.name = this.options.paramName;
+        fld.value = text; // No HTML breaks conversion anymore
+        fld.className = 'editor_field';
+        if (this.options.submitOnBlur)
+            fld.onblur = this._boundSubmitHandler;
+        this._controls.editor = fld;
+        if (this.options.loadTextURL)
+            this.loadExternalText();
+        this._form.appendChild(this._controls.editor);
+    },
+    createForm: function()
+    {
+        var ipe = this;
+        function addText(mode, condition)
+        {
+            var text = ipe.options['text' + mode + 'Controls'];
+            if (!text || condition === false) return;
+            ipe._form.appendChild(document.createTextNode(text));
+        }
+        ;
+        this._form = $(document.createElement('form'));
+        this._form.id = this.options.formId;
+        this._form.addClassName(this.options.formClassName);
+        this._form.onsubmit = this._boundSubmitHandler;
+        this.createEditField();
+        if ('textarea' == this._controls.editor.tagName.toLowerCase())
+            this._form.appendChild(document.createElement('br'));
+        if (this.options.onFormCustomization)
+            this.options.onFormCustomization(this, this._form);
+        addText('Before', this.options.okControl || this.options.cancelControl);
+        this.createControl('ok', this._boundSubmitHandler);
+        addText('Between', this.options.okControl && this.options.cancelControl);
+        this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
+        addText('After', this.options.okControl || this.options.cancelControl);
+    },
+    destroy: function()
+    {
+        if (this._oldInnerHTML)
+            this.element.innerHTML = this._oldInnerHTML;
+        this.leaveEditMode();
+        this.unregisterListeners();
+    },
+    enterEditMode: function(e)
+    {
+        if (this._saving || this._editing) return;
+        this._editing = true;
+        this.triggerCallback('onEnterEditMode');
+        if (this.options.externalControl)
+            this.options.externalControl.hide();
+        this.element.hide();
+        this.createForm();
+        this.element.parentNode.insertBefore(this._form, this.element);
+        if (!this.options.loadTextURL)
+            this.postProcessEditField();
+        if (e) Event.stop(e);
+    },
+    enterHover: function(e)
+    {
+        if (this.options.hoverClassName)
+            this.element.addClassName(this.options.hoverClassName);
+        if (this._saving) return;
+        this.triggerCallback('onEnterHover');
+    },
+    getText: function()
+    {
+        return this.element.innerHTML;
+    },
+    handleAJAXFailure: function(transport)
+    {
+        this.triggerCallback('onFailure', transport);
+        if (this._oldInnerHTML)
+        {
+            this.element.innerHTML = this._oldInnerHTML;
+            this._oldInnerHTML = null;
+        }
+    },
+    handleFormCancellation: function(e)
+    {
+        this.wrapUp();
+        if (e) Event.stop(e);
+    },
+    handleFormSubmission: function(e)
+    {
+        var form = this._form;
+        var value = $F(this._controls.editor);
+        this.prepareSubmission();
+        var params = this.options.callback(form, value) || '';
+        if (Object.isString(params))
+            params = params.toQueryParams();
+        params.editorId = this.element.id;
+        if (this.options.htmlResponse)
+        {
+            var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
+            Object.extend(options, {
+                parameters: params,
+                onComplete: this._boundWrapperHandler,
+                onFailure: this._boundFailureHandler
+            });
+            new Ajax.Updater({ success: this.element }, this.url, options);
+        }
+        else
+        {
+            var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+            Object.extend(options, {
+                parameters: params,
+                onComplete: this._boundWrapperHandler,
+                onFailure: this._boundFailureHandler
+            });
+            new Ajax.Request(this.url, options);
+        }
+        if (e) Event.stop(e);
+    },
+    leaveEditMode: function()
+    {
+        this.element.removeClassName(this.options.savingClassName);
+        this.removeForm();
+        this.leaveHover();
+        this.element.style.backgroundColor = this._originalBackground;
+        this.element.show();
+        if (this.options.externalControl)
+            this.options.externalControl.show();
+        this._saving = false;
+        this._editing = false;
+        this._oldInnerHTML = null;
+        this.triggerCallback('onLeaveEditMode');
+    },
+    leaveHover: function(e)
+    {
+        if (this.options.hoverClassName)
+            this.element.removeClassName(this.options.hoverClassName);
+        if (this._saving) return;
+        this.triggerCallback('onLeaveHover');
+    },
+    loadExternalText: function()
+    {
+        this._form.addClassName(this.options.loadingClassName);
+        this._controls.editor.disabled = true;
+        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+        Object.extend(options, {
+            parameters: 'editorId=' + encodeURIComponent(this.element.id),
+            onComplete: Prototype.emptyFunction,
+            onSuccess: function(transport)
+            {
+                this._form.removeClassName(this.options.loadingClassName);
+                var text = transport.responseText;
+                if (this.options.stripLoadedTextTags)
+                    text = text.stripTags();
+                this._controls.editor.value = text;
+                this._controls.editor.disabled = false;
+                this.postProcessEditField();
+            }.bind(this),
+            onFailure: this._boundFailureHandler
+        });
+        new Ajax.Request(this.options.loadTextURL, options);
+    },
+    postProcessEditField: function()
+    {
+        var fpc = this.options.fieldPostCreation;
+        if (fpc)
+            $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
+    },
+    prepareOptions: function()
+    {
+        this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
+        Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
+        [this._extraDefaultOptions].flatten().compact().each(function(defs)
+        {
+            Object.extend(this.options, defs);
+        }.bind(this));
+    },
+    prepareSubmission: function()
+    {
+        this._saving = true;
+        this.removeForm();
+        this.leaveHover();
+        this.showSaving();
+    },
+    registerListeners: function()
+    {
+        this._listeners = { };
+        var listener;
+        $H(Ajax.InPlaceEditor.Listeners).each(function(pair)
+        {
+            listener = this[pair.value].bind(this);
+            this._listeners[pair.key] = listener;
+            if (!this.options.externalControlOnly)
+                this.element.observe(pair.key, listener);
+            if (this.options.externalControl)
+                this.options.externalControl.observe(pair.key, listener);
+        }.bind(this));
+    },
+    removeForm: function()
+    {
+        if (!this._form) return;
+        this._form.remove();
+        this._form = null;
+        this._controls = { };
+    },
+    showSaving: function()
+    {
+        this._oldInnerHTML = this.element.innerHTML;
+        this.element.innerHTML = this.options.savingText;
+        this.element.addClassName(this.options.savingClassName);
+        this.element.style.backgroundColor = this._originalBackground;
+        this.element.show();
+    },
+    triggerCallback: function(cbName, arg)
+    {
+        if ('function' == typeof this.options[cbName])
+        {
+            this.options[cbName](this, arg);
+        }
+    },
+    unregisterListeners: function()
+    {
+        $H(this._listeners).each(function(pair)
+        {
+            if (!this.options.externalControlOnly)
+                this.element.stopObserving(pair.key, pair.value);
+            if (this.options.externalControl)
+                this.options.externalControl.stopObserving(pair.key, pair.value);
+        }.bind(this));
+    },
+    wrapUp: function(transport)
+    {
+        this.leaveEditMode();
+    // Can't use triggerCallback due to backward compatibility: requires
+        // binding + direct element
+        this._boundComplete(transport, this.element);
+    }
+});
+
+Object.extend(Ajax.InPlaceEditor.prototype, {
+    dispose: Ajax.InPlaceEditor.prototype.destroy
+});
+
+Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
+    initialize: function($super, element, url, options)
+    {
+        this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
+        $super(element, url, options);
+    },
+
+    createEditField: function()
+    {
+        var list = document.createElement('select');
+        list.name = this.options.paramName;
+        list.size = 1;
+        this._controls.editor = list;
+        this._collection = this.options.collection || [];
+        if (this.options.loadCollectionURL)
+            this.loadCollection();
+        else
+            this.checkForExternalText();
+        this._form.appendChild(this._controls.editor);
+    },
+
+    loadCollection: function()
+    {
+        this._form.addClassName(this.options.loadingClassName);
+        this.showLoadingText(this.options.loadingCollectionText);
+        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+        Object.extend(options, {
+            parameters: 'editorId=' + encodeURIComponent(this.element.id),
+            onComplete: Prototype.emptyFunction,
+            onSuccess: function(transport)
+            {
+                var js = transport.responseText.strip();
+                if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
+                    throw 'Server returned an invalid collection representation.';
+                this._collection = eval(js);
+                this.checkForExternalText();
+            }.bind(this),
+            onFailure: this.onFailure
+        });
+        new Ajax.Request(this.options.loadCollectionURL, options);
+    },
+
+    showLoadingText: function(text)
+    {
+        this._controls.editor.disabled = true;
+        var tempOption = this._controls.editor.firstChild;
+        if (!tempOption)
+        {
+            tempOption = document.createElement('option');
+            tempOption.value = '';
+            this._controls.editor.appendChild(tempOption);
+            tempOption.selected = true;
+        }
+        tempOption.update((text || '').stripScripts().stripTags());
+    },
+
+    checkForExternalText: function()
+    {
+        this._text = this.getText();
+        if (this.options.loadTextURL)
+            this.loadExternalText();
+        else
+            this.buildOptionList();
+    },
+
+    loadExternalText: function()
+    {
+        this.showLoadingText(this.options.loadingText);
+        var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
+        Object.extend(options, {
+            parameters: 'editorId=' + encodeURIComponent(this.element.id),
+            onComplete: Prototype.emptyFunction,
+            onSuccess: function(transport)
+            {
+                this._text = transport.responseText.strip();
+                this.buildOptionList();
+            }.bind(this),
+            onFailure: this.onFailure
+        });
+        new Ajax.Request(this.options.loadTextURL, options);
+    },
+
+    buildOptionList: function()
+    {
+        this._form.removeClassName(this.options.loadingClassName);
+        this._collection = this._collection.map(function(entry)
+        {
+            return 2 === entry.length ? entry : [entry, entry].flatten();
+        });
+        var marker = ('value' in this.options) ? this.options.value : this._text;
+        var textFound = this._collection.any(function(entry)
+        {
+            return entry[0] == marker;
+        }.bind(this));
+        this._controls.editor.update('');
+        var option;
+        this._collection.each(function(entry, index)
+        {
+            option = document.createElement('option');
+            option.value = entry[0];
+            option.selected = textFound ? entry[0] == marker : 0 == index;
+            option.appendChild(document.createTextNode(entry[1]));
+            this._controls.editor.appendChild(option);
+        }.bind(this));
+        this._controls.editor.disabled = false;
+        Field.scrollFreeActivate(this._controls.editor);
+    }
+});
+
+//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
+//**** This only  exists for a while,  in order to  let ****
+//**** users adapt to  the new API.  Read up on the new ****
+//**** API and convert your code to it ASAP!            ****
+
+Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options)
+{
+    if (!options) return;
+    function fallback(name, expr)
+    {
+        if (name in options || expr === undefined) return;
+        options[name] = expr;
+    }
+    ;
+    fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
+                                                              options.cancelLink == options.cancelButton == false ? false : undefined)));
+    fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
+                                                      options.okLink == options.okButton == false ? false : undefined)));
+    fallback('highlightColor', options.highlightcolor);
+    fallback('highlightEndColor', options.highlightendcolor);
+};
+
+Object.extend(Ajax.InPlaceEditor, {
+    DefaultOptions: {
+        ajaxOptions: { },
+        autoRows: 3,                                // Use when multi-line w/ rows == 1
+        cancelControl: 'link',                      // 'link'|'button'|false
+        cancelText: 'cancel',
+        clickToEditText: 'Click to edit',
+        externalControl: null,                      // id|elt
+        externalControlOnly: false,
+        fieldPostCreation: 'activate',              // 'activate'|'focus'|false
+        formClassName: 'inplaceeditor-form',
+        formId: null,                               // id|elt
+        highlightColor: '#ffff99',
+        highlightEndColor: '#ffffff',
+        hoverClassName: '',
+        htmlResponse: true,
+        loadingClassName: 'inplaceeditor-loading',
+        loadingText: 'Loading...',
+        okControl: 'button',                        // 'link'|'button'|false
+        okText: 'ok',
+        paramName: 'value',
+        rows: 1,                                    // If 1 and multi-line, uses autoRows
+        savingClassName: 'inplaceeditor-saving',
+        savingText: 'Saving...',
+        size: 0,
+        stripLoadedTextTags: false,
+        submitOnBlur: false,
+        textAfterControls: '',
+        textBeforeControls: '',
+        textBetweenControls: ''
+    },
+    DefaultCallbacks: {
+        callback: function(form)
+        {
+            return Form.serialize(form);
+        },
+        onComplete: function(transport, element)
+        {
+            // For backward compatibility, this one is bound to the IPE, and passes
+            // the element directly.  It was too often customized, so we don't break it.
+            new Effect.Highlight(element, {
+                startcolor: this.options.highlightColor, keepBackgroundImage: true });
+        },
+        onEnterEditMode: null,
+        onEnterHover: function(ipe)
+        {
+            ipe.element.style.backgroundColor = ipe.options.highlightColor;
+            if (ipe._effect)
+                ipe._effect.cancel();
+        },
+        onFailure: function(transport, ipe)
+        {
+            alert('Error communication with the server: ' + transport.responseText.stripTags());
+        },
+        onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
+        onLeaveEditMode: null,
+        onLeaveHover: function(ipe)
+        {
+            ipe._effect = new Effect.Highlight(ipe.element, {
+                startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
+                restorecolor: ipe._originalBackground, keepBackgroundImage: true
+            });
+        }
+    },
+    Listeners: {
+        click: 'enterEditMode',
+        keydown: 'checkForEscapeOrReturn',
+        mouseover: 'enterHover',
+        mouseout: 'leaveHover'
+    }
+});
+
+Ajax.InPlaceCollectionEditor.DefaultOptions = {
+    loadingCollectionText: 'Loading options...'
+};
+
+// Delayed observer, like Form.Element.Observer, 
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create({
+    initialize: function(element, delay, callback)
+    {
+        this.delay = delay || 0.5;
+        this.element = $(element);
+        this.callback = callback;
+        this.timer = null;
+        this.lastValue = $F(this.element);
+        Event.observe(this.element, 'keyup', this.delayedListener.bindAsEventListener(this));
+    },
+    delayedListener: function(event)
+    {
+        if (this.lastValue == $F(this.element)) return;
+        if (this.timer) clearTimeout(this.timer);
+        this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+        this.lastValue = $F(this.element);
+    },
+    onTimerEvent: function()
+    {
+        this.timer = null;
+        this.callback(this.element, $F(this.element));
+    }
+});
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/dragdrop.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/dragdrop.js
new file mode 100644
index 0000000..b72e4d9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/dragdrop.js
@@ -0,0 +1,1174 @@
+// script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if (Object.isUndefined(Effect))
+    throw("dragdrop.js requires including script.aculo.us' effects.js library");
+
+var Droppables = {
+    drops: [],
+
+    remove: function(element)
+    {
+        this.drops = this.drops.reject(function(d)
+        {
+            return d.element == $(element)
+        });
+    },
+
+    add: function(element)
+    {
+        element = $(element);
+        var options = Object.extend({
+            greedy:     true,
+            hoverclass: null,
+            tree:       false
+        }, arguments[1] || { });
+
+    // cache containers
+        if (options.containment)
+        {
+            options._containers = [];
+            var containment = options.containment;
+            if (Object.isArray(containment))
+            {
+                containment.each(function(c)
+                {
+                    options._containers.push($(c))
+                });
+            }
+            else
+            {
+                options._containers.push($(containment));
+            }
+        }
+
+        if (options.accept) options.accept = [options.accept].flatten();
+
+        Element.makePositioned(element); // fix IE
+        options.element = element;
+
+        this.drops.push(options);
+    },
+
+    findDeepestChild: function(drops)
+    {
+        deepest = drops[0];
+
+        for (i = 1; i < drops.length; ++i)
+            if (Element.isParent(drops[i].element, deepest.element))
+                deepest = drops[i];
+
+        return deepest;
+    },
+
+    isContained: function(element, drop)
+    {
+        var containmentNode;
+        if (drop.tree)
+        {
+            containmentNode = element.treeNode;
+        }
+        else
+        {
+            containmentNode = element.parentNode;
+        }
+        return drop._containers.detect(function(c)
+        {
+            return containmentNode == c
+        });
+    },
+
+    isAffected: function(point, element, drop)
+    {
+        return (
+                (drop.element != element) &&
+                ((!drop._containers) ||
+                 this.isContained(element, drop)) &&
+                ((!drop.accept) ||
+                 (Element.classNames(element).detect(
+                         function(v)
+                         {
+                             return drop.accept.include(v)
+                         }) )) &&
+                Position.within(drop.element, point[0], point[1]) );
+    },
+
+    deactivate: function(drop)
+    {
+        if (drop.hoverclass)
+            Element.removeClassName(drop.element, drop.hoverclass);
+        this.last_active = null;
+    },
+
+    activate: function(drop)
+    {
+        if (drop.hoverclass)
+            Element.addClassName(drop.element, drop.hoverclass);
+        this.last_active = drop;
+    },
+
+    show: function(point, element)
+    {
+        if (!this.drops.length) return;
+        var drop, affected = [];
+
+        this.drops.each(function(drop)
+        {
+            if (Droppables.isAffected(point, element, drop))
+                affected.push(drop);
+        });
+
+        if (affected.length > 0)
+            drop = Droppables.findDeepestChild(affected);
+
+        if (this.last_active && this.last_active != drop) this.deactivate(this.last_active);
+        if (drop)
+        {
+            Position.within(drop.element, point[0], point[1]);
+            if (drop.onHover)
+                drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+
+            if (drop != this.last_active) Droppables.activate(drop);
+        }
+    },
+
+    fire: function(event, element)
+    {
+        if (!this.last_active) return;
+        Position.prepare();
+
+        if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
+            if (this.last_active.onDrop)
+            {
+                this.last_active.onDrop(element, this.last_active.element, event);
+                return true;
+            }
+    },
+
+    reset: function()
+    {
+        if (this.last_active)
+            this.deactivate(this.last_active);
+    }
+}
+
+var Draggables = {
+    drags: [],
+    observers: [],
+
+    register: function(draggable)
+    {
+        if (this.drags.length == 0)
+        {
+            this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+            this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+            this.eventKeypress = this.keyPress.bindAsEventListener(this);
+
+            Event.observe(document, "mouseup", this.eventMouseUp);
+            Event.observe(document, "mousemove", this.eventMouseMove);
+            Event.observe(document, "keypress", this.eventKeypress);
+        }
+        this.drags.push(draggable);
+    },
+
+    unregister: function(draggable)
+    {
+        this.drags = this.drags.reject(function(d)
+        {
+            return d == draggable
+        });
+        if (this.drags.length == 0)
+        {
+            Event.stopObserving(document, "mouseup", this.eventMouseUp);
+            Event.stopObserving(document, "mousemove", this.eventMouseMove);
+            Event.stopObserving(document, "keypress", this.eventKeypress);
+        }
+    },
+
+    activate: function(draggable)
+    {
+        if (draggable.options.delay)
+        {
+            this._timeout = setTimeout(function()
+            {
+                Draggables._timeout = null;
+                window.focus();
+                Draggables.activeDraggable = draggable;
+            }.bind(this), draggable.options.delay);
+        }
+        else
+        {
+            window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+            this.activeDraggable = draggable;
+        }
+    },
+
+    deactivate: function()
+    {
+        this.activeDraggable = null;
+    },
+
+    updateDrag: function(event)
+    {
+        if (!this.activeDraggable) return;
+        var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    // Mozilla-based browsers fire successive mousemove events with
+        // the same coordinates, prevent needless redrawing (moz bug?)
+        if (this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
+        this._lastPointer = pointer;
+
+        this.activeDraggable.updateDrag(event, pointer);
+    },
+
+    endDrag: function(event)
+    {
+        if (this._timeout)
+        {
+            clearTimeout(this._timeout);
+            this._timeout = null;
+        }
+        if (!this.activeDraggable) return;
+        this._lastPointer = null;
+        this.activeDraggable.endDrag(event);
+        this.activeDraggable = null;
+    },
+
+    keyPress: function(event)
+    {
+        if (this.activeDraggable)
+            this.activeDraggable.keyPress(event);
+    },
+
+    addObserver: function(observer)
+    {
+        this.observers.push(observer);
+        this._cacheObserverCallbacks();
+    },
+
+    removeObserver: function(element)
+    {  // element instead of observer fixes mem leaks
+        this.observers = this.observers.reject(function(o)
+        {
+            return o.element == element
+        });
+        this._cacheObserverCallbacks();
+    },
+
+    notify: function(eventName, draggable, event)
+    {  // 'onStart', 'onEnd', 'onDrag'
+        if (this[eventName + 'Count'] > 0)
+            this.observers.each(function(o)
+            {
+                if (o[eventName]) o[eventName](eventName, draggable, event);
+            });
+        if (draggable.options[eventName]) draggable.options[eventName](draggable, event);
+    },
+
+    _cacheObserverCallbacks: function()
+    {
+        ['onStart','onEnd','onDrag'].each(function(eventName)
+        {
+            Draggables[eventName + 'Count'] = Draggables.observers.select(
+                    function(o)
+                    {
+                        return o[eventName];
+                    }
+                    ).length;
+        });
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Draggable = Class.create({
+    initialize: function(element)
+    {
+        var defaults = {
+            handle: false,
+            reverteffect: function(element, top_offset, left_offset)
+            {
+                var dur = Math.sqrt(Math.abs(top_offset ^ 2) + Math.abs(left_offset ^ 2)) * 0.02;
+                new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+                    queue: {scope:'_draggable', position:'end'}
+                });
+            },
+            endeffect: function(element)
+            {
+                var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
+                new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+                    queue: {scope:'_draggable', position:'end'},
+                    afterFinish: function()
+                    {
+                        Draggable._dragging[element] = false
+                    }
+                });
+            },
+            zindex: 1000,
+            revert: false,
+            quiet: false,
+            scroll: false,
+            scrollSensitivity: 20,
+            scrollSpeed: 15,
+            snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
+            delay: 0
+        };
+
+        if (!arguments[1] || Object.isUndefined(arguments[1].endeffect))
+            Object.extend(defaults, {
+                starteffect: function(element)
+                {
+                    element._opacity = Element.getOpacity(element);
+                    Draggable._dragging[element] = true;
+                    new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+                }
+            });
+
+        var options = Object.extend(defaults, arguments[1] || { });
+
+        this.element = $(element);
+
+        if (options.handle && Object.isString(options.handle))
+            this.handle = this.element.down('.' + options.handle, 0);
+
+        if (!this.handle) this.handle = $(options.handle);
+        if (!this.handle) this.handle = this.element;
+
+        if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML)
+        {
+            options.scroll = $(options.scroll);
+            this._isScrollChild = Element.childOf(this.element, options.scroll);
+        }
+
+        Element.makePositioned(this.element); // fix IE
+
+        this.options = options;
+        this.dragging = false;
+
+        this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+        Event.observe(this.handle, "mousedown", this.eventMouseDown);
+
+        Draggables.register(this);
+    },
+
+    destroy: function()
+    {
+        Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+        Draggables.unregister(this);
+    },
+
+    currentDelta: function()
+    {
+        return([
+            parseInt(Element.getStyle(this.element, 'left') || '0'),
+            parseInt(Element.getStyle(this.element, 'top') || '0')]);
+    },
+
+    initDrag: function(event)
+    {
+        if (!Object.isUndefined(Draggable._dragging[this.element]) &&
+            Draggable._dragging[this.element]) return;
+        if (Event.isLeftClick(event))
+        {
+            // abort on form elements, fixes a Firefox issue
+            var src = Event.element(event);
+            if ((tag_name = src.tagName.toUpperCase()) && (
+                    tag_name == 'INPUT' ||
+                    tag_name == 'SELECT' ||
+                    tag_name == 'OPTION' ||
+                    tag_name == 'BUTTON' ||
+                    tag_name == 'TEXTAREA')) return;
+
+            var pointer = [Event.pointerX(event), Event.pointerY(event)];
+            var pos = Position.cumulativeOffset(this.element);
+            this.offset = [0,1].map(function(i)
+            {
+                return (pointer[i] - pos[i])
+            });
+
+            Draggables.activate(this);
+            Event.stop(event);
+        }
+    },
+
+    startDrag: function(event)
+    {
+        this.dragging = true;
+        if (!this.delta)
+            this.delta = this.currentDelta();
+
+        if (this.options.zindex)
+        {
+            this.originalZ = parseInt(Element.getStyle(this.element, 'z-index') || 0);
+            this.element.style.zIndex = this.options.zindex;
+        }
+
+        if (this.options.ghosting)
+        {
+            this._clone = this.element.cloneNode(true);
+            this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
+            if (!this.element._originallyAbsolute)
+                Position.absolutize(this.element);
+            this.element.parentNode.insertBefore(this._clone, this.element);
+        }
+
+        if (this.options.scroll)
+        {
+            if (this.options.scroll == window)
+            {
+                var where = this._getWindowScroll(this.options.scroll);
+                this.originalScrollLeft = where.left;
+                this.originalScrollTop = where.top;
+            }
+            else
+            {
+                this.originalScrollLeft = this.options.scroll.scrollLeft;
+                this.originalScrollTop = this.options.scroll.scrollTop;
+            }
+        }
+
+        Draggables.notify('onStart', this, event);
+
+        if (this.options.starteffect) this.options.starteffect(this.element);
+    },
+
+    updateDrag: function(event, pointer)
+    {
+        if (!this.dragging) this.startDrag(event);
+
+        if (!this.options.quiet)
+        {
+            Position.prepare();
+            Droppables.show(pointer, this.element);
+        }
+
+        Draggables.notify('onDrag', this, event);
+
+        this.draw(pointer);
+        if (this.options.change) this.options.change(this);
+
+        if (this.options.scroll)
+        {
+            this.stopScrolling();
+
+            var p;
+            if (this.options.scroll == window)
+            {
+                with (this._getWindowScroll(this.options.scroll))
+                {
+                    p = [ left, top, left + width, top + height ];
+                }
+            }
+            else
+            {
+                p = Position.page(this.options.scroll);
+                p[0] += this.options.scroll.scrollLeft + Position.deltaX;
+                p[1] += this.options.scroll.scrollTop + Position.deltaY;
+                p.push(p[0] + this.options.scroll.offsetWidth);
+                p.push(p[1] + this.options.scroll.offsetHeight);
+            }
+            var speed = [0,0];
+            if (pointer[0] < (p[0] + this.options.scrollSensitivity)) speed[0] = pointer[0] - (p[0] + this.options.scrollSensitivity);
+            if (pointer[1] < (p[1] + this.options.scrollSensitivity)) speed[1] = pointer[1] - (p[1] + this.options.scrollSensitivity);
+            if (pointer[0] > (p[2] - this.options.scrollSensitivity)) speed[0] = pointer[0] - (p[2] - this.options.scrollSensitivity);
+            if (pointer[1] > (p[3] - this.options.scrollSensitivity)) speed[1] = pointer[1] - (p[3] - this.options.scrollSensitivity);
+            this.startScrolling(speed);
+        }
+    
+    // fix AppleWebKit rendering
+        if (Prototype.Browser.WebKit) window.scrollBy(0, 0);
+
+        Event.stop(event);
+    },
+
+    finishDrag: function(event, success)
+    {
+        this.dragging = false;
+
+        if (this.options.quiet)
+        {
+            Position.prepare();
+            var pointer = [Event.pointerX(event), Event.pointerY(event)];
+            Droppables.show(pointer, this.element);
+        }
+
+        if (this.options.ghosting)
+        {
+            if (!this.element._originallyAbsolute)
+                Position.relativize(this.element);
+            delete this.element._originallyAbsolute;
+            Element.remove(this._clone);
+            this._clone = null;
+        }
+
+        var dropped = false;
+        if (success)
+        {
+            dropped = Droppables.fire(event, this.element);
+            if (!dropped) dropped = false;
+        }
+        if (dropped && this.options.onDropped) this.options.onDropped(this.element);
+        Draggables.notify('onEnd', this, event);
+
+        var revert = this.options.revert;
+        if (revert && Object.isFunction(revert)) revert = revert(this.element);
+
+        var d = this.currentDelta();
+        if (revert && this.options.reverteffect)
+        {
+            if (dropped == 0 || revert != 'failure')
+                this.options.reverteffect(this.element,
+                        d[1] - this.delta[1], d[0] - this.delta[0]);
+        }
+        else
+        {
+            this.delta = d;
+        }
+
+        if (this.options.zindex)
+            this.element.style.zIndex = this.originalZ;
+
+        if (this.options.endeffect)
+            this.options.endeffect(this.element);
+
+        Draggables.deactivate(this);
+        Droppables.reset();
+    },
+
+    keyPress: function(event)
+    {
+        if (event.keyCode != Event.KEY_ESC) return;
+        this.finishDrag(event, false);
+        Event.stop(event);
+    },
+
+    endDrag: function(event)
+    {
+        if (!this.dragging) return;
+        this.stopScrolling();
+        this.finishDrag(event, true);
+        Event.stop(event);
+    },
+
+    draw: function(point)
+    {
+        var pos = Position.cumulativeOffset(this.element);
+        if (this.options.ghosting)
+        {
+            var r = Position.realOffset(this.element);
+            pos[0] += r[0] - Position.deltaX;
+            pos[1] += r[1] - Position.deltaY;
+        }
+
+        var d = this.currentDelta();
+        pos[0] -= d[0];
+        pos[1] -= d[1];
+
+        if (this.options.scroll && (this.options.scroll != window && this._isScrollChild))
+        {
+            pos[0] -= this.options.scroll.scrollLeft - this.originalScrollLeft;
+            pos[1] -= this.options.scroll.scrollTop - this.originalScrollTop;
+        }
+
+        var p = [0,1].map(function(i)
+        {
+            return (point[i] - pos[i] - this.offset[i])
+        }.bind(this));
+
+        if (this.options.snap)
+        {
+            if (Object.isFunction(this.options.snap))
+            {
+                p = this.options.snap(p[0], p[1], this);
+            }
+            else
+            {
+                if (Object.isArray(this.options.snap))
+                {
+                    p = p.map(function(v, i)
+                    {
+                        return (v / this.options.snap[i]).round() * this.options.snap[i]
+                    }.bind(this))
+                }
+                else
+                {
+                    p = p.map(function(v)
+                    {
+                        return (v / this.options.snap).round() * this.options.snap
+                    }.bind(this))
+                }
+            }
+        }
+
+        var style = this.element.style;
+        if ((!this.options.constraint) || (this.options.constraint == 'horizontal'))
+            style.left = p[0] + "px";
+        if ((!this.options.constraint) || (this.options.constraint == 'vertical'))
+            style.top = p[1] + "px";
+
+        if (style.visibility == "hidden") style.visibility = ""; // fix gecko rendering
+    },
+
+    stopScrolling: function()
+    {
+        if (this.scrollInterval)
+        {
+            clearInterval(this.scrollInterval);
+            this.scrollInterval = null;
+            Draggables._lastScrollPointer = null;
+        }
+    },
+
+    startScrolling: function(speed)
+    {
+        if (!(speed[0] || speed[1])) return;
+        this.scrollSpeed = [speed[0] * this.options.scrollSpeed,speed[1] * this.options.scrollSpeed];
+        this.lastScrolled = new Date();
+        this.scrollInterval = setInterval(this.scroll.bind(this), 10);
+    },
+
+    scroll: function()
+    {
+        var current = new Date();
+        var delta = current - this.lastScrolled;
+        this.lastScrolled = current;
+        if (this.options.scroll == window)
+        {
+            with (this._getWindowScroll(this.options.scroll))
+            {
+                if (this.scrollSpeed[0] || this.scrollSpeed[1])
+                {
+                    var d = delta / 1000;
+                    this.options.scroll.scrollTo(left + d * this.scrollSpeed[0], top + d * this.scrollSpeed[1]);
+                }
+            }
+        }
+        else
+        {
+            this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+            this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
+        }
+
+        Position.prepare();
+        Droppables.show(Draggables._lastPointer, this.element);
+        Draggables.notify('onDrag', this);
+        if (this._isScrollChild)
+        {
+            Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+            Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+            Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+            if (Draggables._lastScrollPointer[0] < 0)
+                Draggables._lastScrollPointer[0] = 0;
+            if (Draggables._lastScrollPointer[1] < 0)
+                Draggables._lastScrollPointer[1] = 0;
+            this.draw(Draggables._lastScrollPointer);
+        }
+
+        if (this.options.change) this.options.change(this);
+    },
+
+    _getWindowScroll: function(w)
+    {
+        var T, L, W, H;
+        with (w.document)
+        {
+            if (w.document.documentElement && documentElement.scrollTop)
+            {
+                T = documentElement.scrollTop;
+                L = documentElement.scrollLeft;
+            }
+            else if (w.document.body)
+            {
+                T = body.scrollTop;
+                L = body.scrollLeft;
+            }
+            if (w.innerWidth)
+            {
+                W = w.innerWidth;
+                H = w.innerHeight;
+            }
+            else if (w.document.documentElement && documentElement.clientWidth)
+            {
+                W = documentElement.clientWidth;
+                H = documentElement.clientHeight;
+            }
+            else
+            {
+                W = body.offsetWidth;
+                H = body.offsetHeight
+            }
+        }
+        return { top: T, left: L, width: W, height: H };
+    }
+});
+
+Draggable._dragging = { };
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create({
+    initialize: function(element, observer)
+    {
+        this.element = $(element);
+        this.observer = observer;
+        this.lastValue = Sortable.serialize(this.element);
+    },
+
+    onStart: function()
+    {
+        this.lastValue = Sortable.serialize(this.element);
+    },
+
+    onEnd: function()
+    {
+        Sortable.unmark();
+        if (this.lastValue != Sortable.serialize(this.element))
+            this.observer(this.element)
+    }
+});
+
+var Sortable = {
+    SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+
+    sortables: { },
+
+    _findRootElement: function(element)
+    {
+        while (element.tagName.toUpperCase() != "BODY")
+        {
+            if (element.id && Sortable.sortables[element.id]) return element;
+            element = element.parentNode;
+        }
+    },
+
+    options: function(element)
+    {
+        element = Sortable._findRootElement($(element));
+        if (!element) return;
+        return Sortable.sortables[element.id];
+    },
+
+    destroy: function(element)
+    {
+        var s = Sortable.options(element);
+
+        if (s)
+        {
+            Draggables.removeObserver(s.element);
+            s.droppables.each(function(d)
+            {
+                Droppables.remove(d)
+            });
+            s.draggables.invoke('destroy');
+
+            delete Sortable.sortables[s.element.id];
+        }
+    },
+
+    create: function(element)
+    {
+        element = $(element);
+        var options = Object.extend({
+            element:     element,
+            tag:         'li',       // assumes li children, override with tag: 'tagname'
+            dropOnEmpty: false,
+            tree:        false,
+            treeTag:     'ul',
+            overlap:     'vertical', // one of 'vertical', 'horizontal'
+            constraint:  'vertical', // one of 'vertical', 'horizontal', false
+            containment: element,    // also takes array of elements (or id's); or false
+            handle:      false,      // or a CSS class
+            only:        false,
+            delay:       0,
+            hoverclass:  null,
+            ghosting:    false,
+            quiet:       false,
+            scroll:      false,
+            scrollSensitivity: 20,
+            scrollSpeed: 15,
+            format:      this.SERIALIZE_RULE,
+
+            // these take arrays of elements or ids and can be
+            // used for better initialization performance
+            elements:    false,
+            handles:     false,
+
+            onChange:    Prototype.emptyFunction,
+            onUpdate:    Prototype.emptyFunction
+        }, arguments[1] || { });
+
+    // clear any old sortable with same element
+        this.destroy(element);
+
+    // build options for the draggables
+        var options_for_draggable = {
+            revert:      true,
+            quiet:       options.quiet,
+            scroll:      options.scroll,
+            scrollSpeed: options.scrollSpeed,
+            scrollSensitivity: options.scrollSensitivity,
+            delay:       options.delay,
+            ghosting:    options.ghosting,
+            constraint:  options.constraint,
+            handle:      options.handle };
+
+        if (options.starteffect)
+            options_for_draggable.starteffect = options.starteffect;
+
+        if (options.reverteffect)
+            options_for_draggable.reverteffect = options.reverteffect;
+        else
+            if (options.ghosting) options_for_draggable.reverteffect = function(element)
+            {
+                element.style.top = 0;
+                element.style.left = 0;
+            };
+
+        if (options.endeffect)
+            options_for_draggable.endeffect = options.endeffect;
+
+        if (options.zindex)
+            options_for_draggable.zindex = options.zindex;
+
+    // build options for the droppables  
+        var options_for_droppable = {
+            overlap:     options.overlap,
+            containment: options.containment,
+            tree:        options.tree,
+            hoverclass:  options.hoverclass,
+            onHover:     Sortable.onHover
+        }
+
+        var options_for_tree = {
+            onHover:      Sortable.onEmptyHover,
+            overlap:      options.overlap,
+            containment:  options.containment,
+            hoverclass:   options.hoverclass
+        }
+
+    // fix for gecko engine
+        Element.cleanWhitespace(element);
+
+        options.draggables = [];
+        options.droppables = [];
+
+    // drop on empty handling
+        if (options.dropOnEmpty || options.tree)
+        {
+            Droppables.add(element, options_for_tree);
+            options.droppables.push(element);
+        }
+
+        (options.elements || this.findElements(element, options) || []).each(function(e, i)
+        {
+            var handle = options.handles ? $(options.handles[i]) :
+                         (options.handle ? $(e).select('.' + options.handle)[0] : e);
+            options.draggables.push(
+                    new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+            Droppables.add(e, options_for_droppable);
+            if (options.tree) e.treeNode = element;
+            options.droppables.push(e);
+        });
+
+        if (options.tree)
+        {
+            (Sortable.findTreeElements(element, options) || []).each(function(e)
+            {
+                Droppables.add(e, options_for_tree);
+                e.treeNode = element;
+                options.droppables.push(e);
+            });
+        }
+
+    // keep reference
+        this.sortables[element.id] = options;
+
+    // for onupdate
+        Draggables.addObserver(new SortableObserver(element, options.onUpdate));
+
+    },
+
+    // return all suitable-for-sortable elements in a guaranteed order
+    findElements: function(element, options)
+    {
+        return Element.findChildren(
+                element, options.only, options.tree ? true : false, options.tag);
+    },
+
+    findTreeElements: function(element, options)
+    {
+        return Element.findChildren(
+                element, options.only, options.tree ? true : false, options.treeTag);
+    },
+
+    onHover: function(element, dropon, overlap)
+    {
+        if (Element.isParent(dropon, element)) return;
+
+        if (overlap > .33 && overlap < .66 && Sortable.options(dropon).tree)
+        {
+            return;
+        }
+        else if (overlap > 0.5)
+        {
+            Sortable.mark(dropon, 'before');
+            if (dropon.previousSibling != element)
+            {
+                var oldParentNode = element.parentNode;
+                element.style.visibility = "hidden"; // fix gecko rendering
+                dropon.parentNode.insertBefore(element, dropon);
+                if (dropon.parentNode != oldParentNode)
+                    Sortable.options(oldParentNode).onChange(element);
+                Sortable.options(dropon.parentNode).onChange(element);
+            }
+        }
+        else
+        {
+            Sortable.mark(dropon, 'after');
+            var nextElement = dropon.nextSibling || null;
+            if (nextElement != element)
+            {
+                var oldParentNode = element.parentNode;
+                element.style.visibility = "hidden"; // fix gecko rendering
+                dropon.parentNode.insertBefore(element, nextElement);
+                if (dropon.parentNode != oldParentNode)
+                    Sortable.options(oldParentNode).onChange(element);
+                Sortable.options(dropon.parentNode).onChange(element);
+            }
+        }
+    },
+
+    onEmptyHover: function(element, dropon, overlap)
+    {
+        var oldParentNode = element.parentNode;
+        var droponOptions = Sortable.options(dropon);
+
+        if (!Element.isParent(dropon, element))
+        {
+            var index;
+
+            var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
+            var child = null;
+
+            if (children)
+            {
+                var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+
+                for (index = 0; index < children.length; index += 1)
+                {
+                    if (offset - Element.offsetSize(children[index], droponOptions.overlap) >= 0)
+                    {
+                        offset -= Element.offsetSize(children[index], droponOptions.overlap);
+                    }
+                    else if (offset - (Element.offsetSize(children[index], droponOptions.overlap) / 2) >= 0)
+                    {
+                        child = index + 1 < children.length ? children[index + 1] : null;
+                        break;
+                    }
+                    else
+                    {
+                        child = children[index];
+                        break;
+                    }
+                }
+            }
+
+            dropon.insertBefore(element, child);
+
+            Sortable.options(oldParentNode).onChange(element);
+            droponOptions.onChange(element);
+        }
+    },
+
+    unmark: function()
+    {
+        if (Sortable._marker) Sortable._marker.hide();
+    },
+
+    mark: function(dropon, position)
+    {
+        // mark on ghosting only
+        var sortable = Sortable.options(dropon.parentNode);
+        if (sortable && !sortable.ghosting) return;
+
+        if (!Sortable._marker)
+        {
+            Sortable._marker =
+            ($('dropmarker') || Element.extend(document.createElement('DIV'))).
+                    hide().addClassName('dropmarker').setStyle({position:'absolute'});
+            document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+        }
+        var offsets = Position.cumulativeOffset(dropon);
+        Sortable._marker.setStyle({left: offsets[0] + 'px', top: offsets[1] + 'px'});
+
+        if (position == 'after')
+            if (sortable.overlap == 'horizontal')
+                Sortable._marker.setStyle({left: (offsets[0] + dropon.clientWidth) + 'px'});
+            else
+                Sortable._marker.setStyle({top: (offsets[1] + dropon.clientHeight) + 'px'});
+
+        Sortable._marker.show();
+    },
+
+    _tree: function(element, options, parent)
+    {
+        var children = Sortable.findElements(element, options) || [];
+
+        for (var i = 0; i < children.length; ++i)
+        {
+            var match = children[i].id.match(options.format);
+
+            if (!match) continue;
+
+            var child = {
+                id: encodeURIComponent(match ? match[1] : null),
+                element: element,
+                parent: parent,
+                children: [],
+                position: parent.children.length,
+                container: $(children[i]).down(options.treeTag)
+            }
+
+            /* Get the element containing the children and recurse over it */
+            if (child.container)
+                this._tree(child.container, options, child)
+
+            parent.children.push(child);
+        }
+
+        return parent;
+    },
+
+    tree: function(element)
+    {
+        element = $(element);
+        var sortableOptions = this.options(element);
+        var options = Object.extend({
+            tag: sortableOptions.tag,
+            treeTag: sortableOptions.treeTag,
+            only: sortableOptions.only,
+            name: element.id,
+            format: sortableOptions.format
+        }, arguments[1] || { });
+
+        var root = {
+            id: null,
+            parent: null,
+            children: [],
+            container: element,
+            position: 0
+        }
+
+        return Sortable._tree(element, options, root);
+    },
+
+    /* Construct a [i] index for a particular node */
+    _constructIndex: function(node)
+    {
+        var index = '';
+        do {
+            if (node.id) index = '[' + node.position + ']' + index;
+        } while ((node = node.parent) != null);
+        return index;
+    },
+
+    sequence: function(element)
+    {
+        element = $(element);
+        var options = Object.extend(this.options(element), arguments[1] || { });
+
+        return $(this.findElements(element, options) || []).map(function(item)
+        {
+            return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+        });
+    },
+
+    setSequence: function(element, new_sequence)
+    {
+        element = $(element);
+        var options = Object.extend(this.options(element), arguments[2] || { });
+
+        var nodeMap = { };
+        this.findElements(element, options).each(function(n)
+        {
+            if (n.id.match(options.format))
+                nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
+            n.parentNode.removeChild(n);
+        });
+
+        new_sequence.each(function(ident)
+        {
+            var n = nodeMap[ident];
+            if (n)
+            {
+                n[1].appendChild(n[0]);
+                delete nodeMap[ident];
+            }
+        });
+    },
+
+    serialize: function(element)
+    {
+        element = $(element);
+        var options = Object.extend(Sortable.options(element), arguments[1] || { });
+        var name = encodeURIComponent(
+                (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
+
+        if (options.tree)
+        {
+            return Sortable.tree(element, arguments[1]).children.map(function (item)
+            {
+                return [name + Sortable._constructIndex(item) + "[id]=" +
+                        encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+            }).flatten().join('&');
+        }
+        else
+        {
+            return Sortable.sequence(element, arguments[1]).map(function(item)
+            {
+                return name + "[]=" + encodeURIComponent(item);
+            }).join('&');
+        }
+    }
+}
+
+// Returns true if child is contained within element
+Element.isParent = function(child, element)
+{
+    if (!child.parentNode || child == element) return false;
+    if (child.parentNode == element) return true;
+    return Element.isParent(child.parentNode, element);
+}
+
+Element.findChildren = function(element, only, recursive, tagName)
+{
+    if (!element.hasChildNodes()) return null;
+    tagName = tagName.toUpperCase();
+    if (only) only = [only].flatten();
+    var elements = [];
+    $A(element.childNodes).each(function(e)
+    {
+        if (e.tagName && e.tagName.toUpperCase() == tagName &&
+            (!only || (Element.classNames(e).detect(function(v)
+            {
+                return only.include(v)
+            }))))
+            elements.push(e);
+        if (recursive)
+        {
+            var grandchildren = Element.findChildren(e, only, recursive, tagName);
+            if (grandchildren) elements.push(grandchildren);
+        }
+    });
+
+    return (elements.length > 0 ? elements.flatten() : []);
+}
+
+Element.offsetSize = function (element, type)
+{
+    return element['offset' + ((type == 'vertical' || type == 'height') ? 'Height' : 'Width')];
+}
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/effects.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/effects.js
new file mode 100644
index 0000000..ff82910
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/effects.js
@@ -0,0 +1,1340 @@
+// script.aculo.us effects.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+//  Justin Palmer (http://encytemedia.com/)
+//  Mark Pilgrim (http://diveintomark.org/)
+//  Martin Bialasinki
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/ 
+
+// converts rgb() and #xxx to #xxxxxx format,  
+// returns self (or first argument) if not convertable  
+String.prototype.parseColor = function()
+{
+    var color = '#';
+    if (this.slice(0, 4) == 'rgb(')
+    {
+        var cols = this.slice(4, this.length - 1).split(',');
+        var i = 0;
+        do {
+            color += parseInt(cols[i]).toColorPart()
+        } while (++i < 3);
+    }
+    else
+    {
+        if (this.slice(0, 1) == '#')
+        {
+            if (this.length == 4) for (var i = 1; i < 4; i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+            if (this.length == 7) color = this.toLowerCase();
+        }
+    }
+    return (color.length == 7 ? color : (arguments[0] || this));
+};
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element)
+{
+    return $A($(element).childNodes).collect(function(node)
+    {
+        return (node.nodeType == 3 ? node.nodeValue :
+                (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+    }).flatten().join('');
+};
+
+Element.collectTextNodesIgnoreClass = function(element, className)
+{
+    return $A($(element).childNodes).collect(function(node)
+    {
+        return (node.nodeType == 3 ? node.nodeValue :
+                ((node.hasChildNodes() && !Element.hasClassName(node, className)) ?
+                 Element.collectTextNodesIgnoreClass(node, className) : ''));
+    }).flatten().join('');
+};
+
+Element.setContentZoom = function(element, percent)
+{
+    element = $(element);
+    element.setStyle({fontSize: (percent / 100) + 'em'});
+    if (Prototype.Browser.WebKit) window.scrollBy(0, 0);
+    return element;
+};
+
+Element.getInlineOpacity = function(element)
+{
+    return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element)
+{
+    try
+    {
+        element = $(element);
+        var n = document.createTextNode(' ');
+        element.appendChild(n);
+        element.removeChild(n);
+    }
+    catch(e)
+    {
+    }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+    _elementDoesNotExistError: {
+        name: 'ElementDoesNotExistError',
+        message: 'The specified DOM element does not exist, but is required for this effect to operate'
+    },
+    Transitions: {
+        linear: Prototype.K,
+        sinoidal: function(pos)
+        {
+            return (-Math.cos(pos * Math.PI) / 2) + 0.5;
+        },
+        reverse: function(pos)
+        {
+            return 1 - pos;
+        },
+        flicker: function(pos)
+        {
+            var pos = ((-Math.cos(pos * Math.PI) / 4) + 0.75) + Math.random() / 4;
+            return pos > 1 ? 1 : pos;
+        },
+        wobble: function(pos)
+        {
+            return (-Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5;
+        },
+        pulse: function(pos, pulses)
+        {
+            pulses = pulses || 5;
+            return (
+                    ((pos % (1 / pulses)) * pulses).round() == 0 ?
+                    ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
+                    1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
+                    );
+        },
+        spring: function(pos)
+        {
+            return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+        },
+        none: function(pos)
+        {
+            return 0;
+        },
+        full: function(pos)
+        {
+            return 1;
+        }
+    },
+    DefaultOptions: {
+        duration:   1.0,   // seconds
+        fps:        100,   // 100= assume 66fps max.
+        sync:       false, // true for combining
+        from:       0.0,
+        to:         1.0,
+        delay:      0.0,
+        queue:      'parallel'
+    },
+    tagifyText: function(element)
+    {
+        var tagifyStyle = 'position:relative';
+        if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
+        element = $(element);
+        $A(element.childNodes).each(function(child)
+        {
+            if (child.nodeType == 3)
+            {
+                child.nodeValue.toArray().each(function(character)
+                {
+                    element.insertBefore(
+                            new Element('span', {style: tagifyStyle}).update(
+                                    character == ' ' ? String.fromCharCode(160) : character),
+                            child);
+                });
+                Element.remove(child);
+            }
+        });
+    },
+    multiple: function(element, effect)
+    {
+        var elements;
+        if (((typeof element == 'object') ||
+             Object.isFunction(element)) &&
+            (element.length))
+            elements = element;
+        else
+            elements = $(element).childNodes;
+
+        var options = Object.extend({
+            speed: 0.1,
+            delay: 0.0
+        }, arguments[2] || { });
+        var masterDelay = options.delay;
+
+        $A(elements).each(function(element, index)
+        {
+            new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+        });
+    },
+    PAIRS: {
+        'slide':  ['SlideDown','SlideUp'],
+        'blind':  ['BlindDown','BlindUp'],
+        'appear': ['Appear','Fade']
+    },
+    toggle: function(element, effect)
+    {
+        element = $(element);
+        effect = (effect || 'appear').toLowerCase();
+        var options = Object.extend({
+            queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+        }, arguments[2] || { });
+        Effect[element.visible() ?
+               Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+    }
+};
+
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create(Enumerable, {
+    initialize: function()
+    {
+        this.effects = [];
+        this.interval = null;
+    },
+    _each: function(iterator)
+    {
+        this.effects._each(iterator);
+    },
+    add: function(effect)
+    {
+        var timestamp = new Date().getTime();
+
+        var position = Object.isString(effect.options.queue) ?
+                       effect.options.queue : effect.options.queue.position;
+
+        switch (position)
+                {
+            case 'front':
+            // move unstarted effects after this effect
+                this.effects.findAll(function(e)
+                {
+                    return e.state == 'idle'
+                }).each(function(e)
+                {
+                    e.startOn += effect.finishOn;
+                    e.finishOn += effect.finishOn;
+                });
+                break;
+            case 'with-last':
+                timestamp = this.effects.pluck('startOn').max() || timestamp;
+                break;
+            case 'end':
+            // start effect after last queued effect has finished
+                timestamp = this.effects.pluck('finishOn').max() || timestamp;
+                break;
+        }
+
+        effect.startOn += timestamp;
+        effect.finishOn += timestamp;
+
+        if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+            this.effects.push(effect);
+
+        if (!this.interval)
+            this.interval = setInterval(this.loop.bind(this), 15);
+    },
+    remove: function(effect)
+    {
+        this.effects = this.effects.reject(function(e)
+        {
+            return e == effect
+        });
+        if (this.effects.length == 0)
+        {
+            clearInterval(this.interval);
+            this.interval = null;
+        }
+    },
+    loop: function()
+    {
+        var timePos = new Date().getTime();
+        for (var i = 0, len = this.effects.length; i < len; i++)
+            this.effects[i] && this.effects[i].loop(timePos);
+    }
+});
+
+Effect.Queues = {
+    instances: $H(),
+    get: function(queueName)
+    {
+        if (!Object.isString(queueName)) return queueName;
+
+        return this.instances.get(queueName) ||
+               this.instances.set(queueName, new Effect.ScopedQueue());
+    }
+};
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.Base = Class.create({
+    position: null,
+    start: function(options)
+    {
+        function codeForEvent(options, eventName)
+        {
+            return (
+                    (options[eventName + 'Internal'] ? 'this.options.' + eventName + 'Internal(this);' : '') +
+                    (options[eventName] ? 'this.options.' + eventName + '(this);' : '')
+                    );
+        }
+        if (options && options.transition === false) options.transition = Effect.Transitions.linear;
+        this.options = Object.extend(Object.extend({ }, Effect.DefaultOptions), options || { });
+        this.currentFrame = 0;
+        this.state = 'idle';
+        this.startOn = this.options.delay * 1000;
+        this.finishOn = this.startOn + (this.options.duration * 1000);
+        this.fromToDelta = this.options.to - this.options.from;
+        this.totalTime = this.finishOn - this.startOn;
+        this.totalFrames = this.options.fps * this.options.duration;
+
+        eval('this.render = function(pos){ ' +
+             'if (this.state=="idle"){this.state="running";' +
+             codeForEvent(this.options, 'beforeSetup') +
+             (this.setup ? 'this.setup();' : '') +
+             codeForEvent(this.options, 'afterSetup') +
+             '};if (this.state=="running"){' +
+             'pos=this.options.transition(pos)*' + this.fromToDelta + '+' + this.options.from + ';' +
+             'this.position=pos;' +
+             codeForEvent(this.options, 'beforeUpdate') +
+             (this.update ? 'this.update(pos);' : '') +
+             codeForEvent(this.options, 'afterUpdate') +
+             '}}');
+
+        this.event('beforeStart');
+        if (!this.options.sync)
+            Effect.Queues.get(Object.isString(this.options.queue) ?
+                              'global' : this.options.queue.scope).add(this);
+    },
+    loop: function(timePos)
+    {
+        if (timePos >= this.startOn)
+        {
+            if (timePos >= this.finishOn)
+            {
+                this.render(1.0);
+                this.cancel();
+                this.event('beforeFinish');
+                if (this.finish) this.finish();
+                this.event('afterFinish');
+                return;
+            }
+            var pos = (timePos - this.startOn) / this.totalTime,
+                    frame = (pos * this.totalFrames).round();
+            if (frame > this.currentFrame)
+            {
+                this.render(pos);
+                this.currentFrame = frame;
+            }
+        }
+    },
+    cancel: function()
+    {
+        if (!this.options.sync)
+            Effect.Queues.get(Object.isString(this.options.queue) ?
+                              'global' : this.options.queue.scope).remove(this);
+        this.state = 'finished';
+    },
+    event: function(eventName)
+    {
+        if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+        if (this.options[eventName]) this.options[eventName](this);
+    },
+    inspect: function()
+    {
+        var data = $H();
+        for (property in this)
+            if (!Object.isFunction(this[property])) data.set(property, this[property]);
+        return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
+    }
+});
+
+Effect.Parallel = Class.create(Effect.Base, {
+    initialize: function(effects)
+    {
+        this.effects = effects || [];
+        this.start(arguments[1]);
+    },
+    update: function(position)
+    {
+        this.effects.invoke('render', position);
+    },
+    finish: function(position)
+    {
+        this.effects.each(function(effect)
+        {
+            effect.render(1.0);
+            effect.cancel();
+            effect.event('beforeFinish');
+            if (effect.finish) effect.finish(position);
+            effect.event('afterFinish');
+        });
+    }
+});
+
+Effect.Tween = Class.create(Effect.Base, {
+    initialize: function(object, from, to)
+    {
+        object = Object.isString(object) ? $(object) : object;
+        var args = $A(arguments), method = args.last(),
+                options = args.length == 5 ? args[3] : null;
+        this.method = Object.isFunction(method) ? method.bind(object) :
+                      Object.isFunction(object[method]) ? object[method].bind(object) :
+                      function(value)
+                      {
+                          object[method] = value
+                      };
+        this.start(Object.extend({ from: from, to: to }, options || { }));
+    },
+    update: function(position)
+    {
+        this.method(position);
+    }
+});
+
+Effect.Event = Class.create(Effect.Base, {
+    initialize: function()
+    {
+        this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
+    },
+    update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create(Effect.Base, {
+    initialize: function(element)
+    {
+        this.element = $(element);
+        if (!this.element) throw(Effect._elementDoesNotExistError);
+    // make this work on IE on elements without 'layout'
+        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+            this.element.setStyle({zoom: 1});
+        var options = Object.extend({
+            from: this.element.getOpacity() || 0.0,
+            to:   1.0
+        }, arguments[1] || { });
+        this.start(options);
+    },
+    update: function(position)
+    {
+        this.element.setOpacity(position);
+    }
+});
+
+Effect.Move = Class.create(Effect.Base, {
+    initialize: function(element)
+    {
+        this.element = $(element);
+        if (!this.element) throw(Effect._elementDoesNotExistError);
+        var options = Object.extend({
+            x:    0,
+            y:    0,
+            mode: 'relative'
+        }, arguments[1] || { });
+        this.start(options);
+    },
+    setup: function()
+    {
+        this.element.makePositioned();
+        this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+        this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+        if (this.options.mode == 'absolute')
+        {
+            this.options.x = this.options.x - this.originalLeft;
+            this.options.y = this.options.y - this.originalTop;
+        }
+    },
+    update: function(position)
+    {
+        this.element.setStyle({
+            left: (this.options.x * position + this.originalLeft).round() + 'px',
+            top:  (this.options.y * position + this.originalTop).round() + 'px'
+        });
+    }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft)
+{
+    return new Effect.Move(element,
+            Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
+};
+
+Effect.Scale = Class.create(Effect.Base, {
+    initialize: function(element, percent)
+    {
+        this.element = $(element);
+        if (!this.element) throw(Effect._elementDoesNotExistError);
+        var options = Object.extend({
+            scaleX: true,
+            scaleY: true,
+            scaleContent: true,
+            scaleFromCenter: false,
+            scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
+            scaleFrom: 100.0,
+            scaleTo:   percent
+        }, arguments[2] || { });
+        this.start(options);
+    },
+    setup: function()
+    {
+        this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+        this.elementPositioning = this.element.getStyle('position');
+
+        this.originalStyle = { };
+        ['top','left','width','height','fontSize'].each(function(k)
+        {
+            this.originalStyle[k] = this.element.style[k];
+        }.bind(this));
+
+        this.originalTop = this.element.offsetTop;
+        this.originalLeft = this.element.offsetLeft;
+
+        var fontSize = this.element.getStyle('font-size') || '100%';
+        ['em','px','%','pt'].each(function(fontSizeType)
+        {
+            if (fontSize.indexOf(fontSizeType) > 0)
+            {
+                this.fontSize = parseFloat(fontSize);
+                this.fontSizeType = fontSizeType;
+            }
+        }.bind(this));
+
+        this.factor = (this.options.scaleTo - this.options.scaleFrom) / 100;
+
+        this.dims = null;
+        if (this.options.scaleMode == 'box')
+            this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+        if (/^content/.test(this.options.scaleMode))
+            this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+        if (!this.dims)
+            this.dims = [this.options.scaleMode.originalHeight,
+                this.options.scaleMode.originalWidth];
+    },
+    update: function(position)
+    {
+        var currentScale = (this.options.scaleFrom / 100.0) + (this.factor * position);
+        if (this.options.scaleContent && this.fontSize)
+            this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+        this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+    },
+    finish: function(position)
+    {
+        if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+    },
+    setDimensions: function(height, width)
+    {
+        var d = { };
+        if (this.options.scaleX) d.width = width.round() + 'px';
+        if (this.options.scaleY) d.height = height.round() + 'px';
+        if (this.options.scaleFromCenter)
+        {
+            var topd = (height - this.dims[0]) / 2;
+            var leftd = (width - this.dims[1]) / 2;
+            if (this.elementPositioning == 'absolute')
+            {
+                if (this.options.scaleY) d.top = this.originalTop - topd + 'px';
+                if (this.options.scaleX) d.left = this.originalLeft - leftd + 'px';
+            }
+            else
+            {
+                if (this.options.scaleY) d.top = -topd + 'px';
+                if (this.options.scaleX) d.left = -leftd + 'px';
+            }
+        }
+        this.element.setStyle(d);
+    }
+});
+
+Effect.Highlight = Class.create(Effect.Base, {
+    initialize: function(element)
+    {
+        this.element = $(element);
+        if (!this.element) throw(Effect._elementDoesNotExistError);
+        var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
+        this.start(options);
+    },
+    setup: function()
+    {
+        // Prevent executing on elements not in the layout flow
+        if (this.element.getStyle('display') == 'none')
+        {
+            this.cancel();
+            return;
+        }
+    // Disable background image during the effect
+        this.oldStyle = { };
+        if (!this.options.keepBackgroundImage)
+        {
+            this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+            this.element.setStyle({backgroundImage: 'none'});
+        }
+        if (!this.options.endcolor)
+            this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+        if (!this.options.restorecolor)
+            this.options.restorecolor = this.element.getStyle('background-color');
+    // init color calculations
+        this._base = $R(0, 2).map(function(i)
+        {
+            return parseInt(this.options.startcolor.slice(i * 2 + 1, i * 2 + 3), 16)
+        }.bind(this));
+        this._delta = $R(0, 2).map(function(i)
+        {
+            return parseInt(this.options.endcolor.slice(i * 2 + 1, i * 2 + 3), 16) - this._base[i]
+        }.bind(this));
+    },
+    update: function(position)
+    {
+        this.element.setStyle({backgroundColor: $R(0, 2).inject('#', function(m, v, i)
+        {
+            return m + ((this._base[i] + (this._delta[i] * position)).round().toColorPart());
+        }.bind(this)) });
+    },
+    finish: function()
+    {
+        this.element.setStyle(Object.extend(this.oldStyle, {
+            backgroundColor: this.options.restorecolor
+        }));
+    }
+});
+
+Effect.ScrollTo = function(element)
+{
+    var options = arguments[1] || { },
+            scrollOffsets = document.viewport.getScrollOffsets(),
+            elementOffsets = $(element).cumulativeOffset(),
+            max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
+
+    if (options.offset) elementOffsets[1] += options.offset;
+
+    return new Effect.Tween(null,
+            scrollOffsets.top,
+            elementOffsets[1] > max ? max : elementOffsets[1],
+            options,
+            function(p)
+            {
+                scrollTo(scrollOffsets.left, p.round())
+            }
+            );
+};
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element)
+{
+    element = $(element);
+    var oldOpacity = element.getInlineOpacity();
+    var options = Object.extend({
+        from: element.getOpacity() || 1.0,
+        to:   0.0,
+        afterFinishInternal: function(effect)
+        {
+            if (effect.options.to != 0) return;
+            effect.element.hide().setStyle({opacity: oldOpacity});
+        }
+    }, arguments[1] || { });
+    return new Effect.Opacity(element, options);
+};
+
+Effect.Appear = function(element)
+{
+    element = $(element);
+    var options = Object.extend({
+        from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+        to:   1.0,
+        // force Safari to render floated elements properly
+        afterFinishInternal: function(effect)
+        {
+            effect.element.forceRerendering();
+        },
+        beforeSetup: function(effect)
+        {
+            effect.element.setOpacity(effect.options.from).show();
+        }}, arguments[1] || { });
+    return new Effect.Opacity(element, options);
+};
+
+Effect.Puff = function(element)
+{
+    element = $(element);
+    var oldStyle = {
+        opacity: element.getInlineOpacity(),
+        position: element.getStyle('position'),
+        top:  element.style.top,
+        left: element.style.left,
+        width: element.style.width,
+        height: element.style.height
+    };
+    return new Effect.Parallel(
+            [ new Effect.Scale(element, 200,
+            { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+                new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+            Object.extend({ duration: 1.0,
+                beforeSetupInternal: function(effect)
+                {
+                    Position.absolutize(effect.effects[0].element)
+                },
+                afterFinishInternal: function(effect)
+                {
+                    effect.effects[0].element.hide().setStyle(oldStyle);
+                }
+            }, arguments[1] || { })
+            );
+};
+
+Effect.BlindUp = function(element)
+{
+    element = $(element);
+    element.makeClipping();
+    return new Effect.Scale(element, 0,
+            Object.extend({ scaleContent: false,
+                scaleX: false,
+                restoreAfterFinish: true,
+                afterFinishInternal: function(effect)
+                {
+                    effect.element.hide().undoClipping();
+                }
+            }, arguments[1] || { })
+            );
+};
+
+Effect.BlindDown = function(element)
+{
+    element = $(element);
+    var elementDimensions = element.getDimensions();
+    return new Effect.Scale(element, 100, Object.extend({
+        scaleContent: false,
+        scaleX: false,
+        scaleFrom: 0,
+        scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+        restoreAfterFinish: true,
+        afterSetup: function(effect)
+        {
+            effect.element.makeClipping().setStyle({height: '0px'}).show();
+        },
+        afterFinishInternal: function(effect)
+        {
+            effect.element.undoClipping();
+        }
+    }, arguments[1] || { }));
+};
+
+Effect.SwitchOff = function(element)
+{
+    element = $(element);
+    var oldOpacity = element.getInlineOpacity();
+    return new Effect.Appear(element, Object.extend({
+        duration: 0.4,
+        from: 0,
+        transition: Effect.Transitions.flicker,
+        afterFinishInternal: function(effect)
+        {
+            new Effect.Scale(effect.element, 1, {
+                duration: 0.3, scaleFromCenter: true,
+                scaleX: false, scaleContent: false, restoreAfterFinish: true,
+                beforeSetup: function(effect)
+                {
+                    effect.element.makePositioned().makeClipping();
+                },
+                afterFinishInternal: function(effect)
+                {
+                    effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+                }
+            })
+        }
+    }, arguments[1] || { }));
+};
+
+Effect.DropOut = function(element)
+{
+    element = $(element);
+    var oldStyle = {
+        top: element.getStyle('top'),
+        left: element.getStyle('left'),
+        opacity: element.getInlineOpacity() };
+    return new Effect.Parallel(
+            [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+                new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+            Object.extend(
+            { duration: 0.5,
+                beforeSetup: function(effect)
+                {
+                    effect.effects[0].element.makePositioned();
+                },
+                afterFinishInternal: function(effect)
+                {
+                    effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+                }
+            }, arguments[1] || { }));
+};
+
+Effect.Shake = function(element)
+{
+    element = $(element);
+    var options = Object.extend({
+        distance: 20,
+        duration: 0.5
+    }, arguments[1] || {});
+    var distance = parseFloat(options.distance);
+    var split = parseFloat(options.duration) / 10.0;
+    var oldStyle = {
+        top: element.getStyle('top'),
+        left: element.getStyle('left') };
+    return new Effect.Move(element,
+    { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect)
+    {
+        new Effect.Move(effect.element,
+        { x: -distance * 2, y: 0, duration: split * 2,  afterFinishInternal: function(effect)
+        {
+            new Effect.Move(effect.element,
+            { x:  distance * 2, y: 0, duration: split * 2,  afterFinishInternal: function(effect)
+            {
+                new Effect.Move(effect.element,
+                { x: -distance * 2, y: 0, duration: split * 2,  afterFinishInternal: function(effect)
+                {
+                    new Effect.Move(effect.element,
+                    { x:  distance * 2, y: 0, duration: split * 2,  afterFinishInternal: function(effect)
+                    {
+                        new Effect.Move(effect.element,
+                        { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect)
+                        {
+                            effect.element.undoPositioned().setStyle(oldStyle);
+                        }})
+                    }})
+                }})
+            }})
+        }})
+    }});
+};
+
+Effect.SlideDown = function(element)
+{
+    element = $(element).cleanWhitespace();
+  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+    var oldInnerBottom = element.down().getStyle('bottom');
+    var elementDimensions = element.getDimensions();
+    return new Effect.Scale(element, 100, Object.extend({
+        scaleContent: false,
+        scaleX: false,
+        scaleFrom: window.opera ? 0 : 1,
+        scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+        restoreAfterFinish: true,
+        afterSetup: function(effect)
+        {
+            effect.element.makePositioned();
+            effect.element.down().makePositioned();
+            if (window.opera) effect.element.setStyle({top: ''});
+            effect.element.makeClipping().setStyle({height: '0px'}).show();
+        },
+        afterUpdateInternal: function(effect)
+        {
+            effect.element.down().setStyle({bottom:
+                    (effect.dims[0] - effect.element.clientHeight) + 'px' });
+        },
+        afterFinishInternal: function(effect)
+        {
+            effect.element.undoClipping().undoPositioned();
+            effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+        }
+    }, arguments[1] || { })
+            );
+};
+
+Effect.SlideUp = function(element)
+{
+    element = $(element).cleanWhitespace();
+    var oldInnerBottom = element.down().getStyle('bottom');
+    var elementDimensions = element.getDimensions();
+    return new Effect.Scale(element, window.opera ? 0 : 1,
+            Object.extend({ scaleContent: false,
+                scaleX: false,
+                scaleMode: 'box',
+                scaleFrom: 100,
+                scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+                restoreAfterFinish: true,
+                afterSetup: function(effect)
+                {
+                    effect.element.makePositioned();
+                    effect.element.down().makePositioned();
+                    if (window.opera) effect.element.setStyle({top: ''});
+                    effect.element.makeClipping().show();
+                },
+                afterUpdateInternal: function(effect)
+                {
+                    effect.element.down().setStyle({bottom:
+                            (effect.dims[0] - effect.element.clientHeight) + 'px' });
+                },
+                afterFinishInternal: function(effect)
+                {
+                    effect.element.hide().undoClipping().undoPositioned();
+                    effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+                }
+            }, arguments[1] || { })
+            );
+};
+
+// Bug in opera makes the TD containing this element expand for a instance after finish 
+Effect.Squish = function(element)
+{
+    return new Effect.Scale(element, window.opera ? 1 : 0, {
+        restoreAfterFinish: true,
+        beforeSetup: function(effect)
+        {
+            effect.element.makeClipping();
+        },
+        afterFinishInternal: function(effect)
+        {
+            effect.element.hide().undoClipping();
+        }
+    });
+};
+
+Effect.Grow = function(element)
+{
+    element = $(element);
+    var options = Object.extend({
+        direction: 'center',
+        moveTransition: Effect.Transitions.sinoidal,
+        scaleTransition: Effect.Transitions.sinoidal,
+        opacityTransition: Effect.Transitions.full
+    }, arguments[1] || { });
+    var oldStyle = {
+        top: element.style.top,
+        left: element.style.left,
+        height: element.style.height,
+        width: element.style.width,
+        opacity: element.getInlineOpacity() };
+
+    var dims = element.getDimensions();
+    var initialMoveX, initialMoveY;
+    var moveX, moveY;
+
+    switch (options.direction)
+            {
+        case 'top-left':
+            initialMoveX = initialMoveY = moveX = moveY = 0;
+            break;
+        case 'top-right':
+            initialMoveX = dims.width;
+            initialMoveY = moveY = 0;
+            moveX = -dims.width;
+            break;
+        case 'bottom-left':
+            initialMoveX = moveX = 0;
+            initialMoveY = dims.height;
+            moveY = -dims.height;
+            break;
+        case 'bottom-right':
+            initialMoveX = dims.width;
+            initialMoveY = dims.height;
+            moveX = -dims.width;
+            moveY = -dims.height;
+            break;
+        case 'center':
+            initialMoveX = dims.width / 2;
+            initialMoveY = dims.height / 2;
+            moveX = -dims.width / 2;
+            moveY = -dims.height / 2;
+            break;
+    }
+
+    return new Effect.Move(element, {
+        x: initialMoveX,
+        y: initialMoveY,
+        duration: 0.01,
+        beforeSetup: function(effect)
+        {
+            effect.element.hide().makeClipping().makePositioned();
+        },
+        afterFinishInternal: function(effect)
+        {
+            new Effect.Parallel(
+                    [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+                        new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+                        new Effect.Scale(effect.element, 100, {
+                            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+                            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+                    ], Object.extend({
+                beforeSetup: function(effect)
+                {
+                    effect.effects[0].element.setStyle({height: '0px'}).show();
+                },
+                afterFinishInternal: function(effect)
+                {
+                    effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+                }
+            }, options)
+                    )
+        }
+    });
+};
+
+Effect.Shrink = function(element)
+{
+    element = $(element);
+    var options = Object.extend({
+        direction: 'center',
+        moveTransition: Effect.Transitions.sinoidal,
+        scaleTransition: Effect.Transitions.sinoidal,
+        opacityTransition: Effect.Transitions.none
+    }, arguments[1] || { });
+    var oldStyle = {
+        top: element.style.top,
+        left: element.style.left,
+        height: element.style.height,
+        width: element.style.width,
+        opacity: element.getInlineOpacity() };
+
+    var dims = element.getDimensions();
+    var moveX, moveY;
+
+    switch (options.direction)
+            {
+        case 'top-left':
+            moveX = moveY = 0;
+            break;
+        case 'top-right':
+            moveX = dims.width;
+            moveY = 0;
+            break;
+        case 'bottom-left':
+            moveX = 0;
+            moveY = dims.height;
+            break;
+        case 'bottom-right':
+            moveX = dims.width;
+            moveY = dims.height;
+            break;
+        case 'center':
+            moveX = dims.width / 2;
+            moveY = dims.height / 2;
+            break;
+    }
+
+    return new Effect.Parallel(
+            [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+                new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+                new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+            ], Object.extend({
+        beforeStartInternal: function(effect)
+        {
+            effect.effects[0].element.makePositioned().makeClipping();
+        },
+        afterFinishInternal: function(effect)
+        {
+            effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle);
+        }
+    }, options)
+            );
+};
+
+Effect.Pulsate = function(element)
+{
+    element = $(element);
+    var options = arguments[1] || { };
+    var oldOpacity = element.getInlineOpacity();
+    var transition = options.transition || Effect.Transitions.sinoidal;
+    var reverser = function(pos)
+    {
+        return transition(1 - Effect.Transitions.pulse(pos, options.pulses))
+    };
+    reverser.bind(transition);
+    return new Effect.Opacity(element,
+            Object.extend(Object.extend({  duration: 2.0, from: 0,
+                afterFinishInternal: function(effect)
+                {
+                    effect.element.setStyle({opacity: oldOpacity});
+                }
+            }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element)
+{
+    element = $(element);
+    var oldStyle = {
+        top: element.style.top,
+        left: element.style.left,
+        width: element.style.width,
+        height: element.style.height };
+    element.makeClipping();
+    return new Effect.Scale(element, 5, Object.extend({
+        scaleContent: false,
+        scaleX: false,
+        afterFinishInternal: function(effect)
+        {
+            new Effect.Scale(element, 1, {
+                scaleContent: false,
+                scaleY: false,
+                afterFinishInternal: function(effect)
+                {
+                    effect.element.hide().undoClipping().setStyle(oldStyle);
+                } });
+        }}, arguments[1] || { }));
+};
+
+Effect.Morph = Class.create(Effect.Base, {
+    initialize: function(element)
+    {
+        this.element = $(element);
+        if (!this.element) throw(Effect._elementDoesNotExistError);
+        var options = Object.extend({
+            style: { }
+        }, arguments[1] || { });
+
+        if (!Object.isString(options.style)) this.style = $H(options.style);
+        else
+        {
+            if (options.style.include(':'))
+                this.style = options.style.parseStyle();
+            else
+            {
+                this.element.addClassName(options.style);
+                this.style = $H(this.element.getStyles());
+                this.element.removeClassName(options.style);
+                var css = this.element.getStyles();
+                this.style = this.style.reject(function(style)
+                {
+                    return style.value == css[style.key];
+                });
+                options.afterFinishInternal = function(effect)
+                {
+                    effect.element.addClassName(effect.options.style);
+                    effect.transforms.each(function(transform)
+                    {
+                        effect.element.style[transform.style] = '';
+                    });
+                }
+            }
+        }
+        this.start(options);
+    },
+
+    setup: function()
+    {
+        function parseColor(color)
+        {
+            if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+            color = color.parseColor();
+            return $R(0, 2).map(function(i)
+            {
+                return parseInt(color.slice(i * 2 + 1, i * 2 + 3), 16)
+            });
+        }
+        this.transforms = this.style.map(function(pair)
+        {
+            var property = pair[0], value = pair[1], unit = null;
+
+            if (value.parseColor('#zzzzzz') != '#zzzzzz')
+            {
+                value = value.parseColor();
+                unit = 'color';
+            }
+            else if (property == 'opacity')
+            {
+                value = parseFloat(value);
+                if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+                    this.element.setStyle({zoom: 1});
+            }
+            else if (Element.CSS_LENGTH.test(value))
+            {
+                var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+                value = parseFloat(components[1]);
+                unit = (components.length == 3) ? components[2] : null;
+            }
+
+            var originalValue = this.element.getStyle(property);
+            return {
+                style: property.camelize(),
+                originalValue: unit == 'color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+                targetValue: unit == 'color' ? parseColor(value) : value,
+                unit: unit
+            };
+        }.bind(this)).reject(function(transform)
+        {
+            return (
+                    (transform.originalValue == transform.targetValue) ||
+                    (
+                            transform.unit != 'color' &&
+                            (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+                            )
+                    )
+        });
+    },
+    update: function(position)
+    {
+        var style = { }, transform, i = this.transforms.length;
+        while (i--)
+            style[(transform = this.transforms[i]).style] =
+            transform.unit == 'color' ? '#' +
+                                        (Math.round(transform.originalValue[0] +
+                                                    (transform.targetValue[0] - transform.originalValue[0]) * position)).toColorPart() +
+                                        (Math.round(transform.originalValue[1] +
+                                                    (transform.targetValue[1] - transform.originalValue[1]) * position)).toColorPart() +
+                                        (Math.round(transform.originalValue[2] +
+                                                    (transform.targetValue[2] - transform.originalValue[2]) * position)).toColorPart() :
+            (transform.originalValue +
+             (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+            (transform.unit === null ? '' : transform.unit);
+        this.element.setStyle(style, true);
+    }
+});
+
+Effect.Transform = Class.create({
+    initialize: function(tracks)
+    {
+        this.tracks = [];
+        this.options = arguments[1] || { };
+        this.addTracks(tracks);
+    },
+    addTracks: function(tracks)
+    {
+        tracks.each(function(track)
+        {
+            track = $H(track);
+            var data = track.values().first();
+            this.tracks.push($H({
+                ids:     track.keys().first(),
+                effect:  Effect.Morph,
+                options: { style: data }
+            }));
+        }.bind(this));
+        return this;
+    },
+    play: function()
+    {
+        return new Effect.Parallel(
+                this.tracks.map(function(track)
+                {
+                    var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+                    var elements = [$(ids) || $$(ids)].flatten();
+                    return elements.map(function(e)
+                    {
+                        return new effect(e, Object.extend({ sync:true }, options))
+                    });
+                }).flatten(),
+                this.options
+                );
+    }
+});
+
+Element.CSS_PROPERTIES = $w(
+        'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+        'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+        'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+        'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+        'fontSize fontWeight height left letterSpacing lineHeight ' +
+        'marginBottom marginLeft marginRight marginTop markerOffset maxHeight ' +
+        'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+        'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+        'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.__parseStyleElement = document.createElement('div');
+String.prototype.parseStyle = function()
+{
+    var style, styleRules = $H();
+    if (Prototype.Browser.WebKit)
+        style = new Element('div', {style:this}).style;
+    else
+    {
+        String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
+        style = String.__parseStyleElement.childNodes[0].style;
+    }
+
+    Element.CSS_PROPERTIES.each(function(property)
+    {
+        if (style[property]) styleRules.set(property, style[property]);
+    });
+
+    if (Prototype.Browser.IE && this.include('opacity'))
+        styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+    return styleRules;
+};
+
+if (document.defaultView && document.defaultView.getComputedStyle)
+{
+    Element.getStyles = function(element)
+    {
+        var css = document.defaultView.getComputedStyle($(element), null);
+        return Element.CSS_PROPERTIES.inject({ }, function(styles, property)
+        {
+            styles[property] = css[property];
+            return styles;
+        });
+    };
+}
+else
+{
+    Element.getStyles = function(element)
+    {
+        element = $(element);
+        var css = element.currentStyle, styles;
+        styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property)
+        {
+            hash.set(property, css[property]);
+            return hash;
+        });
+        if (!styles.opacity) styles.set('opacity', element.getOpacity());
+        return styles;
+    };
+}
+;
+
+Effect.Methods = {
+    morph: function(element, style)
+    {
+        element = $(element);
+        new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+        return element;
+    },
+    visualEffect: function(element, effect, options)
+    {
+        element = $(element)
+        var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+        new Effect[klass](element, options);
+        return element;
+    },
+    highlight: function(element, options)
+    {
+        element = $(element);
+        new Effect.Highlight(element, options);
+        return element;
+    }
+};
+
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown ' +
+   'pulsate shake puff squish switchOff dropOut').each(
+        function(effect)
+        {
+            Effect.Methods[effect] = function(element, options)
+            {
+                element = $(element);
+                Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+                return element;
+            }
+        }
+        );
+
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+        function(f)
+        {
+            Effect.Methods[f] = Element[f];
+        }
+        );
+
+Element.addMethods(Effect.Methods);
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/prototype.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/prototype.js
new file mode 100644
index 0000000..c74d7e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/prototype.js
@@ -0,0 +1,5104 @@
+/*  Prototype JavaScript framework, version 1.6.0.1
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+    Version: '1.6.0.1',
+
+    Browser: {
+        IE:     !!(window.attachEvent && !window.opera),
+        Opera:  !!window.opera,
+        WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+        Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+        MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+    },
+
+    BrowserFeatures: {
+        XPath: !!document.evaluate,
+        ElementExtensions: !!window.HTMLElement,
+        SpecificElementExtensions:
+                document.createElement('div').__proto__ &&
+                document.createElement('div').__proto__ !==
+                document.createElement('form').__proto__
+    },
+
+    ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+    JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+    emptyFunction: function()
+    {
+    },
+    K: function(x)
+    {
+        return x
+    }
+};
+
+if (Prototype.Browser.MobileSafari)
+    Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+/* Based on Alex Arnell's inheritance implementation. */
+var Class = {
+    create: function()
+    {
+        var parent = null, properties = $A(arguments);
+        if (Object.isFunction(properties[0]))
+            parent = properties.shift();
+
+        function klass()
+        {
+            this.initialize.apply(this, arguments);
+        }
+
+        Object.extend(klass, Class.Methods);
+        klass.superclass = parent;
+        klass.subclasses = [];
+
+        if (parent)
+        {
+            var subclass = function()
+            {
+            };
+            subclass.prototype = parent.prototype;
+            klass.prototype = new subclass;
+            parent.subclasses.push(klass);
+        }
+
+        for (var i = 0; i < properties.length; i++)
+            klass.addMethods(properties[i]);
+
+        if (!klass.prototype.initialize)
+            klass.prototype.initialize = Prototype.emptyFunction;
+
+        klass.prototype.constructor = klass;
+
+        return klass;
+    }
+};
+
+Class.Methods = {
+    addMethods: function(source)
+    {
+        var ancestor = this.superclass && this.superclass.prototype;
+        var properties = Object.keys(source);
+
+        if (!Object.keys({ toString: true }).length)
+            properties.push("toString", "valueOf");
+
+        for (var i = 0, length = properties.length; i < length; i++)
+        {
+            var property = properties[i], value = source[property];
+            if (ancestor && Object.isFunction(value) &&
+                value.argumentNames().first() == "$super")
+            {
+                var method = value, value = Object.extend((function(m)
+                {
+                    return function()
+                    {
+                        return ancestor[m].apply(this, arguments)
+                    };
+                })(property).wrap(method), {
+                    valueOf:  function()
+                    {
+                        return method
+                    },
+                    toString: function()
+                    {
+                        return method.toString()
+                    }
+                });
+            }
+            this.prototype[property] = value;
+        }
+
+        return this;
+    }
+};
+
+var Abstract = { };
+
+Object.extend = function(destination, source)
+{
+    for (var property in source)
+        destination[property] = source[property];
+    return destination;
+};
+
+Object.extend(Object, {
+    inspect: function(object)
+    {
+        try
+        {
+            if (Object.isUndefined(object)) return 'undefined';
+            if (object === null) return 'null';
+            return object.inspect ? object.inspect() : object.toString();
+        }
+        catch (e)
+        {
+            if (e instanceof RangeError) return '...';
+            throw e;
+        }
+    },
+
+    toJSON: function(object)
+    {
+        var type = typeof object;
+        switch (type)
+                {
+            case 'undefined':
+            case 'function':
+            case 'unknown': return;
+            case 'boolean': return object.toString();
+        }
+
+        if (object === null) return 'null';
+        if (object.toJSON) return object.toJSON();
+        if (Object.isElement(object)) return;
+
+        var results = [];
+        for (var property in object)
+        {
+            var value = Object.toJSON(object[property]);
+            if (!Object.isUndefined(value))
+                results.push(property.toJSON() + ': ' + value);
+        }
+
+        return '{' + results.join(', ') + '}';
+    },
+
+    toQueryString: function(object)
+    {
+        return $H(object).toQueryString();
+    },
+
+    toHTML: function(object)
+    {
+        return object && object.toHTML ? object.toHTML() : String.interpret(object);
+    },
+
+    keys: function(object)
+    {
+        var keys = [];
+        for (var property in object)
+            keys.push(property);
+        return keys;
+    },
+
+    values: function(object)
+    {
+        var values = [];
+        for (var property in object)
+            values.push(object[property]);
+        return values;
+    },
+
+    clone: function(object)
+    {
+        return Object.extend({ }, object);
+    },
+
+    isElement: function(object)
+    {
+        return object && object.nodeType == 1;
+    },
+
+    isArray: function(object)
+    {
+        return object && object.constructor === Array;
+    },
+
+    isHash: function(object)
+    {
+        return object instanceof Hash;
+    },
+
+    isFunction: function(object)
+    {
+        return typeof object == "function";
+    },
+
+    isString: function(object)
+    {
+        return typeof object == "string";
+    },
+
+    isNumber: function(object)
+    {
+        return typeof object == "number";
+    },
+
+    isUndefined: function(object)
+    {
+        return typeof object == "undefined";
+    }
+});
+
+Object.extend(Function.prototype, {
+    argumentNames: function()
+    {
+        var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+        return names.length == 1 && !names[0] ? [] : names;
+    },
+
+    bind: function()
+    {
+        if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+        var __method = this, args = $A(arguments), object = args.shift();
+        return function()
+        {
+            return __method.apply(object, args.concat($A(arguments)));
+        }
+    },
+
+    bindAsEventListener: function()
+    {
+        var __method = this, args = $A(arguments), object = args.shift();
+        return function(event)
+        {
+            return __method.apply(object, [event || window.event].concat(args));
+        }
+    },
+
+    curry: function()
+    {
+        if (!arguments.length) return this;
+        var __method = this, args = $A(arguments);
+        return function()
+        {
+            return __method.apply(this, args.concat($A(arguments)));
+        }
+    },
+
+    delay: function()
+    {
+        var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+        return window.setTimeout(function()
+        {
+            return __method.apply(__method, args);
+        }, timeout);
+    },
+
+    wrap: function(wrapper)
+    {
+        var __method = this;
+        return function()
+        {
+            return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+        }
+    },
+
+    methodize: function()
+    {
+        if (this._methodized) return this._methodized;
+        var __method = this;
+        return this._methodized = function()
+        {
+            return __method.apply(null, [this].concat($A(arguments)));
+        };
+    }
+});
+
+Function.prototype.defer = Function.prototype.delay.curry(0.01);
+
+Date.prototype.toJSON = function()
+{
+    return '"' + this.getUTCFullYear() + '-' +
+           (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+           this.getUTCDate().toPaddedString(2) + 'T' +
+           this.getUTCHours().toPaddedString(2) + ':' +
+           this.getUTCMinutes().toPaddedString(2) + ':' +
+           this.getUTCSeconds().toPaddedString(2) + 'Z"';
+};
+
+var Try = {
+    these: function()
+    {
+        var returnValue;
+
+        for (var i = 0, length = arguments.length; i < length; i++)
+        {
+            var lambda = arguments[i];
+            try
+            {
+                returnValue = lambda();
+                break;
+            }
+            catch (e)
+            {
+            }
+        }
+
+        return returnValue;
+    }
+};
+
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str)
+{
+    return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create({
+    initialize: function(callback, frequency)
+    {
+        this.callback = callback;
+        this.frequency = frequency;
+        this.currentlyExecuting = false;
+
+        this.registerCallback();
+    },
+
+    registerCallback: function()
+    {
+        this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+    },
+
+    execute: function()
+    {
+        this.callback(this);
+    },
+
+    stop: function()
+    {
+        if (!this.timer) return;
+        clearInterval(this.timer);
+        this.timer = null;
+    },
+
+    onTimerEvent: function()
+    {
+        if (!this.currentlyExecuting)
+        {
+            try
+            {
+                this.currentlyExecuting = true;
+                this.execute();
+            }
+            finally
+            {
+                this.currentlyExecuting = false;
+            }
+        }
+    }
+});
+Object.extend(String, {
+    interpret: function(value)
+    {
+        return value == null ? '' : String(value);
+    },
+    specialChar: {
+        '\b': '\\b',
+        '\t': '\\t',
+        '\n': '\\n',
+        '\f': '\\f',
+        '\r': '\\r',
+        '\\': '\\\\'
+    }
+});
+
+Object.extend(String.prototype, {
+    gsub: function(pattern, replacement)
+    {
+        var result = '', source = this, match;
+        replacement = arguments.callee.prepareReplacement(replacement);
+
+        while (source.length > 0)
+        {
+            if (match = source.match(pattern))
+            {
+                result += source.slice(0, match.index);
+                result += String.interpret(replacement(match));
+                source = source.slice(match.index + match[0].length);
+            }
+            else
+            {
+                result += source,source = '';
+            }
+        }
+        return result;
+    },
+
+    sub: function(pattern, replacement, count)
+    {
+        replacement = this.gsub.prepareReplacement(replacement);
+        count = Object.isUndefined(count) ? 1 : count;
+
+        return this.gsub(pattern, function(match)
+        {
+            if (--count < 0) return match[0];
+            return replacement(match);
+        });
+    },
+
+    scan: function(pattern, iterator)
+    {
+        this.gsub(pattern, iterator);
+        return String(this);
+    },
+
+    truncate: function(length, truncation)
+    {
+        length = length || 30;
+        truncation = Object.isUndefined(truncation) ? '...' : truncation;
+        return this.length > length ?
+               this.slice(0, length - truncation.length) + truncation : String(this);
+    },
+
+    strip: function()
+    {
+        return this.replace(/^\s+/, '').replace(/\s+$/, '');
+    },
+
+    stripTags: function()
+    {
+        return this.replace(/<\/?[^>]+>/gi, '');
+    },
+
+    stripScripts: function()
+    {
+        return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+    },
+
+    extractScripts: function()
+    {
+        var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+        var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+        return (this.match(matchAll) || []).map(function(scriptTag)
+        {
+            return (scriptTag.match(matchOne) || ['', ''])[1];
+        });
+    },
+
+    evalScripts: function()
+    {
+        return this.extractScripts().map(function(script)
+        {
+            return eval(script)
+        });
+    },
+
+    escapeHTML: function()
+    {
+        var self = arguments.callee;
+        self.text.data = this;
+        return self.div.innerHTML;
+    },
+
+    unescapeHTML: function()
+    {
+        var div = new Element('div');
+        div.innerHTML = this.stripTags();
+        return div.childNodes[0] ? (div.childNodes.length > 1 ?
+                                    $A(div.childNodes).inject('', function(memo, node)
+                                    {
+                                        return memo + node.nodeValue
+                                    }) :
+                                    div.childNodes[0].nodeValue) : '';
+    },
+
+    toQueryParams: function(separator)
+    {
+        var match = this.strip().match(/([^?#]*)(#.*)?$/);
+        if (!match) return { };
+
+        return match[1].split(separator || '&').inject({ }, function(hash, pair)
+        {
+            if ((pair = pair.split('='))[0])
+            {
+                var key = decodeURIComponent(pair.shift());
+                var value = pair.length > 1 ? pair.join('=') : pair[0];
+                if (value != undefined) value = decodeURIComponent(value);
+
+                if (key in hash)
+                {
+                    if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+                    hash[key].push(value);
+                }
+                else hash[key] = value;
+            }
+            return hash;
+        });
+    },
+
+    toArray: function()
+    {
+        return this.split('');
+    },
+
+    succ: function()
+    {
+        return this.slice(0, this.length - 1) +
+               String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+    },
+
+    times: function(count)
+    {
+        return count < 1 ? '' : new Array(count + 1).join(this);
+    },
+
+    camelize: function()
+    {
+        var parts = this.split('-'), len = parts.length;
+        if (len == 1) return parts[0];
+
+        var camelized = this.charAt(0) == '-'
+                ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+                : parts[0];
+
+        for (var i = 1; i < len; i++)
+            camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+        return camelized;
+    },
+
+    capitalize: function()
+    {
+        return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+    },
+
+    underscore: function()
+    {
+        return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '#{1}_#{2}').gsub(/([a-z\d])([A-Z])/, '#{1}_#{2}').gsub(/-/, '_').toLowerCase();
+    },
+
+    dasherize: function()
+    {
+        return this.gsub(/_/, '-');
+    },
+
+    inspect: function(useDoubleQuotes)
+    {
+        var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match)
+        {
+            var character = String.specialChar[match[0]];
+            return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+        });
+        if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+        return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+    },
+
+    toJSON: function()
+    {
+        return this.inspect(true);
+    },
+
+    unfilterJSON: function(filter)
+    {
+        return this.sub(filter || Prototype.JSONFilter, '#{1}');
+    },
+
+    isJSON: function()
+    {
+        var str = this;
+        if (str.blank()) return false;
+        str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
+        return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
+    },
+
+    evalJSON: function(sanitize)
+    {
+        var json = this.unfilterJSON();
+        try
+        {
+            if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+        }
+        catch (e)
+        {
+        }
+        throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+    },
+
+    include: function(pattern)
+    {
+        return this.indexOf(pattern) > -1;
+    },
+
+    startsWith: function(pattern)
+    {
+        return this.indexOf(pattern) === 0;
+    },
+
+    endsWith: function(pattern)
+    {
+        var d = this.length - pattern.length;
+        return d >= 0 && this.lastIndexOf(pattern) === d;
+    },
+
+    empty: function()
+    {
+        return this == '';
+    },
+
+    blank: function()
+    {
+        return /^\s*$/.test(this);
+    },
+
+    interpolate: function(object, pattern)
+    {
+        return new Template(this, pattern).evaluate(object);
+    }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+    escapeHTML: function()
+    {
+        return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+    },
+    unescapeHTML: function()
+    {
+        return this.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
+    }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement)
+{
+    if (Object.isFunction(replacement)) return replacement;
+    var template = new Template(replacement);
+    return function(match)
+    {
+        return template.evaluate(match)
+    };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+    div:  document.createElement('div'),
+    text: document.createTextNode('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create({
+    initialize: function(template, pattern)
+    {
+        this.template = template.toString();
+        this.pattern = pattern || Template.Pattern;
+    },
+
+    evaluate: function(object)
+    {
+        if (Object.isFunction(object.toTemplateReplacements))
+            object = object.toTemplateReplacements();
+
+        return this.template.gsub(this.pattern, function(match)
+        {
+            if (object == null) return '';
+
+            var before = match[1] || '';
+            if (before == '\\') return match[2];
+
+            var ctx = object, expr = match[3];
+            var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+            match = pattern.exec(expr);
+            if (match == null) return before;
+
+            while (match != null)
+            {
+                var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+                ctx = ctx[comp];
+                if (null == ctx || '' == match[3]) break;
+                expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+                match = pattern.exec(expr);
+            }
+
+            return before + String.interpret(ctx);
+        }.bind(this));
+    }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = {
+    each: function(iterator, context)
+    {
+        var index = 0;
+        iterator = iterator.bind(context);
+        try
+        {
+            this._each(function(value)
+            {
+                iterator(value, index++);
+            });
+        }
+        catch (e)
+        {
+            if (e != $break) throw e;
+        }
+        return this;
+    },
+
+    eachSlice: function(number, iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var index = -number, slices = [], array = this.toArray();
+        while ((index += number) < array.length)
+            slices.push(array.slice(index, index + number));
+        return slices.collect(iterator, context);
+    },
+
+    all: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var result = true;
+        this.each(function(value, index)
+        {
+            result = result && !!iterator(value, index);
+            if (!result) throw $break;
+        });
+        return result;
+    },
+
+    any: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var result = false;
+        this.each(function(value, index)
+        {
+            if (result = !!iterator(value, index))
+                throw $break;
+        });
+        return result;
+    },
+
+    collect: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var results = [];
+        this.each(function(value, index)
+        {
+            results.push(iterator(value, index));
+        });
+        return results;
+    },
+
+    detect: function(iterator, context)
+    {
+        iterator = iterator.bind(context);
+        var result;
+        this.each(function(value, index)
+        {
+            if (iterator(value, index))
+            {
+                result = value;
+                throw $break;
+            }
+        });
+        return result;
+    },
+
+    findAll: function(iterator, context)
+    {
+        iterator = iterator.bind(context);
+        var results = [];
+        this.each(function(value, index)
+        {
+            if (iterator(value, index))
+                results.push(value);
+        });
+        return results;
+    },
+
+    grep: function(filter, iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var results = [];
+
+        if (Object.isString(filter))
+            filter = new RegExp(filter);
+
+        this.each(function(value, index)
+        {
+            if (filter.match(value))
+                results.push(iterator(value, index));
+        });
+        return results;
+    },
+
+    include: function(object)
+    {
+        if (Object.isFunction(this.indexOf))
+            if (this.indexOf(object) != -1) return true;
+
+        var found = false;
+        this.each(function(value)
+        {
+            if (value == object)
+            {
+                found = true;
+                throw $break;
+            }
+        });
+        return found;
+    },
+
+    inGroupsOf: function(number, fillWith)
+    {
+        fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+        return this.eachSlice(number, function(slice)
+        {
+            while (slice.length < number) slice.push(fillWith);
+            return slice;
+        });
+    },
+
+    inject: function(memo, iterator, context)
+    {
+        iterator = iterator.bind(context);
+        this.each(function(value, index)
+        {
+            memo = iterator(memo, value, index);
+        });
+        return memo;
+    },
+
+    invoke: function(method)
+    {
+        var args = $A(arguments).slice(1);
+        return this.map(function(value)
+        {
+            return value[method].apply(value, args);
+        });
+    },
+
+    max: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var result;
+        this.each(function(value, index)
+        {
+            value = iterator(value, index);
+            if (result == null || value >= result)
+                result = value;
+        });
+        return result;
+    },
+
+    min: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var result;
+        this.each(function(value, index)
+        {
+            value = iterator(value, index);
+            if (result == null || value < result)
+                result = value;
+        });
+        return result;
+    },
+
+    partition: function(iterator, context)
+    {
+        iterator = iterator ? iterator.bind(context) : Prototype.K;
+        var trues = [], falses = [];
+        this.each(function(value, index)
+        {
+            (iterator(value, index) ?
+             trues : falses).push(value);
+        });
+        return [trues, falses];
+    },
+
+    pluck: function(property)
+    {
+        var results = [];
+        this.each(function(value)
+        {
+            results.push(value[property]);
+        });
+        return results;
+    },
+
+    reject: function(iterator, context)
+    {
+        iterator = iterator.bind(context);
+        var results = [];
+        this.each(function(value, index)
+        {
+            if (!iterator(value, index))
+                results.push(value);
+        });
+        return results;
+    },
+
+    sortBy: function(iterator, context)
+    {
+        iterator = iterator.bind(context);
+        return this.map(function(value, index)
+        {
+            return {value: value, criteria: iterator(value, index)};
+        }).sort(function(left, right)
+        {
+            var a = left.criteria, b = right.criteria;
+            return a < b ? -1 : a > b ? 1 : 0;
+        }).pluck('value');
+    },
+
+    toArray: function()
+    {
+        return this.map();
+    },
+
+    zip: function()
+    {
+        var iterator = Prototype.K, args = $A(arguments);
+        if (Object.isFunction(args.last()))
+            iterator = args.pop();
+
+        var collections = [this].concat(args).map($A);
+        return this.map(function(value, index)
+        {
+            return iterator(collections.pluck(index));
+        });
+    },
+
+    size: function()
+    {
+        return this.toArray().length;
+    },
+
+    inspect: function()
+    {
+        return '#<Enumerable:' + this.toArray().inspect() + '>';
+    }
+};
+
+Object.extend(Enumerable, {
+    map:     Enumerable.collect,
+    find:    Enumerable.detect,
+    select:  Enumerable.findAll,
+    filter:  Enumerable.findAll,
+    member:  Enumerable.include,
+    entries: Enumerable.toArray,
+    every:   Enumerable.all,
+    some:    Enumerable.any
+});
+function $A(iterable)
+{
+    if (!iterable) return [];
+    if (iterable.toArray) return iterable.toArray();
+    var length = iterable.length, results = new Array(length);
+    while (length--) results[length] = iterable[length];
+    return results;
+}
+
+if (Prototype.Browser.WebKit)
+{
+    function $A(iterable)
+    {
+        if (!iterable) return [];
+        if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+            iterable.toArray) return iterable.toArray();
+        var length = iterable.length, results = new Array(length);
+        while (length--) results[length] = iterable[length];
+        return results;
+    }
+}
+
+Array.from = $A;
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+    _each: function(iterator)
+    {
+        for (var i = 0, length = this.length; i < length; i++)
+            iterator(this[i]);
+    },
+
+    clear: function()
+    {
+        this.length = 0;
+        return this;
+    },
+
+    first: function()
+    {
+        return this[0];
+    },
+
+    last: function()
+    {
+        return this[this.length - 1];
+    },
+
+    compact: function()
+    {
+        return this.select(function(value)
+        {
+            return value != null;
+        });
+    },
+
+    flatten: function()
+    {
+        return this.inject([], function(array, value)
+        {
+            return array.concat(Object.isArray(value) ?
+                                value.flatten() : [value]);
+        });
+    },
+
+    without: function()
+    {
+        var values = $A(arguments);
+        return this.select(function(value)
+        {
+            return !values.include(value);
+        });
+    },
+
+    reverse: function(inline)
+    {
+        return (inline !== false ? this : this.toArray())._reverse();
+    },
+
+    reduce: function()
+    {
+        return this.length > 1 ? this : this[0];
+    },
+
+    uniq: function(sorted)
+    {
+        return this.inject([], function(array, value, index)
+        {
+            if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+                array.push(value);
+            return array;
+        });
+    },
+
+    intersect: function(array)
+    {
+        return this.uniq().findAll(function(item)
+        {
+            return array.detect(function(value)
+            {
+                return item === value
+            });
+        });
+    },
+
+    clone: function()
+    {
+        return [].concat(this);
+    },
+
+    size: function()
+    {
+        return this.length;
+    },
+
+    inspect: function()
+    {
+        return '[' + this.map(Object.inspect).join(', ') + ']';
+    },
+
+    toJSON: function()
+    {
+        var results = [];
+        this.each(function(object)
+        {
+            var value = Object.toJSON(object);
+            if (!Object.isUndefined(value)) results.push(value);
+        });
+        return '[' + results.join(', ') + ']';
+    }
+});
+
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+    Array.prototype._each = Array.prototype.forEach;
+
+if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i)
+{
+    i || (i = 0);
+    var length = this.length;
+    if (i < 0) i = length + i;
+    for (; i < length; i++)
+        if (this[i] === item) return i;
+    return -1;
+};
+
+if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i)
+{
+    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+    var n = this.slice(0, i).reverse().indexOf(item);
+    return (n < 0) ? n : i - n - 1;
+};
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string)
+{
+    if (!Object.isString(string)) return [];
+    string = string.strip();
+    return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera)
+{
+    Array.prototype.concat = function()
+    {
+        var array = [];
+        for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+        for (var i = 0, length = arguments.length; i < length; i++)
+        {
+            if (Object.isArray(arguments[i]))
+            {
+                for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+                    array.push(arguments[i][j]);
+            }
+            else
+            {
+                array.push(arguments[i]);
+            }
+        }
+        return array;
+    };
+}
+Object.extend(Number.prototype, {
+    toColorPart: function()
+    {
+        return this.toPaddedString(2, 16);
+    },
+
+    succ: function()
+    {
+        return this + 1;
+    },
+
+    times: function(iterator)
+    {
+        $R(0, this, true).each(iterator);
+        return this;
+    },
+
+    toPaddedString: function(length, radix)
+    {
+        var string = this.toString(radix || 10);
+        return '0'.times(length - string.length) + string;
+    },
+
+    toJSON: function()
+    {
+        return isFinite(this) ? this.toString() : 'null';
+    }
+});
+
+$w('abs round ceil floor').each(function(method)
+{
+    Number.prototype[method] = Math[method].methodize();
+});
+function $H(object)
+{
+    return new Hash(object);
+}
+;
+
+var Hash = Class.create(Enumerable, (function()
+{
+
+    function toQueryPair(key, value)
+    {
+        if (Object.isUndefined(value)) return key;
+        return key + '=' + encodeURIComponent(String.interpret(value));
+    }
+
+    return {
+        initialize: function(object)
+        {
+            this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+        },
+
+        _each: function(iterator)
+        {
+            for (var key in this._object)
+            {
+                var value = this._object[key], pair = [key, value];
+                pair.key = key;
+                pair.value = value;
+                iterator(pair);
+            }
+        },
+
+        set: function(key, value)
+        {
+            return this._object[key] = value;
+        },
+
+        get: function(key)
+        {
+            return this._object[key];
+        },
+
+        unset: function(key)
+        {
+            var value = this._object[key];
+            delete this._object[key];
+            return value;
+        },
+
+        toObject: function()
+        {
+            return Object.clone(this._object);
+        },
+
+        keys: function()
+        {
+            return this.pluck('key');
+        },
+
+        values: function()
+        {
+            return this.pluck('value');
+        },
+
+        index: function(value)
+        {
+            var match = this.detect(function(pair)
+            {
+                return pair.value === value;
+            });
+            return match && match.key;
+        },
+
+        merge: function(object)
+        {
+            return this.clone().update(object);
+        },
+
+        update: function(object)
+        {
+            return new Hash(object).inject(this, function(result, pair)
+            {
+                result.set(pair.key, pair.value);
+                return result;
+            });
+        },
+
+        toQueryString: function()
+        {
+            return this.map(function(pair)
+            {
+                var key = encodeURIComponent(pair.key), values = pair.value;
+
+                if (values && typeof values == 'object')
+                {
+                    if (Object.isArray(values))
+                        return values.map(toQueryPair.curry(key)).join('&');
+                }
+                return toQueryPair(key, values);
+            }).join('&');
+        },
+
+        inspect: function()
+        {
+            return '#<Hash:{' + this.map(function(pair)
+            {
+                return pair.map(Object.inspect).join(': ');
+            }).join(', ') + '}>';
+        },
+
+        toJSON: function()
+        {
+            return Object.toJSON(this.toObject());
+        },
+
+        clone: function()
+        {
+            return new Hash(this);
+        }
+    }
+})());
+
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
+    initialize: function(start, end, exclusive)
+    {
+        this.start = start;
+        this.end = end;
+        this.exclusive = exclusive;
+    },
+
+    _each: function(iterator)
+    {
+        var value = this.start;
+        while (this.include(value))
+        {
+            iterator(value);
+            value = value.succ();
+        }
+    },
+
+    include: function(value)
+    {
+        if (value < this.start)
+            return false;
+        if (this.exclusive)
+            return value < this.end;
+        return value <= this.end;
+    }
+});
+
+var $R = function(start, end, exclusive)
+{
+    return new ObjectRange(start, end, exclusive);
+};
+
+var Ajax = {
+    getTransport: function()
+    {
+        return Try.these(
+                function()
+                {
+                    return new XMLHttpRequest()
+                },
+                function()
+                {
+                    return new ActiveXObject('Msxml2.XMLHTTP')
+                },
+                function()
+                {
+                    return new ActiveXObject('Microsoft.XMLHTTP')
+                }
+                ) || false;
+    },
+
+    activeRequestCount: 0
+};
+
+Ajax.Responders = {
+    responders: [],
+
+    _each: function(iterator)
+    {
+        this.responders._each(iterator);
+    },
+
+    register: function(responder)
+    {
+        if (!this.include(responder))
+            this.responders.push(responder);
+    },
+
+    unregister: function(responder)
+    {
+        this.responders = this.responders.without(responder);
+    },
+
+    dispatch: function(callback, request, transport, json)
+    {
+        this.each(function(responder)
+        {
+            if (Object.isFunction(responder[callback]))
+            {
+                try
+                {
+                    responder[callback].apply(responder, [request, transport, json]);
+                }
+                catch (e)
+                {
+                }
+            }
+        });
+    }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+    onCreate:   function()
+    {
+        Ajax.activeRequestCount++
+    },
+    onComplete: function()
+    {
+        Ajax.activeRequestCount--
+    }
+});
+
+Ajax.Base = Class.create({
+    initialize: function(options)
+    {
+        this.options = {
+            method:       'post',
+            asynchronous: true,
+            contentType:  'application/x-www-form-urlencoded',
+            encoding:     'UTF-8',
+            parameters:   '',
+            evalJSON:     true,
+            evalJS:       true
+        };
+        Object.extend(this.options, options || { });
+
+        this.options.method = this.options.method.toLowerCase();
+
+        if (Object.isString(this.options.parameters))
+            this.options.parameters = this.options.parameters.toQueryParams();
+        else if (Object.isHash(this.options.parameters))
+            this.options.parameters = this.options.parameters.toObject();
+    }
+});
+
+Ajax.Request = Class.create(Ajax.Base, {
+    _complete: false,
+
+    initialize: function($super, url, options)
+    {
+        $super(options);
+        this.transport = Ajax.getTransport();
+        this.request(url);
+    },
+
+    request: function(url)
+    {
+        this.url = url;
+        this.method = this.options.method;
+        var params = Object.clone(this.options.parameters);
+
+        if (!['get', 'post'].include(this.method))
+        {
+            // simulate other verbs over post
+            params['_method'] = this.method;
+            this.method = 'post';
+        }
+
+        this.parameters = params;
+
+        if (params = Object.toQueryString(params))
+        {
+            // when GET, append parameters to URL
+            if (this.method == 'get')
+                this.url += (this.url.include('?') ? '&' : '?') + params;
+            else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+                params += '&_=';
+        }
+
+        try
+        {
+            var response = new Ajax.Response(this);
+            if (this.options.onCreate) this.options.onCreate(response);
+            Ajax.Responders.dispatch('onCreate', this, response);
+
+            this.transport.open(this.method.toUpperCase(), this.url,
+                    this.options.asynchronous);
+
+            if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+            this.transport.onreadystatechange = this.onStateChange.bind(this);
+            this.setRequestHeaders();
+
+            this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+            this.transport.send(this.body);
+
+            /* Force Firefox to handle ready state 4 for synchronous requests */
+            if (!this.options.asynchronous && this.transport.overrideMimeType)
+                this.onStateChange();
+
+        }
+        catch (e)
+        {
+            this.dispatchException(e);
+        }
+    },
+
+    onStateChange: function()
+    {
+        var readyState = this.transport.readyState;
+        if (readyState > 1 && !((readyState == 4) && this._complete))
+            this.respondToReadyState(this.transport.readyState);
+    },
+
+    setRequestHeaders: function()
+    {
+        var headers = {
+            'X-Requested-With': 'XMLHttpRequest',
+            'X-Prototype-Version': Prototype.Version,
+            'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+        };
+
+        if (this.method == 'post')
+        {
+            headers['Content-type'] = this.options.contentType +
+                                      (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+            /* Force "Connection: close" for older Mozilla browsers to work
+            * around a bug where XMLHttpRequest sends an incorrect
+            * Content-length header. See Mozilla Bugzilla #246651.
+            */
+            if (this.transport.overrideMimeType &&
+                (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+                headers['Connection'] = 'close';
+        }
+
+    // user-defined headers
+        if (typeof this.options.requestHeaders == 'object')
+        {
+            var extras = this.options.requestHeaders;
+
+            if (Object.isFunction(extras.push))
+                for (var i = 0, length = extras.length; i < length; i += 2)
+                    headers[extras[i]] = extras[i + 1];
+            else
+                $H(extras).each(function(pair)
+                {
+                    headers[pair.key] = pair.value
+                });
+        }
+
+        for (var name in headers)
+            this.transport.setRequestHeader(name, headers[name]);
+    },
+
+    success: function()
+    {
+        var status = this.getStatus();
+        return !status || (status >= 200 && status < 300);
+    },
+
+    getStatus: function()
+    {
+        try
+        {
+            return this.transport.status || 0;
+        }
+        catch (e)
+        {
+            return 0
+        }
+    },
+
+    respondToReadyState: function(readyState)
+    {
+        var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+        if (state == 'Complete')
+        {
+            try
+            {
+                this._complete = true;
+                (this.options['on' + response.status]
+                        || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+                        || Prototype.emptyFunction)(response, response.headerJSON);
+            }
+            catch (e)
+            {
+                this.dispatchException(e);
+            }
+
+            var contentType = response.getHeader('Content-type');
+            if (this.options.evalJS == 'force'
+                    || (this.options.evalJS && contentType
+                    && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+                this.evalResponse();
+        }
+
+        try
+        {
+            (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+            Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+        }
+        catch (e)
+        {
+            this.dispatchException(e);
+        }
+
+        if (state == 'Complete')
+        {
+            // avoid memory leak in MSIE: clean up
+            this.transport.onreadystatechange = Prototype.emptyFunction;
+        }
+    },
+
+    getHeader: function(name)
+    {
+        try
+        {
+            return this.transport.getResponseHeader(name);
+        }
+        catch (e)
+        {
+            return null
+        }
+    },
+
+    evalResponse: function()
+    {
+        try
+        {
+            return eval((this.transport.responseText || '').unfilterJSON());
+        }
+        catch (e)
+        {
+            this.dispatchException(e);
+        }
+    },
+
+    dispatchException: function(exception)
+    {
+        (this.options.onException || Prototype.emptyFunction)(this, exception);
+        Ajax.Responders.dispatch('onException', this, exception);
+    }
+});
+
+Ajax.Request.Events =
+['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Response = Class.create({
+    initialize: function(request)
+    {
+        this.request = request;
+        var transport = this.transport = request.transport,
+                readyState = this.readyState = transport.readyState;
+
+        if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4)
+        {
+            this.status = this.getStatus();
+            this.statusText = this.getStatusText();
+            this.responseText = String.interpret(transport.responseText);
+            this.headerJSON = this._getHeaderJSON();
+        }
+
+        if (readyState == 4)
+        {
+            var xml = transport.responseXML;
+            this.responseXML = Object.isUndefined(xml) ? null : xml;
+            this.responseJSON = this._getResponseJSON();
+        }
+    },
+
+    status:      0,
+    statusText: '',
+
+    getStatus: Ajax.Request.prototype.getStatus,
+
+    getStatusText: function()
+    {
+        try
+        {
+            return this.transport.statusText || '';
+        }
+        catch (e)
+        {
+            return ''
+        }
+    },
+
+    getHeader: Ajax.Request.prototype.getHeader,
+
+    getAllHeaders: function()
+    {
+        try
+        {
+            return this.getAllResponseHeaders();
+        }
+        catch (e)
+        {
+            return null
+        }
+    },
+
+    getResponseHeader: function(name)
+    {
+        return this.transport.getResponseHeader(name);
+    },
+
+    getAllResponseHeaders: function()
+    {
+        return this.transport.getAllResponseHeaders();
+    },
+
+    _getHeaderJSON: function()
+    {
+        var json = this.getHeader('X-JSON');
+        if (!json) return null;
+        json = decodeURIComponent(escape(json));
+        try
+        {
+            return json.evalJSON(this.request.options.sanitizeJSON);
+        }
+        catch (e)
+        {
+            this.request.dispatchException(e);
+        }
+    },
+
+    _getResponseJSON: function()
+    {
+        var options = this.request.options;
+        if (!options.evalJSON || (options.evalJSON != 'force' &&
+                                  !(this.getHeader('Content-type') || '').include('application/json')) ||
+            this.responseText.blank())
+            return null;
+        try
+        {
+            return this.responseText.evalJSON(options.sanitizeJSON);
+        }
+        catch (e)
+        {
+            this.request.dispatchException(e);
+        }
+    }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+    initialize: function($super, container, url, options)
+    {
+        this.container = {
+            success: (container.success || container),
+            failure: (container.failure || (container.success ? null : container))
+        };
+
+        options = Object.clone(options);
+        var onComplete = options.onComplete;
+        options.onComplete = (function(response, json)
+        {
+            this.updateContent(response.responseText);
+            if (Object.isFunction(onComplete)) onComplete(response, json);
+        }).bind(this);
+
+        $super(url, options);
+    },
+
+    updateContent: function(responseText)
+    {
+        var receiver = this.container[this.success() ? 'success' : 'failure'],
+                options = this.options;
+
+        if (!options.evalScripts) responseText = responseText.stripScripts();
+
+        if (receiver = $(receiver))
+        {
+            if (options.insertion)
+            {
+                if (Object.isString(options.insertion))
+                {
+                    var insertion = { };
+                    insertion[options.insertion] = responseText;
+                    receiver.insert(insertion);
+                }
+                else options.insertion(receiver, responseText);
+            }
+            else receiver.update(responseText);
+        }
+    }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+    initialize: function($super, container, url, options)
+    {
+        $super(options);
+        this.onComplete = this.options.onComplete;
+
+        this.frequency = (this.options.frequency || 2);
+        this.decay = (this.options.decay || 1);
+
+        this.updater = { };
+        this.container = container;
+        this.url = url;
+
+        this.start();
+    },
+
+    start: function()
+    {
+        this.options.onComplete = this.updateComplete.bind(this);
+        this.onTimerEvent();
+    },
+
+    stop: function()
+    {
+        this.updater.options.onComplete = undefined;
+        clearTimeout(this.timer);
+        (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+    },
+
+    updateComplete: function(response)
+    {
+        if (this.options.decay)
+        {
+            this.decay = (response.responseText == this.lastText ?
+                          this.decay * this.options.decay : 1);
+
+            this.lastText = response.responseText;
+        }
+        this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+    },
+
+    onTimerEvent: function()
+    {
+        this.updater = new Ajax.Updater(this.container, this.url, this.options);
+    }
+});
+function $(element)
+{
+    if (arguments.length > 1)
+    {
+        for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+            elements.push($(arguments[i]));
+        return elements;
+    }
+    if (Object.isString(element))
+        element = document.getElementById(element);
+    return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath)
+{
+    document._getElementsByXPath = function(expression, parentElement)
+    {
+        var results = [];
+        var query = document.evaluate(expression, $(parentElement) || document,
+                null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+        for (var i = 0, length = query.snapshotLength; i < length; i++)
+            results.push(Element.extend(query.snapshotItem(i)));
+        return results;
+    };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Node) var Node = { };
+
+if (!Node.ELEMENT_NODE)
+{
+    // DOM level 2 ECMAScript Language Binding
+    Object.extend(Node, {
+        ELEMENT_NODE: 1,
+        ATTRIBUTE_NODE: 2,
+        TEXT_NODE: 3,
+        CDATA_SECTION_NODE: 4,
+        ENTITY_REFERENCE_NODE: 5,
+        ENTITY_NODE: 6,
+        PROCESSING_INSTRUCTION_NODE: 7,
+        COMMENT_NODE: 8,
+        DOCUMENT_NODE: 9,
+        DOCUMENT_TYPE_NODE: 10,
+        DOCUMENT_FRAGMENT_NODE: 11,
+        NOTATION_NODE: 12
+    });
+}
+
+(function()
+{
+    var element = this.Element;
+    this.Element = function(tagName, attributes)
+    {
+        attributes = attributes || { };
+        tagName = tagName.toLowerCase();
+        var cache = Element.cache;
+        if (Prototype.Browser.IE && attributes.name)
+        {
+            tagName = '<' + tagName + ' name="' + attributes.name + '">';
+            delete attributes.name;
+            return Element.writeAttribute(document.createElement(tagName), attributes);
+        }
+        if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+        return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+    };
+    Object.extend(this.Element, element || { });
+}).call(window);
+
+Element.cache = { };
+
+Element.Methods = {
+    visible: function(element)
+    {
+        return $(element).style.display != 'none';
+    },
+
+    toggle: function(element)
+    {
+        element = $(element);
+        Element[Element.visible(element) ? 'hide' : 'show'](element);
+        return element;
+    },
+
+    hide: function(element)
+    {
+        $(element).style.display = 'none';
+        return element;
+    },
+
+    show: function(element)
+    {
+        $(element).style.display = '';
+        return element;
+    },
+
+    remove: function(element)
+    {
+        element = $(element);
+        element.parentNode.removeChild(element);
+        return element;
+    },
+
+    update: function(element, content)
+    {
+        element = $(element);
+        if (content && content.toElement) content = content.toElement();
+        if (Object.isElement(content)) return element.update().insert(content);
+        content = Object.toHTML(content);
+        element.innerHTML = content.stripScripts();
+        content.evalScripts.bind(content).defer();
+        return element;
+    },
+
+    replace: function(element, content)
+    {
+        element = $(element);
+        if (content && content.toElement) content = content.toElement();
+        else if (!Object.isElement(content))
+        {
+            content = Object.toHTML(content);
+            var range = element.ownerDocument.createRange();
+            range.selectNode(element);
+            content.evalScripts.bind(content).defer();
+            content = range.createContextualFragment(content.stripScripts());
+        }
+        element.parentNode.replaceChild(content, element);
+        return element;
+    },
+
+    insert: function(element, insertions)
+    {
+        element = $(element);
+
+        if (Object.isString(insertions) || Object.isNumber(insertions) ||
+            Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+            insertions = {bottom:insertions};
+
+        var content, t, range;
+
+        for (position in insertions)
+        {
+            content = insertions[position];
+            position = position.toLowerCase();
+            t = Element._insertionTranslations[position];
+
+            if (content && content.toElement) content = content.toElement();
+            if (Object.isElement(content))
+            {
+                t.insert(element, content);
+                continue;
+            }
+
+            content = Object.toHTML(content);
+
+            range = element.ownerDocument.createRange();
+            t.initializeRange(element, range);
+            t.insert(element, range.createContextualFragment(content.stripScripts()));
+
+            content.evalScripts.bind(content).defer();
+        }
+
+        return element;
+    },
+
+    wrap: function(element, wrapper, attributes)
+    {
+        element = $(element);
+        if (Object.isElement(wrapper))
+            $(wrapper).writeAttribute(attributes || { });
+        else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+        else wrapper = new Element('div', wrapper);
+        if (element.parentNode)
+            element.parentNode.replaceChild(wrapper, element);
+        wrapper.appendChild(element);
+        return wrapper;
+    },
+
+    inspect: function(element)
+    {
+        element = $(element);
+        var result = '<' + element.tagName.toLowerCase();
+        $H({'id': 'id', 'className': 'class'}).each(function(pair)
+        {
+            var property = pair.first(), attribute = pair.last();
+            var value = (element[property] || '').toString();
+            if (value) result += ' ' + attribute + '=' + value.inspect(true);
+        });
+        return result + '>';
+    },
+
+    recursivelyCollect: function(element, property)
+    {
+        element = $(element);
+        var elements = [];
+        while (element = element[property])
+            if (element.nodeType == 1)
+                elements.push(Element.extend(element));
+        return elements;
+    },
+
+    ancestors: function(element)
+    {
+        return $(element).recursivelyCollect('parentNode');
+    },
+
+    descendants: function(element)
+    {
+        return $(element).getElementsBySelector("*");
+    },
+
+    firstDescendant: function(element)
+    {
+        element = $(element).firstChild;
+        while (element && element.nodeType != 1) element = element.nextSibling;
+        return $(element);
+    },
+
+    immediateDescendants: function(element)
+    {
+        if (!(element = $(element).firstChild)) return [];
+        while (element && element.nodeType != 1) element = element.nextSibling;
+        if (element) return [element].concat($(element).nextSiblings());
+        return [];
+    },
+
+    previousSiblings: function(element)
+    {
+        return $(element).recursivelyCollect('previousSibling');
+    },
+
+    nextSiblings: function(element)
+    {
+        return $(element).recursivelyCollect('nextSibling');
+    },
+
+    siblings: function(element)
+    {
+        element = $(element);
+        return element.previousSiblings().reverse().concat(element.nextSiblings());
+    },
+
+    match: function(element, selector)
+    {
+        if (Object.isString(selector))
+            selector = new Selector(selector);
+        return selector.match($(element));
+    },
+
+    up: function(element, expression, index)
+    {
+        element = $(element);
+        if (arguments.length == 1) return $(element.parentNode);
+        var ancestors = element.ancestors();
+        return expression ? Selector.findElement(ancestors, expression, index) :
+               ancestors[index || 0];
+    },
+
+    down: function(element, expression, index)
+    {
+        element = $(element);
+        if (arguments.length == 1) return element.firstDescendant();
+        var descendants = element.descendants();
+        return expression ? Selector.findElement(descendants, expression, index) :
+               descendants[index || 0];
+    },
+
+    previous: function(element, expression, index)
+    {
+        element = $(element);
+        if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+        var previousSiblings = element.previousSiblings();
+        return expression ? Selector.findElement(previousSiblings, expression, index) :
+               previousSiblings[index || 0];
+    },
+
+    next: function(element, expression, index)
+    {
+        element = $(element);
+        if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+        var nextSiblings = element.nextSiblings();
+        return expression ? Selector.findElement(nextSiblings, expression, index) :
+               nextSiblings[index || 0];
+    },
+
+    select: function()
+    {
+        var args = $A(arguments), element = $(args.shift());
+        return Selector.findChildElements(element, args);
+    },
+
+    adjacent: function()
+    {
+        var args = $A(arguments), element = $(args.shift());
+        return Selector.findChildElements(element.parentNode, args).without(element);
+    },
+
+    identify: function(element)
+    {
+        element = $(element);
+        var id = element.readAttribute('id'), self = arguments.callee;
+        if (id) return id;
+        do {
+            id = 'anonymous_element_' + self.counter++
+        } while ($(id));
+        element.writeAttribute('id', id);
+        return id;
+    },
+
+    readAttribute: function(element, name)
+    {
+        element = $(element);
+        if (Prototype.Browser.IE)
+        {
+            var t = Element._attributeTranslations.read;
+            if (t.values[name]) return t.values[name](element, name);
+            if (t.names[name]) name = t.names[name];
+            if (name.include(':'))
+            {
+                return (!element.attributes || !element.attributes[name]) ? null :
+                       element.attributes[name].value;
+            }
+        }
+        return element.getAttribute(name);
+    },
+
+    writeAttribute: function(element, name, value)
+    {
+        element = $(element);
+        var attributes = { }, t = Element._attributeTranslations.write;
+
+        if (typeof name == 'object') attributes = name;
+        else attributes[name] = Object.isUndefined(value) ? true : value;
+
+        for (var attr in attributes)
+        {
+            name = t.names[attr] || attr;
+            value = attributes[attr];
+            if (t.values[attr]) name = t.values[attr](element, value);
+            if (value === false || value === null)
+                element.removeAttribute(name);
+            else if (value === true)
+                element.setAttribute(name, name);
+            else element.setAttribute(name, value);
+        }
+        return element;
+    },
+
+    getHeight: function(element)
+    {
+        return $(element).getDimensions().height;
+    },
+
+    getWidth: function(element)
+    {
+        return $(element).getDimensions().width;
+    },
+
+    classNames: function(element)
+    {
+        return new Element.ClassNames(element);
+    },
+
+    hasClassName: function(element, className)
+    {
+        if (!(element = $(element))) return;
+        var elementClassName = element.className;
+        return (elementClassName.length > 0 && (elementClassName == className ||
+                                                new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+    },
+
+    addClassName: function(element, className)
+    {
+        if (!(element = $(element))) return;
+        if (!element.hasClassName(className))
+            element.className += (element.className ? ' ' : '') + className;
+        return element;
+    },
+
+    removeClassName: function(element, className)
+    {
+        if (!(element = $(element))) return;
+        element.className = element.className.replace(
+                new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+        return element;
+    },
+
+    toggleClassName: function(element, className)
+    {
+        if (!(element = $(element))) return;
+        return element[element.hasClassName(className) ?
+                       'removeClassName' : 'addClassName'](className);
+    },
+
+    // removes whitespace-only text node children
+    cleanWhitespace: function(element)
+    {
+        element = $(element);
+        var node = element.firstChild;
+        while (node)
+        {
+            var nextNode = node.nextSibling;
+            if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+                element.removeChild(node);
+            node = nextNode;
+        }
+        return element;
+    },
+
+    empty: function(element)
+    {
+        return $(element).innerHTML.blank();
+    },
+
+    descendantOf: function(element, ancestor)
+    {
+        element = $(element),ancestor = $(ancestor);
+        var originalAncestor = ancestor;
+
+        if (element.compareDocumentPosition)
+            return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+        if (element.sourceIndex && !Prototype.Browser.Opera)
+        {
+            var e = element.sourceIndex, a = ancestor.sourceIndex,
+                    nextAncestor = ancestor.nextSibling;
+            if (!nextAncestor)
+            {
+                do {
+                    ancestor = ancestor.parentNode;
+                }
+                while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+            }
+            if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
+        }
+
+        while (element = element.parentNode)
+            if (element == originalAncestor) return true;
+        return false;
+    },
+
+    scrollTo: function(element)
+    {
+        element = $(element);
+        var pos = element.cumulativeOffset();
+        window.scrollTo(pos[0], pos[1]);
+        return element;
+    },
+
+    getStyle: function(element, style)
+    {
+        element = $(element);
+        style = style == 'float' ? 'cssFloat' : style.camelize();
+        var value = element.style[style];
+        if (!value)
+        {
+            var css = document.defaultView.getComputedStyle(element, null);
+            value = css ? css[style] : null;
+        }
+        if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+        return value == 'auto' ? null : value;
+    },
+
+    getOpacity: function(element)
+    {
+        return $(element).getStyle('opacity');
+    },
+
+    setStyle: function(element, styles)
+    {
+        element = $(element);
+        var elementStyle = element.style, match;
+        if (Object.isString(styles))
+        {
+            element.style.cssText += ';' + styles;
+            return styles.include('opacity') ?
+                   element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+        }
+        for (var property in styles)
+            if (property == 'opacity') element.setOpacity(styles[property]);
+            else
+                elementStyle[(property == 'float' || property == 'cssFloat') ?
+                             (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+                             property] = styles[property];
+
+        return element;
+    },
+
+    setOpacity: function(element, value)
+    {
+        element = $(element);
+        element.style.opacity = (value == 1 || value === '') ? '' :
+                                (value < 0.00001) ? 0 : value;
+        return element;
+    },
+
+    getDimensions: function(element)
+    {
+        element = $(element);
+        var display = $(element).getStyle('display');
+        if (display != 'none' && display != null) // Safari bug
+            return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+        // so enable the element temporarily
+        var els = element.style;
+        var originalVisibility = els.visibility;
+        var originalPosition = els.position;
+        var originalDisplay = els.display;
+        els.visibility = 'hidden';
+        els.position = 'absolute';
+        els.display = 'block';
+        var originalWidth = element.clientWidth;
+        var originalHeight = element.clientHeight;
+        els.display = originalDisplay;
+        els.position = originalPosition;
+        els.visibility = originalVisibility;
+        return {width: originalWidth, height: originalHeight};
+    },
+
+    makePositioned: function(element)
+    {
+        element = $(element);
+        var pos = Element.getStyle(element, 'position');
+        if (pos == 'static' || !pos)
+        {
+            element._madePositioned = true;
+            element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+            // element is position relative but top and left have not been defined
+            if (window.opera)
+            {
+                element.style.top = 0;
+                element.style.left = 0;
+            }
+        }
+        return element;
+    },
+
+    undoPositioned: function(element)
+    {
+        element = $(element);
+        if (element._madePositioned)
+        {
+            element._madePositioned = undefined;
+            element.style.position =
+            element.style.top =
+            element.style.left =
+            element.style.bottom =
+            element.style.right = '';
+        }
+        return element;
+    },
+
+    makeClipping: function(element)
+    {
+        element = $(element);
+        if (element._overflow) return element;
+        element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+        if (element._overflow !== 'hidden')
+            element.style.overflow = 'hidden';
+        return element;
+    },
+
+    undoClipping: function(element)
+    {
+        element = $(element);
+        if (!element._overflow) return element;
+        element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+        element._overflow = null;
+        return element;
+    },
+
+    cumulativeOffset: function(element)
+    {
+        var valueT = 0, valueL = 0;
+        do {
+            valueT += element.offsetTop || 0;
+            valueL += element.offsetLeft || 0;
+            element = element.offsetParent;
+        } while (element);
+        return Element._returnOffset(valueL, valueT);
+    },
+
+    positionedOffset: function(element)
+    {
+        var valueT = 0, valueL = 0;
+        do {
+            valueT += element.offsetTop || 0;
+            valueL += element.offsetLeft || 0;
+            element = element.offsetParent;
+            if (element)
+            {
+                if (element.tagName == 'BODY') break;
+                var p = Element.getStyle(element, 'position');
+                if (p == 'relative' || p == 'absolute') break;
+            }
+        } while (element);
+        return Element._returnOffset(valueL, valueT);
+    },
+
+    absolutize: function(element)
+    {
+        element = $(element);
+        if (element.getStyle('position') == 'absolute') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+        var offsets = element.positionedOffset();
+        var top = offsets[1];
+        var left = offsets[0];
+        var width = element.clientWidth;
+        var height = element.clientHeight;
+
+        element._originalLeft = left - parseFloat(element.style.left || 0);
+        element._originalTop = top - parseFloat(element.style.top || 0);
+        element._originalWidth = element.style.width;
+        element._originalHeight = element.style.height;
+
+        element.style.position = 'absolute';
+        element.style.top = top + 'px';
+        element.style.left = left + 'px';
+        element.style.width = width + 'px';
+        element.style.height = height + 'px';
+        return element;
+    },
+
+    relativize: function(element)
+    {
+        element = $(element);
+        if (element.getStyle('position') == 'relative') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+        element.style.position = 'relative';
+        var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+        var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+        element.style.top = top + 'px';
+        element.style.left = left + 'px';
+        element.style.height = element._originalHeight;
+        element.style.width = element._originalWidth;
+        return element;
+    },
+
+    cumulativeScrollOffset: function(element)
+    {
+        var valueT = 0, valueL = 0;
+        do {
+            valueT += element.scrollTop || 0;
+            valueL += element.scrollLeft || 0;
+            element = element.parentNode;
+        } while (element);
+        return Element._returnOffset(valueL, valueT);
+    },
+
+    getOffsetParent: function(element)
+    {
+        if (element.offsetParent) return $(element.offsetParent);
+        if (element == document.body) return $(element);
+
+        while ((element = element.parentNode) && element != document.body)
+            if (Element.getStyle(element, 'position') != 'static')
+                return $(element);
+
+        return $(document.body);
+    },
+
+    viewportOffset: function(forElement)
+    {
+        var valueT = 0, valueL = 0;
+
+        var element = forElement;
+        do {
+            valueT += element.offsetTop || 0;
+            valueL += element.offsetLeft || 0;
+
+      // Safari fix
+            if (element.offsetParent == document.body &&
+                Element.getStyle(element, 'position') == 'absolute') break;
+
+        } while (element = element.offsetParent);
+
+        element = forElement;
+        do {
+            if (!Prototype.Browser.Opera || element.tagName == 'BODY')
+            {
+                valueT -= element.scrollTop || 0;
+                valueL -= element.scrollLeft || 0;
+            }
+        } while (element = element.parentNode);
+
+        return Element._returnOffset(valueL, valueT);
+    },
+
+    clonePosition: function(element, source)
+    {
+        var options = Object.extend({
+            setLeft:    true,
+            setTop:     true,
+            setWidth:   true,
+            setHeight:  true,
+            offsetTop:  0,
+            offsetLeft: 0
+        }, arguments[2] || { });
+
+    // find page position of source
+        source = $(source);
+        var p = source.viewportOffset();
+
+    // find coordinate system to use
+        element = $(element);
+        var delta = [0, 0];
+        var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+        // position:absolute needs offsetParent deltas
+        if (Element.getStyle(element, 'position') == 'absolute')
+        {
+            parent = element.getOffsetParent();
+            delta = parent.viewportOffset();
+        }
+
+    // correct by body offsets (fixes Safari)
+        if (parent == document.body)
+        {
+            delta[0] -= document.body.offsetLeft;
+            delta[1] -= document.body.offsetTop;
+        }
+
+    // set position
+        if (options.setLeft)   element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+        if (options.setTop)    element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+        if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
+        if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+        return element;
+    }
+};
+
+Element.Methods.identify.counter = 1;
+
+Object.extend(Element.Methods, {
+    getElementsBySelector: Element.Methods.select,
+    childElements: Element.Methods.immediateDescendants
+});
+
+Element._attributeTranslations = {
+    write: {
+        names: {
+            className: 'class',
+            htmlFor:   'for'
+        },
+        values: { }
+    }
+};
+
+
+if (!document.createRange || Prototype.Browser.Opera)
+{
+    Element.Methods.insert = function(element, insertions)
+    {
+        element = $(element);
+
+        if (Object.isString(insertions) || Object.isNumber(insertions) ||
+            Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+            insertions = { bottom: insertions };
+
+        var t = Element._insertionTranslations, content, position, pos, tagName;
+
+        for (position in insertions)
+        {
+            content = insertions[position];
+            position = position.toLowerCase();
+            pos = t[position];
+
+            if (content && content.toElement) content = content.toElement();
+            if (Object.isElement(content))
+            {
+                pos.insert(element, content);
+                continue;
+            }
+
+            content = Object.toHTML(content);
+            tagName = ((position == 'before' || position == 'after')
+                    ? element.parentNode : element).tagName.toUpperCase();
+
+            if (t.tags[tagName])
+            {
+                var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+                if (position == 'top' || position == 'after') fragments.reverse();
+                fragments.each(pos.insert.curry(element));
+            }
+            else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
+
+            content.evalScripts.bind(content).defer();
+        }
+
+        return element;
+    };
+}
+
+if (Prototype.Browser.Opera)
+{
+    Element.Methods.getStyle = Element.Methods.getStyle.wrap(
+            function(proceed, element, style)
+            {
+                switch (style)
+                        {
+                    case 'left': case 'top': case 'right': case 'bottom':
+                    if (proceed(element, 'position') === 'static') return null;
+                    case 'height': case 'width':
+                // returns '0px' for hidden elements; we want it to return null
+                    if (!Element.visible(element)) return null;
+
+                // returns the border-box dimensions rather than the content-box
+                // dimensions, so we subtract padding and borders from the value
+                    var dim = parseInt(proceed(element, style), 10);
+
+                    if (dim !== element['offset' + style.capitalize()])
+                        return dim + 'px';
+
+                    var properties;
+                    if (style === 'height')
+                    {
+                        properties = ['border-top-width', 'padding-top',
+                            'padding-bottom', 'border-bottom-width'];
+                    }
+                    else
+                    {
+                        properties = ['border-left-width', 'padding-left',
+                            'padding-right', 'border-right-width'];
+                    }
+                    return properties.inject(dim, function(memo, property)
+                    {
+                        var val = proceed(element, property);
+                        return val === null ? memo : memo - parseInt(val, 10);
+                    }) + 'px';
+                    default: return proceed(element, style);
+                }
+            }
+            );
+
+    Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+            function(proceed, element, attribute)
+            {
+                if (attribute === 'title') return element.title;
+                return proceed(element, attribute);
+            }
+            );
+}
+
+else if (Prototype.Browser.IE)
+{
+    $w('positionedOffset getOffsetParent viewportOffset').each(function(method)
+    {
+        Element.Methods[method] = Element.Methods[method].wrap(
+                function(proceed, element)
+                {
+                    element = $(element);
+                    var position = element.getStyle('position');
+                    if (position != 'static') return proceed(element);
+                    element.setStyle({ position: 'relative' });
+                    var value = proceed(element);
+                    element.setStyle({ position: position });
+                    return value;
+                }
+                );
+    });
+
+    Element.Methods.getStyle = function(element, style)
+    {
+        element = $(element);
+        style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+        var value = element.style[style];
+        if (!value && element.currentStyle) value = element.currentStyle[style];
+
+        if (style == 'opacity')
+        {
+            if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+                if (value[1]) return parseFloat(value[1]) / 100;
+            return 1.0;
+        }
+
+        if (value == 'auto')
+        {
+            if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+                return element['offset' + style.capitalize()] + 'px';
+            return null;
+        }
+        return value;
+    };
+
+    Element.Methods.setOpacity = function(element, value)
+    {
+        function stripAlpha(filter)
+        {
+            return filter.replace(/alpha\([^\)]*\)/gi, '');
+        }
+        element = $(element);
+        var currentStyle = element.currentStyle;
+        if ((currentStyle && !currentStyle.hasLayout) ||
+            (!currentStyle && element.style.zoom == 'normal'))
+            element.style.zoom = 1;
+
+        var filter = element.getStyle('filter'), style = element.style;
+        if (value == 1 || value === '')
+        {
+            (filter = stripAlpha(filter)) ?
+            style.filter = filter : style.removeAttribute('filter');
+            return element;
+        }
+        else if (value < 0.00001) value = 0;
+        style.filter = stripAlpha(filter) +
+                       'alpha(opacity=' + (value * 100) + ')';
+        return element;
+    };
+
+    Element._attributeTranslations = {
+        read: {
+            names: {
+                'class': 'className',
+                'for':   'htmlFor'
+            },
+            values: {
+                _getAttr: function(element, attribute)
+                {
+                    return element.getAttribute(attribute, 2);
+                },
+                _getAttrNode: function(element, attribute)
+                {
+                    var node = element.getAttributeNode(attribute);
+                    return node ? node.value : "";
+                },
+                _getEv: function(element, attribute)
+                {
+                    attribute = element.getAttribute(attribute);
+                    return attribute ? attribute.toString().slice(23, -2) : null;
+                },
+                _flag: function(element, attribute)
+                {
+                    return $(element).hasAttribute(attribute) ? attribute : null;
+                },
+                style: function(element)
+                {
+                    return element.style.cssText.toLowerCase();
+                },
+                title: function(element)
+                {
+                    return element.title;
+                }
+            }
+        }
+    };
+
+    Element._attributeTranslations.write = {
+        names: Object.clone(Element._attributeTranslations.read.names),
+        values: {
+            checked: function(element, value)
+            {
+                element.checked = !!value;
+            },
+
+            style: function(element, value)
+            {
+                element.style.cssText = value ? value : '';
+            }
+        }
+    };
+
+    Element._attributeTranslations.has = {};
+
+    $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+       'encType maxLength readOnly longDesc').each(function(attr)
+    {
+        Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+        Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+    });
+
+    (function(v)
+    {
+        Object.extend(v, {
+            href:        v._getAttr,
+            src:         v._getAttr,
+            type:        v._getAttr,
+            action:      v._getAttrNode,
+            disabled:    v._flag,
+            checked:     v._flag,
+            readonly:    v._flag,
+            multiple:    v._flag,
+            onload:      v._getEv,
+            onunload:    v._getEv,
+            onclick:     v._getEv,
+            ondblclick:  v._getEv,
+            onmousedown: v._getEv,
+            onmouseup:   v._getEv,
+            onmouseover: v._getEv,
+            onmousemove: v._getEv,
+            onmouseout:  v._getEv,
+            onfocus:     v._getEv,
+            onblur:      v._getEv,
+            onkeypress:  v._getEv,
+            onkeydown:   v._getEv,
+            onkeyup:     v._getEv,
+            onsubmit:    v._getEv,
+            onreset:     v._getEv,
+            onselect:    v._getEv,
+            onchange:    v._getEv
+        });
+    })(Element._attributeTranslations.read.values);
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent))
+{
+    Element.Methods.setOpacity = function(element, value)
+    {
+        element = $(element);
+        element.style.opacity = (value == 1) ? 0.999999 :
+                                (value === '') ? '' : (value < 0.00001) ? 0 : value;
+        return element;
+    };
+}
+
+else if (Prototype.Browser.WebKit)
+{
+    Element.Methods.setOpacity = function(element, value)
+    {
+        element = $(element);
+        element.style.opacity = (value == 1 || value === '') ? '' :
+                                (value < 0.00001) ? 0 : value;
+
+        if (value == 1)
+            if (element.tagName == 'IMG' && element.width)
+            {
+                element.width++;
+                element.width--;
+            }
+            else try
+            {
+                var n = document.createTextNode(' ');
+                element.appendChild(n);
+                element.removeChild(n);
+            }
+            catch (e)
+            {
+            }
+
+        return element;
+    };
+
+  // Safari returns margins on body which is incorrect if the child is absolutely
+    // positioned.  For performance reasons, redefine Element#cumulativeOffset for
+    // KHTML/WebKit only.
+    Element.Methods.cumulativeOffset = function(element)
+    {
+        var valueT = 0, valueL = 0;
+        do {
+            valueT += element.offsetTop || 0;
+            valueL += element.offsetLeft || 0;
+            if (element.offsetParent == document.body)
+                if (Element.getStyle(element, 'position') == 'absolute') break;
+
+            element = element.offsetParent;
+        } while (element);
+
+        return Element._returnOffset(valueL, valueT);
+    };
+}
+
+if (Prototype.Browser.IE || Prototype.Browser.Opera)
+{
+    // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+    Element.Methods.update = function(element, content)
+    {
+        element = $(element);
+
+        if (content && content.toElement) content = content.toElement();
+        if (Object.isElement(content)) return element.update().insert(content);
+
+        content = Object.toHTML(content);
+        var tagName = element.tagName.toUpperCase();
+
+        if (tagName in Element._insertionTranslations.tags)
+        {
+            $A(element.childNodes).each(function(node)
+            {
+                element.removeChild(node)
+            });
+            Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+                    .each(function(node)
+            {
+                element.appendChild(node)
+            });
+        }
+        else element.innerHTML = content.stripScripts();
+
+        content.evalScripts.bind(content).defer();
+        return element;
+    };
+}
+
+if (document.createElement('div').outerHTML)
+{
+    Element.Methods.replace = function(element, content)
+    {
+        element = $(element);
+
+        if (content && content.toElement) content = content.toElement();
+        if (Object.isElement(content))
+        {
+            element.parentNode.replaceChild(content, element);
+            return element;
+        }
+
+        content = Object.toHTML(content);
+        var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+        if (Element._insertionTranslations.tags[tagName])
+        {
+            var nextSibling = element.next();
+            var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+            parent.removeChild(element);
+            if (nextSibling)
+                fragments.each(function(node)
+                {
+                    parent.insertBefore(node, nextSibling)
+                });
+            else
+                fragments.each(function(node)
+                {
+                    parent.appendChild(node)
+                });
+        }
+        else element.outerHTML = content.stripScripts();
+
+        content.evalScripts.bind(content).defer();
+        return element;
+    };
+}
+
+Element._returnOffset = function(l, t)
+{
+    var result = [l, t];
+    result.left = l;
+    result.top = t;
+    return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html)
+{
+    var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+    div.innerHTML = t[0] + html + t[1];
+    t[2].times(function()
+    {
+        div = div.firstChild
+    });
+    return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+    before: {
+        adjacency: 'beforeBegin',
+        insert: function(element, node)
+        {
+            element.parentNode.insertBefore(node, element);
+        },
+        initializeRange: function(element, range)
+        {
+            range.setStartBefore(element);
+        }
+    },
+    top: {
+        adjacency: 'afterBegin',
+        insert: function(element, node)
+        {
+            element.insertBefore(node, element.firstChild);
+        },
+        initializeRange: function(element, range)
+        {
+            range.selectNodeContents(element);
+            range.collapse(true);
+        }
+    },
+    bottom: {
+        adjacency: 'beforeEnd',
+        insert: function(element, node)
+        {
+            element.appendChild(node);
+        }
+    },
+    after: {
+        adjacency: 'afterEnd',
+        insert: function(element, node)
+        {
+            element.parentNode.insertBefore(node, element.nextSibling);
+        },
+        initializeRange: function(element, range)
+        {
+            range.setStartAfter(element);
+        }
+    },
+    tags: {
+        TABLE:  ['<table>',                '</table>',                   1],
+        TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
+        TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
+        TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+        SELECT: ['<select>',               '</select>',                  1]
+    }
+};
+
+(function()
+{
+    this.bottom.initializeRange = this.top.initializeRange;
+    Object.extend(this.tags, {
+        THEAD: this.tags.TBODY,
+        TFOOT: this.tags.TBODY,
+        TH:    this.tags.TD
+    });
+}).call(Element._insertionTranslations);
+
+Element.Methods.Simulated = {
+    hasAttribute: function(element, attribute)
+    {
+        attribute = Element._attributeTranslations.has[attribute] || attribute;
+        var node = $(element).getAttributeNode(attribute);
+        return node && node.specified;
+    }
+};
+
+Element.Methods.ByTag = { };
+
+Object.extend(Element, Element.Methods);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+    document.createElement('div').__proto__)
+{
+    window.HTMLElement = { };
+    window.HTMLElement.prototype = document.createElement('div').__proto__;
+    Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.extend = (function()
+{
+    if (Prototype.BrowserFeatures.SpecificElementExtensions)
+        return Prototype.K;
+
+    var Methods = { }, ByTag = Element.Methods.ByTag;
+
+    var extend = Object.extend(function(element)
+    {
+        if (!element || element._extendedByPrototype ||
+            element.nodeType != 1 || element == window) return element;
+
+        var methods = Object.clone(Methods),
+                tagName = element.tagName, property, value;
+
+    // extend methods for specific tags
+        if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+        for (property in methods)
+        {
+            value = methods[property];
+            if (Object.isFunction(value) && !(property in element))
+                element[property] = value.methodize();
+        }
+
+        element._extendedByPrototype = Prototype.emptyFunction;
+        return element;
+
+    }, {
+        refresh: function()
+        {
+            // extend methods for all tags (Safari doesn't need this)
+            if (!Prototype.BrowserFeatures.ElementExtensions)
+            {
+                Object.extend(Methods, Element.Methods);
+                Object.extend(Methods, Element.Methods.Simulated);
+            }
+        }
+    });
+
+    extend.refresh();
+    return extend;
+})();
+
+Element.hasAttribute = function(element, attribute)
+{
+    if (element.hasAttribute) return element.hasAttribute(attribute);
+    return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods)
+{
+    var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+    if (!methods)
+    {
+        Object.extend(Form, Form.Methods);
+        Object.extend(Form.Element, Form.Element.Methods);
+        Object.extend(Element.Methods.ByTag, {
+            "FORM":     Object.clone(Form.Methods),
+            "INPUT":    Object.clone(Form.Element.Methods),
+            "SELECT":   Object.clone(Form.Element.Methods),
+            "TEXTAREA": Object.clone(Form.Element.Methods)
+        });
+    }
+
+    if (arguments.length == 2)
+    {
+        var tagName = methods;
+        methods = arguments[1];
+    }
+
+    if (!tagName) Object.extend(Element.Methods, methods || { });
+    else
+    {
+        if (Object.isArray(tagName)) tagName.each(extend);
+        else extend(tagName);
+    }
+
+    function extend(tagName)
+    {
+        tagName = tagName.toUpperCase();
+        if (!Element.Methods.ByTag[tagName])
+            Element.Methods.ByTag[tagName] = { };
+        Object.extend(Element.Methods.ByTag[tagName], methods);
+    }
+
+    function copy(methods, destination, onlyIfAbsent)
+    {
+        onlyIfAbsent = onlyIfAbsent || false;
+        for (var property in methods)
+        {
+            var value = methods[property];
+            if (!Object.isFunction(value)) continue;
+            if (!onlyIfAbsent || !(property in destination))
+                destination[property] = value.methodize();
+        }
+    }
+
+    function findDOMClass(tagName)
+    {
+        var klass;
+        var trans = {
+            "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+            "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+            "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+            "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+            "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+                "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+                "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+                "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+                "FrameSet", "IFRAME": "IFrame"
+        };
+        if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+        if (window[klass]) return window[klass];
+        klass = 'HTML' + tagName + 'Element';
+        if (window[klass]) return window[klass];
+        klass = 'HTML' + tagName.capitalize() + 'Element';
+        if (window[klass]) return window[klass];
+
+        window[klass] = { };
+        window[klass].prototype = document.createElement(tagName).__proto__;
+        return window[klass];
+    }
+
+    if (F.ElementExtensions)
+    {
+        copy(Element.Methods, HTMLElement.prototype);
+        copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    }
+
+    if (F.SpecificElementExtensions)
+    {
+        for (var tag in Element.Methods.ByTag)
+        {
+            var klass = findDOMClass(tag);
+            if (Object.isUndefined(klass)) continue;
+            copy(T[tag], klass.prototype);
+        }
+    }
+
+    Object.extend(Element, Element.Methods);
+    delete Element.ByTag;
+
+    if (Element.extend.refresh) Element.extend.refresh();
+    Element.cache = { };
+};
+
+document.viewport = {
+    getDimensions: function()
+    {
+        var dimensions = { };
+        var B = Prototype.Browser;
+        $w('width height').each(function(d)
+        {
+            var D = d.capitalize();
+            dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
+                            (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
+        });
+        return dimensions;
+    },
+
+    getWidth: function()
+    {
+        return this.getDimensions().width;
+    },
+
+    getHeight: function()
+    {
+        return this.getDimensions().height;
+    },
+
+    getScrollOffsets: function()
+    {
+        return Element._returnOffset(
+                window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+                window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+    }
+};
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license.  Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create({
+    initialize: function(expression)
+    {
+        this.expression = expression.strip();
+        this.compileMatcher();
+    },
+
+    shouldUseXPath: function()
+    {
+        if (!Prototype.BrowserFeatures.XPath) return false;
+
+        var e = this.expression;
+
+    // Safari 3 chokes on :*-of-type and :empty
+        if (Prototype.Browser.WebKit &&
+            (e.include("-of-type") || e.include(":empty")))
+            return false;
+
+    // XPath can't do namespaced attributes, nor can it read
+        // the "checked" property from DOM nodes
+        if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
+            return false;
+
+        return true;
+    },
+
+    compileMatcher: function()
+    {
+        if (this.shouldUseXPath())
+            return this.compileXPathMatcher();
+
+        var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+                c = Selector.criteria, le, p, m;
+
+        if (Selector._cache[e])
+        {
+            this.matcher = Selector._cache[e];
+            return;
+        }
+
+        this.matcher = ["this.matcher = function(root) {",
+            "var r = root, h = Selector.handlers, c = false, n;"];
+
+        while (e && le != e && (/\S/).test(e))
+        {
+            le = e;
+            for (var i in ps)
+            {
+                p = ps[i];
+                if (m = e.match(p))
+                {
+                    this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+                                      new Template(c[i]).evaluate(m));
+                    e = e.replace(m[0], '');
+                    break;
+                }
+            }
+        }
+
+        this.matcher.push("return h.unique(n);\n}");
+        eval(this.matcher.join('\n'));
+        Selector._cache[this.expression] = this.matcher;
+    },
+
+    compileXPathMatcher: function()
+    {
+        var e = this.expression, ps = Selector.patterns,
+                x = Selector.xpath, le, m;
+
+        if (Selector._cache[e])
+        {
+            this.xpath = Selector._cache[e];
+            return;
+        }
+
+        this.matcher = ['.//*'];
+        while (e && le != e && (/\S/).test(e))
+        {
+            le = e;
+            for (var i in ps)
+            {
+                if (m = e.match(ps[i]))
+                {
+                    this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+                                      new Template(x[i]).evaluate(m));
+                    e = e.replace(m[0], '');
+                    break;
+                }
+            }
+        }
+
+        this.xpath = this.matcher.join('');
+        Selector._cache[this.expression] = this.xpath;
+    },
+
+    findElements: function(root)
+    {
+        root = root || document;
+        if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+        return this.matcher(root);
+    },
+
+    match: function(element)
+    {
+        this.tokens = [];
+
+        var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+        var le, p, m;
+
+        while (e && le !== e && (/\S/).test(e))
+        {
+            le = e;
+            for (var i in ps)
+            {
+                p = ps[i];
+                if (m = e.match(p))
+                {
+                    // use the Selector.assertions methods unless the selector
+                    // is too complex.
+                    if (as[i])
+                    {
+                        this.tokens.push([i, Object.clone(m)]);
+                        e = e.replace(m[0], '');
+                    }
+                    else
+                    {
+                        // reluctantly do a document-wide search
+                        // and look for a match in the array
+                        return this.findElements(document).include(element);
+                    }
+                }
+            }
+        }
+
+        var match = true, name, matches;
+        for (var i = 0, token; token = this.tokens[i]; i++)
+        {
+            name = token[0],matches = token[1];
+            if (!Selector.assertions[name](element, matches))
+            {
+                match = false;
+                break;
+            }
+        }
+
+        return match;
+    },
+
+    toString: function()
+    {
+        return this.expression;
+    },
+
+    inspect: function()
+    {
+        return "#<Selector:" + this.expression.inspect() + ">";
+    }
+});
+
+Object.extend(Selector, {
+    _cache: { },
+
+    xpath: {
+        descendant:   "//*",
+        child:        "/*",
+        adjacent:     "/following-sibling::*[1]",
+        laterSibling: '/following-sibling::*',
+        tagName:      function(m)
+        {
+            if (m[1] == '*') return '';
+            return "[local-name()='" + m[1].toLowerCase() +
+                   "' or local-name()='" + m[1].toUpperCase() + "']";
+        },
+        className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+        id:           "[@id='#{1}']",
+        attrPresence: function(m)
+        {
+            m[1] = m[1].toLowerCase();
+            return new Template("[@#{1}]").evaluate(m);
+        },
+        attr: function(m)
+        {
+            m[1] = m[1].toLowerCase();
+            m[3] = m[5] || m[6];
+            return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+        },
+        pseudo: function(m)
+        {
+            var h = Selector.xpath.pseudos[m[1]];
+            if (!h) return '';
+            if (Object.isFunction(h)) return h(m);
+            return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+        },
+        operators: {
+            '=':  "[@#{1}='#{3}']",
+            '!=': "[@#{1}!='#{3}']",
+            '^=': "[starts-with(@#{1}, '#{3}')]",
+            '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+            '*=': "[contains(@#{1}, '#{3}')]",
+            '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+            '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+        },
+        pseudos: {
+            'first-child': '[not(preceding-sibling::*)]',
+            'last-child':  '[not(following-sibling::*)]',
+            'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
+            'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+            'checked':     "[@checked]",
+            'disabled':    "[@disabled]",
+            'enabled':     "[not(@disabled)]",
+            'not': function(m)
+            {
+                var e = m[6], p = Selector.patterns,
+                        x = Selector.xpath, le, v;
+
+                var exclusion = [];
+                while (e && le != e && (/\S/).test(e))
+                {
+                    le = e;
+                    for (var i in p)
+                    {
+                        if (m = e.match(p[i]))
+                        {
+                            v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+                            exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+                            e = e.replace(m[0], '');
+                            break;
+                        }
+                    }
+                }
+                return "[not(" + exclusion.join(" and ") + ")]";
+            },
+            'nth-child':      function(m)
+            {
+                return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+            },
+            'nth-last-child': function(m)
+            {
+                return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+            },
+            'nth-of-type':    function(m)
+            {
+                return Selector.xpath.pseudos.nth("position() ", m);
+            },
+            'nth-last-of-type': function(m)
+            {
+                return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+            },
+            'first-of-type':  function(m)
+            {
+                m[6] = "1";
+                return Selector.xpath.pseudos['nth-of-type'](m);
+            },
+            'last-of-type':   function(m)
+            {
+                m[6] = "1";
+                return Selector.xpath.pseudos['nth-last-of-type'](m);
+            },
+            'only-of-type':   function(m)
+            {
+                var p = Selector.xpath.pseudos;
+                return p['first-of-type'](m) + p['last-of-type'](m);
+            },
+            nth: function(fragment, m)
+            {
+                var mm, formula = m[6], predicate;
+                if (formula == 'even') formula = '2n+0';
+                if (formula == 'odd')  formula = '2n+1';
+                if (mm = formula.match(/^(\d+)$/)) // digit only
+                    return '[' + fragment + "= " + mm[1] + ']';
+                if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/))
+                { // an+b
+                    if (mm[1] == "-") mm[1] = -1;
+                    var a = mm[1] ? Number(mm[1]) : 1;
+                    var b = mm[2] ? Number(mm[2]) : 0;
+                    predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+                                "((#{fragment} - #{b}) div #{a} >= 0)]";
+                    return new Template(predicate).evaluate({
+                        fragment: fragment, a: a, b: b });
+                }
+            }
+        }
+    },
+
+    criteria: {
+        tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
+        className:    'n = h.className(n, r, "#{1}", c); c = false;',
+        id:           'n = h.id(n, r, "#{1}", c);        c = false;',
+        attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
+        attr: function(m)
+        {
+            m[3] = (m[5] || m[6]);
+            return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
+        },
+        pseudo: function(m)
+        {
+            if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+            return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+        },
+        descendant:   'c = "descendant";',
+        child:        'c = "child";',
+        adjacent:     'c = "adjacent";',
+        laterSibling: 'c = "laterSibling";'
+    },
+
+    patterns: {
+        // combinators must be listed first
+        // (and descendant needs to be last combinator)
+        laterSibling: /^\s*~\s*/,
+        child:        /^\s*>\s*/,
+        adjacent:     /^\s*\+\s*/,
+        descendant:   /^\s/,
+
+        // selectors follow
+        tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
+        id:           /^#([\w\-\*]+)(\b|$)/,
+        className:    /^\.([\w\-\*]+)(\b|$)/,
+        pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
+        attrPresence: /^\[([\w]+)\]/,
+        attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+    },
+
+    // for Selector.match and Element#match
+    assertions: {
+        tagName: function(element, matches)
+        {
+            return matches[1].toUpperCase() == element.tagName.toUpperCase();
+        },
+
+        className: function(element, matches)
+        {
+            return Element.hasClassName(element, matches[1]);
+        },
+
+        id: function(element, matches)
+        {
+            return element.id === matches[1];
+        },
+
+        attrPresence: function(element, matches)
+        {
+            return Element.hasAttribute(element, matches[1]);
+        },
+
+        attr: function(element, matches)
+        {
+            var nodeValue = Element.readAttribute(element, matches[1]);
+            return Selector.operators[matches[2]](nodeValue, matches[3]);
+        }
+    },
+
+    handlers: {
+        // UTILITY FUNCTIONS
+        // joins two collections
+        concat: function(a, b)
+        {
+            for (var i = 0, node; node = b[i]; i++)
+                a.push(node);
+            return a;
+        },
+
+        // marks an array of nodes for counting
+        mark: function(nodes)
+        {
+            for (var i = 0, node; node = nodes[i]; i++)
+                node._counted = true;
+            return nodes;
+        },
+
+        unmark: function(nodes)
+        {
+            for (var i = 0, node; node = nodes[i]; i++)
+                node._counted = undefined;
+            return nodes;
+        },
+
+        // mark each child node with its position (for nth calls)
+        // "ofType" flag indicates whether we're indexing for nth-of-type
+        // rather than nth-child
+        index: function(parentNode, reverse, ofType)
+        {
+            parentNode._counted = true;
+            if (reverse)
+            {
+                for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--)
+                {
+                    var node = nodes[i];
+                    if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+                }
+            }
+            else
+            {
+                for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+                    if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+            }
+        },
+
+        // filters out duplicates and extends all nodes
+        unique: function(nodes)
+        {
+            if (nodes.length == 0) return nodes;
+            var results = [], n;
+            for (var i = 0, l = nodes.length; i < l; i++)
+                if (!(n = nodes[i])._counted)
+                {
+                    n._counted = true;
+                    results.push(Element.extend(n));
+                }
+            return Selector.handlers.unmark(results);
+        },
+
+        // COMBINATOR FUNCTIONS
+        descendant: function(nodes)
+        {
+            var h = Selector.handlers;
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                h.concat(results, node.getElementsByTagName('*'));
+            return results;
+        },
+
+        child: function(nodes)
+        {
+            var h = Selector.handlers;
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+            {
+                for (var j = 0, child; child = node.childNodes[j]; j++)
+                    if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+            }
+            return results;
+        },
+
+        adjacent: function(nodes)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+            {
+                var next = this.nextElementSibling(node);
+                if (next) results.push(next);
+            }
+            return results;
+        },
+
+        laterSibling: function(nodes)
+        {
+            var h = Selector.handlers;
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                h.concat(results, Element.nextSiblings(node));
+            return results;
+        },
+
+        nextElementSibling: function(node)
+        {
+            while (node = node.nextSibling)
+                if (node.nodeType == 1) return node;
+            return null;
+        },
+
+        previousElementSibling: function(node)
+        {
+            while (node = node.previousSibling)
+                if (node.nodeType == 1) return node;
+            return null;
+        },
+
+        // TOKEN FUNCTIONS
+        tagName: function(nodes, root, tagName, combinator)
+        {
+            tagName = tagName.toUpperCase();
+            var results = [], h = Selector.handlers;
+            if (nodes)
+            {
+                if (combinator)
+                {
+                    // fastlane for ordinary descendant combinators
+                    if (combinator == "descendant")
+                    {
+                        for (var i = 0, node; node = nodes[i]; i++)
+                            h.concat(results, node.getElementsByTagName(tagName));
+                        return results;
+                    }
+                    else nodes = this[combinator](nodes);
+                    if (tagName == "*") return nodes;
+                }
+                for (var i = 0, node; node = nodes[i]; i++)
+                    if (node.tagName.toUpperCase() == tagName) results.push(node);
+                return results;
+            }
+            else return root.getElementsByTagName(tagName);
+        },
+
+        id: function(nodes, root, id, combinator)
+        {
+            var targetNode = $(id), h = Selector.handlers;
+            if (!targetNode) return [];
+            if (!nodes && root == document) return [targetNode];
+            if (nodes)
+            {
+                if (combinator)
+                {
+                    if (combinator == 'child')
+                    {
+                        for (var i = 0, node; node = nodes[i]; i++)
+                            if (targetNode.parentNode == node) return [targetNode];
+                    }
+                    else if (combinator == 'descendant')
+                    {
+                        for (var i = 0, node; node = nodes[i]; i++)
+                            if (Element.descendantOf(targetNode, node)) return [targetNode];
+                    }
+                    else if (combinator == 'adjacent')
+                    {
+                        for (var i = 0, node; node = nodes[i]; i++)
+                            if (Selector.handlers.previousElementSibling(targetNode) == node)
+                                return [targetNode];
+                    }
+                    else nodes = h[combinator](nodes);
+                }
+                for (var i = 0, node; node = nodes[i]; i++)
+                    if (node == targetNode) return [targetNode];
+                return [];
+            }
+            return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+        },
+
+        className: function(nodes, root, className, combinator)
+        {
+            if (nodes && combinator) nodes = this[combinator](nodes);
+            return Selector.handlers.byClassName(nodes, root, className);
+        },
+
+        byClassName: function(nodes, root, className)
+        {
+            if (!nodes) nodes = Selector.handlers.descendant([root]);
+            var needle = ' ' + className + ' ';
+            for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++)
+            {
+                nodeClassName = node.className;
+                if (nodeClassName.length == 0) continue;
+                if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+                    results.push(node);
+            }
+            return results;
+        },
+
+        attrPresence: function(nodes, root, attr)
+        {
+            if (!nodes) nodes = root.getElementsByTagName("*");
+            var results = [];
+            for (var i = 0, node; node = nodes[i]; i++)
+                if (Element.hasAttribute(node, attr)) results.push(node);
+            return results;
+        },
+
+        attr: function(nodes, root, attr, value, operator)
+        {
+            if (!nodes) nodes = root.getElementsByTagName("*");
+            var handler = Selector.operators[operator], results = [];
+            for (var i = 0, node; node = nodes[i]; i++)
+            {
+                var nodeValue = Element.readAttribute(node, attr);
+                if (nodeValue === null) continue;
+                if (handler(nodeValue, value)) results.push(node);
+            }
+            return results;
+        },
+
+        pseudo: function(nodes, name, value, root, combinator)
+        {
+            if (nodes && combinator) nodes = this[combinator](nodes);
+            if (!nodes) nodes = root.getElementsByTagName("*");
+            return Selector.pseudos[name](nodes, value, root);
+        }
+    },
+
+    pseudos: {
+        'first-child': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+            {
+                if (Selector.handlers.previousElementSibling(node)) continue;
+                results.push(node);
+            }
+            return results;
+        },
+        'last-child': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+            {
+                if (Selector.handlers.nextElementSibling(node)) continue;
+                results.push(node);
+            }
+            return results;
+        },
+        'only-child': function(nodes, value, root)
+        {
+            var h = Selector.handlers;
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+                    results.push(node);
+            return results;
+        },
+        'nth-child':        function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, formula, root);
+        },
+        'nth-last-child':   function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, formula, root, true);
+        },
+        'nth-of-type':      function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, formula, root, false, true);
+        },
+        'nth-last-of-type': function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, formula, root, true, true);
+        },
+        'first-of-type':    function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, "1", root, false, true);
+        },
+        'last-of-type':     function(nodes, formula, root)
+        {
+            return Selector.pseudos.nth(nodes, "1", root, true, true);
+        },
+        'only-of-type':     function(nodes, formula, root)
+        {
+            var p = Selector.pseudos;
+            return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+        },
+
+        // handles the an+b logic
+        getIndices: function(a, b, total)
+        {
+            if (a == 0) return b > 0 ? [b] : [];
+            return $R(1, total).inject([], function(memo, i)
+            {
+                if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+                return memo;
+            });
+        },
+
+        // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+        nth: function(nodes, formula, root, reverse, ofType)
+        {
+            if (nodes.length == 0) return [];
+            if (formula == 'even') formula = '2n+0';
+            if (formula == 'odd')  formula = '2n+1';
+            var h = Selector.handlers, results = [], indexed = [], m;
+            h.mark(nodes);
+            for (var i = 0, node; node = nodes[i]; i++)
+            {
+                if (!node.parentNode._counted)
+                {
+                    h.index(node.parentNode, reverse, ofType);
+                    indexed.push(node.parentNode);
+                }
+            }
+            if (formula.match(/^\d+$/))
+            { // just a number
+                formula = Number(formula);
+                for (var i = 0, node; node = nodes[i]; i++)
+                    if (node.nodeIndex == formula) results.push(node);
+            }
+            else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/))
+            { // an+b
+                if (m[1] == "-") m[1] = -1;
+                var a = m[1] ? Number(m[1]) : 1;
+                var b = m[2] ? Number(m[2]) : 0;
+                var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+                for (var i = 0, node, l = indices.length; node = nodes[i]; i++)
+                {
+                    for (var j = 0; j < l; j++)
+                        if (node.nodeIndex == indices[j]) results.push(node);
+                }
+            }
+            h.unmark(nodes);
+            h.unmark(indexed);
+            return results;
+        },
+
+        'empty': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+            {
+                // IE treats comments as element nodes
+                if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+                results.push(node);
+            }
+            return results;
+        },
+
+        'not': function(nodes, selector, root)
+        {
+            var h = Selector.handlers, selectorType, m;
+            var exclusions = new Selector(selector).findElements(root);
+            h.mark(exclusions);
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                if (!node._counted) results.push(node);
+            h.unmark(exclusions);
+            return results;
+        },
+
+        'enabled': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                if (!node.disabled) results.push(node);
+            return results;
+        },
+
+        'disabled': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                if (node.disabled) results.push(node);
+            return results;
+        },
+
+        'checked': function(nodes, value, root)
+        {
+            for (var i = 0, results = [], node; node = nodes[i]; i++)
+                if (node.checked) results.push(node);
+            return results;
+        }
+    },
+
+    operators: {
+        '=':  function(nv, v)
+        {
+            return nv == v;
+        },
+        '!=': function(nv, v)
+        {
+            return nv != v;
+        },
+        '^=': function(nv, v)
+        {
+            return nv.startsWith(v);
+        },
+        '$=': function(nv, v)
+        {
+            return nv.endsWith(v);
+        },
+        '*=': function(nv, v)
+        {
+            return nv.include(v);
+        },
+        '~=': function(nv, v)
+        {
+            return (' ' + nv + ' ').include(' ' + v + ' ');
+        },
+        '|=': function(nv, v)
+        {
+            return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-');
+        }
+    },
+
+    matchElements: function(elements, expression)
+    {
+        var matches = new Selector(expression).findElements(), h = Selector.handlers;
+        h.mark(matches);
+        for (var i = 0, results = [], element; element = elements[i]; i++)
+            if (element._counted) results.push(element);
+        h.unmark(matches);
+        return results;
+    },
+
+    findElement: function(elements, expression, index)
+    {
+        if (Object.isNumber(expression))
+        {
+            index = expression;
+            expression = false;
+        }
+        return Selector.matchElements(elements, expression || '*')[index || 0];
+    },
+
+    findChildElements: function(element, expressions)
+    {
+        var exprs = expressions.join(',');
+        expressions = [];
+        exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m)
+        {
+            expressions.push(m[1].strip());
+        });
+        var results = [], h = Selector.handlers;
+        for (var i = 0, l = expressions.length, selector; i < l; i++)
+        {
+            selector = new Selector(expressions[i].strip());
+            h.concat(results, selector.findElements(element));
+        }
+        return (l > 1) ? h.unique(results) : results;
+    }
+});
+
+if (Prototype.Browser.IE)
+{
+    // IE returns comment nodes on getElementsByTagName("*").
+    // Filter them out.
+    Selector.handlers.concat = function(a, b)
+    {
+        for (var i = 0, node; node = b[i]; i++)
+            if (node.tagName !== "!") a.push(node);
+        return a;
+    };
+}
+
+function $$()
+{
+    return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+    reset: function(form)
+    {
+        $(form).reset();
+        return form;
+    },
+
+    serializeElements: function(elements, options)
+    {
+        if (typeof options != 'object') options = { hash: !!options };
+        else if (Object.isUndefined(options.hash)) options.hash = true;
+        var key, value, submitted = false, submit = options.submit;
+
+        var data = elements.inject({ }, function(result, element)
+        {
+            if (!element.disabled && element.name)
+            {
+                key = element.name;
+                value = $(element).getValue();
+                if (value != null && (element.type != 'submit' || (!submitted &&
+                                                                   submit !== false && (!submit || key == submit) && (submitted = true))))
+                {
+                    if (key in result)
+                    {
+                        // a key is already present; construct an array of values
+                        if (!Object.isArray(result[key])) result[key] = [result[key]];
+                        result[key].push(value);
+                    }
+                    else result[key] = value;
+                }
+            }
+            return result;
+        });
+
+        return options.hash ? data : Object.toQueryString(data);
+    }
+};
+
+Form.Methods = {
+    serialize: function(form, options)
+    {
+        return Form.serializeElements(Form.getElements(form), options);
+    },
+
+    getElements: function(form)
+    {
+        return $A($(form).getElementsByTagName('*')).inject([],
+                function(elements, child)
+                {
+                    if (Form.Element.Serializers[child.tagName.toLowerCase()])
+                        elements.push(Element.extend(child));
+                    return elements;
+                }
+                );
+    },
+
+    getInputs: function(form, typeName, name)
+    {
+        form = $(form);
+        var inputs = form.getElementsByTagName('input');
+
+        if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+        for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++)
+        {
+            var input = inputs[i];
+            if ((typeName && input.type != typeName) || (name && input.name != name))
+                continue;
+            matchingInputs.push(Element.extend(input));
+        }
+
+        return matchingInputs;
+    },
+
+    disable: function(form)
+    {
+        form = $(form);
+        Form.getElements(form).invoke('disable');
+        return form;
+    },
+
+    enable: function(form)
+    {
+        form = $(form);
+        Form.getElements(form).invoke('enable');
+        return form;
+    },
+
+    findFirstElement: function(form)
+    {
+        var elements = $(form).getElements().findAll(function(element)
+        {
+            return 'hidden' != element.type && !element.disabled;
+        });
+        var firstByIndex = elements.findAll(function(element)
+        {
+            return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+        }).sortBy(function(element)
+        {
+            return element.tabIndex
+        }).first();
+
+        return firstByIndex ? firstByIndex : elements.find(function(element)
+        {
+            return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+        });
+    },
+
+    focusFirstElement: function(form)
+    {
+        form = $(form);
+        form.findFirstElement().activate();
+        return form;
+    },
+
+    request: function(form, options)
+    {
+        form = $(form),options = Object.clone(options || { });
+
+        var params = options.parameters, action = form.readAttribute('action') || '';
+        if (action.blank()) action = window.location.href;
+        options.parameters = form.serialize(true);
+
+        if (params)
+        {
+            if (Object.isString(params)) params = params.toQueryParams();
+            Object.extend(options.parameters, params);
+        }
+
+        if (form.hasAttribute('method') && !options.method)
+            options.method = form.method;
+
+        return new Ajax.Request(action, options);
+    }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+    focus: function(element)
+    {
+        $(element).focus();
+        return element;
+    },
+
+    select: function(element)
+    {
+        $(element).select();
+        return element;
+    }
+};
+
+Form.Element.Methods = {
+    serialize: function(element)
+    {
+        element = $(element);
+        if (!element.disabled && element.name)
+        {
+            var value = element.getValue();
+            if (value != undefined)
+            {
+                var pair = { };
+                pair[element.name] = value;
+                return Object.toQueryString(pair);
+            }
+        }
+        return '';
+    },
+
+    getValue: function(element)
+    {
+        element = $(element);
+        var method = element.tagName.toLowerCase();
+        return Form.Element.Serializers[method](element);
+    },
+
+    setValue: function(element, value)
+    {
+        element = $(element);
+        var method = element.tagName.toLowerCase();
+        Form.Element.Serializers[method](element, value);
+        return element;
+    },
+
+    clear: function(element)
+    {
+        $(element).value = '';
+        return element;
+    },
+
+    present: function(element)
+    {
+        return $(element).value != '';
+    },
+
+    activate: function(element)
+    {
+        element = $(element);
+        try
+        {
+            element.focus();
+            if (element.select && (element.tagName.toLowerCase() != 'input' ||
+                                   !['button', 'reset', 'submit'].include(element.type)))
+                element.select();
+        }
+        catch (e)
+        {
+        }
+        return element;
+    },
+
+    disable: function(element)
+    {
+        element = $(element);
+        element.blur();
+        element.disabled = true;
+        return element;
+    },
+
+    enable: function(element)
+    {
+        element = $(element);
+        element.disabled = false;
+        return element;
+    }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+    input: function(element, value)
+    {
+        switch (element.type.toLowerCase())
+                {
+            case 'checkbox':
+            case 'radio':
+                return Form.Element.Serializers.inputSelector(element, value);
+            default:
+                return Form.Element.Serializers.textarea(element, value);
+        }
+    },
+
+    inputSelector: function(element, value)
+    {
+        if (Object.isUndefined(value)) return element.checked ? element.value : null;
+        else element.checked = !!value;
+    },
+
+    textarea: function(element, value)
+    {
+        if (Object.isUndefined(value)) return element.value;
+        else element.value = value;
+    },
+
+    select: function(element, index)
+    {
+        if (Object.isUndefined(index))
+            return this[element.type == 'select-one' ?
+                        'selectOne' : 'selectMany'](element);
+        else
+        {
+            var opt, value, single = !Object.isArray(index);
+            for (var i = 0, length = element.length; i < length; i++)
+            {
+                opt = element.options[i];
+                value = this.optionValue(opt);
+                if (single)
+                {
+                    if (value == index)
+                    {
+                        opt.selected = true;
+                        return;
+                    }
+                }
+                else opt.selected = index.include(value);
+            }
+        }
+    },
+
+    selectOne: function(element)
+    {
+        var index = element.selectedIndex;
+        return index >= 0 ? this.optionValue(element.options[index]) : null;
+    },
+
+    selectMany: function(element)
+    {
+        var values, length = element.length;
+        if (!length) return null;
+
+        for (var i = 0, values = []; i < length; i++)
+        {
+            var opt = element.options[i];
+            if (opt.selected) values.push(this.optionValue(opt));
+        }
+        return values;
+    },
+
+    optionValue: function(opt)
+    {
+        // extend element because hasAttribute may not be native
+        return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+    }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+    initialize: function($super, element, frequency, callback)
+    {
+        $super(callback, frequency);
+        this.element = $(element);
+        this.lastValue = this.getValue();
+    },
+
+    execute: function()
+    {
+        var value = this.getValue();
+        if (Object.isString(this.lastValue) && Object.isString(value) ?
+            this.lastValue != value : String(this.lastValue) != String(value))
+        {
+            this.callback(this.element, value);
+            this.lastValue = value;
+        }
+    }
+});
+
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
+    getValue: function()
+    {
+        return Form.Element.getValue(this.element);
+    }
+});
+
+Form.Observer = Class.create(Abstract.TimedObserver, {
+    getValue: function()
+    {
+        return Form.serialize(this.element);
+    }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = Class.create({
+    initialize: function(element, callback)
+    {
+        this.element = $(element);
+        this.callback = callback;
+
+        this.lastValue = this.getValue();
+        if (this.element.tagName.toLowerCase() == 'form')
+            this.registerFormCallbacks();
+        else
+            this.registerCallback(this.element);
+    },
+
+    onElementEvent: function()
+    {
+        var value = this.getValue();
+        if (this.lastValue != value)
+        {
+            this.callback(this.element, value);
+            this.lastValue = value;
+        }
+    },
+
+    registerFormCallbacks: function()
+    {
+        Form.getElements(this.element).each(this.registerCallback, this);
+    },
+
+    registerCallback: function(element)
+    {
+        if (element.type)
+        {
+            switch (element.type.toLowerCase())
+                    {
+                case 'checkbox':
+                case 'radio':
+                    Event.observe(element, 'click', this.onElementEvent.bind(this));
+                    break;
+                default:
+                    Event.observe(element, 'change', this.onElementEvent.bind(this));
+                    break;
+            }
+        }
+    }
+});
+
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
+    getValue: function()
+    {
+        return Form.Element.getValue(this.element);
+    }
+});
+
+Form.EventObserver = Class.create(Abstract.EventObserver, {
+    getValue: function()
+    {
+        return Form.serialize(this.element);
+    }
+});
+if (!window.Event) var Event = { };
+
+Object.extend(Event, {
+    KEY_BACKSPACE: 8,
+    KEY_TAB:       9,
+    KEY_RETURN:   13,
+    KEY_ESC:      27,
+    KEY_LEFT:     37,
+    KEY_UP:       38,
+    KEY_RIGHT:    39,
+    KEY_DOWN:     40,
+    KEY_DELETE:   46,
+    KEY_HOME:     36,
+    KEY_END:      35,
+    KEY_PAGEUP:   33,
+    KEY_PAGEDOWN: 34,
+    KEY_INSERT:   45,
+
+    cache: { },
+
+    relatedTarget: function(event)
+    {
+        var element;
+        switch (event.type)
+                {
+            case 'mouseover': element = event.fromElement; break;
+            case 'mouseout':  element = event.toElement;   break;
+            default: return null;
+        }
+        return Element.extend(element);
+    }
+});
+
+Event.Methods = (function()
+{
+    var isButton;
+
+    if (Prototype.Browser.IE)
+    {
+        var buttonMap = { 0: 1, 1: 4, 2: 2 };
+        isButton = function(event, code)
+        {
+            return event.button == buttonMap[code];
+        };
+
+    }
+    else if (Prototype.Browser.WebKit)
+    {
+        isButton = function(event, code)
+        {
+            switch (code)
+                    {
+                case 0: return event.which == 1 && !event.metaKey;
+                case 1: return event.which == 1 && event.metaKey;
+                default: return false;
+            }
+        };
+
+    }
+    else
+    {
+        isButton = function(event, code)
+        {
+            return event.which ? (event.which === code + 1) : (event.button === code);
+        };
+    }
+
+    return {
+        isLeftClick:   function(event)
+        {
+            return isButton(event, 0)
+        },
+        isMiddleClick: function(event)
+        {
+            return isButton(event, 1)
+        },
+        isRightClick:  function(event)
+        {
+            return isButton(event, 2)
+        },
+
+        element: function(event)
+        {
+            var node = Event.extend(event).target;
+            return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
+        },
+
+        findElement: function(event, expression)
+        {
+            var element = Event.element(event);
+            if (!expression) return element;
+            var elements = [element].concat(element.ancestors());
+            return Selector.findElement(elements, expression, 0);
+        },
+
+        pointer: function(event)
+        {
+            return {
+                x: event.pageX || (event.clientX +
+                                   (document.documentElement.scrollLeft || document.body.scrollLeft)),
+                y: event.pageY || (event.clientY +
+                                   (document.documentElement.scrollTop || document.body.scrollTop))
+            };
+        },
+
+        pointerX: function(event)
+        {
+            return Event.pointer(event).x
+        },
+        pointerY: function(event)
+        {
+            return Event.pointer(event).y
+        },
+
+        stop: function(event)
+        {
+            Event.extend(event);
+            event.preventDefault();
+            event.stopPropagation();
+            event.stopped = true;
+        }
+    };
+})();
+
+Event.extend = (function()
+{
+    var methods = Object.keys(Event.Methods).inject({ }, function(m, name)
+    {
+        m[name] = Event.Methods[name].methodize();
+        return m;
+    });
+
+    if (Prototype.Browser.IE)
+    {
+        Object.extend(methods, {
+            stopPropagation: function()
+            {
+                this.cancelBubble = true
+            },
+            preventDefault:  function()
+            {
+                this.returnValue = false
+            },
+            inspect: function()
+            {
+                return "[object Event]"
+            }
+        });
+
+        return function(event)
+        {
+            if (!event) return false;
+            if (event._extendedByPrototype) return event;
+
+            event._extendedByPrototype = Prototype.emptyFunction;
+            var pointer = Event.pointer(event);
+            Object.extend(event, {
+                target: event.srcElement,
+                relatedTarget: Event.relatedTarget(event),
+                pageX:  pointer.x,
+                pageY:  pointer.y
+            });
+            return Object.extend(event, methods);
+        };
+
+    }
+    else
+    {
+        Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+        Object.extend(Event.prototype, methods);
+        return Prototype.K;
+    }
+})();
+
+Object.extend(Event, (function()
+{
+    var cache = Event.cache;
+
+    function getEventID(element)
+    {
+        if (element._eventID) return element._eventID;
+        arguments.callee.id = arguments.callee.id || 1;
+        return element._eventID = ++arguments.callee.id;
+    }
+
+    function getDOMEventName(eventName)
+    {
+        if (eventName && eventName.include(':')) return "dataavailable";
+        return eventName;
+    }
+
+    function getCacheForID(id)
+    {
+        return cache[id] = cache[id] || { };
+    }
+
+    function getWrappersForEventName(id, eventName)
+    {
+        var c = getCacheForID(id);
+        return c[eventName] = c[eventName] || [];
+    }
+
+    function createWrapper(element, eventName, handler)
+    {
+        var id = getEventID(element);
+        var c = getWrappersForEventName(id, eventName);
+        if (c.pluck("handler").include(handler)) return false;
+
+        var wrapper = function(event)
+        {
+            if (!Event || !Event.extend ||
+                (event.eventName && event.eventName != eventName))
+                return false;
+
+            Event.extend(event);
+            handler.call(element, event)
+        };
+
+        wrapper.handler = handler;
+        c.push(wrapper);
+        return wrapper;
+    }
+
+    function findWrapper(id, eventName, handler)
+    {
+        var c = getWrappersForEventName(id, eventName);
+        return c.find(function(wrapper)
+        {
+            return wrapper.handler == handler
+        });
+    }
+
+    function destroyWrapper(id, eventName, handler)
+    {
+        var c = getCacheForID(id);
+        if (!c[eventName]) return false;
+        c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+    }
+
+    function destroyCache()
+    {
+        for (var id in cache)
+            for (var eventName in cache[id])
+                cache[id][eventName] = null;
+    }
+
+    if (window.attachEvent)
+    {
+        window.attachEvent("onunload", destroyCache);
+    }
+
+    return {
+        observe: function(element, eventName, handler)
+        {
+            element = $(element);
+            var name = getDOMEventName(eventName);
+
+            var wrapper = createWrapper(element, eventName, handler);
+            if (!wrapper) return element;
+
+            if (element.addEventListener)
+            {
+                element.addEventListener(name, wrapper, false);
+            }
+            else
+            {
+                element.attachEvent("on" + name, wrapper);
+            }
+
+            return element;
+        },
+
+        stopObserving: function(element, eventName, handler)
+        {
+            element = $(element);
+            var id = getEventID(element), name = getDOMEventName(eventName);
+
+            if (!handler && eventName)
+            {
+                getWrappersForEventName(id, eventName).each(function(wrapper)
+                {
+                    element.stopObserving(eventName, wrapper.handler);
+                });
+                return element;
+
+            }
+            else if (!eventName)
+            {
+                Object.keys(getCacheForID(id)).each(function(eventName)
+                {
+                    element.stopObserving(eventName);
+                });
+                return element;
+            }
+
+            var wrapper = findWrapper(id, eventName, handler);
+            if (!wrapper) return element;
+
+            if (element.removeEventListener)
+            {
+                element.removeEventListener(name, wrapper, false);
+            }
+            else
+            {
+                element.detachEvent("on" + name, wrapper);
+            }
+
+            destroyWrapper(id, eventName, handler);
+
+            return element;
+        },
+
+        fire: function(element, eventName, memo)
+        {
+            element = $(element);
+            if (element == document && document.createEvent && !element.dispatchEvent)
+                element = document.documentElement;
+
+            if (document.createEvent)
+            {
+                var event = document.createEvent("HTMLEvents");
+                event.initEvent("dataavailable", true, true);
+            }
+            else
+            {
+                var event = document.createEventObject();
+                event.eventType = "ondataavailable";
+            }
+
+            event.eventName = eventName;
+            event.memo = memo || { };
+
+            if (document.createEvent)
+            {
+                element.dispatchEvent(event);
+            }
+            else
+            {
+                element.fireEvent(event.eventType, event);
+            }
+
+            return Event.extend(event);
+        }
+    };
+})());
+
+Object.extend(Event, Event.Methods);
+
+Element.addMethods({
+    fire:          Event.fire,
+    observe:       Event.observe,
+    stopObserving: Event.stopObserving
+});
+
+Object.extend(document, {
+    fire:          Element.Methods.fire.methodize(),
+    observe:       Element.Methods.observe.methodize(),
+    stopObserving: Element.Methods.stopObserving.methodize()
+});
+
+(function()
+{
+    /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+Matthias Miller, Dean Edwards and John Resig. */
+
+    var timer, fired = false;
+
+    function fireContentLoadedEvent()
+    {
+        if (fired) return;
+        if (timer) window.clearInterval(timer);
+        document.fire("dom:loaded");
+        fired = true;
+    }
+
+    if (document.addEventListener)
+    {
+        // Note: patch from http://dev.rubyonrails.org/ticket/10532
+        if (Prototype.Browser.WebKit || navigator.userAgent.include('KHTML'))
+        {
+            timer = window.setInterval(function()
+            {
+                if (/loaded|complete/.test(document.readyState))
+                    fireContentLoadedEvent();
+            }, 0);
+
+            Event.observe(window, "load", fireContentLoadedEvent);
+
+        }
+        else
+        {
+            document.addEventListener("DOMContentLoaded",
+                    fireContentLoadedEvent, false);
+        }
+
+    }
+    else
+    {
+        document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
+        $("__onDOMContentLoaded").onreadystatechange = function()
+        {
+            if (this.readyState == "complete")
+            {
+                this.onreadystatechange = null;
+                fireContentLoadedEvent();
+            }
+        };
+    }
+})();
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+    Before: function(element, content)
+    {
+        return Element.insert(element, {before:content});
+    },
+
+    Top: function(element, content)
+    {
+        return Element.insert(element, {top:content});
+    },
+
+    Bottom: function(element, content)
+    {
+        return Element.insert(element, {bottom:content});
+    },
+
+    After: function(element, content)
+    {
+        return Element.insert(element, {after:content});
+    }
+};
+
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+// This should be moved to script.aculo.us; notice the deprecated methods
+// further below, that map to the newer Element methods.
+var Position = {
+    // set to true if needed, warning: firefox performance problems
+    // NOT neeeded for page scrolling, only if draggable contained in
+    // scrollable elements
+    includeScrollOffsets: false,
+
+    // must be called before calling withinIncludingScrolloffset, every time the
+    // page is scrolled
+    prepare: function()
+    {
+        this.deltaX = window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+        this.deltaY = window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+    },
+
+    // caches x/y coordinate pair to use with overlap
+    within: function(element, x, y)
+    {
+        if (this.includeScrollOffsets)
+            return this.withinIncludingScrolloffsets(element, x, y);
+        this.xcomp = x;
+        this.ycomp = y;
+        this.offset = Element.cumulativeOffset(element);
+
+        return (y >= this.offset[1] &&
+                y < this.offset[1] + element.offsetHeight &&
+                x >= this.offset[0] &&
+                x < this.offset[0] + element.offsetWidth);
+    },
+
+    withinIncludingScrolloffsets: function(element, x, y)
+    {
+        var offsetcache = Element.cumulativeScrollOffset(element);
+
+        this.xcomp = x + offsetcache[0] - this.deltaX;
+        this.ycomp = y + offsetcache[1] - this.deltaY;
+        this.offset = Element.cumulativeOffset(element);
+
+        return (this.ycomp >= this.offset[1] &&
+                this.ycomp < this.offset[1] + element.offsetHeight &&
+                this.xcomp >= this.offset[0] &&
+                this.xcomp < this.offset[0] + element.offsetWidth);
+    },
+
+    // within must be called directly before
+    overlap: function(mode, element)
+    {
+        if (!mode) return 0;
+        if (mode == 'vertical')
+            return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+                   element.offsetHeight;
+        if (mode == 'horizontal')
+            return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+                   element.offsetWidth;
+    },
+
+    // Deprecation layer -- use newer Element methods now (1.5.2).
+
+    cumulativeOffset: Element.Methods.cumulativeOffset,
+
+    positionedOffset: Element.Methods.positionedOffset,
+
+    absolutize: function(element)
+    {
+        Position.prepare();
+        return Element.absolutize(element);
+    },
+
+    relativize: function(element)
+    {
+        Position.prepare();
+        return Element.relativize(element);
+    },
+
+    realOffset: Element.Methods.cumulativeScrollOffset,
+
+    offsetParent: Element.Methods.getOffsetParent,
+
+    page: Element.Methods.viewportOffset,
+
+    clone: function(source, target, options)
+    {
+        options = options || { };
+        return Element.clonePosition(target, source, options);
+    }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods)
+{
+    function iter(name)
+    {
+        return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+    }
+
+    instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+                                             function(element, className)
+                                             {
+                                                 className = className.toString().strip();
+                                                 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+                                                 return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+                                             } : function(element, className)
+    {
+        className = className.toString().strip();
+        var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+        if (!classNames && !className) return elements;
+
+        var nodes = $(element).getElementsByTagName('*');
+        className = ' ' + className + ' ';
+
+        for (var i = 0, child, cn; child = nodes[i]; i++)
+        {
+            if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+                                                                          (classNames && classNames.all(function(name)
+                                                                          {
+                                                                              return !name.toString().blank() && cn.include(' ' + name + ' ');
+                                                                          }))))
+                elements.push(Element.extend(child));
+        }
+        return elements;
+    };
+
+    return function(className, parentElement)
+    {
+        return $(parentElement || document.body).getElementsByClassName(className);
+    };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+    initialize: function(element)
+    {
+        this.element = $(element);
+    },
+
+    _each: function(iterator)
+    {
+        this.element.className.split(/\s+/).select(function(name)
+        {
+            return name.length > 0;
+        })._each(iterator);
+    },
+
+    set: function(className)
+    {
+        this.element.className = className;
+    },
+
+    add: function(classNameToAdd)
+    {
+        if (this.include(classNameToAdd)) return;
+        this.set($A(this).concat(classNameToAdd).join(' '));
+    },
+
+    remove: function(classNameToRemove)
+    {
+        if (!this.include(classNameToRemove)) return;
+        this.set($A(this).without(classNameToRemove).join(' '));
+    },
+
+    toString: function()
+    {
+        return $A(this).join(' ');
+    }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
+
+Element.addMethods();
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js
new file mode 100644
index 0000000..46eeb36
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js
@@ -0,0 +1,62 @@
+// script.aculo.us scriptaculous.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// 
+// 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.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+    Version: '1.8.0',
+    require: function(libraryName)
+    {
+        // inserting via DOM fails in Safari 2.0, so brute force approach
+        document.write('<script type="text/javascript" src="' + libraryName + '"><\/script>');
+    },
+    REQUIRED_PROTOTYPE: '1.6.0',
+    load: function()
+    {
+        function convertVersionString(versionString)
+        {
+            var r = versionString.split('.');
+            return parseInt(r[0]) * 100000 + parseInt(r[1]) * 1000 + parseInt(r[2]);
+        }
+
+        if ((typeof Prototype == 'undefined') || (typeof Element == 'undefined') || (typeof Element.Methods == 'undefined') || (convertVersionString(Prototype.Version) < convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
+            throw("script.aculo.us requires the Prototype JavaScript framework >= " + Scriptaculous.REQUIRED_PROTOTYPE);
+
+// Tapestry turns off this mechanism, and replaces it with RenderSupport.addScriptLink().
+        //        $A(document.getElementsByTagName("script")).findAll(function(s)
+        //        {
+        //            return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+        //        }).each(function(s)
+        //        {
+        //            var path = s.src.replace(/scriptaculous\.js(\?.*)?$/, '');
+        //            var includes = s.src.match(/\?.*load=([a-z,]*)/);
+        //            (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
+        //                    function(include)
+        //                    {
+        //                        Scriptaculous.require(path + include + '.js')
+        //                    });
+        //        });
+    }
+}
+
+Scriptaculous.load();
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/slider.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/slider.js
new file mode 100644
index 0000000..9880716
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/slider.js
@@ -0,0 +1,334 @@
+// script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if (!Control) var Control = { };
+
+// options:
+//  axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+//  onChange(value)
+//  onSlide(value)
+Control.Slider = Class.create({
+    initialize: function(handle, track, options)
+    {
+        var slider = this;
+
+        if (Object.isArray(handle))
+        {
+            this.handles = handle.collect(function(e)
+            {
+                return $(e)
+            });
+        }
+        else
+        {
+            this.handles = [$(handle)];
+        }
+
+        this.track = $(track);
+        this.options = options || { };
+
+        this.axis = this.options.axis || 'horizontal';
+        this.increment = this.options.increment || 1;
+        this.step = parseInt(this.options.step || '1');
+        this.range = this.options.range || $R(0, 1);
+
+        this.value = 0; // assure backwards compat
+        this.values = this.handles.map(function()
+        {
+            return 0
+        });
+        this.spans = this.options.spans ? this.options.spans.map(function(s)
+        {
+            return $(s)
+        }) : false;
+        this.options.startSpan = $(this.options.startSpan || null);
+        this.options.endSpan = $(this.options.endSpan || null);
+
+        this.restricted = this.options.restricted || false;
+
+        this.maximum = this.options.maximum || this.range.end;
+        this.minimum = this.options.minimum || this.range.start;
+
+    // Will be used to align the handle onto the track, if necessary
+        this.alignX = parseInt(this.options.alignX || '0');
+        this.alignY = parseInt(this.options.alignY || '0');
+
+        this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+        this.handleLength = this.isVertical() ?
+                            (this.handles[0].offsetHeight != 0 ?
+                             this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/, "")) :
+                            (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
+                             this.handles[0].style.width.replace(/px$/, ""));
+
+        this.active = false;
+        this.dragging = false;
+        this.disabled = false;
+
+        if (this.options.disabled) this.setDisabled();
+
+    // Allowed values array
+        this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+        if (this.allowedValues)
+        {
+            this.minimum = this.allowedValues.min();
+            this.maximum = this.allowedValues.max();
+        }
+
+        this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+        this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+        this.eventMouseMove = this.update.bindAsEventListener(this);
+
+    // Initialize handles in reverse (make sure first handle is active)
+        this.handles.each(function(h, i)
+        {
+            i = slider.handles.length - 1 - i;
+            slider.setValue(parseFloat(
+                    (Object.isArray(slider.options.sliderValue) ?
+                     slider.options.sliderValue[i] : slider.options.sliderValue) ||
+                    slider.range.start), i);
+            h.makePositioned().observe("mousedown", slider.eventMouseDown);
+        });
+
+        this.track.observe("mousedown", this.eventMouseDown);
+        document.observe("mouseup", this.eventMouseUp);
+        document.observe("mousemove", this.eventMouseMove);
+
+        this.initialized = true;
+    },
+    dispose: function()
+    {
+        var slider = this;
+        Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+        Event.stopObserving(document, "mouseup", this.eventMouseUp);
+        Event.stopObserving(document, "mousemove", this.eventMouseMove);
+        this.handles.each(function(h)
+        {
+            Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+        });
+    },
+    setDisabled: function()
+    {
+        this.disabled = true;
+    },
+    setEnabled: function()
+    {
+        this.disabled = false;
+    },
+    getNearestValue: function(value)
+    {
+        if (this.allowedValues)
+        {
+            if (value >= this.allowedValues.max()) return(this.allowedValues.max());
+            if (value <= this.allowedValues.min()) return(this.allowedValues.min());
+
+            var offset = Math.abs(this.allowedValues[0] - value);
+            var newValue = this.allowedValues[0];
+            this.allowedValues.each(function(v)
+            {
+                var currentOffset = Math.abs(v - value);
+                if (currentOffset <= offset)
+                {
+                    newValue = v;
+                    offset = currentOffset;
+                }
+            });
+            return newValue;
+        }
+        if (value > this.range.end) return this.range.end;
+        if (value < this.range.start) return this.range.start;
+        return value;
+    },
+    setValue: function(sliderValue, handleIdx)
+    {
+        if (!this.active)
+        {
+            this.activeHandleIdx = handleIdx || 0;
+            this.activeHandle = this.handles[this.activeHandleIdx];
+            this.updateStyles();
+        }
+        handleIdx = handleIdx || this.activeHandleIdx || 0;
+        if (this.initialized && this.restricted)
+        {
+            if ((handleIdx > 0) && (sliderValue < this.values[handleIdx - 1]))
+                sliderValue = this.values[handleIdx - 1];
+            if ((handleIdx < (this.handles.length - 1)) && (sliderValue > this.values[handleIdx + 1]))
+                sliderValue = this.values[handleIdx + 1];
+        }
+        sliderValue = this.getNearestValue(sliderValue);
+        this.values[handleIdx] = sliderValue;
+        this.value = this.values[0]; // assure backwards compat
+
+        this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
+        this.translateToPx(sliderValue);
+
+        this.drawSpans();
+        if (!this.dragging || !this.event) this.updateFinished();
+    },
+    setValueBy: function(delta, handleIdx)
+    {
+        this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
+                handleIdx || this.activeHandleIdx || 0);
+    },
+    translateToPx: function(value)
+    {
+        return Math.round(
+                ((this.trackLength - this.handleLength) / (this.range.end - this.range.start)) *
+                (value - this.range.start)) + "px";
+    },
+    translateToValue: function(offset)
+    {
+        return ((offset / (this.trackLength - this.handleLength) *
+                 (this.range.end - this.range.start)) + this.range.start);
+    },
+    getRange: function(range)
+    {
+        var v = this.values.sortBy(Prototype.K);
+        range = range || 0;
+        return $R(v[range], v[range + 1]);
+    },
+    minimumOffset: function()
+    {
+        return(this.isVertical() ? this.alignY : this.alignX);
+    },
+    maximumOffset: function()
+    {
+        return(this.isVertical() ?
+               (this.track.offsetHeight != 0 ? this.track.offsetHeight :
+                this.track.style.height.replace(/px$/, "")) - this.alignY :
+               (this.track.offsetWidth != 0 ? this.track.offsetWidth :
+                this.track.style.width.replace(/px$/, "")) - this.alignX);
+    },
+    isVertical:  function()
+    {
+        return (this.axis == 'vertical');
+    },
+    drawSpans: function()
+    {
+        var slider = this;
+        if (this.spans)
+            $R(0, this.spans.length - 1).each(function(r)
+            {
+                slider.setSpan(slider.spans[r], slider.getRange(r))
+            });
+        if (this.options.startSpan)
+            this.setSpan(this.options.startSpan,
+                    $R(0, this.values.length > 1 ? this.getRange(0).min() : this.value));
+        if (this.options.endSpan)
+            this.setSpan(this.options.endSpan,
+                    $R(this.values.length > 1 ? this.getRange(this.spans.length - 1).max() : this.value, this.maximum));
+    },
+    setSpan: function(span, range)
+    {
+        if (this.isVertical())
+        {
+            span.style.top = this.translateToPx(range.start);
+            span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+        }
+        else
+        {
+            span.style.left = this.translateToPx(range.start);
+            span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+        }
+    },
+    updateStyles: function()
+    {
+        this.handles.each(function(h)
+        {
+            Element.removeClassName(h, 'selected')
+        });
+        Element.addClassName(this.activeHandle, 'selected');
+    },
+    startDrag: function(event)
+    {
+        if (Event.isLeftClick(event))
+        {
+            if (!this.disabled)
+            {
+                this.active = true;
+
+                var handle = Event.element(event);
+                var pointer = [Event.pointerX(event), Event.pointerY(event)];
+                var track = handle;
+                if (track == this.track)
+                {
+                    var offsets = Position.cumulativeOffset(this.track);
+                    this.event = event;
+                    this.setValue(this.translateToValue(
+                            (this.isVertical() ? pointer[1] - offsets[1] : pointer[0] - offsets[0]) - (this.handleLength / 2)
+                            ));
+                    var offsets = Position.cumulativeOffset(this.activeHandle);
+                    this.offsetX = (pointer[0] - offsets[0]);
+                    this.offsetY = (pointer[1] - offsets[1]);
+                }
+                else
+                {
+                    // find the handle (prevents issues with Safari)
+                    while ((this.handles.indexOf(handle) == -1) && handle.parentNode)
+                        handle = handle.parentNode;
+
+                    if (this.handles.indexOf(handle) != -1)
+                    {
+                        this.activeHandle = handle;
+                        this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+                        this.updateStyles();
+
+                        var offsets = Position.cumulativeOffset(this.activeHandle);
+                        this.offsetX = (pointer[0] - offsets[0]);
+                        this.offsetY = (pointer[1] - offsets[1]);
+                    }
+                }
+            }
+            Event.stop(event);
+        }
+    },
+    update: function(event)
+    {
+        if (this.active)
+        {
+            if (!this.dragging) this.dragging = true;
+            this.draw(event);
+            if (Prototype.Browser.WebKit) window.scrollBy(0, 0);
+            Event.stop(event);
+        }
+    },
+    draw: function(event)
+    {
+        var pointer = [Event.pointerX(event), Event.pointerY(event)];
+        var offsets = Position.cumulativeOffset(this.track);
+        pointer[0] -= this.offsetX + offsets[0];
+        pointer[1] -= this.offsetY + offsets[1];
+        this.event = event;
+        this.setValue(this.translateToValue(this.isVertical() ? pointer[1] : pointer[0]));
+        if (this.initialized && this.options.onSlide)
+            this.options.onSlide(this.values.length > 1 ? this.values : this.value, this);
+    },
+    endDrag: function(event)
+    {
+        if (this.active && this.dragging)
+        {
+            this.finishDrag(event, true);
+            Event.stop(event);
+        }
+        this.active = false;
+        this.dragging = false;
+    },
+    finishDrag: function(event, success)
+    {
+        this.active = false;
+        this.dragging = false;
+        this.updateFinished();
+    },
+    updateFinished: function()
+    {
+        if (this.initialized && this.options.onChange)
+            this.options.onChange(this.values.length > 1 ? this.values : this.value, this);
+        this.event = null;
+    }
+});
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/sound.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/sound.js
new file mode 100644
index 0000000..0b8fe71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/sound.js
@@ -0,0 +1,66 @@
+// script.aculo.us sound.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Based on code created by Jules Gravinese (http://www.webveteran.com/)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+Sound = {
+    tracks: {},
+    _enabled: true,
+    template:
+            new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
+    enable: function()
+    {
+        Sound._enabled = true;
+    },
+    disable: function()
+    {
+        Sound._enabled = false;
+    },
+    play: function(url)
+    {
+        if (!Sound._enabled) return;
+        var options = Object.extend({
+            track: 'global', url: url, replace: false
+        }, arguments[1] || {});
+
+        if (options.replace && this.tracks[options.track])
+        {
+            $R(0, this.tracks[options.track].id).each(function(id)
+            {
+                var sound = $('sound_' + options.track + '_' + id);
+                sound.Stop && sound.Stop();
+                sound.remove();
+            })
+            this.tracks[options.track] = null;
+        }
+
+        if (!this.tracks[options.track])
+            this.tracks[options.track] = { id: 0 }
+        else
+            this.tracks[options.track].id++;
+
+        options.id = this.tracks[options.track].id;
+        $$('body')[0].insert(
+                Prototype.Browser.IE ? new Element('bgsound', {
+                    id: 'sound_' + options.track + '_' + options.id,
+                    src: options.url, loop: 1, autostart: true
+                }) : Sound.template.evaluate(options));
+    }
+};
+
+if (Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0)
+{
+    if (navigator.plugins && $A(navigator.plugins).detect(function(p)
+    {
+        return p.name.indexOf('QuickTime') != -1
+    }))
+        Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>')
+    else
+        Sound.play = function()
+        {
+        }
+}
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/unittest.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/unittest.js
new file mode 100644
index 0000000..37cd450
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/unittest.js
@@ -0,0 +1,785 @@
+// script.aculo.us unittest.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
+//           (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// experimental, Firefox-only
+Event.simulateMouse = function(element, eventName)
+{
+    var options = Object.extend({
+        pointerX: 0,
+        pointerY: 0,
+        buttons:  0,
+        ctrlKey:  false,
+        altKey:   false,
+        shiftKey: false,
+        metaKey:  false
+    }, arguments[2] || {});
+    var oEvent = document.createEvent("MouseEvents");
+    oEvent.initMouseEvent(eventName, true, true, document.defaultView,
+            options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
+            options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
+
+    if (this.mark) Element.remove(this.mark);
+    this.mark = document.createElement('div');
+    this.mark.appendChild(document.createTextNode(" "));
+    document.body.appendChild(this.mark);
+    this.mark.style.position = 'absolute';
+    this.mark.style.top = options.pointerY + "px";
+    this.mark.style.left = options.pointerX + "px";
+    this.mark.style.width = "5px";
+    this.mark.style.height = "5px;";
+    this.mark.style.borderTop = "1px solid red;"
+    this.mark.style.borderLeft = "1px solid red;"
+
+    if (this.step)
+        alert('[' + new Date().getTime().toString() + '] ' + eventName + '/' + Test.Unit.inspect(options));
+
+    $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function(element, eventName)
+{
+    var options = Object.extend({
+        ctrlKey: false,
+        altKey: false,
+        shiftKey: false,
+        metaKey: false,
+        keyCode: 0,
+        charCode: 0
+    }, arguments[2] || {});
+
+    var oEvent = document.createEvent("KeyEvents");
+    oEvent.initKeyEvent(eventName, true, true, window,
+            options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
+            options.keyCode, options.charCode);
+    $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function(element, command)
+{
+    for (var i = 0; i < command.length; i++)
+    {
+        Event.simulateKey(element, 'keypress', {charCode:command.charCodeAt(i)});
+    }
+};
+
+var Test = {}
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = Object.inspect;
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+    initialize: function(log)
+    {
+        this.log = $(log);
+        if (this.log)
+        {
+            this._createLogTable();
+        }
+    },
+    start: function(testName)
+    {
+        if (!this.log) return;
+        this.testName = testName;
+        this.lastLogLine = document.createElement('tr');
+        this.statusCell = document.createElement('td');
+        this.nameCell = document.createElement('td');
+        this.nameCell.className = "nameCell";
+        this.nameCell.appendChild(document.createTextNode(testName));
+        this.messageCell = document.createElement('td');
+        this.lastLogLine.appendChild(this.statusCell);
+        this.lastLogLine.appendChild(this.nameCell);
+        this.lastLogLine.appendChild(this.messageCell);
+        this.loglines.appendChild(this.lastLogLine);
+    },
+    finish: function(status, summary)
+    {
+        if (!this.log) return;
+        this.lastLogLine.className = status;
+        this.statusCell.innerHTML = status;
+        this.messageCell.innerHTML = this._toHTML(summary);
+        this.addLinksToResults();
+    },
+    message: function(message)
+    {
+        if (!this.log) return;
+        this.messageCell.innerHTML = this._toHTML(message);
+    },
+    summary: function(summary)
+    {
+        if (!this.log) return;
+        this.logsummary.innerHTML = this._toHTML(summary);
+    },
+    _createLogTable: function()
+    {
+        this.log.innerHTML =
+        '<div id="logsummary"></div>' +
+        '<table id="logtable">' +
+        '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+        '<tbody id="loglines"></tbody>' +
+        '</table>';
+        this.logsummary = $('logsummary')
+        this.loglines = $('loglines');
+    },
+    _toHTML: function(txt)
+    {
+        return txt.escapeHTML().replace(/\n/g, "<br/>");
+    },
+    addLinksToResults: function()
+    {
+        $$("tr.failed .nameCell").each(function(td)
+        { // todo: limit to children of this.log
+            td.title = "Run only this test"
+            Event.observe(td, 'click', function()
+            {
+                window.location.search = "?tests=" + td.innerHTML;
+            });
+        });
+        $$("tr.passed .nameCell").each(function(td)
+        { // todo: limit to children of this.log
+            td.title = "Run all tests"
+            Event.observe(td, 'click', function()
+            {
+                window.location.search = "";
+            });
+        });
+    }
+}
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+    initialize: function(testcases)
+    {
+        this.options = Object.extend({
+            testLog: 'testlog'
+        }, arguments[1] || {});
+        this.options.resultsURL = this.parseResultsURLQueryParameter();
+        this.options.tests = this.parseTestsQueryParameter();
+        if (this.options.testLog)
+        {
+            this.options.testLog = $(this.options.testLog) || null;
+        }
+        if (this.options.tests)
+        {
+            this.tests = [];
+            for (var i = 0; i < this.options.tests.length; i++)
+            {
+                if (/^test/.test(this.options.tests[i]))
+                {
+                    this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+                }
+            }
+        }
+        else
+        {
+            if (this.options.test)
+            {
+                this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+            }
+            else
+            {
+                this.tests = [];
+                for (var testcase in testcases)
+                {
+                    if (/^test/.test(testcase))
+                    {
+                        this.tests.push(
+                                new Test.Unit.Testcase(
+                                        this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
+                                        testcases[testcase], testcases["setup"], testcases["teardown"]
+                                        ));
+                    }
+                }
+            }
+        }
+        this.currentTest = 0;
+        this.logger = new Test.Unit.Logger(this.options.testLog);
+        setTimeout(this.runTests.bind(this), 1000);
+    },
+    parseResultsURLQueryParameter: function()
+    {
+        return window.location.search.parseQuery()["resultsURL"];
+    },
+    parseTestsQueryParameter: function()
+    {
+        if (window.location.search.parseQuery()["tests"])
+        {
+            return window.location.search.parseQuery()["tests"].split(',');
+        }
+        ;
+    },
+    // Returns:
+    //  "ERROR" if there was an error,
+    //  "FAILURE" if there was a failure, or
+    //  "SUCCESS" if there was neither
+    getResult: function()
+    {
+        var hasFailure = false;
+        for (var i = 0; i < this.tests.length; i++)
+        {
+            if (this.tests[i].errors > 0)
+            {
+                return "ERROR";
+            }
+            if (this.tests[i].failures > 0)
+            {
+                hasFailure = true;
+            }
+        }
+        if (hasFailure)
+        {
+            return "FAILURE";
+        }
+        else
+        {
+            return "SUCCESS";
+        }
+    },
+    postResults: function()
+    {
+        if (this.options.resultsURL)
+        {
+            new Ajax.Request(this.options.resultsURL,
+            { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
+        }
+    },
+    runTests: function()
+    {
+        var test = this.tests[this.currentTest];
+        if (!test)
+        {
+            // finished!
+            this.postResults();
+            this.logger.summary(this.summary());
+            return;
+        }
+        if (!test.isWaiting)
+        {
+            this.logger.start(test.name);
+        }
+        test.run();
+        if (test.isWaiting)
+        {
+            this.logger.message("Waiting for " + test.timeToWait + "ms");
+            setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+        }
+        else
+        {
+            this.logger.finish(test.status(), test.summary());
+            this.currentTest++;
+      // tail recursive, hopefully the browser will skip the stackframe
+            this.runTests();
+        }
+    },
+    summary: function()
+    {
+        var assertions = 0;
+        var failures = 0;
+        var errors = 0;
+        var messages = [];
+        for (var i = 0; i < this.tests.length; i++)
+        {
+            assertions += this.tests[i].assertions;
+            failures += this.tests[i].failures;
+            errors += this.tests[i].errors;
+        }
+        return (
+                (this.options.context ? this.options.context + ': ' : '') +
+                this.tests.length + " tests, " +
+                assertions + " assertions, " +
+                failures + " failures, " +
+                errors + " errors");
+    }
+}
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+    initialize: function()
+    {
+        this.assertions = 0;
+        this.failures = 0;
+        this.errors = 0;
+        this.messages = [];
+    },
+    summary: function()
+    {
+        return (
+                this.assertions + " assertions, " +
+                this.failures + " failures, " +
+                this.errors + " errors" + "\n" +
+                this.messages.join("\n"));
+    },
+    pass: function()
+    {
+        this.assertions++;
+    },
+    fail: function(message)
+    {
+        this.failures++;
+        this.messages.push("Failure: " + message);
+    },
+    info: function(message)
+    {
+        this.messages.push("Info: " + message);
+    },
+    error: function(error)
+    {
+        this.errors++;
+        this.messages.push(error.name + ": " + error.message + "(" + Test.Unit.inspect(error) + ")");
+    },
+    status: function()
+    {
+        if (this.failures > 0) return 'failed';
+        if (this.errors > 0) return 'error';
+        return 'passed';
+    },
+    assert: function(expression)
+    {
+        var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+        try
+        {
+            expression ? this.pass() :
+            this.fail(message);
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertEqual: function(expected, actual)
+    {
+        var message = arguments[2] || "assertEqual";
+        try
+        {
+            (expected == actual) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertInspect: function(expected, actual)
+    {
+        var message = arguments[2] || "assertInspect";
+        try
+        {
+            (expected == actual.inspect()) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertEnumEqual: function(expected, actual)
+    {
+        var message = arguments[2] || "assertEnumEqual";
+        try
+        {
+            $A(expected).length == $A(actual).length &&
+            expected.zip(actual).all(function(pair)
+            {
+                return pair[0] == pair[1]
+            }) ?
+            this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
+                                    ', actual ' + Test.Unit.inspect(actual));
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertNotEqual: function(expected, actual)
+    {
+        var message = arguments[2] || "assertNotEqual";
+        try
+        {
+            (expected != actual) ? this.pass() :
+            this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertIdentical: function(expected, actual)
+    {
+        var message = arguments[2] || "assertIdentical";
+        try
+        {
+            (expected === actual) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertNotIdentical: function(expected, actual)
+    {
+        var message = arguments[2] || "assertNotIdentical";
+        try
+        {
+            !(expected === actual) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertNull: function(obj)
+    {
+        var message = arguments[1] || 'assertNull'
+        try
+        {
+            (obj == null) ? this.pass() :
+            this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertMatch: function(expected, actual)
+    {
+        var message = arguments[2] || 'assertMatch';
+        var regex = new RegExp(expected);
+        try
+        {
+            (regex.exec(actual)) ? this.pass() :
+            this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertHidden: function(element)
+    {
+        var message = arguments[1] || 'assertHidden';
+        this.assertEqual("none", element.style.display, message);
+    },
+    assertNotNull: function(object)
+    {
+        var message = arguments[1] || 'assertNotNull';
+        this.assert(object != null, message);
+    },
+    assertType: function(expected, actual)
+    {
+        var message = arguments[2] || 'assertType';
+        try
+        {
+            (actual.constructor == expected) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + (actual.constructor) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertNotOfType: function(expected, actual)
+    {
+        var message = arguments[2] || 'assertNotOfType';
+        try
+        {
+            (actual.constructor != expected) ? this.pass() :
+            this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+                      '", actual "' + (actual.constructor) + '"');
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertInstanceOf: function(expected, actual)
+    {
+        var message = arguments[2] || 'assertInstanceOf';
+        try
+        {
+            (actual instanceof expected) ? this.pass() :
+            this.fail(message + ": object was not an instance of the expected type");
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertNotInstanceOf: function(expected, actual)
+    {
+        var message = arguments[2] || 'assertNotInstanceOf';
+        try
+        {
+            !(actual instanceof expected) ? this.pass() :
+            this.fail(message + ": object was an instance of the not expected type");
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertRespondsTo: function(method, obj)
+    {
+        var message = arguments[2] || 'assertRespondsTo';
+        try
+        {
+            (obj[method] && typeof obj[method] == 'function') ? this.pass() :
+            this.fail(message + ": object doesn't respond to [" + method + "]");
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertReturnsTrue: function(method, obj)
+    {
+        var message = arguments[2] || 'assertReturnsTrue';
+        try
+        {
+            var m = obj[method];
+            if (!m) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
+            m() ? this.pass() :
+            this.fail(message + ": method returned false");
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertReturnsFalse: function(method, obj)
+    {
+        var message = arguments[2] || 'assertReturnsFalse';
+        try
+        {
+            var m = obj[method];
+            if (!m) m = obj['is' + method.charAt(0).toUpperCase() + method.slice(1)];
+            !m() ? this.pass() :
+            this.fail(message + ": method returned true");
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    },
+    assertRaise: function(exceptionName, method)
+    {
+        var message = arguments[2] || 'assertRaise';
+        try
+        {
+            method();
+            this.fail(message + ": exception expected but none was raised");
+        }
+        catch(e)
+        {
+            ((exceptionName == null) || (e.name == exceptionName)) ? this.pass() : this.error(e);
+        }
+    },
+    assertElementsMatch: function()
+    {
+        var expressions = $A(arguments), elements = $A(expressions.shift());
+        if (elements.length != expressions.length)
+        {
+            this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
+            return false;
+        }
+        elements.zip(expressions).all(function(pair, index)
+        {
+            var element = $(pair.first()), expression = pair.last();
+            if (element.match(expression)) return true;
+            this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
+        }.bind(this)) && this.pass();
+    },
+    assertElementMatches: function(element, expression)
+    {
+        this.assertElementsMatch([element], expression);
+    },
+    benchmark: function(operation, iterations)
+    {
+        var startAt = new Date();
+        (iterations || 1).times(operation);
+        var timeTaken = ((new Date()) - startAt);
+        this.info((arguments[2] || 'Operation') + ' finished ' +
+                  iterations + ' iterations in ' + (timeTaken / 1000) + 's');
+        return timeTaken;
+    },
+    _isVisible: function(element)
+    {
+        element = $(element);
+        if (!element.parentNode) return true;
+        this.assertNotNull(element);
+        if (element.style && Element.getStyle(element, 'display') == 'none')
+            return false;
+
+        return this._isVisible(element.parentNode);
+    },
+    assertNotVisible: function(element)
+    {
+        this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
+    },
+    assertVisible: function(element)
+    {
+        this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+    },
+    benchmark: function(operation, iterations)
+    {
+        var startAt = new Date();
+        (iterations || 1).times(operation);
+        var timeTaken = ((new Date()) - startAt);
+        this.info((arguments[2] || 'Operation') + ' finished ' +
+                  iterations + ' iterations in ' + (timeTaken / 1000) + 's');
+        return timeTaken;
+    }
+}
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+    initialize: function(name, test, setup, teardown)
+    {
+        Test.Unit.Assertions.prototype.initialize.bind(this)();
+        this.name = name;
+
+        if (typeof test == 'string')
+        {
+            test = test.gsub(/(\.should[^\(]+\()/, '#{0}this,');
+            test = test.gsub(/(\.should[^\(]+)\(this,\)/, '#{1}(this)');
+            this.test = function()
+            {
+                eval('with(this){' + test + '}');
+            }
+        }
+        else
+        {
+            this.test = test || function()
+            {
+            };
+        }
+
+        this.setup = setup || function()
+        {
+        };
+        this.teardown = teardown || function()
+        {
+        };
+        this.isWaiting = false;
+        this.timeToWait = 1000;
+    },
+    wait: function(time, nextPart)
+    {
+        this.isWaiting = true;
+        this.test = nextPart;
+        this.timeToWait = time;
+    },
+    run: function()
+    {
+        try
+        {
+            try
+            {
+                if (!this.isWaiting) this.setup.bind(this)();
+                this.isWaiting = false;
+                this.test.bind(this)();
+            }
+            finally
+            {
+                if (!this.isWaiting)
+                {
+                    this.teardown.bind(this)();
+                }
+            }
+        }
+        catch(e)
+        {
+            this.error(e);
+        }
+    }
+});
+
+// *EXPERIMENTAL* BDD-style testing to please non-technical folk
+// This draws many ideas from RSpec http://rspec.rubyforge.org/
+
+Test.setupBDDExtensionMethods = function()
+{
+    var METHODMAP = {
+        shouldEqual:     'assertEqual',
+        shouldNotEqual:  'assertNotEqual',
+        shouldEqualEnum: 'assertEnumEqual',
+        shouldBeA:       'assertType',
+        shouldNotBeA:    'assertNotOfType',
+        shouldBeAn:      'assertType',
+        shouldNotBeAn:   'assertNotOfType',
+        shouldBeNull:    'assertNull',
+        shouldNotBeNull: 'assertNotNull',
+
+        shouldBe:        'assertReturnsTrue',
+        shouldNotBe:     'assertReturnsFalse',
+        shouldRespondTo: 'assertRespondsTo'
+    };
+    var makeAssertion = function(assertion, args, object)
+    {
+        this[assertion].apply(this, (args || []).concat([object]));
+    }
+
+    Test.BDDMethods = {};
+    $H(METHODMAP).each(function(pair)
+    {
+        Test.BDDMethods[pair.key] = function()
+        {
+            var args = $A(arguments);
+            var scope = args.shift();
+            makeAssertion.apply(scope, [pair.value, args, this]);
+        };
+    });
+
+    [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
+            function(p)
+            {
+                Object.extend(p, Test.BDDMethods)
+            }
+            );
+}
+
+Test.context = function(name, spec, log)
+{
+    Test.setupBDDExtensionMethods();
+
+    var compiledSpec = {};
+    var titles = {};
+    for (specName in spec)
+    {
+        switch (specName)
+                {
+            case "setup":
+            case "teardown":
+                compiledSpec[specName] = spec[specName];
+                break;
+            default:
+                var testName = 'test' + specName.gsub(/\s+/, '-').camelize();
+                var body = spec[specName].toString().split('\n').slice(1);
+                if (/^\{/.test(body[0])) body = body.slice(1);
+                body.pop();
+                body = body.map(function(statement)
+                {
+                    return statement.strip()
+                });
+                compiledSpec[testName] = body.join('\n');
+                titles[testName] = specName;
+        }
+    }
+    new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
+};
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
new file mode 100644
index 0000000..b36e7d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
@@ -0,0 +1,969 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var Tapestry = {
+
+    FORM_VALIDATE_EVENT : "form:validate",
+
+    FORM_PREPARE_FOR_SUBMIT_EVENT : "form:prepareforsubmit",
+
+    DEBUG_ENABLED : false,
+
+    /** Time, in seconds, that console messages are visible. */
+    CONSOLE_DURATION : 10,
+
+    FormEvent : Class.create(),
+
+    FormEventManager : Class.create(),
+
+    FieldEventManager : Class.create(),
+
+    Zone : Class.create(),
+
+    FormFragment : Class.create(),
+
+    FormInjector : Class.create(),
+
+    ErrorPopup : Class.create(),
+
+    // An array of Tapestry.ErrorPopup instances that have been created for fields within the page.
+
+    errorPopups : [],
+
+    // Adds a callback function that will be invoked when the DOM is loaded (which
+    // occurs *before* window.onload, which has to wait for images and such to load
+    // first.  This simply observes the dom:loaded event on the document object (support for
+    // which is provided by Prototype).
+    onDOMLoaded : function(callback)
+    {
+        document.observe("dom:loaded", callback);
+    },
+
+    /** Find all elements marked with the "t-invisible" CSS class and hide()s them, so that
+     * Prototype's visible() method operates correctly. This is invoked when the
+     * DOM is first loaded, and AGAIN whenever dynamic content is loaded via the Zone
+     * mechanism.     In addition, adds a focus listener for each form element.
+     */
+    onDomLoadedCallback : function()
+    {
+        $$(".t-invisible").each(function(element)
+        {
+            element.hide();
+            element.removeClassName("t-invisible");
+        });
+
+        // Adds a focus observer that fades all error popups except for the
+        // field in question.
+
+        $$("INPUT", "SELECT", "TEXTAREA").each(function(element)
+        {
+            // Due to Ajax, we may execute the callback multiple times,
+            // and we don't want to add multiple listeners to the same
+            // element.
+
+            if (! element.isObservingFocusChange)
+            {
+                element.observe("focus", function()
+                {
+                    Tapestry.focusedElement = element;
+
+                    $(Tapestry.errorPopups).each(function(popup)
+                    {
+                        popup.handleFocusChange(element);
+                    });
+                });
+
+                element.isObservingFocusChange = true;
+            }
+        });
+    },
+
+    // Generalized initialize function for Tapestry, used to help minimize the amount of JavaScript
+    // for the page by removing redundancies such as repeated Object and method names. The spec
+    // is a hash whose keys are the names of methods of the Tapestry object.
+    // The value is an array of arrays.  The outer arrays represent invocations
+    // of the method.  The inner array are the parameters for each invocation.
+    // As an optimization, the inner value may not be an array but instead
+    // a single value.
+
+    init : function(spec)
+    {
+        $H(spec).each(function(pair)
+        {
+            var functionName = pair.key;
+
+            // Tapestry.logWarning("Initialize: #{name} ...", { name:functionName });
+
+            var initf = Tapestry.Initializer[functionName];
+
+            if (initf == undefined)
+            {
+                Tapestry.error("Function Tapestry.Initializer.#{name}() does not exist.", { name:functionName });
+                return;
+            }
+
+            pair.value.each(function(parameterList)
+            {
+                if (! Object.isArray(parameterList))
+                {
+                    parameterList = [parameterList];
+                }
+
+                initf.apply(this, parameterList);
+            });
+        });
+    },
+
+    error : function (message, substitutions)
+    {
+        Tapestry.updateConsole("t-err", message, substitutions);
+    },
+
+    warn : function (message, substitutions)
+    {
+        Tapestry.updateConsole("t-warn", message, substitutions);
+    },
+
+    debug : function (message, substitutions)
+    {
+        if (Tapestry.DEBUG_ENABLED)
+            Tapestry.updateConsole("t-debug", message, substitutions);
+    },
+
+    updateConsole : function (className, message, substitutions)
+    {
+        if (substitutions != undefined)
+            message = message.interpolate(substitutions);
+
+        if (Tapestry.console == undefined)
+        {
+            var body = $$("BODY").first();
+
+            Tapestry.console = new Element("div", { 'class': "t-console" });
+
+            body.insert({ bottom: Tapestry.console });
+        }
+
+        var div = new Element("div", { 'class': className }).update(message);
+
+        Tapestry.console.insert({ bottom: div });
+
+        var effect = new Effect.BlindUp(div, { delay: Tapestry.CONSOLE_DURATION,
+            afterFinish: function()
+            {
+                div.remove();
+            }});
+
+        div.observe("click", function()
+        {
+            effect.cancel();
+            div.remove();
+        });
+
+    },
+
+    getFormEventManager : function(form)
+    {
+        form = $(form);
+
+        var manager = form.eventManager;
+
+        if (manager == undefined)
+            manager = new Tapestry.FormEventManager(form);
+
+        return manager;
+    },
+
+    /**
+     * Passed the JSON content of a Tapestry partial markup response, extracts
+     * the script key (if present) and evals it, then uses the DOM loaded callback
+     * to hide invisible fields and add notifications for any form elements.
+     */
+    processScriptInReply : function(reply)
+    {
+        if (reply.script != undefined)
+            eval(reply.script);
+
+        Tapestry.onDomLoadedCallback();
+    },
+
+    // Adds a validator for a field.  A FieldEventManager is added, if necessary.
+    // The validator will be called only for non-blank values, unless acceptBlank is
+    // true (in most cases, acceptBlank is flase). The validator is a function
+    // that accepts the current field value as its first parameter, and a
+    // Tapestry.FormEvent as its second.  It can invoke recordError() on the event
+    // if the input is not valid.
+
+    addValidator : function(field, acceptBlank, validator)
+    {
+        this.getFieldEventManager(field).addValidator(acceptBlank, validator);
+    },
+
+    getFieldEventManager : function(field)
+    {
+        field = $(field);
+
+        var manager = field.fieldEventManager;
+
+        if (manager == undefined) manager = new Tapestry.FieldEventManager(field);
+
+        return manager;
+    }
+};
+
+/** Container of functions that may be invoked by the Tapestry.init() function. */
+Tapestry.Initializer = {
+
+    /**
+     * Convert a form or link into a trigger of an Ajax update that
+     * updates the indicated Zone.
+     */
+    linkZone : function(element, zoneDiv)
+    {
+        element = $(element);
+        var zone = $(zoneDiv).zone;
+
+        var successHandler = function(transport)
+        {
+            var reply = transport.responseJSON;
+
+            zone.show(reply.content);
+
+            Tapestry.processScriptInReply(reply);
+        };
+
+        if (element.tagName == "FORM")
+        {
+            // The existing handler, if present, will be responsible for form validations, which must
+            // come before submitting the form via XHR.
+
+            var existingHandler = element.onsubmit;
+
+            var handler = function(event)
+            {
+                if (existingHandler != undefined)
+                {
+                    var existingResult = existingHandler.call(element, event);
+                    if (! existingResult) return false;
+                }
+
+                element.request({ onSuccess : successHandler });
+
+                Event.stop(event); // Should be domevent.stop(), but that fails under IE
+
+                return false;
+            };
+
+            element.onsubmit = handler;
+
+            return;
+        }
+
+        // Otherwise, assume it's just an ordinary link.
+
+        var handler = function(event)
+        {
+            new Ajax.Request(element.href, { onSuccess : successHandler });
+
+            return false;
+        };
+
+        element.onclick = handler;
+    },
+
+    validate : function (field, specs)
+    {
+        field = $(field);
+
+        Tapestry.getFormEventManager(field.form);
+
+        specs.each(function(spec)
+        {
+            // spec is a 2 or 3 element array.
+            // validator function name, message, optional constraint
+
+            var name = spec[0];
+            var message = spec[1];
+            var constraint = spec[2];
+
+            var vfunc = Tapestry.Validator[name];
+
+            if (vfunc == undefined)
+            {
+                Tapestry.error("Function Tapestry.Validator.#{name}() does not exist for field '#{fieldName}'.", {name:name, fieldName:pair.key});
+                return;
+            }
+
+            vfunc.call(this, field, message, constraint);
+        });
+    },
+
+    zone : function(spec)
+    {
+        new Tapestry.Zone(spec);
+    },
+
+    formFragment : function(spec)
+    {
+        new Tapestry.FormFragment(spec)
+    },
+
+    formInjector : function(spec)
+    {
+        new Tapestry.FormInjector(spec);
+    },
+
+    // Links a FormFragment to a trigger (a radio or a checkbox), such that changing the trigger will hide
+    // or show the FormFragment. Care should be taken to render the page with the
+    // checkbox and the FormFragment('s visibility) in agreement.
+
+    linkTriggerToFormFragment : function(trigger, element)
+    {
+        trigger = $(trigger);
+
+        if (trigger.type == "radio")
+        {
+            $(trigger.form).observe("click", function()
+            {
+                $(element).formFragment.setVisible(trigger.checked);
+            });
+
+            return;
+        }
+
+        // Otherwise, we assume it is a checkbox.  The difference is
+        // that we can observe just the single checkbox element,
+        // rather than handling clicks anywhere in the form (as with
+        // the radio).
+
+        trigger.observe("click", function()
+        {
+            $(element).formFragment.setVisible(trigger.checked);
+        });
+
+    }
+};
+
+// New methods added to Element.
+
+Tapestry.ElementAdditions = {
+    // This is added to all Elements, but really only applys to form control elements. This method is invoked
+    // when a validation error is associated with a field. This gives the field a chance to decorate itself, its label
+    // and its icon.
+    decorateForValidationError : function(element, message)
+    {
+        Tapestry.getFieldEventManager(element).addDecorations(message);
+    },
+
+    removeDecorations : function(element)
+    {
+        Tapestry.getFieldEventManager(element).removeDecorations();
+    },
+
+    // Checks to see if an element is truly visible, meaning the receiver and all
+    // its anscestors (up to the containing form), are visible.
+
+    isDeepVisible : function(element)
+    {
+        element = $(element);
+
+        if (! element.visible()) return false;
+
+        // Stop at a form, which is sufficient for validation purposes.
+
+        if (element.tagName == "FORM") return true;
+
+        return $(element.parentNode).isDeepVisible();
+    }
+};
+
+Element.addMethods(Tapestry.ElementAdditions);
+
+// Collection of field based functions related to validation. Each
+// function takes a field, a message and an optional constraint value.
+
+Tapestry.Validator = {
+    required : function(field, message)
+    {
+        Tapestry.addValidator(field, true, function(value, event)
+        {
+            if (value.strip() == '')
+                event.recordError(message);
+        });
+    },
+
+    minlength : function(field, message, length)
+    {
+        Tapestry.addValidator(field, false, function(value, event)
+        {
+            if (value.length < length)
+                event.recordError(message);
+        });
+    },
+
+    maxlength : function(field, message, maxlength)
+    {
+        Tapestry.addValidator(field, false, function(value, event)
+        {
+            if (value.length > maxlength)
+                event.recordError(message);
+        });
+    },
+
+    min : function(field, message, minValue)
+    {
+        Tapestry.addValidator(field, false, function(value, event)
+        {
+            if (value < minValue)
+                event.recordError(message);
+        });
+    },
+
+    max : function(field, message, maxValue)
+    {
+        Tapestry.addValidator(field, false, function(value, event)
+        {
+            if (value > maxValue)
+                event.recordError(message);
+        });
+    },
+
+    regexp : function(field, message, pattern)
+    {
+        var regexp = new RegExp(pattern);
+
+        Tapestry.addValidator(field, false, function(value, event)
+        {
+            if (! regexp.test(value))
+                event.recordError(message);
+        });
+    }
+};
+
+
+// A Tapestry.FormEvent is used when the form sends presubmit and submit events to
+// a FieldEventManager. It allows the associated handlers to indirectly invoke
+// the Form's invalidField() method, and it tracks a result flag (true for success ==
+// no field errors, false if any field errors).
+
+Tapestry.FormEvent.prototype = {
+
+    initialize : function(form)
+    {
+        this.form = $(form);
+        this.result = true;
+        this.firstError = true;
+    },
+
+    // Invoked by a validator function (which is passed the event) to record an error
+    // for the associated field. The event knows the field and form and invoke's
+    // the (added) form method invalidField().  Sets the event's result field to false
+    // (i.e., don't allow the form to submit), and sets the event's error field to
+    // true.
+
+    recordError : function(message)
+    {
+        if (this.firstError)
+        {
+            this.field.activate();
+            this.firstError = false;
+        }
+
+        this.field.decorateForValidationError(message);
+
+        this.result = false;
+        this.error = true;
+    }
+};
+
+Tapestry.ErrorPopup.prototype = {
+
+    BUBBLE_VERT_OFFSET : -34,
+
+    BUBBLE_HORIZONTAL_OFFSET : -5,
+
+    BUBBLE_WIDTH: "auto",
+
+    BUBBLE_HEIGHT: "39px",
+
+    initialize : function(field)
+    {
+        this.field = $(field);
+
+        this.innerSpan = new Element("span");
+        this.outerDiv = $(new Element("div", { 'class' : 't-error-popup' })).update(this.innerSpan).hide();
+
+        var body = $$('BODY').first();
+
+        body.insert({ bottom: this.outerDiv });
+
+        this.outerDiv.absolutize();
+
+        this.outerDiv.observe("click", function(event)
+        {
+            this.stopAnimation();
+
+            this.outerDiv.hide();
+
+            this.field.focus();
+
+            Event.stop(event);  // Should be domevent.stop(), but that fails under IE
+        }.bindAsEventListener(this));
+
+        Tapestry.errorPopups.push(this);
+
+        this.state = "hidden";
+
+        this.queue = { position: 'end', scope: this.field.id };
+
+        Event.observe(window, "resize", this.repositionBubble.bind(this));
+    },
+
+    showMessage : function(message)
+    {
+        this.stopAnimation();
+
+        this.innerSpan.update(message);
+
+        this.hasMessage = true;
+
+        this.fadeIn();
+    },
+
+    repositionBubble : function()
+    {
+        var fieldPos = this.field.positionedOffset();
+
+        this.outerDiv.setStyle({
+            top: (fieldPos[1] + this.BUBBLE_VERT_OFFSET) + "px",
+            left: (fieldPos[0] + this.BUBBLE_HORIZONTAL_OFFSET) + "px",
+            width: this.BUBBLE_WIDTH,
+            height: this.BUBBLE_HEIGHT });
+    },
+
+    fadeIn : function()
+    {
+        this.repositionBubble();
+
+        if (this.state == "hidden")
+        {
+            this.state = "visible";
+
+            this.animation = new Effect.Appear(this.outerDiv, { afterFinish : this.afterFadeIn.bind(this), queue: this.queue });
+        }
+    },
+
+    stopAnimation : function()
+    {
+        if (this.animation) this.animation.cancel();
+
+        this.animation = null;
+    },
+
+    fadeOut : function ()
+    {
+        this.stopAnimation();
+
+        if (this.state == "visible")
+        {
+            this.state = "hidden";
+
+            this.animation = new Effect.Fade(this.outerDiv, { queue : this.queue });
+        }
+    },
+
+    hide : function()
+    {
+        this.hasMessage = false;
+
+        this.stopAnimation();
+
+        this.outerDiv.hide();
+
+        this.state = "hidden";
+    },
+
+    afterFadeIn : function()
+    {
+        this.animation = null;
+
+        if (this.field != Tapestry.focusedElement) this.fadeOut();
+    },
+
+    handleFocusChange : function(element)
+    {
+        if (element == this.field)
+        {
+            if (this.hasMessage) this.fadeIn();
+            return;
+        }
+
+        if (this.animation == null)
+        {
+            this.fadeOut();
+            return;
+        }
+
+        // Must be fading in, let it finish, then fade it back out.
+
+        this.animation = new Effect.Fade(this.outerDiv, { queue : this.queue });
+    }
+};
+
+Tapestry.FormEventManager.prototype = {
+
+    initialize : function(form)
+    {
+        this.form = $(form);
+
+        this.form.onsubmit = this.handleSubmit.bindAsEventListener(this);
+    },
+
+    handleSubmit : function(domevent)
+    {
+        // Locate elements that have an event manager (and therefore, validations)
+        // and let those validations execute, which may result in calls to recordError().
+
+        var event = new Tapestry.FormEvent(this.form);
+
+        this.form.getElements().each(function(element)
+        {
+            if (element.fieldEventManager != undefined)
+            {
+                event.field = element;
+                element.fieldEventManager.validateInput(event);
+
+                if (event.abort) throw $break;
+            }
+        });
+
+        // Allow observers to validate the form as a whole.  The FormEvent will be visible
+        // as event.memo.  The Form will not be submitted if event.result is set to false (it defaults
+        // to true).
+
+        this.form.fire(Tapestry.FORM_VALIDATE_EVENT, event);
+
+
+        if (! event.result)
+        {
+            Event.stop(domevent); // Should be domevent.stop(), but that fails under IE
+        }
+        else
+        {
+            this.form.fire(Tapestry.FORM_PREPARE_FOR_SUBMIT_EVENT);
+        }
+
+        return event.result;
+    }
+};
+
+Tapestry.FieldEventManager.prototype = {
+
+    initialize : function(field)
+    {
+        this.field = $(field);
+
+        field.fieldEventManager = this;
+
+        this.validators = [ ];
+
+        var id = field.id;
+        this.label = $(id + ':label');
+        this.icon = $(id + ':icon');
+
+        this.field.observe("blur", function()
+        {
+            var event = new Tapestry.FormEvent(this.field.form);
+
+     // This prevents the field from taking focus if there is an error.
+            event.firstError = false;
+
+            event.field = this.field;
+
+            this.validateInput(event);
+        }.bindAsEventListener(this));
+    },
+
+    // Adds a validator.  acceptBlank is true if the validator should be invoked regardless of
+    // the value.  Usually acceptBlank is false, meaning that the validator will be skipped if
+    // the field's value is blank. The validator itself is a function that is passed the
+    // field's value and the Tapestry.FormEvent object.  When a validator invokes event.recordError(),
+    // any subsequent validators for that field are skipped.
+
+    addValidator : function(acceptBlank, validator)
+    {
+        this.validators.push([ acceptBlank, validator]);
+    },
+
+    // Removes decorations on the field and label (the "t-error" CSS class) and makes the icon
+    // invisible.  A field that has special decoration needs will override this method.
+
+    removeDecorations : function()
+    {
+        this.field.removeClassName("t-error");
+
+        if (this.label)
+            this.label.removeClassName("t-error");
+
+        if (this.icon)
+            this.icon.hide();
+
+        if (this.errorPopup)
+            this.errorPopup.hide();
+    },
+
+    // Adds decorations to the field (including label and icon if present).
+    // event - the validation event
+    // message - error message
+
+    addDecorations : function(message)
+    {
+        this.field.addClassName("t-error");
+
+        if (this.label)
+            this.label.addClassName("t-error");
+
+        if (this.icon)
+        {
+            if (! this.icon.visible())
+                new Effect.Appear(this.icon);
+        }
+
+        if (this.errorPopup == undefined)
+            this.errorPopup = new Tapestry.ErrorPopup(this.field);
+
+        this.errorPopup.showMessage(message);
+    },
+
+
+    // Invoked from the Form's onsubmit event handler. Gets the fields value and invokes
+    // each validator (unless the value is blank) until a validator returns false. Validators
+    // should not modify the field's value.
+
+    validateInput : function(event)
+    {
+        if (this.field.disabled) return;
+
+        if (! this.field.isDeepVisible()) return;
+
+        var value = $F(event.field);
+        var isBlank = (value == '');
+
+        event.error = false;
+
+        this.validators.each(function(tuple)
+        {
+            var acceptBlank = tuple[0];
+            var validator = tuple[1];
+
+            if (acceptBlank || !isBlank)
+            {
+
+                validator(value, event);
+
+     // event.error is set by Tapestry.FormEvent.recordError().
+
+                if (event.error) throw $break;
+            }
+        });
+
+        if (! event.error)
+            this.removeDecorations();
+    }
+};
+
+// Wrappers around Prototype and Scriptaculous effects, invoked from Tapestry.Zone.show().
+// All the functions of this object should have all-lowercase names. 
+
+Tapestry.ElementEffect = {
+
+    show : function(element)
+    {
+        element.show();
+    },
+
+    highlight : function(element)
+    {
+        new Effect.Highlight(element);
+    },
+
+    slidedown : function (element)
+    {
+        new Effect.SlideDown(element);
+    },
+
+    slideup : function(element)
+    {
+        new Effect.SlideUp(element);
+    },
+
+    fade : function(element)
+    {
+        new Effect.Fade(element);
+    }
+};
+
+
+Tapestry.Zone.prototype = {
+    // spec are the parameters for the Zone:
+    // trigger: required -- name or instance of link.
+    // element: required -- name or instance of div element to be shown, hidden and updated
+    // show: name of Tapestry.ElementEffect function used to reveal the zone if hidden
+    // update: name of Tapestry.ElementEffect function used to highlight the zone after it is updated
+    initialize: function(spec)
+    {
+        if (Object.isString(spec))
+            spec = { element: spec }
+
+        this.element = $(spec.element);
+        this.showFunc = Tapestry.ElementEffect[spec.show] || Tapestry.ElementEffect.show;
+        this.updateFunc = Tapestry.ElementEffect[spec.update] || Tapestry.ElementEffect.highlight;
+
+        // Link the div back to this zone.
+
+        this.element.zone = this;
+
+        // Look inside the Zone element for an element with the CSS class "t-zone-update".
+        // If present, then this is the elements whose content will be changed, rather
+        // then the entire Zone div.  This allows a Zone div to contain "wrapper" markup
+        // (borders and such).  Typically, such a Zone element will initially be invisible.
+        // The show and update functions apply to the Zone element, not the update element.
+
+        var updates = this.element.select(".t-zone-update");
+
+        this.updateElement = updates.length == 0 ? this.element : updates[0];
+    },
+
+    // Updates the content of the div controlled by this Zone, then
+    // invokes the show function (if not visible) or the update function (if visible).
+
+    show: function(content)
+    {
+        this.updateElement.update(content);
+
+        var func = this.element.visible() ? this.updateFunc : this.showFunc;
+
+        func.call(this, this.element);
+    }
+};
+
+// A class that managed an element (usually a <div>) that is conditionally visible and
+// part of the form when visible.
+
+Tapestry.FormFragment.prototype = {
+
+    initialize: function(spec)
+    {
+        if (Object.isString(spec))
+            spec = { element: spec };
+
+        this.element = $(spec.element);
+
+        this.element.formFragment = this;
+
+        this.hidden = $(spec.element + ":hidden");
+
+        this.showFunc = Tapestry.ElementEffect[spec.show] || Tapestry.ElementEffect.slidedown;
+        this.hideFunc = Tapestry.ElementEffect[spec.hide] || Tapestry.ElementEffect.slideup;
+
+        $(this.hidden.form).observe(Tapestry.FORM_PREPARE_FOR_SUBMIT_EVENT, function()
+        {
+            this.hidden.value = this.element.isDeepVisible();
+        }.bind(this));
+    },
+
+    hide : function()
+    {
+        if (this.element.visible())
+            this.hideFunc(this.element);
+    },
+
+    show : function()
+    {
+        if (! this.element.visible())
+            this.showFunc(this.element);
+    },
+
+    toggle : function()
+    {
+        this.setVisible(! this.element.visible());
+    },
+
+    setVisible : function(visible)
+    {
+        if (visible)
+        {
+            this.show();
+            return;
+        }
+
+        this.hide();
+    }
+};
+
+
+Tapestry.FormInjector.prototype = {
+
+    initialize: function(spec)
+    {
+        this.element = $(spec.element);
+        this.url = spec.url;
+        this.below = spec.below;
+
+        this.showFunc = Tapestry.ElementEffect[spec.show] || Tapestry.ElementEffect.highlight;
+
+        this.element.trigger = function()
+        {
+            var successHandler = function(transport)
+            {
+                var reply = transport.responseJSON;
+
+                // Clone the FormInjector element (usually a div)
+                // to create the new element, that gets inserted
+                // before or after the FormInjector's element.
+
+                var newElement = new Element(this.element.tagName, { 'class' : this.element.className });
+
+                // Insert the new element before or after the existing element.
+
+                var param = { };
+                var key = this.below ? "after" : "before";
+                param[key] = newElement;
+
+                // Add the new element with the downloaded content.
+
+                this.element.insert(param);
+
+                // Update the empty element with the content from the server
+
+                newElement.update(reply.content);
+
+                // Handle any scripting issues.
+
+                Tapestry.processScriptInReply(reply);
+
+                // Add some animation to reveal it all.
+
+                this.showFunc(newElement);
+
+            }.bind(this);
+
+            new Ajax.Request(this.url, { onSuccess : successHandler });
+
+            return false;
+        }.bind(this);
+    }
+};
+
+Tapestry.onDOMLoaded(Tapestry.onDomLoadedCallback);
diff --git a/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/util/PublicUtilStrings.properties b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/util/PublicUtilStrings.properties
new file mode 100644
index 0000000..ba1ac69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/main/resources/org/apache/tapestry/util/PublicUtilStrings.properties
@@ -0,0 +1,17 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+duplicate-key=Key %s may not be added with value %s, as an existing value, %s, is already present.
+missing-value=Key for value %s not found. Available values: %s
+missing-enum-value=Input '%s' does not identify a value from enumerated type %s. Available values: %s.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/ajax.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/ajax.apt
new file mode 100644
index 0000000..a45951d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/ajax.apt
@@ -0,0 +1,330 @@
+ ---
+ Tapestry Ajax Support
+ ---
+
+Tapestry Ajax Support
+
+  Tapestry includes sophisticated JavaScript and Ajax support, based on the
+  {{{http://www.prototypejs.org/}Prototype}} and
+  {{{http://script.aculo.us/}Scriptaculous}} libraries.  These libraries are
+  all packaged with Tapestry itself ... no extra download required.
+
+  The goal for Tapestry is to have many basic and useful components available within the
+  application itself, and make it easy for other JavaScript widgets to be encapsulated as
+  Tapestry components.
+
+  Ajax support takes the form of new components and, occasionally,
+  {{{mixins.html}component mixins}}.  
+
+Changes to Prototype
+
+  Tapestry currently uses
+  {{{http://www.thebungeebook.net/wp-content/uploads/2008/01/prototype-1601.js}Prototype 1.6.0.1}}.  Version 1.6.0.2
+  appears to have some issues supporting Internet Explorer.  Tapestry's version is slightly patched
+  for {{{https://issues.apache.org/jira/browse/TAPESTRY-2108}TAPESTRY-2108}}.
+
+Changes to Scriptaculous
+
+  Scriptaculous normally has a special {{{http://wiki.script.aculo.us/scriptaculous/show/Usage}script loading option}}.
+  Loading just the Scriptaculous main library, scriptaculous.js, will also load <all> the other scripts in the library. Normally,
+  you can fine-tune this using "load" query parameter.
+
+  This doesn't fit well with the Tapestry; as discussed below, Tapestry has the capability to allow
+  individual components to control which JavaScript libraries are loaded with the page.  Further, the exact set of scripts
+  needed is determined over the course of rendering the page, and depends on the needs of the specific components that have
+  rendered.
+
+  The main Scriptaculous library, scriptaculous.js, is modified to turn off the autoloading behavior.
+  Tapestry will automatically link in prototype.js, scriptaculous.js, effects.js and the Tapestry library, tapestry.js.
+  You can add additional libraries as needed.
+
+
+Basic JavaScript
+
+  The general strategy in Tapestry is that any significant amount of JavaScript should be packaged up
+  as a static JavaScript library, a .js file that can be downloaded to the client.
+
+  Page specific JavaScript should be in the form of minimal statements to initialize objects, referencing
+  the JavaScript libraries.
+
+  Most of this is accomplished via the
+  {{{../../apidocs/org/apache/tapestry/RenderSupport.html}RenderSupport}} object.
+
+  RenderSupport include a number of methods that will be used by components, or event by
+  services that are called from components.
+
+* addScriptLink()
+
+  <<<void addScriptLink(Asset... scriptAssets);>>>
+
+  This method adds a link to a script file, a JavaScript library.  A component can inject such a script and
+  pass one or more of assets to this method.  Tapestry will ensure that the necessary \<link\> elements
+  are added to the <top> of the document (just inside the \<head\> element).
+
+  Adding the same asset multiple times does <not> create duplicate links.  The subsequent ones are simply
+  ignored.  In this way, each component can add the assets it needs, without worrying about conflicts
+  with other components.
+
+  Note that the Prototype, Scriptaculous main and effects libraries, and the base Tapestry library (which largely consists of
+  support for form input validation) are included automatically.
+
+  If you are need access to other Scriptaculous libraries, you can provide them as follows:
+
++---+
+
+  @Inject @Path("${tapestry.scriptaculous}/dragdrop.js")
+  private Asset dragDropLibrary;
+
+  @Environmental
+  private RenderSupport renderSupport;
+
+  void setupRender()
+  {
+    renderSupport.addScriptLink(dragDropLibrary);
+  }
+
++---+
+
+  The Asset is injected, using the $\{tapestry.scriptaculous\} symbol to reference the location
+  of the Scriptaculous library.
+
+  The RenderSupport is accessed as an Environmental service.
+
+  The setupRender() method (the name is specifically linked to a
+  {{{rendering.html}render phase}}) is the correct place to inform the RenderSupport service that
+  the library is needed.
+
+  
+
+* addScript()
+
+  <<<void addScript(String format, Object... arguments);>>>
+
+  This method adds some initialization JavaScript to the page.  By <initialization> we mean that
+  it goes at the bottom of the document, and will only be executed when the document has finished loading
+  on the client (i.e., from the window.onload event handler).
+  
+  When calling the method, the format string can include standard substitutions (such as '%s')
+  for arguments.  This saves you the trouble of calling String.format() yourself.  In any case, the
+  formatting JavaScript is added to the script block.
+
+* Injecting RenderSupport
+
+  RenderSupport is an <environmental> object, so you will normally inject it via the
+  {{{../../apidocs/org/apache/tapestry/annotation/Environmental.html}Environmental}} annotation:
+
++---+
+  @Environmental
+  private RenderSupport renderSupport;
++---+
+
+  Environmental only works inside components and occasionally a service may want to
+  inject RenderSupport.  Fortunately, a proxy of RenderSupport has been set up.  The upshot of which
+  is, you may also:
+
++---+
+  @Inject
+  private RenderSupport renderSupport;
++----+
+
+  ... or, in a service implementation constructor:
+
++---+
+  public MyServiceImpl(RenderSupport support)
+  {
+    . . .
+  }
++---+
+
+  Inside a component, you should use Environmental, to highlight the fact that RenderSupport (like most
+  environmental objects) is only available during rendering, not during action requests.
+
+IncludeJavaScriptLibrary Annotation
+
+  The
+  {{{../../apidocs/org/apache/tapestry/annotation/IncludeJavaScriptLibrary.html}IncludeJavaScriptLibrary}} annotation
+  is the easy way to include one or more JavaScript libraries.
+
+  The previous example could be re-written as:
+
++---+
+@IncludeJavaScriptLibrary("${tapestry.scriptaculous}/dragdrop.js")
+public class MyComponent
+{
+ . . .
+}
++---+
+
+  This saves you the effort of injecting the asset and making the call to RenderSupport.
+  Chances are you will <still> inject RenderSupport so as to add some initialization JavaScript.
+
+Ajax Components and Mixins
+
+* Autocomplete Mixin
+
+  The
+  {{{../../apidocs/org/apache/tapestry/corelib/mixins/Autocomplete.html}Autocomplete}}
+   mixin exists to allow a text field to query the server for completions for a partially
+  entered phrase.  It is often used in situations where the field exists to select a single value from
+  a large set, too large to succesfully download to the client as a drop down list; for example, when the
+  number of values to select from is numbered in the thousands.
+
+  Autocomplete can be added to an existing text field:
+
++---+
+  <t:textfield t:id="accountName" t:mixins="autocomplete" size="100"/>
++---+
+
+
+  The mixin can be configured in a number of ways, see the
+  {{{../component-parameters.html}component reference}}.
+
+  When the user types into the field, the client-side JavaScript will send a request to the server to
+  get completions.
+
+  You must write an event handler to provide these completions.  The name of the event is "providecompletions".
+  The context is the partial input value, and the return value will be converted into the selections
+  for the user.
+
+  For example:
+
++---+
+  List<String> onProvideCompletionsFromAccountName(String partial)
+  {
+    List<Account> matches = accountDAO.findByPartialAccountName(partial);
+
+    List<String> result = new ArrayList<String>():
+
+    for (Account a : matches)
+    {
+      result.add(a.getName());
+    }
+
+    return result;
+  }
++---+
+
+  This presumes that <<<findByPartialAccountName()>>> will sort the values, otherwise you will probably
+  want to sort them.  Certainly the Autocomplete mixin does <not> do any sorting.
+
+  You can return an object array, a list, even a single object.  You may return objects instead of strings ... and
+  <<<toString()>>> will be used to convert them into client-side strings.
+
+  Tapestry's default stylesheet includes entries for controlling the look of the floating popup of selections.
+
+  You may override <<<DIV.t-autocomplete-menu UL>>> to change the main look and feel,
+  <<<DIV.t-autocomplete-menu LI>>> for a normal item in the popup list, and
+   <<<DIV.t-autocomplete-menu LI.selected>>> for the element under the cursor (or selecting using the arrow keys).
+
+* Zone
+
+  Initial support for Zones is now in place.  Zones are Tapestry's approach to performing partial updates to
+  the client side.  A Zone component renders as a \<div\> element with the "t-zone" CSS class.  It also
+  adds some JavaScript to the page to "wire up" a Tapestry.Zone object to control updating
+  the \<div\> element.
+
+  A Zone can be updated via an ActionLink component.  ActionLink supports a zone parameter, which is the id
+  of the Zone's \<div\>. Clicking such a link will invoke an event handler method on the server as normal ...
+   except that the return value of the event handler method is used to send a <partial page response>
+   to the client, and the content of that response is used to update the Zone's \<div\> in place.
+
+** Zone div vs. update div
+
+  In many situations, a Zone is a kind of "wrapper" or "container" for dynamic content, that provides
+  a look and feel ... a bit of wrapping markup to create a border.  In that situtation,
+  the Zone \<div\> may contain an update \<div\>.
+
+  An update \<div\> is a \<div\> with the CSS class "t-zone-update", <inside> the Zone's \<div\>.
+
+  When an update occurs, the update \<div\>'s content will be changed, rather than the entire Zone \<div\>.
+
+  The show and update functions apply to the Zone \<div\>.
+
+** Event Handler Return Types
+
+  In a traditional request, the return value of an event handler method is used to determine
+  which page will render a <complete> response, and a <redirect> is sent to the client to render the new page (as
+  a new request).
+
+  With a Zone update, the return value is used to render a <partial response> within the <same request>.
+
+  This return value should be an injected component or block.  The value will be rendered, and that
+  markup will be used on the client side to update the Zone's \<div\>.
+
+** Graceful Degradation
+
+  Users who do not have JavaScript enabled may click ActionLinks that are configured to update a Zone.
+
+  When that occurs, the request will still be sent to the server, but will be handled as a <traditional> request.
+
+  To support graceful degradation, you should detect that case and return a traditional response: a page, page name
+  or page class.
+
+  This is accomplished by injecting the
+  {{{../../apidocs/org/apache/tapestry/services/Request.html}Request}} object, and invoking the isXHR() method.
+  This value will be true for Ajax requests, and false for traditional request.
+
+** Zone Functions
+
+  A Zone may be initially visible or invisible.  When a Zone is updated, it is made visible if not currently so.
+  This is accomplished via a function on the Tapestry.ElementEffect client-side object.  By default, the show()
+  function is used for this purpose.  The Zone's show parameter is the <name> of a Tapestry.ElementEffect function.
+
+  If a Zone is already visible, then a different function is used to highlight the change. Here it is
+  the Zone's update parameter, and a default highlight() function, which perfroms a yellow fade to highlight
+  that the content of the Zone has changed.
+
+
+** Zone Limitations
+
+   Unlike many other situations, Tapestry relies on you to specify useful and unique ids to Zone components,
+   then reference those ids inside ActionLink components. Using Zone components inside any kind of loop
+   may cause additional problems, as Tapestry will <uniqueify> the client id you specify (appending an index number).
+
+   The show and update function names are converted to lower case; all the methods of Tapestry.ElementEffect should have
+   all lower-case names.  Because client-side JavaScript is so fluid (new methods may be added to
+   existing objects), Tapestry makes no attempt to validate the function names ... however, if the names
+   are not valid, then the default show and highlight methods will be used.
+
+   Currently, the partial page content that is rendered may <<not>> use an Environmental services.  This is expected
+   to change soon.
+
+** Coming Soon
+
+  * zone parameter for Form components
+
+  * Extending a Form with a Zone
+
+  * Additional Tapestry.ElementEffect functions, plus documentation
+
+  * Real examples ...
+
+  []
+
+Your own Ajax Components
+
+  A study of the Autocomplete mixin's code should be very helpful: it shows how to
+  ask the ComponentResources object to create a link.
+
+  The key part is the way Tapestry invokes a component event handler method on the component.
+
+  For an Ajax request, the return value from an event handler method is processed differently
+  than for a traditional action request.  In an normal request, the return value
+  is the normally name of a page (to redirect to), or the Class of a page to redirect to, or
+  an instance of a page to redirect to.
+
+  For an Ajax request, a redirect is not sent: any response is rendered as part of the same
+  request and sent back immediately.
+
+  The possible return values are:
+
+  * A Block or Component to render as the response.  The response will be a JSON hash, with a "content" key
+    whose value is the rendered markup.  This is the basis for updates with the Zone component.
+
+  * A {{{../../apidocs/org/apache/tapestry/json/JSONObject.html}JSONObject}}, which will be sent as the response.
+
+  * A {{{../../apidocs/org/apache/tapestry/StreamResponse.html}StreamResponse}}, which will be sent as the response.
+
+  []
+
+
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/alias.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/alias.apt
new file mode 100644
index 0000000..35d55cf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/alias.apt
@@ -0,0 +1,59 @@
+ ----

+ Aliases and Overrides

+ ----

+

+Introduction

+

+  Tapestry goes to great lengths so that you can use the 

+  {{{inject.htmll}Inject}} annotation on a field

+  and provide no additional data, yet end up with the correct object or service.

+  

+  In many cases, Tapestry must match a field type to an available IoC service.

+  

+  If there is only single service in the registry that implements the service, Tapestry will utilize that service.

+  

+  When there is more than one such service, it is necessary to disambiguate which service is to be injected. To disambiguate

+  globally (across all injections), you must create an alias from the service interface directly to the particular service.

+  

+  This takes the form of a contribution to the Alias service.

+  

+  The Alias service has additional purposes: first, it allows for spot overrides on injected services, based on

+  the application's mode.  Currently, the only mode is "servlet", but future modes may include "portlet" and possibly "offline".

+  

+  Secondly, the companion AliasOverrides service configuration allows for spot overrides of specific services, without disturbing

+  the rest of the network of services within the IoC Registry.

+

+Contributing an Alias

+

+  To contribute a new service to the Alias service, you must first decide on a logical name.  Often, this is the

+  name of the service interface implemented by the service.

+  

+  You can then contribute into the Infrastructure service's configuration:

+  

++---+

+  public static void contributeAlias(@InjectService("MyService") MyService myService,

+     Configuration<AliasContribution> configuration)

+  {

+     configuration.add(AliasContribution.create(MyService.class, myService));

+  }

++---+

+

+  The above example follows a typical pattern; the service to be vended is injected into the contributor method, using

+  the explicit InjectService annotation.

+  A contribution is made providing the service type. 

+  

+  Notice that the contribution doesn't <have> to be a service; you can just instantiate an object inside the

+  contribution method and contribute that.  That's what we're doing in the example, though we're using a create() static

+  method rather than <<new>> (just to smooth out some Java Generics ugliness).

+  

+Contributing to AliasOverrides

+

+  To override a service, you need to know its service interface name.

+  

+  You can then make a contribution to the AliasOverrides service configuration, as described in the previous section.

+  

+  The object contributed as an override will mask the default contribution.

+ 

+  

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/appstate.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/appstate.apt
new file mode 100644
index 0000000..574019a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/appstate.apt
@@ -0,0 +1,111 @@
+ ----
+ Application State
+ ----
+ 
+Application State
+
+  Often, you will have a situation where you have a bit of data that is needed across multiple pages. Perhaps you are creating a multi-page wizard, or perhaps
+  you have an object that tracks the user's identify once logged in.
+  
+  Ordinary {{{persist.html}persistent page data}} is not appropriate, since persistent fields apply to a specific page and aren't shared across pages.
+  
+  Instead, you want to use an <Application State Object> (an ASO).
+  
+  With an ASO, the value is automatically stored outside the page; with the default storage strategy, it is stored in the session. 
+  
+  A field holding an ASO is marked with the
+  {{{../../apidocs/org/apache/tapestry/annotation/ApplicationState.html}ApplicationState}} annotation.
+  
+  Example:
+  
++---+
+public class MyPage
+{
+  @ApplicationState
+  private MyState myState;
+  
+  . . .
+}
++---+
+
+  Any other component or page that declares a field of the same type, regardless of name, and marks it with the ApplicationState
+  annotation will share the same value.  It's that simple.
+  
+  <For Tapestry 4 Users:> a big change here is that you don't need to provide any configuration for the ASO before using it, nor
+  do you provide a logical name.
+  Tapestry 5 uses the class name to identify the ASO, so there's no need for a logical name.
+  
+  The first time you access an ASO, it is created automatically.  Typically, the ASO will have a public no-args constructor ... but you may
+  inject dependencies into the ASO via its constructor, as you can with a Tapestry IoC service implementation.
+  
+  Assigning a value to an ASO field will store that value.  Assigning null to an ASO field will remove the ASO (reading the field subsequently
+  will force a new ASO instance to be created).
+  
+Check for Creation
+
+  Scalable web applications do not create the server-side session needlessly. If you can avoid creating the session, especially on first
+  access to your web application, you will be able to handle an order of magnitude more users. So, if you can avoid creating the ASO, you should do so.
+  
+  But how to avoid creating it?  Simply checking ("_myState != null") will force the creation of the ASO and the session to store it in.
+  
+  Instead, create a second field:
+  
++---+
+  private boolean myStateExists;
++---+
+
+  This companion field is used to see if the ASO already exists. It is not annotated; it is located by name ("Exists" is appended to the name of the field
+  storing the ASO). It must be type boolean and must be a private instance variable.  
+
+  Alternately, you may allow for the state being null:
+
++---+
+  @ApplicationState(create=false)
+  private MyState myState;
++---+
+
+  In this case, the myState field will be null if the MyState ASO does not exist, but will be non-null if it has been
+  created (either by assigning a value to the field, or by a different ASO field where create is true).
+
+Persistence Strategies
+
+  Each ASO is managed according to a persistence strategy. The default persistence strategy, "session", stores the ASOs inside the session.
+  The session is created as needed.
+  
+Configuring ASOs
+
+  Generally, you will configure an ASO if you need to change it from the default persistence strategy.  Right now there's only one built in
+  strategy, but more will be coming in the future.
+  
+  Alternately, you will configure an ASO so that you can control how it is instantiated.  You may need to inject some values into the ASO
+  when it is first created, or otherwise initialize it.  In this second case, you may provide an
+  {{{../../apidocs/org/apache/tapestry/services/ApplicationStateCreator.html}ApplicationStateCreator}} object, which will be called upon to create the ASO
+  as necessary.  This is also the technique to use when you want your ASO to be represented by an <interface> rather than a <class>: you need to provide
+  a creator that knows about the class that implements the interface.
+  
+  Contributions to the tapestry.ApplicationStateManager are used to configure an ASO.  From your application's module:
+  
++----+
+  public void contributeApplicationStateManager(MappedConfiguration<Class, ApplicationStateContribution> configuration)
+  {
+    ApplicationStateCreator<MyState> creator = new ApplicationStateCreator<MyState>()
+    {
+      public MyState create()
+      {
+        return new MyState(new Date());
+      }
+    };
+  
+    configuration.add(MyState.class, new ApplicationStateContribution("session", creator));
+  }
++---+
+
+  Here, we have an ASO type of MyState, and we're providing a creator for it.  We've dolled the creator up with some generic types, but
+  that isn't essential. 
+  
+  Our creator creates a new MyState instance using an alternate constructor that takes the current date and time.  Again, just an
+  example.
+  
+  Finally, we create an 
+  {{{../../apidocs/org/apache/tapestry/services/ApplicationStateContribution.html}ApplicationStateContribution}}
+  identifying the strategy name and the creator, and give that to the configuration.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/assets.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/assets.apt
new file mode 100644
index 0000000..6d0a8bf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/assets.apt
@@ -0,0 +1,101 @@
+ ----
+  Assets
+ ----
+ 
+Assets
+
+  Assets are any kind of file that may be downloaded to a client web browser in addition to the dynamically generated HTML.
+  
+  Assets are most often images, stylesheets, and JavaScript libraries.
+  
+  Normal assets are stored in the web application's context folder ... stored inside the web application WAR file in the ordinary way.
+  
+  Tapestry will also make files stored <on the classpath>, with your Java class files, visible to the web browser.
+  
+  Assets are exposed to your code as instances of the {{{../../apidocs/org/apache/tapestry/Asset.html}Asset}} interface.
+  
+Injecting Assets
+
+  Components learn about assets via injection.  The 
+  {{{inject.html}Inject}} annotation allows Assets to be injected into components as read-only properties.  The path to
+  the resource is specified using the
+  {{{../../apidocs/org/apache/tapestry/annotation/Path.html}Path}} annotation.
+  
++----+
+  @Inject
+  @Path("context:images/tapestry_banner.gif")
+  private Asset banner;
++----+
+
+  Assets are located within <domains>; these domains are identified by the prefix on the Inject annotation's value.
+  
+  If the prefix is omitted, the value will be interpreted as a path relative to the Java class file itself, within
+  the "classpath:" domain. This is often used when creating component libraries, where the assets used by the components
+  are packaged in the JAR with the components themselves.
+  
+  Unlike elsewhere in Tapestry, <case matters>. This is because Tapestry is dependenent on the Servlet API and the Java runtime
+  to access the underlying files, and those APIs, unlike Tapestry, are case sensitive. Be aware that some <operating systems> (such as Windows)
+  are case insenitive, which may mask errors that will be revealed at deployment (if the deployment operating system is case sensitive,
+  such as Linux).
+  
+Relative Assets
+
+  You can use relative paths with domains (if you omit the prefix):
+
++----+
+  @Inject
+  @Path("../edit.png")
+  private Asset icon;
++----+  
+
+  Since you must omit the prefix, this only makes sense for components packaged in a library for reuse.
+  
+Symbols For Assets
+
+  {{{http://tapestry.apache.org/tapestry5/tapestry-ioc/symbols.html}Symbols}} inside the annotation value are
+  expanded. This allows you to define a symbol and reference it as part of the path.  For example, you could contribute
+  a symbol named "skin.root" as "context:/skins/basic" and then reference an asset from within it:
+  
++----+
+  @Inject
+  @Path("${skin.root}/style.css")
+  private Asset style;
++----+
+
+  An override of the skin.root symbol would affect all references to the named asset.
+  
+Localization of Assets
+
+  Assets are {{{localization.html}localized}}; Tapestry will search for a variation of the file appropriate
+  to the effective locale for the request. In the previous example, a German user of the application may
+  see a file named <<<edit_de.png>>> (if such a file exists).
+  
+New Asset Domains
+
+  If you wish to create new domains for assets, for example to allow assets to be stored on the file system or in a database,
+  you may define a new
+  {{{../../apidocs/org/apache/tapestry/services/AssetFactory.html}AssetFactory}}
+  and contribute it to the AssetSource service configuration.  
+  
+Simplified Paths
+
+  Private assets (assets on the classpath) normally have the form: <<</assets/foo/bar/Baz.css>>> where <<<Baz.css>>> is a file inside the <<<foo.bar>>> Java package.
+  In other words, the package name is converted into a path underneath the virtual folder, <<</assets/>>>.  
+  
+  You are given some control over this, allowing for shorter paths.  The ClasspathAssetAliasManager service has a mapped configuration. The map keys
+  are logical folder names, and the map values are the complete classpath.  For example, Tapestry itself makes this contribution:
+  
++----+
+    public static void contributeClasspathAssetAliasManager(
+            MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("tapestry", "org/apache/tapestry");
+    }
++---+
+
+  Thus, the generated URLs may say <<</assets/tapestry/Foo.gif>>> but the underlying file will be <<</org/apache/tapestry/Foo.gif>>> (within the classpath).
+  
+  Care should be taken to not create overlapping mappings, as the results would not be predictable.  
+
+
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/beaneditform.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/beaneditform.apt
new file mode 100644
index 0000000..75eb940
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/beaneditform.apt
@@ -0,0 +1,232 @@
+ --- 
+ Using the BeanEditForm Component
+ ---
+ 
+Using the BeanEditForm Component
+
+  Tapestry includes a powerful component capable of generating a complete create/edit user interface for a typical JavaBean, BeanEditForm.
+  
+  BeanEditForm analyzes the the properties of the bean, locating just those properties that are readable and writable. It filters down
+  to properties whose type is mapped to a known editor (this is described in more detail below).
+  
+  The default ordering for properties is in the order in which the <getter methods> for the properties are defined.
+  When a super-class defines edittable properties, those are ordered before sub-class properties.
+  
+* Supported Types
+
+  The default set of property types supported by BeanEditForm:
+  
+  * String: as a text field
+  
+  * Number: as a text field
+  
+  * Enum: as a drop-down list
+  
+  * Boolean: as a checkbox
+  
+  []
+  
+  Resolving a property type to an editor type involves a search up the inheritance hierarchy: thus the super-type of Integer, Long, BigDecimal, etc. is
+  Number, which uses a text field for data entry.
+  
+  The list of supported property types is extensible (this is documented below).
+    
+    
+* Automatic Object Creation
+
+  When a page is rendered, the BeanEditForm component will read its object parameter as the JavaBean to edit (with the current properties
+  of the JavaBean becoming the defaults for the various fields).  Likewise, when the form is submitted by the user, the object parameter
+  is read and its properties populated from the request.
+  
+  If the object does not exist, it will be created as needed. The type is determined from the property type, which should be a specific type
+  in order for automatic creation to operate properly.
+  
+* Implicit Object Binding
+
+  If the object parameter is not bound, then an implicit binding to a property of the containing component is made. The bound property will be
+  the BeanEditForm component's id, if such a property exists.  Thus you may typically give the BeanEditForm component an id (that matches a property)
+  and not have to bind the object parameter.
+  
+* Non-Visual Properties
+
+  In some cases, a property may be updatable and of a supported type for editing, but should not be presented to the user for editing: for example,
+  a property that holds the primary key of a database entity. In such a case, the
+  {{{../../apidocs/org/apache/tapestry/beaneditor/NonVisual.html}NonVisual}} annotation may be applied to the property (either the getter
+  or the setter method). 
+    
+* Default Validation
+
+  Default validation for fields is primary determined by property type.
+  
+  If desired, additional validation may be specified using the 
+  {{{../../apidocs/org/apache/tapestry/beaneditor/Validate.html}Validate}} annotation.
+  
+* Property ordering
+
+  By default, the order in which properties are presented is as defined above (order of the getter method).
+  The {{{../../apidocs/org/apache/tapestry/beaneditor/Order.html}Order}} annotation may be used to modify the normal ordering.
+  
+* Default Label
+
+  Tapestry will attempt to provide a reasonable default label for each field, based on the property name being emitted.  The property name
+  is capitalized, and spaces are added before case changes, thus property "name" becomes label "Name" and property "streetAddress" becomes label
+  "Street Address".  
+  
+  BeanEditForm also searches for a label for the field in the containing component's message catalog.  The message key is the property name suffixed with "-label".
+  If such a label is found, it takes precedence.
+  
+Property Editor Overrides
+
+  You may override the editor for any particular property, using the a block parameter to the BeanEditForm component.  
+  
+  An editor normally consists of a Label component and some form of field component (such as TextField or TextArea).
+  
+  For example, you may want to selectively use a PasswordField component:
+  
++---+
+  <t:beaneditform object="loginCredentials">
+    <t:parameter name="password">
+      <t:label for="password"/>
+      <t:passwordfield t:id="password" value="loginCredentials.password"/>
+    </t:parameter>
+  </t:beaneditform>
++---+
+
+  The other fields will render normally (using the built-in editors).
+  
+Customizing the BeanModel
+
+  You may want to customize the BeanModel further, to remove from the form properties that should not be editable by the user,
+  and to change the order in which properties are presented within the form.
+  
+  The BeanEditForm component has two parameters for this purpose:
+  
+  * remove: A comma separated list of property names to remove from the model.
+  
+  * reorder: A comma separated list of property names indicating the desired order.
+  
+  []
+  
+  If a model has more properties that are listed in the reorder parameter, then the additional properties will be ordered at the end of the form.
+  
+  Note that these parameters <modify> the BeanModel.
+    
+Providing the BeanModel
+
+  The BeanEditForm component operates in terms of a {{{../../apidocs/org/apache/tapestry/beaneditor/BeanModel.html}BeanModel}}, which describes
+  the properties, their presentation order, labels and so forth.
+  
+  Normally, the BeanEditForm automatically creates the BeanModel as needed, based on the type of object bound to its object parameter.
+  
+  Alternately, the BeanModel can be supplied as the model parameter. This can be useful in situations where the remove and reorder parameters
+  are insufficient.  For example, if the the type of the property being edited is an interface type, it may be useful to provide
+  an explicit BeanModel around an underlying implementation class.
+  
+  The model can be created when the page is first instantiated:
+  
++---+
+public class MyPage
+{
+  @Inject
+  private BeanModelSource beanModelSource;
+  
+  @Inject
+  private ComponentResources resources;
+  
+  @Retain
+  private BeanModel model;
+
+  @Property
+  private MyBean bean;
+  
+  {
+     model = beanModelSource.create(MyBean.class, true, resources);
+     
+     // Make other changes to model here.
+  }  
+  
+
+  public BeanModel getModel() { return model; }
+}
++---+
+
+  And, in the component template, the built model can be passed to the BeanEditForm component explicitly:
+
++---+
+  <t:beaneditform  object="bean" model="model"/>
++--+
+
+Adding New Property Editors
+
+  Adding a new property editor is a three step process.
+  
+  First, decide on a logical name for the data type.  For example, you may decide that the BigDecimal type will represent currency in your application, so name the data type "currency".
+  
+  Next, you must make contributions to the
+  {{{../../apidocs/org/apache/tapestry/services/DataTypeAnalyzer.html}DataTypeAnalyzer}} or
+  {{{../../apidocs/org/apache/tapestry/services/DefaultDataTypeAnalyzer.html}DefaultDataTypeAnalyzer}} services to match properties to your new name.
+  
+  DataTypeAnalyzer is a chain of command that can make match properties to data types based on property type or annotations on the property.  In general, 
+  DefaultDataTypeAnalyzer is used, as that only needs to consider property type.  DefaultDataTypeAnalyzer matches property types to data types, based on a search up
+  the inheritance path.
+  
++---+
+public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class, String> configuration)
+{
+  configuration.add(BigDecimal.class, "currency");
+}
++---+
+
+  You must provide an editor for the "currency" data type.  An editor is a block of a page of the application; this page is not normally rendered itself, but acts as a container for
+  one or more blocks.
+  
++---+
+public class AppPropertyEditBlocks
+{
+    @Environmental
+    private PropertyEditContext context;
+  
+    @Component(parameters =
+    { "value=context.propertyValue", "label=prop:context.label",
+            "translate=prop:currencyTranslator", "validate=prop:currencyValidator",
+            "clientId=prop:context.propertyId" })
+    private TextField currency;
+    
+    public PropertyEditContext getContext() { return _context; }
+    
+    public FieldValidator getCurrencyValidator()
+    {
+      return context.getValidator(_currency);
+    }
+    
+    public Translator getCurrencyTranslator()
+    {
+      return ...;
+    }
+}
++---+
+
+  The editor is a block inside the component template:
+  
++---+
+  <t:block id="currency">
+    <t:label for="currency"/>
+    <t:textfield t:id="currency" size="10"/>
+  </t:block>
++--+
+
+  Finally, we tell the BeanEditForm component about the editor via a contribution to the 
+  {{{../../apidocs/org/apache/tapestry/services/BeanBlockSource.html}BeanBlockSource}} service:
+  
++---+
+public static void contributeBeanBlockSource(Configuration<BeanBlockContribution> configuration)
+{
+  configuration.add(new BeanBlockContribution("currency", "AppPropertyEditBlocks", "currency", true));
+}
++--+
+
+  Now, when the BeanEditForm sees a property of type BigDecimal, it will map that to datatype "currency" and from there
+  to the currency block of the AppPropertyEditBlocks page of the application.
+   
+
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/coercion.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/coercion.apt
new file mode 100644
index 0000000..a70fb2d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/coercion.apt
@@ -0,0 +1,50 @@
+ ----

+ Parameter Type Coercions

+ ----

+ 

+Parameter Type Coercions

+

+  Tapestry automatically handles type coercions for parameters.

+  

+  Type coercions occur when a value passed into a parameter (as bound in template or

+  in an annoation) does not match the type of the parameter.

+  

+  For example, consider the Count component:

+  

++---+

+public class Count

+{

+    @Parameter

+    private int start = 1;

+

+    @Parameter(required = true)

+    private int end;

+

+    @Parameter

+    private int value;

+    

+    . . .

++---+

+

+  Here, the type of all three parameters is int.

+  

+  However, it is likely that the component will be used as so:

+  

++---+

+  Merry Christmas: <t:count end="3"> Ho! </t:count>

++---+

+

+  A bare whole number is interpreted by the prop binding prefix as a long. So this is the <long> value 3.

+  

+  Tapestry will automatically coerce the bound value, a long, to the parameter's type, int. This may be a lossy coercion (if the long represents a number larger

+  than can be stored in an int).

+  

+TypeCoercer Service

+

+  The TypeCoercer service is responsible for this type coercion. This service is part of the tapestry-ioc module, and 

+  is {{{../../tapestry-ioc/coerce.html}documented there}}.  The service

+  is quite extensible, allowing for new types and coercions to be added easily.  The TapestryModule contributes a few additional

+  coercions into the TypeCoercer service.

+  

+  

+                
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/component-classes.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/component-classes.apt
new file mode 100644
index 0000000..de171e5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/component-classes.apt
@@ -0,0 +1,233 @@
+ ---

+  Component Classes

+ ----

+ 

+Component Classes

+

+  Component classes in Tapestry 5 are much easier than in Tapestry 4.  There are no base classes to extend from, the classes are concrete (not abstract), and there's no XML file. There is still

+  a bit of configuration in the form of Java annotations, but

+  those now go directly onto fields of your class, rather than on abstract getters and setters (the case in Tapestry 4).  

+  

+  Classes for pages, for components and for component mixins are all created in an identical way.

+

+* Component Class Basics

+

+  Creating page and component classes in Tapestry 5 is a breeze.

+  

+  Unlike Tapestry 4, in Tapestry 5, component classes are not <abstract>, nor do

+  they extend from framework base classes. They are pure POJOs (Plain Old Java Objects).

+  

+  There are only a few constraints:

+  

+  * The classes must be public.

+  

+  * The classes must be in the correct package, as per the {{{conf.html}application configuration}}.

+  

+  * The class must have a standard public, no arguments constructor.

+  

+  []

+  

+  Here's a very basic component:

+  

+  

++----+

+package org.example.myapp.components;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.annotation.BeginRender;

+

+public class HelloWorld

+{

+    @BeginRender

+    void renderMessage(MarkupWriter writer)

+    {

+        writer.write("Bonjour from HelloWorld component.");

+    }

+}

++----+  

+  

+  This component's only job is to write out a fixed message. The

+  {{{../../apidocs/org/apache/tapestry/annotation/BeginRender.html}BeginRender}} annotation is

+  a type of <{{{rendering.html}component lifecycle annotation}}>, a method annotation that instructs

+  Tapestry when and under what circumstances to invoke methods of your class.

+ 

+  In another departure from Tapestry 4, these methods are not necessarily public; they

+  can have any visibility you like.

+  

+Component Packages

+

+  Component classes must exist within an appropriate package (this is necessary for runtime code transformation

+  and class reloading to operate).

+  

+  These packages exist under the application's root package.

+  

+  For pages, place classes in <root>.<<pages>>.  Page names are mapped to classes within this package.

+  

+  For components, place classes in <root>.<<components>>.  Component types are mapped to classes within this package.

+  

+  For mixins, place classes in <root>.<<mixins>>.   Mixin types are mapped to classes within this package.

+  

+  In addition, it is common for an application to have base classes, often <abstract> base classes, that should not be directly referenced. These

+  should not go in the <<pages>>, <<components>> or <<mixins>> packages, because they then look like valid pages, components or mixins. Instead,

+  use the <root>.<<base>> package to store such base classes.

+  

+Sub-Folders / Sub-Packages

+

+  Classes do not have to go directly inside the package (pages, components, mixins, etc.). It is valid to create a sub-package 

+  to store some of the classes.  The sub-package name becomes part of the page name or component type.  Thus you might define a page component 

+  <<<com.example.myapp.pages.admin.CreateUser>>> and the logical page name (which often shows up inside URLs) will be <<admin/CreateUser>>.

+  

+  Tapestry performs some simple optimizations of the logical page name (or component type, or mixin type).  It checks to see if the package name

+  is either a prefix or a suffix of the unqualified class name (case insensitively, of course) and removes the prefix or suffix if so.  The net result is

+  that a class name such as <<<com.example.myapp.pages.user.EditUser>>> will have a page name of <<<user/Edit>>> (<not> <<<user/EditUser>>>).  The goal here is to provide

+  shorter, more natural URLs.

+  

+Pages vs. Components

+

+  The distinction in Tapestry 5 between pages and component is very, very small.  The only

+  real difference is the package name:  <root>.<<pages>>.<PageName> for pages,

+  and <root>.<<components>>.<ComponentType> for components.

+  

+  In Tapestry 4, there was a much greater distinction between pages

+  and components, which showed up as seperate interfaces and a hierarchy of

+  abstract implementations to extend your classes from.

+  

+  In Tapestry 5, the "page" is still somewhat present, but is really

+  an internal Tapestry class. Page components are simply the <root component> of a page's

+  component tree.

+  

+Class Transformation

+

+  Tapestry uses your class as a starting point. It <transforms> your class at runtime. This is necessary

+  for a number of reasons, including to address how Tapestry pools pages between requests.

+  

+  For the most part, these transformations are both sensible and invisible. In a few limited cases, they

+  are maginally {{{http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html}leaky}} -- for instance,

+  the requirement that instance variables be private -- but we feel that the programming

+  model in general will support very high levels of developer productivity.

+  

+  Because transformation doesn't occur until <runtime>, the build stage of your application is not

+  affected by the fact that you are creating a Tapestry application. Further, your classes are absolutely

+  simple POJOs during unit testing.

+  

+Live Class Reloading

+

+  Component classes are monitored for changes by the framework. 

+  {{{reload.html}Classes are reloaded when changed.}} This allows you to build your application

+  with a speed approaching that of a scripting environment, without sacrificing any of the power

+  of the Java platform.

+  

+  And it's fast!  You won't even notice that this magic class reloading has occured. 

+  

+  The net result: super productivity --- change your class, see the change instantly. This is designed to be

+  a blend of the best of scripting environments (such as Python or Ruby) with all the speed and power of Java backing it up.

+  

+  However, class reloading <only> applies to component classes.  Other classes, such as service interfaces and implementations, or

+  other data objects, are loaded by the normal class loader and not subject to live class reloading.

+  

+Instance Variables

+

+  Tapestry components may have instance variables (unlike Tapestry 4, where you had to 

+  use <abstract properties>). 

+  

+  <<Instance variables must be private.>> Tapestry must perform runtime class modifications to

+  support instance variables, and may only do so for private variables. You may have

+  non-private variables in your class, but you may then see unexpected behavior in

+  a production application because of how Tapestry pools and reuses pages and components. Tapestry

+  will log an error for each component class that contains fields that are neither static nor private.  

+  

+  Be aware that you will need to provide getter and setter methods to access your classes'

+  instance variables. Tapestry <does not> do this automatically unless you provide

+  the {{{../../apidocs/org/apache/tapestry/annotation/Property.html}Property}} annotation on the field.

+    

+  

+Transient Instance Variables

+

+  Unless an instance variable is decorated with an annotation, it will be a

+  <transient> instance variable. This means that its value resets to its

+  default value

+  at the end of reach request (when the

+  {{{lifecycle.html}page is detached from the request}}).

+  

+  If you have a variable that can keep its value between requests and you would like

+  to defeat that reset logic, then you should attach a

+  {{{../../apidocs/org/apache/tapestry/annotation/Retain.html}Retain}} annotation to the field.  You should take

+  care that no client-specific data is stored into such a field, since on a later request

+  the same page <instance> may be used for a different user. Likewise, on a later request for the <same> user,

+  a <different> page instance may be used.

+  

+  Use {{{persist.html}persistent fields}} to hold information from one request to the next.

+  

+  Further, final fields are (in fact) final, and will not be reset.

+  

+Constructors

+

+  Tapestry will instantiate your class using the default, no arguments constructor.  Other constructors will

+  be ignored.

+  

+Injection

+

+  {{{inject.html}Injection}} of dependencies occurs at the field level, via additional annotations.  At runtime,

+  fields that contain injections become read-only.

+  

+Parameters

+

+  {{{parameters.html}Component parameters}} are also identified using private fields of your class, with

+  the {{{.../apidocs/org/apache/tapestry/annotation/Parameter.html}Parameter}} annotation.

+  

+Persistent Fields

+

+  Fields may be annotated so that they {{{persist.html}retain their value across requests}}.  

+  

+{Embedded Components}

+

+  Components often contain other components.  Components inside another component's template are called <embedded components>.  

+  The containing component's

+  {{{templates.html}template}} will contain special elements, in the Tapestry namespace, identifying where the the embedded components go.

+  

+  You can define the type of component inside template, or you can create an instance variable for the component

+  and use the

+  {{{../../apidocs/org/apache/tapestry/annotation/Component.html}Component}} annotation to define the component type

+  and parameters. 

+  

+  Example:

+  

++---+

+package org.example.app.pages;

+

+import org.apache.tapestry.annotation.Component;

+import org.apache.tapestry.annotation.Property;

+import org.example.app.components.Count;

+

+public class Countdown

+{

+    @Component(parameters =

+    { "start=5", "end=1", "value=countValue" })

+    private Count count;

+

+    @Property

+    private int countValue;

+}

++---+

+

+  The above defines a component whose embedded id is "count" (this id is derived from the name of the field).  The type

+  of component is org.example.app.components.Count.  

+  The start and end parameters of the Count component are bound to literal values, and the value

+  parameter of the Count component is bound to the countValue property of the Countdown component.

+  

+  Technically, the start and end parameters should be bound to properties, just the the value parameter.  However,

+  certain literal values, such as the numeric literals in the example,

+  are accepted by the prop: binding prefix even though they are not actually properties (this is largely as a convienience

+  to the application developer).  We could also use the "literal:" prefix, <<<"start=literal:5">>> which accomplishes

+  largely the same thing.

+  

+  You may specify additional parameters inside the component template, but parameters in the component class

+  take precendence.  

+  

+  <<TODO: May want a more complex check; what if user uses prop: in the template and there's a conflict?>>

+  

+  You may override the default component id (as derived from the field name)

+  using the id() attribute of the Component annotation.

+  

+  If you define a component in the component class, and there is no corresponding  element in the template,

+  Tapestry will log an error.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/conf.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/conf.apt
new file mode 100644
index 0000000..49121b2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/conf.apt
@@ -0,0 +1,225 @@
+ ---

+ Configuring Tapestry

+ ---

+ 

+Configuring Tapestry

+

+  Tapestry runs on top of the standard Java Servlet API.  To the servlet container,

+  such as Tomcat, Tapestry appears as a <servlet filter>.  This gives Tapestry great

+  flexibility in matching URLs without requiring lots of configuration inside web.xml.

+  

+* web.xml

+

+  The majority of configuration occurs inside the servlet deployment descriptor,

+  WEB-INF/web.xml.

+  

+  Most of the configuration is boilerplate; the same for all applications.

+  

+  The application specific configuration is to identify the root application package.

+  Tapestry uses this package name to locate your page and component classes.

+  

+  Page classes must go in the pages sub-package, and components must go in the

+  components sub-package.

+  

+  You specify the root package as a context parameter:

+  

++----+

+<!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>My Tapestry Application</display-name>

+    <context-param>

+        <param-name>tapestry.app-package</param-name>

+        <param-value>org.example.myapp</param-value>

+    </context-param>

+    <filter>

+        <filter-name>app</filter-name>

+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>

+    </filter>

+    <filter-mapping>

+        <filter-name>app</filter-name>

+        <url-pattern>/*</url-pattern>

+    </filter-mapping>

+</web-app>

++----+  

+

+  You may name the filter whatever you want, though "app" is a common convention.

+  

+  In this example, page classes will be stored in the <<<org.example.myapp.pages>>> package (or in sub-packages below).

+  Likewise, component classes will be stored in the <<<org.example.myapp.components>>> package.

+  

+* Tapestry Requests vs. Container Requests

+

+  The Tapestry filter matches all the requests that apply to Tapestry, and passes the rest off to the

+  servlet container.

+  

+  Actual files inside the web application take precedence over Tapestry pages, in situation where there

+  would be a naming conflict.  

+  

+  Tapestry recognizes the <root URL>, where the servlet path is simply "/", and renders the application page "Start",

+  if it exists.  

+  

+* Tapestry IoC Configuration

+

+  Most other configuration occurs inside your application's module builder class.  The application module builder

+  will often define new services, provide overrides of services, or make contributions to service configurations.

+  

+  Tapestry looks for a module builder class in the services package (under the root package). It capitalizes

+  the \<filter-name\> and appends "Module".  In the previous example, the module builder class

+  would be org.example.myapp.services.AppModule.

+  

+  If such a class exists, it is added to the IoC Registry. It is not an error for your application to not have a module, though

+  any non-trivial application will have a module.

+  

+* Configuration Symbols

+

+  Tapestry may also be configured via {{{../../tapestry-ioc/symbols.html}symbols}}.  A certain number of built-in services

+  (some of which are not even public) are configured via symbols.  These symbols can be overridden

+  by contributing to the ApplicationDefaults service configuration, or on the command line

+  by defining JVM System Properties with the -D command line option.

+

+  These symbols are always defined in terms of strings, that are coerced to the appropriate type (a number,

+  a boolean, etc.).  Of special note are <time intervals>, which are specified in a

+  {{{../../apidocs/org/apache/tapestry/ioc/util/TimeInterval.html}particular format}}.

+

+

+  [tapestry.compress-whitespace]

+    A flag (true or false).  When true (the default) whitespace in component templates is compressed by default

+    (this can be fine-tuned using the standard xml:space attribute on an element in the template).

+    When this flag is false, then whitespace is retained by default (but can still be overridden).

+

+  [tapestry.default-cookie-max-age]

+    The default time interval that cookies created by Tapestry will be kept in the client web browser.

+    The dfault value is equal to one week. 

+    

+    Primarily, this is used with a cookie that exists 

+    to track the preferred user locale.

+

+    The default is "7 d" (that is, seven days).

+

+  [tapestry.default-stylesheet]

+    The default stylesheet automatically injected into every rendered HTML page.  Many Tapestry components assume that

+    this stylesheet is available.  All the classes defined in the stylesheet are prefixed with "t-". The exact contents

+    of the stylesheet are subject to change at any time (they are considered internal), so replacing the stylesheet,

+    rather than overriding selected rules within it, entails some risk.

+

+    The default is org/apache/tapestry/default.css, stored on the classpath.

+  

+  [tapestry.file-check-interval]

+    Time interval between file system checks. During a file system check, only a single thread is active (all others

+    are blocked) and any files loaded are checked for changes (this is part of {{{reload.html}automatic component reloading}}).

+

+    The default is "1 s" (one second),  and is usually overridden with a higher value in production (say, between one and five minutes).

+

+  [tapestry.file-check-update-timeout]

+    Time interval that Tapestry will wait to obtain the exclusive lock needed for a file check. The default is "50 ms" (50 milliseconds).

+

+    If the exclusive lock can't be obtained in that amount of time, the request will proceeed normally (without the check),

+    but each successive request will attempt to get the lock and perform the check until successful.

+

+  [tapestry.force-absolute-uris]

+     A flag (true or false). When false (the default), Tapestry will attempt to optimize URIs that it generates, using

+     relative URIs when such URIs are shorter than absolute URIs.  You will see some savings when you make generous

+     use of libraries, sub-folders and page activation contexts ... otherwise, no significant difference.

+

+     When true, all URIs will be absolute URIs (including the

+     context path, and the complete path for the request).

+

+  [tapestry.production-mode]

+    A flag (true or false) indicating whether the application is running in production or in development. The default

+    is true, which means that runtime exceptions are not reported with full detail (only the root exception message

+    is displayed, not the entire stack of exceptions, properties and other information shown in development mode).

+

+  [tapestry.page-pool.active-window]

+    The time interval that an instantiated page instance may be cached before being removed. As pages are

+    returned to the pool, they are time stamped. Periodically (as per the file check interval),

+    the pool is scanned for page instances that have not been used recently; those that are outside

+    the active window are discarded.  This is used to free up unnecessary page instances after

+    a request surge.

+

+    The default is "10 m" (10 minutes).

+    

+  [tapestry.page-pool.hard-limit]

+    The absolute maximum number of page instances (for a particular page name / locale combination) that Tapestry

+    will create at any time.  If this number is reached, then requests will fail because a page instance is not

+    available ... this can happen as part of a denial of service attack.  For this value to have any meaning, it

+    should be lower than the number of threads that the servlet container is configured to use when processing

+    requests.

+

+    The default is 20 page instances.

+

+  [tapestry.page-pool.soft-limit]

+    The number of pages in the page pool (for a given page name / locale combination) before which Tapestry will

+    start to wait for existing pages to be made available.  Under this limit of pages, Tapestry will simply

+    create a new page instance if no existing instance is readily available.  Once the soft limit is reached,

+    Tapestry will wait a short period of time (the soft wait interval) to see if an existing page instance

+    is made available.  It will then create a new page instance (unless the hard limit has been reached).

+

+    The default is 5 page instances.    Remember that page pooling is done seperately for each

+    page (and localization of the page).  

+

+  [tapestry.page-pool.soft-wait]

+    The time interval that Tapestry will wait for a page instance to become available before deciding whether to create

+    an entirely new page instance.  The default is "10 ms".

+

+  [tapestry.secure-page]

+    If true, then the page may only be accessed via HTTPS.  The {{{../../apidocs/org/apache/tapestry/annotation/Secure.html}@Secure}}

+    annotation will set this value to true.

+

+  [tapestry.scriptaculous]

+    The path to the embedded copy of {{{http://script.aculo.us/}script.aculo.us}} packaged with Tapestry. This value may be overridden

+    to use a different version of the script.aculo.us library. Tapestry's default version is 1.8.0

+    (including Prototype 1.6.0).

+

+  [tapestry.start-page-name]

+    The logical name of the start page, the page that is rendered for the <root URL>.  This is normally "start".    

+

+  [tapestry.supported-locales]

+    A comma-separated list of supported locales.  Incoming requests as "narrowed" to one of these locales, based on closest match.

+    If no match can be found, the first locale in the list is treated as the default.

+

+    The default is (currently) "en,it,zn_CH".  As the community contributes new localizations of the necessary messages files,

+    this list will expand.  Note that the Tapestry quickstart archetype overrides the factory default, forcing the

+    application to be localized only for "en".

+

+  [tapestry.suppress-redirect-from-action-requests]

+    Normally, Tapestry responds to action requests (such as form submissions) by sending a client-side redirect

+    to the renderring page.  This has a lot of benefits in terms of improving browser navigation, making sure

+    URLs are bookmarkable, and so forth.  However, it has a cost: more data stored persistently in the session,

+    and a double-request for each user action (one action request, one render request).

+

+    Setting this symbol to "true" changes the Tapestry behavior to make it more like Tapestry 4: a markup response

+    is sent directly for the action request, no redirect in the middle. This option should be used with care,

+    and only in cases where you are certain that the benefits outweigh the disadvantages.

+

+

+Ignored Paths

+

+  In some cases, you may use Tapestry is concert with other servlets.  This can cause problems, since

+  Tapestry (being a servlet filter) may see URLs intended for another servlet and attempt to process them.

+

+  The Servlet API does not provide Tapestry with any clues about what other servlets are available in the

+  web application.  Instead, you must configure Tapestry to ignore paths intended for other servlets.

+

+  The IgnoredPathsFilter service is the method for this kind of configuration.  Its configuration

+  is an unordered collection of regular expression patterns.  A request whose path matches any of these

+  patterns is <<not>> processed by Tapestry.

+

+  For example, say you are using {{{http://getahead.org/dwr/}Direct Web Remoting}}.  You'll likely have

+  the servlet path /dwr mapped to the Direct Web Remoting servlet.

+

+  You contribution would look like:

+

+---

+  public static void contributeIgnoredPathsFilter(UnorderedCollection<String> configuration)

+  {

+    configuration.add("/dwr/.*");

+  }

+---

+

+  The regular expression matches any path that begins with "/dwr/".

+

+  The regular expressions provided in the configuration are always compiled with case insensetivity enabled.

+

+  Also note that actual files in your web application (images, stylesheets, etc.) are always ignored by Tapestry.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/css.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/css.apt
new file mode 100644
index 0000000..ac461bf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/css.apt
@@ -0,0 +1,56 @@
+ ---
+ Tapestry CSS Support
+ ---
+
+Tapestry CSS Support
+
+  Cascading Style Sheets (CSS) is an important technology, even with Tapestry.  Tapestry works best when the
+  rendered HTML is simple and semantic -- semantic meaning HTML that goes back to its roots, simple, straightforward,
+  with tags used for structure and, as much as possible, details about font, color and layout delegated to CSS.
+
+Default CSS Stylesheet
+
+  Tapestry includes a built-in stylesheet, default.css, is all HTML documents (documents that have an outer
+  \<html\> element and a nested \<head\> element).  The default.css stylesheet is always ordered <first> ... any additional stylesheets
+  will come after.  This allows Tapestry's default styles to be overridden.
+
+  All the styles in the default stylesheet are prefixed with "t-" (for Tapestry).
+
+Adding your own CSS
+
+  A page or component that is rendering the \<head\> tag can add a stylesheet directly in the markup.
+
++---+
+<head>
+  <link href="/css/myapp.css" rel="stylesheet" type="text/css"/>
+  . . .
++---+
+
+  If you want to leverage Tapestry's localization support, you may want to make use of an expansion and the asset: binding prefix:
+
+
++---+
+<head>
+  <link href="${asset:context:css/myapp.css}" rel="stylesheet" type="text/css"/>
+  . . .
++---+
+
+  The "asset:" prefix means that the remainder of the expansion is a path to a resource.  The "context:" part
+  indicates that it should look for the resource in the web application root (src/main/webapp in your workspace).  If you
+  left this out, it would look for the file on the classpath, relative to the component's Java class.
+
+Using the IncludeStylesheet Annotation
+
+ Another approach to adding a stylesheet is to include an
+ {{{../../apidocs/org/apache/tapestry/annotation/IncludeStylesheet.html}IncludeStylesheet}} annotation on your component class:
+
++---+
+@IncludeStylesheet("context:css/myapp.css")
+public class MyComponent
+{
+
+}
++---+
+
+ As with  {{{ajax.html}included JavaScript libraries}}, the stylesheet will only be added once,
+ regardless of the number of components that include it via the annotation.
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/dom.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/dom.apt
new file mode 100644
index 0000000..0ac7a25
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/dom.apt
@@ -0,0 +1,158 @@
+ ---

+ Document Object Model

+ ---

+ 

+Document Object Model

+

+  Tapestry 5 takes a very different approach to markup generation than Tapestry 4,

+  or most other frameworks.

+  

+* Tapestry 4 Approach

+  

+  In Tapestry 4, markup generation was based on generating a character stream.

+  At the lowest level, the fact that the output was in a markup format such as HTML, XHTML

+  or WML was not known.  Higher levels, such as the IMarkupWriter interface (and its

+  implementations) provide the concept of markup generation: elements, attributes, start

+  tags and end tags.

+

+  Often, components would work together to generate markup. A common example would

+  be a Form component and the many form control components it contains (such

+  as TextField, Checkbox, etc.).  The Form could not fully render until all

+  such enclosed components had rendered first. 

+  

+  IMarkupWriter supported <nested writers>. Nested writers are a way to buffer output

+  until needed. A Form component would render its body using a nested writer, then

+  write out its \<form\> and \<input type="hidden"\>  elements, as well as the nested,

+  buffered body.

+  

+  This technique breaks down when two elements are peers, and not in a parent/child

+  relationship. For example, the rendering of a FieldLabel component is affected by its

+  companion TextField component. Handling these cases in Tapestry 4 required a number of

+  kludges and special cases.

+  

+* Tapestry 5 Approach

+

+  Tapestry 5 components render out a DOM, a Document Object Model.  This is a tree of

+  nodes representing elements, attributes and text within a document.

+  

+  The DOM may ultimately be operated upon in a random access manner, rather than

+  the serial (or buffered) approach used in Tapestry 4.

+  

+  A new 

+  {{{../../apidocs/org/apache/tapestry/MarkupWriter.html}MarkupWriter}} interface

+  allows the majority of code to treat the generation of output as a stream. In fact,

+  MarkupWriter is more like a cursor into the DOM tree.

+  

+  Once all rendering is complete, the DOM tree is streamed to the client.  Planned enhancements

+  will control output formatting, including pretty-printing and/or output compression (elimination

+  of all unnecessary whitespace).

+  

+DOM Classes

+

+  The implementation of this DOM is part of Tapestry, despite the fact that several third-party

+  alternatives exist. This represents a desire to limit dependencies for the framework, but also

+  the Tapestry DOM is streamlined for initial creation, and a limited amount of subsequent modification.

+  Most DOM implemenations are more sophisticated, with greater support for querying (often using XPath) and

+  manipulation. 

+    

+  Once the Document object is created, you don't directly create new DOM objects; instead, each

+  DOM object includes methods that create new sub-objects.  This primarily applies to the Element

+  class, which can be a container of text, comments and other elements.

+  

+* {{{../../apidocs/org/apache/tapestry/dom/Document.html}Document}}

+

+  The Document object represents the an entire document, which is to say, an entire response to be

+  sent to the client.

+  

+  Documents will have a single root element.

+  The newRootElement() method is used to create the root element for the document.

+  

+  <<TODO: Support for doctypes, content type, processing instructions, and top-level comments.>>

+  

+* {{{../../apidocs/org/apache/tapestry/dom/Element.html}Element}}

+

+  An element of the document. Elements may have attributes, and they may themselves contain other

+  elements, as well as text and comments.

+  

+  The addAttribute() method adds a new attribute/value pair to the Element.  If an existing attribute

+  with the specified name already exists, then then the new value is ignored. This has implications when

+  different pieces of code try to add attributes to an Element ... the first to add an attribute will "win"

+  

+  Not yet implemented are some basic methods for manipulating the DOM after it is built. Plans are to add

+  a few methods for re-parenting DOM nodes into new elements. In addition, some searching methods may be added.

+  

+  

+{{{../../apidocs/org/apache/tapestry/MarkupWriter.html}MarkupWriter}}

+

+  The MarkupWriter interface allows the structure of the document to be built while maintaining a streaming metaphor.

+  

+* element() and end()

+

+  Calls to element() create a new element within the tree, and may provide attributes for the new element as well.  

+  Calls to write(), writeln() and writef() write text nodes

+  within the current element.  <Every call to element() should be matched with a call to end()>, which is used to move

+  the current node up one level.

+

+    

++-----+

+

+  writer.element("img", "src", "icon.png", "width", 20, "height", 20, alt, "*");

+  writer.end();

++-----+

+  

+  Note that end() must be called here, even though the \<img\> element is empty (has no body).  If the call to

+  end() is omitted, then later elements created by calls to element() will be 

+  nested <inside> the \<img\> element, which is not desired.

+  

+  Again, <<every call to element() must be matched with a call to end()>>:

+

+  

++-----+

+  writer.element("select", "name", "choice");

+  

+  for (String name : optionsNames)

+  {

+    writer.element("option");

+    writer.write(name);

+    writer.end();

+  }

+  

+  writer.end();

++-------

+    

+

+* attributes()

+  

+  Adds additional name/value pairs to the current element.

+ 

+  When a value is null, no attribute is added.

+  

+  When a new name conflicts with an existing name, the new value is ignored. This gives precedence to the first value specified

+  for an attribute over any subsequent value.

+  

+* write()

+

+  The write() method writes text inside the current element.  It scans the provided text for XML control characters

+  ('\<', '\>', and '&') and converts them to their XML entity equivalents ('&lt;', '&gt;', and '&amp;').  The result is correct, safe,

+  HTML/XML output even when the content (which may come from a template, or from an external source such as a database)

+  contains such problematic characters.

+   

+* writef()

+

+  The writef() method formats an number of arguments.  It uses a java.util.Formatter.  It is a convience for formatting that ultimately

+  invokes write().

+  

+* writeRaw()

+

+  The writeRaw() method writes unfiltered text into the DOM.  When the DOM is rendered to markup, the provided string is written to the

+  output stream exactly as-is. Care should be taken, as this can easily result invalid markup, or even markup that is not well formed.

+  

+* comment()

+

+  Adds an XML comment.  The comment delimiters will be supplied by Tapestry:

+  

++----+

+

+  writer.comment("Start of JS Menu code");

+  

++----+

diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/env.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/env.apt
new file mode 100644
index 0000000..8396a71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/env.apt
@@ -0,0 +1,139 @@
+ ----
+ Environmental Services
+ ----
+
+Environmental Services
+
+  Environmental services represent yet another, distinct form of injection.
+
+  Unlike service injection (injection via a service implementation's constructor) or
+  normal component injection (directly into component fields, via the @Inject annotation) where the injected value
+  is always the same, with environmental services, the injected value is very late bound and dynamic.
+
+  Environmental services are often a conduit of communication between an outer component
+  and the components it encloses.
+
+  An example of this is form support; the
+  {{{../ref/org/apache/tapestry/corelib/components/Form.html}Form}}
+  component creates an environmental of type
+  {{{../../apidocs/org/apache/tapestry/services/FormSupport.html}FormSupport}}.  The FormSupport
+  interface allows enclosed components to participate in both the rendering of the Form
+  and the Form's eventual submission. This is how control names and client-side ids are determined, how fields
+   register callbacks so that they can process their part of the submission, and
+  how fields hook themselves to client-side validation.
+
+Using the @Environmental annotation
+
+  The {{{../../apidocs/org/apache/tapestry/annotation/Environmental.html}Environmental}} annotation
+  is used to dynamically connect to a Environmental service provided by an enclosing component.
+
+  A very common Environmental is
+  {{{../../apidocs/org/apache/tapestry/RenderSupport.html}RenderSupport}}, used
+  when generating  {{{ajax.html}client-side JavaScript}}.
+
++---+
+
+  @Inject @Path("${tapestry.scriptaculous}/dragdrop.js")
+  private Asset dragDropLibrary;
+
+  @Environmental
+  private RenderSupport renderSupport;
+
+  void setupRender()
+  {
+    renderSupport.addScriptLink(_dragDropLibrary);
+  }
+
++---+
+
+  Environmental services are, by their nature, per-thread (and therefore per-request).
+
+  Accessing an environmental field causes a lookup, by type, against
+  the {{{../../apidocs/org/apache/tapestry/services/Environment.html}Environment}} service.
+
+  Normally, an environmental of the specified type must be available in the Environment, or an exception
+  is thrown when accessing the field.
+
+  If the value of the Environmental annotation is false, then the environmental value is optional.
+
+
+Placing a value in the environment
+
+  The Environment service has push() and pop() methods to put a value in the Environment, and discard it.
+
+  For example, say you were building a tab-based menu system and you needed to allow an outer TabGroup component
+  to communicate with inner Tab components, to control various aspects of presentation.
+
+  The relevant information could be exposed as an interface, TabModel.
+
++----+
+public class TabGroup
+{
+  @Inject
+  private Environment environment;
+
+  void beginRender()
+  {
+     environment.push(TabModel.class, new TabModelImpl(...));
+  }
+
+  void afterRender()
+  {
+    environment.pop(TabModel.class);
+  }
+}
+
+public class Tab
+{
+  @Environmental
+  private TabModel model;
+
+  void beginRender(MarkupWriter writer)
+  {
+    ...
+  }
+}
++----+
+
+    Notice that when pushing a value into the Environment, you identify its type as well as the
+    instance.  Environment maintains a number of stacks, one for each type.  Thus, pushing a TabModel into
+    the environment won't disturb the RenderSupport or other environmentals already there.
+
+    What's important here is that the code that pushes a environmental onto a stack should also pop it off.
+
+    The enclosed class, Tab, has full access to whatever object was pushed onto the stack by the TabGroup.
+
+    The reason why Environment is a stack is so that a component can, when it makes sense, easily replace
+    or intercept access to an Environmental.
+
+Fundamental Environmentals
+
+  Not all environmentals are pushed into the Environment by components.
+
+  A number of environmentals are initialized as part of page rendering, even before the first
+  component starts to render.  This initialization is accomplished
+  with
+  {{{../../apidocs/org/apache/tapestry/services/MarkupRendererFilter.html}MarkupRendererFilter}}
+  contributions to the
+  {{{../../apidocs/org/apache/tapestry/service/MarkupRenderer.html}MarkupRenderer}} service.
+
+Accessing Environmentals in Services
+
+  The Environmenal annotation only works inside components.
+
+  To access an Environmental inside a service implementation, you must inject the Environment service and obtain values from
+  it using the peek() method.
+
+  If this is something that will occur frequently, it is possible to create a service implementation
+  that is "backed" by the Environment.  For example, RenderSupport is accessible as a normal injection, because
+  a service is built for it in TapestryModule:
+
++---+
+  public RenderSupport buildRenderSupport(EnvironmentalShadowBuilder builder)
+  {
+    return builder.build(RenderSupport.class);
+  }
++----+
+
+   The EnvironmentShadowBuilder service creates a service implementation that delegates to the proper instance
+   in the environment.  The same technique can be used for your own services and environmentals.
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/event.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/event.apt
new file mode 100644
index 0000000..647bbef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/event.apt
@@ -0,0 +1,263 @@
+ ---

+ Component Events

+ ---

+ 

+Component Events

+

+  Component events are the means by which components are made aware of behaviors by the user, such

+  as clicking links and submitting forms.

+  

+  Component events are used for two purposes:

+  

+  * They represent requests initiated by the user, triggered by links and forms in the client web browser.

+    These are described more fully in {{{pagenav.html}page navigation}} and in 

+    {{{request.html}requst processing}}.

+    

+  * They represent flow-of-control within a request, allowing one component to notify its container

+    about some kind of circumstance ("a form was submitted"), or to collect some piece for data

+    from the container.

+    

+  []

+  

+  Often, a navigation request (originating with the user) will spawn a number of flow-of-control

+  requests.  For example, a Form component will be triggered by an action request, and will then

+  send notification events to announce when the form submission is about to be processed, and

+  whether it was succesful or not.

+  

+  In Tapestry 4, you would configure a parameter of a component with the name of a method to invoke

+  when a certain event occured, usually a request from the client.

+  

+  This has some limitations, including the fact that only a single method could be invoked, and that

+  it tied together a component and a method based on a method name, which required careful coordination

+  between the template and the Java code.

+  

+  Tapestry 5 introduces the concept of <event handler methods>, identified via a naming convention, or

+  via the 

+  {{{../../apidocs/org/apache/tapestry/annotation/OnEvent.html}OnEvent annotation}}.  Event handler methods

+  have any visibility, even private (normally they are given package private visibility, to support testing).

+  

+  Rather than configure a component to invoke a particular method, you identify one or more

+  methods to listen for events from that component. A single event handler method may receive notifications from

+  many different components.

+  

+  For example, here's a portion of a page (let's call it "Chooser") that lets the user choose a number between 1 and 10:

+  

++---+

+<p> Choose a number from 1 to 10: </p>

+

+<p>

+    <t:count end="10" value="index">

+        <a t:id="select" t:type="actionlink" context="index">${index}</t:comp>

+    </t:count>

+</p>

++---+

+

+  The ActionLink component creates an action URL.

+  

+  The URL identifies the page that contains the component ("chooser"), the type of event

+  (unless it is "action", the default and most common event type),

+  the id of the component within the page ("select"), plus the additional context value(s).

+  

+  A sample URL: <<<http://localhost:8080/chooser.select/3>>>.

+

+  When there are additional context values, they are appended to the path.

+  

+  This demonstrates a critical difference between Tapestry and a more traditional, action oriented framework.

+  This URL doesn't say what happens when the link is clicked, it identifies <which component is responsible>.

+

+  There's no simple mapping from URL to a piece of code; instead the component sends notifications, in the form

+  of invocations of event handler methods, and Tapestry ensures that the correct bit of code, that you supply,

+  gts invoked.

+  

+   

+  A Java method can be invoked when the link for the component is clicked by the user:

+  

++---+

+  @OnEvent(component = "select")

+  void valueChosen(int value)

+  {

+    this.value = value;

+  }

++---+

+

+  Tapestry has done two things here:

+  

+  * It has identified method valueChosen() as the method to invoke.

+  

+  * It has converted the context value from a string to an integer and passed it into the method.

+  

+  []

+  

+  In the above example, the valueChosen() method will be invoked on the default event, "action", that originates

+  in component <<<choose>>> (and has at least one context value).

+  

+  Some components can emit more than one type of event, in which case you will want to be more specific:

+  

++---+

+  @OnEvent(value = "action", component = "select")

+  void valueChosen(int value)

+  {

+    this.value = value;

+  }

++---+

+  

+  The value attribute of the OnEvent annotation is the name of the event to match.

+  

+  "action" is the name of the default event type; the ActionLink and Form components each use this event type.

+  If you omit the component part of the OnEvent annotation, then you'll recieve notifications from

+  <all> contained components, possibly including nested components (due to event bubbling).

+

+  As elsewhere, the comparison of event type and component id is caseless.

+  

+  You should qualify exactly which component(s) you wish to recieve events from.   Using @OnEvent on a method

+  and not specifying a specific component id means that the method will be invoked for events from <any> component.

+  

+Event Handler Method Convention Names

+  

+  As an alternative to the use of annotations, you may name your events in a specific fashion, and Tapestry will invoke your methods just as if

+  they were annotated.  

+  

+  This style of event handler methods start with the prefix "on", followed by the name of the action.  You may then continue by adding "From" and

+  a capitalized component id.

+  

+  The previous example may be rewritten as:

+  

++---+

+  void onActionFromSelect(int value)

+  {

+    this.value = value;

+  }

++---+  

+

+  Note from Howard: I've found that I prefer the naming convention approach, and reserve the annotation just for situations that don't otherwise fit.  

+  

+Event Handler Method Return Values

+  

+  For page navigation events, the value returned from an event handler method {{{pagenav.html}determines how Tapestry will render a response}}.

+

+Multiple Method Matches

+

+ In some cases, you may have multiple event methods match a single event.

+

+ The order is as follows:

+

+ * Base class methods before sub-class methods.

+

+ * Matching methods within a class in alphabetical order.

+

+ * For a single method name with multiple overrides, by number of parameters, descending.

+

+ []

+

+ There's only rare cases where it makes sense for more than one method to handle an event.

+

+Event Context

+

+  The context values (the context parameter to the ActionLink component) can be any object.

+  However, only a simple conversion to string occurs.  This is in contrast to Tapestry 4, which had

+  an elaborate type mechanism with the odd name "DataSqueezer".

+  

+  Again, whatever your value is (string, number, date), it is converted into a plain string.

+  This results in a more readable URL.

+  

+  If you have multiple context values (by binding a list or array of objects to the ActionLink's

+  context parameter), then each one, in order, will be added to the URL.

+  

+  When an event handler method is invoked, the strings are converted back into

+  values, or even objects. A

+  {{{../../apidocs/org/apache/tapestry/ValueEncoder.html}ValueEncoder}} is used to convert between client-side strings

+  and server-side objects.  The {{{../../apidocs/org/apache/tapestry/services/ValueEncoderSource.html}ValueEncoderSource}} service

+  provides the necessary value encoders.

+

+* Method Matching

+

+  An event handler method will only be invoked

+    <if the context contains at least as many values as the method has parameters>.  Methods with too many parameters

+    will be silently skipped.

+

+* Collections

+

+  To designate that an event handler method should be invoked regardless of how many context parameters are available,

+  change the method to accept a <single> parameter of type Object[], type List, or

+  {{{../../apidocs/org/apache/tapestry/EventContext.html}EventContext}}.  

+

+Event Bubbling

+

+  The event will bubble up the hierarchy, until it is aborted. The event is aborted

+  when an event handler method returns a non-null value.

+

+  Returning a boolean value from an event handler method is special.  Returning true will abort the event

+  with no result; use this when the event is fully handled without a return value and no further event handlers

+  (in the same component, or in containing components) should be invoked.

+

+  Returning false is the same as returning null.

+

+Event Method Exceptions

+

+  Event methods are allowed to throw any exception (not just runtime exceptions). If an event method does

+  throw an exception, Tapestry will catch the thrown exception and ultimately display the exception report

+  page.

+

+  In other words, there's no need to do this:

+

++---+

+  void onActionFromRunQuery()

+  {

+    try

+    {

+      dao.executeQuery();

+    }

+    catch (JDBCException ex)

+    {

+      throw new RuntimeException(ex);

+    }

+  }

++---+

+

+  Instead, you may simply say:

+

++---+

+  void onActionFromRunQuery() throws JDBCException

+  {

+    dao.executeQuery();

+  }

++----+

+

+

+  Your event handler method may even declare that it "throws Exception" if that is more convienient.

+

+

+Intercepting Event Exceptions

+

+  When an event handler method throws an exception (checked or runtime), Tapestry gives the component and

+  its containing page a chance to handle the exception, before continuing on to

+  report the exception.

+

+  Tapestry fires a new event, of type "exception", passing the thrown exception as the context.  In fact,

+  the exception is wrapped inside a

+  {{{../../apidocs/org/apache/tapestry/runtime/ComponentEventException.html}ComponentEventException}}, from which

+  you may extract the event type and context.

+

+  Thus:

+

+---

+  Object onException(Throwable cause)

+  {

+    message = cause.getMessage();

+

+    return this;

+  }

+---

+

+  The return value of the exception event handler <replaces> the return value of original event handler method.

+  For the typical case (an exception thrown by an "activate" or "action" event), this will be

+  a {{{pagenav.html}navigational response}} such as a page instance or page name.

+

+  This can be handy for handling cases where the data in the URL is misformatted.

+

+  In the above example, the navigational response is the page itself.

+

+  If there is no exception event handler, or the exception event handler returns null (or is void), then

+  then the exception will be passed to the

+  {{{../../apidocs/org/apache/tapestry/services/RequestExceptionHandler.html}RequestExceptionHandler}} service,

+  which (in default configuraton) will be render the exception page.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/inject.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/inject.apt
new file mode 100644
index 0000000..007bd3e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/inject.apt
@@ -0,0 +1,135 @@
+ ----

+ Injection with Components

+ ----

+ 

+Injection with Components

+

+  A key concept in Tapestry is the use of <injection>. The

+  {{{http://tapestry.apache.org/tapestry5/tapestry-ioc/index.html}Tapestry IoC container}} makes use of one form

+  of injection, via parameters to service builder methods.

+  

+  For components, Tapestry takes a completely different tack: injection directly into

+  instance variables.

+  

+Inject Annotation

+

+  The {{{../../apidocs/org/apache/tapestry/ioc/annotation/Inject.html}Inject annotation}} is used to identify fields that will contain injected services and other resources.

+  

+  Tapestry allows for two kinds of injection:

+  

+  * Explicit injection, where the particular service to be injected is specified.  

+    

+  * Default injection, where Tapestry determines the object to inject into the field based on its type.

+  

+  []

+ 

+  

+  In both cases, the field is transformed into a read only value.  As elsewhere in Tapestry, this transformation occurs

+  at runtime (which is very important in terms of being able to test your components).

+  Attempting to update an injected field will result in a runtime exception.

+ 

+  In addition, there are a few special cases that are triggered by specific field types, or additional annotations,

+  in addition, to Inject, on a field.

+  

+* Asset Injection

+

+  When the 

+  {{{../../apidocs/org/apache/tapestry/annotation/Path.html}Path}} annotation is also present, then the injected value

+  (relative to the component) will be a localized  {{{assets.html}asset}}.  

+  

+  Symbols in the annotation value are expanded.  

+  

+* Block Injection

+

+  For field type {{{../../apidocs/org/apache/tapestry/Block.html}Block}}, the value of the Inject annotation is the

+  id of the {{{templates.apt}\<block\> element}} within the component's template.  Normally, the id of the block is determined from the field name

+  (after stripping out leading "_" and "$" characters).  Where that is not appropriate, an

+  {{{../../apidocs/org/apache/tapestry/annotation/Id.html}Id}} annotation can be supplied:

+  

++---+

+  @Inject

+  private Block foo;

+  

+  @Inject

+  @Id("bar")

+  private Block barBlock;

++---+

+

+  The first injection will inject the Block with id "foo" (as always, case is ignored).  The second injection will inject the Block with id "bar".

+ 

+  

+* Resource Injection

+

+  For a particular set of field types, Tapestry will inject a <resource> related to the component, such as its Locale.

+  

+  A very common example occurs when a component needs access to its

+  {{{../../apidocs/org/apache/tapestry/ComponentResources.html}resources}}.  The component

+  can define a field of the appropriate type

+  and use the Inject annotation without a value:

+  

++----+

+@Inject

+private ComponentResources resources;

++----+

+

+  Tapestry uses the type of the field, ComponentResources, to determine what to inject into this field.

+

+  The following types are supported for resources injection:

+  

+  [java.lang.String]

+    The complete id of the component, which incorporates the complete class name of the containing page and the nested

+    id of the component within the page.

+    

+  [java.util.Locale]

+    The locale for the component (all components within a page use the same locale).

+    

+  [org.apache.commons.logging.Log]

+    A Log instance configured for the component, based on the component's class name.

+  

+  [org.apache.tapestry.ComponentResources]

+  	The resources for the component, often used to generate links related to the component.

+  		

+  [org.apache.tapestry.ioc.Messages]

+    The component message catalog for the component, from which

+    {{{localization.html}localized}} messages can be generated.

+   

+

+Explicit Service Injection

+

+  Here, a specific object is requested. A {{{../../apidocs/org/apache/tapestry/annotation/Service.html}Service}} annotation

+  is used to identify the service name.

+  

+  Example:

+  

++----+

+@Inject

+@Service("Request")

+private Request request;

++----+

+

+  This is generally not necessary; you should always be able to identify the service to be injected just by type, not

+  by explicit id.  Explicit ids have the disadvantage of not being refactoring-safe:  this won't happen with the Request service,

+  but perhaps in your own ... if you rename the service interface and rename the service id to  match, your existing

+  injections using the explicit service id will break.

+  

+Default Injection

+  

+  When the type and/or other annotations are not sufficient to identify the object or service to inject, Tapestry falls back on two remaining steps. It assumes

+  that the field type will be used to identify a service, by the service interface.

+  

+  First, the object provider created by the Alias service is consulted. This object provider is used to disambiguate injections when there is more

+  than one service that implements the same service interface.

+  

+  Second, a search for a unique service that implements the interface occurs. This will fail if either there are no services that implement the interface,

+  or there is more than one.  In the latter case, you must disambiguate, either with a contribution to the Alias service, or by explicitly

+  identifying the service with the @Service annotation.

+

+    

+Defining New Injection Logic

+

+  Annonymous injection is controlled by the 

+  {{{../../apidocs/org/apache/tapestry/services/InjectionProvider.html}InjectionProvider}}

+  service. The configuration for this service is a 

+  {{{http://tapestry.apache.org/tapestry5/tapestry-ioc/command.html}chain of command}} for handling component injections.

+

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/layout.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/layout.apt
new file mode 100644
index 0000000..fc4c480
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/layout.apt
@@ -0,0 +1,106 @@
+ ----
+ Layout Component
+ ----
+
+Layout Component
+
+  You may see frequent reference to a Layout Component, but you won't find it
+  in the {{{../ref/index.html}component reference}}.  Layout isn't a component, it's
+  a component <pattern>.
+
+  A Layout component exists to provide common content across all pages in your application.
+  In traditional servlet development, you may be familiar with
+  the use of a JSP include to include a banner across the top of your page and a copyright
+  message across the bottom.
+
+  Tapestry doesn't have a mechanism for such includes, nor does it have the need.
+
+  Instead, you can create a component that acts like a template for your pages.
+
+* Layout.tml
+
+----
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>My Nifty Web Application</title>
+    </head>
+    <body>
+        <div class="nav-top">
+            Nifty Web Application
+        </div>
+    
+        <t:body/>
+
+        <div class="nav-bottom">
+            (C) 2008 NiftyWebCo, Inc.
+        </div>
+    </body>
+</html>
+----
+
+  Layout is a standard component, with a standard component template.  Like all component
+  templates, it will be stored on the classpath (i.e., under src/main/resources).
+
+  The magic is in the \<t:body/\> element in the center; this will be replaced
+  by the <page's content>, whatever that is.
+
+  The two \<div\> elements above and below the \<t:body\> are, in this example, placeholders for
+  the typical content you'll see in a web application: banners (and banner ads!),
+  menus, login forms and so forth.
+
+  Often these get very complex ... in fact, in most applications, the Layout component grows
+  to be more complex than almost any page in the application.
+
+  Remember that if you include a link to a resource such as an image or a stylesheet, you
+  must use an absolute URL. The same component will be used for pages in many different folders,
+  or with many different activation contexts, meaning that relative URLs are not only
+  different for different pages, but may shift unexpectedly.
+
+* Layout.java
+
+----
+@IncludeStylesheet("context:css/site.css")
+public class Layout
+{
+}
+----
+
+  Components must always have a Java class. In this trivial example, the Layout component
+  does not have much logic.  We can save ourselves some typing using the
+  {{{../../apidocs/org/apache/tapestry/annotation/IncludeStylesheet.html}@IncludeStylesheet}}
+  annotation (as opposed to directly adding the
+  \<link\> element to the template.
+
+
+* Start.tml
+
+----
+<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+   <h1>Welcome to the Nifty Web Application!</h1>
+
+   <p>
+        Would you like to <t:pagelink page="login">Log In</t:pagelink>?
+   </p>
+</html>
+----
+
+  This is an example of using the Layout component.  To keep our Start.tml template
+  relatively previewable, we are using an \<html\> element and the t:type
+  attribute to specify that it is a component.
+
+  The \<html\> tag will be removed, and replaced with the content from
+  the Layout.tml template (which convieniently starts with an \<html\> element).
+  The \<t:body\> in Layout.tml will be replaced
+  with the page specific content here: the \<h1\> and \<p\> tags.
+
+  Any page in the application that follows this pattern, using the Layout component,
+  will have the same look and feel.
+
+  You may find that your application has more than one look and feel: perhaps
+  user registration pages have one look, while administrative pages have another.
+  This can be accomplished by having multiple Layout components and using different
+  layout types for different pages.
+
+
+
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/lifecycle.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/lifecycle.apt
new file mode 100644
index 0000000..8646831
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/lifecycle.apt
@@ -0,0 +1,146 @@
+ ----
+ Page Lifecycle
+ ----
+
+Page Lifecycle
+
+   In Tapestry, you are free to develop your presentation objects, page and components classes,
+   as ordinary objects, complete with instance variables and so forth.
+
+   This is somewhat revolutionary in terms of web development in Java.  Using servlets, or Struts,
+   your presentation objects (Servlets, or Struts Actions, or the equivalent in other frameworks)
+   are <stateless singletons>.  That is, a <single> instance is created, and all incoming requests
+   are threaded through that single instance.
+
+   Because multiple requests are handled by many different threads, this means that the single instance's
+   variable are useless ... any value written into an instance variable would immediately be
+   overwritten by a different thread.  Thus, it is necessary to use the
+   Servlet API's HttpServletRequest object to store per-request data, and the HttpSession object
+   to store data between requests.
+
+   Tapestry takes a very different approach.
+
+   In Tapestry, you will have many different instances of any particular page, each either in use
+   for a single request (on a single thread), or waiting in a <page pool> to be used.
+
+   By reserving page instances to particular threads, all the difficult, ugly issues related to
+   multi-threading go by the wayside.  Instead, familiar, simple coding practices (using ordinary methods and fields)
+   can be used.
+
+   However, there's a risk: it would be a disaster if data could "bleed" from one request to another. Imagine
+   the outcome in a banking application if the first user's account number and password became the default
+   for the second user to reach the application!
+
+   Tapestry takes special care to purge all instance variables back to their default value at the end of each request.
+
+   The end result is that all pages in the pool are entirely equivalent to each other; it doesn't matter which
+   instance is used for processing any particular request.
+
+   Remember that the page instance is just the tip of the iceberg: a page instance encompasses the page component,
+   its templates, all of its parameter bindings, tokens read from its template and (recursively) the same
+   thing for all components inside the page. It adds up.
+
+   A page instance will be "checked out" of the pool for a short period of time: a few milliseconds
+   to service a typical request. Because of this, it is generally the case that Tapestry
+   can handle a large number of end users with a relatively small pool of page instances.
+
+Comparison to JavaServer Pages
+
+   JSPs also use a caching mechanism; the JSP itself is compiled into a Java servlet class, and acts as a singleton.
+
+   However, the individual JSP tags are pooled.
+
+   This is one of the areas where Tapestry can significantly outperform JSPs.  Much of the code inside a compiled
+   JSP class concerns
+   getting tags from a tag pool, configuring the properties of the tag instance, using the tag instance, then
+   cleaning up the tag instance and putting it back in the pool.
+
+   The operations Tapestry does once per request are instead executed dozens or potentially hundreds of times (dependending
+   the complexity of the page, and if any nested loops occur).
+
+   Pooling JSP tags is simply the wrong granularity.
+
+   Tapestry can also take advantage of its more coarse grained caching to optimize how data moves, via parameters,
+   between components. This means that Tapestry pages will actually speed up after they render the first time.
+
+Page Pool Configuration
+
+   Tapestry's page pool is used to store page instances.  The pool is "keyed" on the name of the page (such as "start")
+   and the <locale> for the page (such as "en" or "fr").
+
+   Within each key, Tapestry tracks the number of page instances that have been created, as well as the number
+   that are in use (currently attached to a request).
+
+   When a page is first accessed in a request, it is taken from the pool.  Tapestry has some
+   {{{conf.html}configuration values}} that control the details of how and when page instances are created.
+
+   * If a free page instance is available, the page is marked in use and attached to the request.
+
+   * If there are fewer page instances than the <soft limit>, then a new page instance is simply created and
+     attached to the request.
+
+   * If the soft limit has been reached, Tapestry will wait for a short period of time for
+     a page instance to become available before creating a new page instance.
+
+   * If the hard limit has been reached, Tapestry will throw an exception rather than create a new page instance.
+
+   * Otherwise, Tapestry will create a new page instance.
+
+   []
+
+   Thus a busy application will initially create pages up-to the soft limit (which defaults to five page
+   instances).  If the application continues to be pounded with requests, it will slow its request
+   processing, using the soft wait time in an attempt to reuse an existing page instance.
+
+   A truly busy application will continue to create new page instances as needed until the
+   hard limit is reached.
+
+   Remember that all these configuration values are  per key: the combination of page name and locale.
+   Thus even with a hard limit of 20, you may eventually find that Tapestry
+   has created 20 start page instances for locale "en" <and> 20 start page
+   instances for locale "fr" (if your application is configured to support both English and French).  Likewise,
+   you may have 20 instances for the start page, and 20 instances for the newaccount page.
+
+   Tapestry periodically checks its cache for page instances that have not been used recently
+   (within a configurable window).  Unused page instances are release to the garbage collector.
+
+   The end result is that you have quite a degree of tuning control over the process.  If memory is a limitation
+   and throughput can be sacrificed, try lowering the soft and hard limit and increasing the soft wait.
+
+   If performance is absolute and you have lots of memory, then increase the soft and hard limit and reduce 
+   the soft wait.  This encourages Tapestry to create more page instances and not wait as long to re-use
+   existing instances.
+
+Page Lifecycle Methods
+
+  There are a few situations where it is useful for a component to perform some operations, usually some kind of initialization or
+  caching, based on the lifecycle of the page.
+  
+  The page lifecycle is quite simple.  When first needed, a page is loaded.  Loading a page involves instantitating the components of the page
+  and connecting them together.
+  
+  Once a page is loaded, it is <attached> to the current request.  Remember that there will be many threads, each handling its own request.
+  In many cases, there will be multiple copies of the same page attached to different requests (and different threads). This is how Tapestry keeps you
+  from worrying about multi-threading issues ... the objects involved in any request are reserved to <just> that request (and <just> that thread).
+  
+  At the end of a request, after a response has been sent to the client, the page is <detached> from the request.  This is a chance to perform
+  a lot of cleanup of the page, discarding temporary objects (so that they can be reclaimed by the garbage collector) and otherwise returning the
+  page to its pristine state.  After detaching, a page is placed into the page pool, where it will await reuse for some future request (likely by a completely
+  different user).
+  
+  As with {{{rendering.html}component rendering}}, you have the ability to make your components "aware" of these events by identifying methods to be invoked.
+  
+  You have the choice of attaching an annotation to a method, or simply naming the method correctly.  
+  
+  Page lifecycle methods should take no parameters and return void.
+  
+  The annotations / method names are:
+  
+   * {{{../../apidocs/org/apache/tapestry/annotation/PageLoaded.html}PageLoaded}} annotation, or method name "pageLoaded"
+   
+   * {{{../../apidocs/org/apache/tapestry/annotation/PageAttached.html}PageAttached}} annotation, or method name "pageAttached"
+   
+   * {{{../../apidocs/org/apache/tapestry/annotation/PageDetached.html}PageDetached}} annotation, or method name "pageDetached"
+   
+   
+   
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/localization.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/localization.apt
new file mode 100644
index 0000000..50ce069
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/localization.apt
@@ -0,0 +1,170 @@
+ ----
+  Localization
+ ----
+ 
+Localization
+
+  Localization is all about getting the right text to the user, in the right language.
+  
+  Localization support is well integrated into Tapestry.  Tapestry allows you to easily seperate the text you present to your users
+  from the rest of your application ... pull it out of your Java code and even out of your component templates.  You can then translate
+  your messages into other languages and let Tapestry put everthing together.
+  
+Component Message Catalogs
+
+  Each component class may have a component message catalog. A component message catalog is a set of files with the extension ".properties".
+  These property files are the same format used by java.util.ResourceBundle, just lines of <<<key=value>>>.  These files are packaged with the component's HTML template.
+  
+  So for a class named org.example.myapp.pages.MyPage, you would have a main properties file as <<<org/example/myapp/pages/MyPage.properties>>>.
+  
+  If you have a translations of these values, you provide additional properties file, adding an
+  {{{http://www.loc.gov/standards/iso639-2/englangn.html}ISO language code}} before the extension.  Thus, if you have a French translation,
+  you could create a file <<<MyPage_fr.properties>>>.
+  
+  Any values in the more language specific file will <override> values from the main properties file.  If you had an even more specific
+  localization for just French as spoken in France, you could create <<<MyPage_fr_FR.properties>>> (thats a language code plus a country code, you can even go further
+  and add variants ... but its unlikely that you'll ever need to go beyond just language codes in practice).
+  
+  The messages in the catalog are accessed by keys.  Tapestry ignores the case of the keys when accessing messages in the catalog.
+  
+Message Catalog Inheritance
+
+  If a component class is a subclass of another component class, then it inherits that base class' message catalog. Its own message catalog extends and overrides
+  the values inherited from the base class.
+  
+  In this way, you could have a base component class that contained common messages, and extend or override those messages in subclasses (just as you would
+  extend or override the methods of the base component class). This, of course, works for as many levels of inheritance as you care to support.
+  
+Application Message Catalog
+
+  If the file <<<WEB-INF/>>><AppName><<<.properties>>> exists in the context, it will be used as an application-wide message catalog.  The <AppName>
+  is derived from the name of the filter inside the web.xml file.  The search for the file is case sensitive. The properties file may be localized.
+  
+  Individual pages and components
+  can override the values defined in this message catalog.
+  
+Localized Component Templates
+
+  The same lookup mechanism applies to component templates.  Tapestry will search for a localized version of each component template and use the closest
+  match.  Thus you could have <<<MyPage_fr.html>>> for French users, and <<<MyPage.html>>> for all other users.
+  
+Accessing Localized Messages
+
+  The above discusses what files to create and where to store them, but doesn't address how to make use of that information.
+  
+  Messages can be accessed in one of two ways:
+  
+  * Using the {{{parameters.html}message: binding prefix}} in a component template
+  
+  * By injecting the comopnent's Messages object
+  
+  []
+  
+  In the first case, you may use the message: binding prefix with component parameters, or with template expansions:
+  
++-----+
+<t:layout title="message:page-title">
+
+  ${message:greeting}, ${user.name}!
+  
+  . . .
+</t:layout>
++-----+
+
+  Here, the <<<page-title>>> message is extracted from the catalog and passed to the Border component's title parameter.
+  
+  In addition, the <<<greeting>>> message is extracted and written into the response as part of the template.
+  
+  As usual, "prop:" is the defalt binding prefix, thus <<<user.name>>> is a property path, not a message key.
+  
+  You would extend this with a set of properties files:
+  
++----+
+page-title=Your Account
+greeting=Welcome back
++----+
+
+  Or, perhaps, a French version:
+  
++----+
+page-title=Votre Compte
+greeting=Bienvenue en arriere
++----+
+    
+    Programatically, you may inject your component message catalog into your class, as an instance of the Messages interface:
+    
++----+
+  @Inject
+  private Messages messages;
++----+
+
+  You could then <<<get()>>> messages, or <<<format()>>> them:
+  
++----+
+
+  public String getCartSummary()     
+  {
+    if (items.isEmpty())
+      return messages.get("no-items");
+      
+    return messages.format("item-summary", _items.size());
+  }
++----+
+
+  The format() option works using a java.text.Formatter, with all the printf-style loveliness you've come to expect:
+  
++----+
+no-items=Your shopping cart is empty.     
+item-summary=You have %d items in your cart.
++----+
+
+  As easy as conditionals are to do inside a Tapestry template, sometimes its even easier to do it in Java code.    
+ 
+    
+Missing Keys
+
+  If you reference a key that is not in the message catalog, Tapestry does not throw an exception (that would make initially developing
+  an application very frustrating).  When a key can not be located, a "placeholder" message is generated, such as "[[missing key: key-not-found]]".
+  
+  
+Reloading
+
+  If you change a property file in a message catalog, you'll see the change immediately, just as with component classes and component templates.
+  
+Asset Localization
+
+  When {{{inject.html}injecting assets}}, the injected asset will be localized as well.  A search for the closest match for the active locale
+  is made, and the final Asset will reflect that.
+      
+Locale Selection
+
+  The locale for each request is determined from the HTTP request headers.  The request locale reflects the environment of the web browser and possibly even
+  the keyboard selection of the user on the client.  It can be highly specific, for example, identifying British English (as en_GB) vs. American English (en).
+  
+  Tapestry "narrows" the raw request locale, as specified in the request, to a known quantity. 
+  It uses the {{{conf.html}configuration symbol}} tapestry.supported-locales to choose the effective locale for each request.  This value is a comma-separated
+  list of locale names. Tapestry searches the list for the best
+  match for the request locale; for example, a request locale of "fr_FR" would match "fr" but not "de".  If no match is found, then the first locale name
+  in the list is used as the effective locale (it is used as the default for non-matches).  Thus a site that primarily caters to French speakers
+  would want to list "fr" as the first locale in the list.  
+  
+Changing the Locale
+
+  Tapestry does not yet support changing the locale, but that will be available shortly.  The intent is to mimic Tapestry 4 behavior: store a cookie
+  on the client to provide the default for the locale on the next visit, and store a locale name in the session (if a session exists).  <<TODO: I believe
+  this has been implemented by Kent.>>
+  
+Output Content Type and Charset
+
+  When Tapestry renders a page, the very first step is to determine the output content type and charset.  
+  
+  This information is obtained from meta data on the page itself.  Meta data is specified using the
+  {{{../../apidocs/org/apache/tapestry/annotation/Meta.html}Meta}} annotation.
+  
+  First, the response content type is obtained via meta-data key "tapestry.response-content-type".  This value defaults to "text/html".
+  
+  Next, the encoding is obtained via meta-data key "tapestry.response-encoding".  This value defaults to "UTF-8".  This is only necessary if
+  the content type does not provide a charset parameter (i.e., "text/html;charset=ISO-8559-1").  The encoding becomes the charset.
+  
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/logging.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/logging.apt
new file mode 100644
index 0000000..2d360aa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/logging.apt
@@ -0,0 +1,154 @@
+ ----
+  Logging
+ ----
+ 
+Logging of Tapestry Components and Pages
+
+  Tapestry makes extensive use of
+  {{{http://www.slf4j.org/}SLF4J}} to log details about the creation and operation of your page and component classes.
+  
+  The default configuration for logging uses 
+  {{{http://logging.apache.org/log4j/}Log4J}} as the logging toolkit, though
+  {{{../../tapestry-ioc/logging.html}this can be changed}}.
+  
+  
+Class to Logger
+
+  The logger name for a page or component matches the fully qualified class name.  You can configure this in log4j.properties:
+  
+----
+log4j.category.org.apache.tapestry.integration.app1.pages.MerryChristmas=trace
+----
+  
+Injecting Loggers
+
+  You may mark a field of type 
+  {{{http://www.slf4j.org/api/org/slf4j/Logger.html}Logger}} with the @Inject annotation.  The proper Logger for your
+  page or component will be injected.
+  
+---
+public class MyPage
+{
+  @Inject
+  private Logger logger;
+  
+  . . .
+---
+
+@Log annotation
+
+  You may mark any component method with the {{{../../apidocs/org/apache/tapestry/annotation/Log.html}Log}} annotation.
+  Method entry, exit (and any thrown exceptions) will be logged at DEBUG level. This is very convienient for
+  debugging, especially when placed on event handler methods.
+
+
+DEBUG Level
+
+  When a component's logger is configured at the DEBUG level, you will also see added output when the class is first
+  accessed identifying how Tapestry is modifying the bytecode of the class.  
+  
+  Example:
+  
+---
+[DEBUG] MerryChristmas Finished class transformation: InternalClassTransformation[
+public org.apache.tapestry.integration.app1.pages.MerryChristmas extends java.lang.Object
+  implements org.apache.tapestry.runtime.Component, org.apache.tapestry.runtime.RenderCommand
+
+add default method: public void postRenderCleanup()
+<default>
+
+add default method: public void setupRender(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void beginRender(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void beforeRenderTemplate(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void afterRenderTemplate(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void beforeRenderBody(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void afterRenderBody(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void afterRender(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public void cleanupRender(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.Event $2)
+<default>
+
+add default method: public boolean handleComponentEvent(org.apache.tapestry.runtime.ComponentEvent $1)
+<default>
+
+add default method: public org.apache.tapestry.ComponentResources getComponentResources()
+<default>
+
+add default method: public void containingPageDidLoad()
+<default>
+
+add default method: public void containingPageDidDetach()
+<default>
+
+add default method: public void containingPageDidAttach()
+<default>
+
+add field: protected final org.apache.tapestry.internal.InternalComponentResources _$resources;
+
+replace method: public final org.apache.tapestry.ComponentResources getComponentResources()
+return _$resources;
+
+add default method: public void render(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.RenderQueue $2)
+<default>
+
+replace method: public void render(org.apache.tapestry.MarkupWriter $1, org.apache.tapestry.runtime.RenderQueue $2)
+_$resources.queueRender($2);
+
+convert default constructor: initializer();
+
+add constructor: org.apache.tapestry.integration.app1.pages.MerryChristmas(org.apache.tapestry.internal.InternalComponentResources $1)
+{
+  _$resources = $1;
+  initializer();
+
+}
+
+]
+----
+
+  Is this helpful?  Probably only if you are developing your own code that integrates into the component class transformation chain; for example,
+  to support your own field and method annotations.
+  
+TRACE Level
+
+  Enabling the TRACE level <for pages> results in extremely verbose logging of every activity that drives the rendering of output, such as each component
+  working its way through the {{{rendering.html}rendering stage machine}}.  Example:
+  
+----
+[TRACE] MerryChristmas Executing: ComponentPageElement[MerryChristmas]
+[TRACE] MerryChristmas Executing: SetupRender[MerryChristmas]
+[TRACE] MerryChristmas Executing: BeginRender[MerryChristmas]
+[TRACE] MerryChristmas Executing: BeforeRenderTemplate[MerryChristmas]
+[TRACE] MerryChristmas Executing: ComponentPageElement[MerryChristmas:border]
+[TRACE] MerryChristmas Executing: SetupRender[MerryChristmas:border]
+[TRACE] MerryChristmas Executing: BeginRender[MerryChristmas:border]
+[TRACE] MerryChristmas Executing: BeforeRenderTemplate[MerryChristmas:border]
+[TRACE] MerryChristmas Executing: Start[html]
+[TRACE] MerryChristmas Executing: Text[
+    ]
+[TRACE] MerryChristmas Executing: Start[head]
+[TRACE] MerryChristmas Executing: Text[
+        ]
+[TRACE] MerryChristmas Executing: Start[title]
+[TRACE] MerryChristmas Executing: Text[Tapestry Integration Test Application #1]
+
+  . . .
+----
+
+  Is this helpful?  Only if you are writing your own components and get an exception about unbalanced elements. This output gives
+  you a detailed view into what has rendered and when, so you can track it down.
+    
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/mixins.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/mixins.apt
new file mode 100644
index 0000000..dd5cc53
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/mixins.apt
@@ -0,0 +1,136 @@
+ ---

+ Component Mixins

+ ---

+ 

+Component Mixins

+

+  Tapestry 5 includes a radical feature, <component mixins>.  Component mixins are a tricky concept; it basically allows

+  a true component to be mixed together with special limited components called mixins.  The component plus its mixins are

+  represented as just a single tag in the component template, but all the behavior of all the elements.

+  

+  The planned uses for this are to add validation to user input fields, or to add Ajax effects and behaviors to all

+  sorts of components.

+  

+  You can think of a mixin as a kind of mashup for a component; it combines the behavior of the component

+  with the behavior of the mixin, and bundles it all in one place.

+  

+  Mixins are used in two different scenarios: <Instance mixins> and <Implementation mixins>.

+  

+Mixin Classes

+

+  Mixin classes are stored in a <<<mixins>>> sub-package, below the application (or library)

+  root package. This parallels where component and page classes are stored.

+  

+  Other than that, mixin classes are exactly the same as any other component class.

+  

+Mixin Limitations

+

+  Currently, mixins are allowed to do anything a component can do, including parameters,

+  render phase methods.

+  

+  Mixins may not have a template. They integrate with the component strictly in terms of invoking

+  render phase methods.

+  

+  Mixins may have persistent fields, but currently, this is not implemented perfectly (there is a potential

+  for a name clash between a mixin and the component or another mixin).  Use persistent fields with

+  mixins with care ... or better yet, delegate persistence to the container using parameters.

+  

+  Mixins may not, themselves, have mixins.

+  

+  

+Instance Mixins

+

+  An instance mixin is a mixin applied to a specific <instance> of a component.  This can be done

+  in the {{{templates.html}component template}} with the mixins attribute of the

+  \<comp\> element.  This is a comma-separated list of mixin names.

+  

+  Alternately, when the {{{../../apidocs/org/apache/tapestry/annotation/Component.html}Component annotation}}

+  is used to define the component type, you may specify the mixins in two ways:

+  

+  * The {{{../../apidocs/org/apache/tapestry/annotation/Mixins.html}Mixins annotation}} allows a list

+    of mixin names to be specified.

+    

+  * The {{{../../apidocs/org/apache/tapestry/annotation/MixinClasses.html}MixinClasses annotation}}

+    allows a set of mixin class to be specified directly.

+    

+  []

+  

+  The former is often less verbose, and allows core mixins to be overridden with application-specific

+  mixins.  The later format is more specific and more friendly in terms of refactoring (renaming a 

+  mixin class will rename the entry in the MixinClasses annotation as well).

+  

+  Example:

+  

++----+

+

+  @Component(parameters=. . .) @Mixins({"Autocomplete", "DefaultFromCookie"})

+  private TextField userId;

++----+

+

+  This example defines a component of type TextField and mixes in the <hypothetical> Autocomplete

+  and DefaultFromCookie mixins.  

+

+

+Implementation Mixins

+

+  Implementation mixins, mixins which apply to all isntances of a component, are added using the

+  {{{../../apidocs/org/apache/tapestry/annotation/Mixin.html}Mixin annotation}}. This annotation

+  defines a field that will containg the mixin instance.

+  

++---+

+public class AutocompleteField extendes TextField

+{

+  @Mixin

+  private Autocomplete autocompleteMixin;

+  

+  . . .

+}

++---+

+

+  Often, the type of the field is the exact mixin class to be instantiated.

+  

+  In other cases, such as when the field's type is an interface or a base class, the value

+  attribute of the annotation will be used to determine the mixin class name:

+  

++---+

+public class AutocompleteField extendes TextField

+{

+  @Mixin("Autocomplete")

+  private Object autocompleteMixin;

+  

+  . . .

+}

++---+

+

+Mixin Parameters

+

+  Mixins are allowed to have parameters, just like components.

+  

+  When binding parameters (either in the template, or using the parameters attribute

+  of the Component annotation).

+  

+  Tapestry will match each parameter name against the parameters defined by each class

+  (which is to say, the component and each mixin).

+  

+  If the component and a mix both define a parameter with the same name, then the component wins:

+  the component's parameter will be bound, and the mixin's parameter will be unbound.

+  

+  Alternately, you may prefix the name of the parameter with the <unqualified> name of the Mixin class;

+  this eliminates the ambiguity.  Example:

+  

++-----+

+  @Component(parameters={"Autocomplete.id=auto", . . . }) @Mixins("Autocomplete", "DefaultFromCookie"})

+  private TextField userId;

++-----+

+

+  

+Render Phase Ordering

+

+  All mixins for a component execute their render phase methods <before> the component's render phase

+  methods for most phases.  However, in the later phases (AfterRender, CleanupRender) the order of executing

+  is reversed.

+  

+  Exception: Mixins whose class is annotated with

+  {{{../../apidocs/org/apache/tapestry/annotation/MixinAfter.html}MixinAfter}} are ordered

+  <after> the component, not before.  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/pagenav.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/pagenav.apt
new file mode 100644
index 0000000..07fd738
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/pagenav.apt
@@ -0,0 +1,309 @@
+ ----
+ Page Navigation
+ ----
+
+Page Navigation
+
+  In essense, a Tapestry application is a number of related pages, working together.  To some degree, each page is like an application unto itself.
+  
+  Any individual request will be targetted at a single page.  Requests come in two forms: 
+  
+  * <action> requests target a specific component on a specific page, triggering an event within that component
+  
+  * <render> requests target a specific page, and stream the HTML markup for that page back to the client
+  
+  []
+  
+  This dictomy between action requests 
+  and render requests is new in Tapestry 5. It is in some ways based on ideas from the Portlet specification and differentiating
+  the two types of requests alleviates a number of problems in traditional web applications related to the browser back button, or to the user hitting the
+  refresh button in their browser.
+  
+Action Requests
+  
+  Action requests may take the form of hyperlinks
+  ({{{../component-parameters.html#org.apache.tapestry.corelib.components.actionlink}ActionLink}}) or form submissions
+  ({{{../component-parameters.html#org.apache.tapestry.corelib.components.form}Form}}).
+  
+  In both cases, the value returned from an {{{event.html}event handler method}} controls the response sent to the client web browser.
+  
+  The URL for an action request identifies the name of the page, the nested id of the component, and the name of the event to trigger on the component (this is usually "action").
+  Further, an action request may contain additional context information, which will be provided to the event handler method.  
+  
+  These URLs expose a bit of the internal structure of the application.  Over time, as an application grows and is maintained, the ids of components may change. This means that
+  action request URLs should not be bookmarked.  Fortunately, users will rarely have the chance to do so (see below).
+  
+* Null response
+
+  If the event handler method returns no value, or returns null, then the current page (the page containing the component) will render the response.
+  
+  A page render link for the current page is created and sent to the client as a client side redirect.  The client browser will automatically submit a new request
+  to generate the page.
+  
+  The user will see the newly generated content in their browser. In addition, the URL in the browser's address bar will be a render request URL.  Render request URLs are
+  shorter and contain less application structure (for instance, they don't include component ids or event types).  Render requests URLs are what your users will bookmark. The action request URLs
+  are transitory, meaningful only while the application is actively engaged, and not meant to be used in later sessions.
+  
+* String response
+  
+  When a string is returned, it is expected to be the logical name of a page (as opposed to the page's
+  fully qualified class name).  As elsewhere, the name of the page is case insensitive.
+  
+  Again, a render request URL will be constructed and sent to the client as a redirect.
+  
+* Class response
+  
+  When a class is returned, it is expected to be a page class. Returning a page class from an event handler is safer for refactoring
+  than returning a page name.
+  
+  As with other response types, a render request URL will be constructed and sent to the client as a redirect.
+  
+* Page response
+  
+  You may also return an instance of a page, rather than the name or class of a page.
+  
+  A page may be injected via the {{{../../apidocs/org/apache/tapestry/annotation/InjectPage.html}InjectPage}} annotation.
+  
+  Often, you will configure the page in some way before returning the page (examples below).
+  
+  You can also return a component within the page, but this will generate a runtime warning.
+  
+* Link response
+
+  An event handler method may return a 
+  {{{../../apidocs/org/apache/tapestry/Link.html}Link}} instance directly.  The Link is converted into a URL and a client redirect to that URL is sent to the client.
+  
+  The {{{../../apidocs/org/apache/tapestry/ComponentResources.html}ComponentResources}} object that is injected into your pages (and components) has methods
+  for creating action and page links (they are actually defined in
+  {{{../../apidocs/org/apache/tapestry/ComponentResourcesCommon.html}ComponentResourcesCommon}}).
+  
+* Stream response
+
+  An event handler can also return a {{{../../apidocs/org/apache/tapestry/StreamResponse.html}StreamResponse}} object, which encapsulates a stream to
+  be sent directly to the client browser.  This is useful for compnents that want to, say, generate an image or PDF and provide it to the client.
+
+
+* URL response
+
+  A URL is handled as a client redirect to an external URL.
+  
+* Object response
+
+  Any other type of object returned from an event handler method is an error.
+  
+Page Render Requests
+
+  Render requests are simpler in structure and behavior than action requests. In the simplest case, the URL is simply the
+  logical name of the page.
+  
+  Pages may have an <activation context>.  The activation context represents persistent information about the state of the page.  In practical terms,
+  the activation context is usually the id of some database-persistent object.
+  
+  When a page has an activation context, the values of the context are appended to the URL path.  
+  
+  Not all pages have an activation context.
+  
+  The activation context may be explicitly set when the render request link is created (the PageLink component has a context parameter for this purpose).
+  When no explicit activation context is provided, the page itself is queried for its activation context.
+  
+  This querying takes the form of an event trigger. The event name is "passivate" (as we'll see shortly, there's a corresponding "activate").  The 
+  return value of the method is used as the context.  For example:
+  
++---+
+public class ProductDetail
+{
+  private Product product;
+  
+  . . .
+  
+  long onPassivate() { return product.getId(); }
+}
++----+
+
+  The activation context may consist of a series of values, in which case the return value of the method should be an array or a List.
+
+  <<Note: If you are using the {{{../tapestry-hibernate/}tapestry-hibernate}} integration library and your passivate context
+  is a Hibernate entity, then you can just use the entity itself, not its id.  Tapestry will automatically extract the entities' id into the URL,
+  and convert it back for the "activate" event handler method.>>
+  
+* Page activation
+
+  When a page render request arrives, the page is activated before it is rendered.
+  
+  Activation serves two purposes:
+  
+  * It allows the page to restore its internal state from data encoded into the URL (the activation context discussed above).
+  
+  * It provides coarse approach to validating access to the page.
+  
+  []
+  
+  The later case, validation, is generally concerned with user identity and access; if you have pages that may only be accessed by certain users,
+  you may use the page's activate event handler responsible for verifying that access.
+  
+  A page's activate event handler mirrors its passivate handler:
+  
++----+
+  . . .
+  
+  void onActivate(long productId)
+  {
+     product = productDAO.getById(productId);
+  }
+  
+  . . .
++-----+
+
+  Here's the relevant part: when the page renders, it is likely to include more action request URLs (links and forms). The action requests
+  for those links and forms will <also> start by activating the page, before performing other work. This forms an unbroken chain of requests
+  that include the same activation context.
+  
+  To some degree, this same effect could be accomplished using a {{{persist.html}persistent page value}}, but that requires an active session,
+  and the result is not bookmarkable.
+
+  The activate event handler may also return a value, which is treated identically to a return value of an action request event trigger.  This will typically
+  be used in an access validation scenario.
+  
+Page Navigation Patterns
+
+  This combination of action links and context and page context can be put together in any number of ways.
+  
+  Let's take a typical master/detail relationship using the concept of a product catalog page.  In this example, the 
+  ProductListing page is a list of products, and the ProductDetails page must display the details for a specific product.
+  
+* Action Requests / Persistent Data
+
+  In this pattern, the ProductListing page uses action events and a persistent field on the ProductDetails page.
+  
+  ProductListing.html:
+  
++---+
+  <t:loop source="products" value="product">
+    <a t:type="actionlink" t:id="select" context="product.id">${product.name}</a>
+  </t:loop>
++---+
+
+  ProductListing.java:  
+  
++---+
+  @InjectPage
+  private ProductDetails details;
+  
+  Object onActionFromSelect(long productId)
+  {
+    details.setProductId(productId);
+    
+    return details;
+  }
++---+
+
+  ProductDetails.java:
+
++----+
+  @Inject
+  private ProductDAO dao;
+  
+  private Product product;
+  
+  @Persist
+  private long productId;
+  
+  public void setProductId(long productId) { this.productId = productId; }
+  
+  void onActivate()
+  {
+    product = dao.getById(productId);
+  }
++----+
+
+  This is a minimal approach, perhaps good enough for a prototype. 
+  
+  When the user clicks a link, the action request URL will initially be something like "http://.../productlisting.select/99" and the final
+  render request URL will be something like "http://.../productdetails".  Notice that the product id ("99") does not appear in the render request URL.
+  
+  It has some minor flaws:
+  
+  * It requires a session (to store the _productId field between requests).
+  
+  * It may fail if the ProductDetails page is accessed before a valid product id is set.
+  
+  * The URL does not indicate the identity of the product; if the user bookmarks the URL and comes back later, they will trigger the previous case (no valid product id).
+  
+* Action Requests / Persistent Data
+
+  We can improve the previous example without changing the ProductListing page,  using a passivation and activation context
+  to avoid the session and make the links more bookmarkable.
+  
+  ProductDetails.java:
+
++----+
+  @Inject
+  private ProductDAO dao;
+  
+  private Product product;
+  
+  private long productId;
+  
+  public void setProductId(long productId) { productId = productId; }
+  
+  void onActivate(long productId)
+  {
+    this.productId = productId;
+    
+    product = dao.getById(productId);
+  }
+  
+  long onPassivate() { return productId; }
++----+   
+
+  This change ensures that the render request URL will include the product id, i.e., "http://.../productdetails/99".
+  
+  It has the advantage that the connection from page to page occurs in typesafe Java code, inside the onActionFromSelect method of ProductListing.
+  It has the disadvantage that clicking a link requires two round trips to the server.
+  
+* Render Requests Only
+
+  This is the most common version of this master/detail relationship.
+  
+  ProductListing.html:
+  
++---+
+  <t:loop source="products" value="product">
+    <a t:type="pagelink" page="productdetails" context="product.id">${product.name}</a>
+  </t:loop>
++---+  
+
+  ProductListing.java:
+  
+  No code is needed to support the link.
+  
+  ProductDetails.java:
+
++----+
+  @Inject
+  private ProductDAO dao;
+  
+  private Product product;
+  
+  private long productId;
+   
+  void onActivate(long productId)
+  {
+    this.productId = productId;
+    
+    product = dao.getById(productId);
+  }
+  
+  long onPassivate() { return productId; }
++----+     
+  
+  The setProductId() method is no longer needed.
+  
+* Limitations
+
+  As your application's workflow expands, you may find that there is not a reasonable way to avoid storing some data persistently between requests, outside
+  of the page activation context.  For example, if from the ProductDetails page, the user is allowed to navigate to related pages and then back to ProductDetails, it
+  starts to become necessary to keep passing that product id around from page to page to page.
+  
+  At some point, persistent values make more sense.  In the near future, there will be a client-side persistence strategy that will encode persistent data, such as
+  the product id field, into query parameters (and hidden form fields) automatically.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/parameters.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/parameters.apt
new file mode 100644
index 0000000..c809c4c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/parameters.apt
@@ -0,0 +1,503 @@
+ ---

+  Component Parameters

+ ----

+ 

+Component Parameters

+

+  Component parameters are a critical aspect of Tapestry.  It is not enough that an instance of

+  a component class <exists>, it must be <configured> to do the right thing. Configuration is in

+  terms of the parameters of the component.

+  

+  A component may have any number of parameters.  Each parameter has a specific name,

+  a specific Java type (which may be a primitive value), and may be <optional> or <required>.

+  

+  Parameters are defined by placing a

+  {{{../../apidocs/org/apache/tapestry/annotation/Parameter.html}Parameter}} annotation

+  onto a private field.

+  

+  The component listed below is a looping component; it renders its body

+  a number of times, defined by its start and end parameters (which set the boundaries

+  of the loop).  The component can update a value parameter bound to a property of its container,

+  it will automatically count up or down depending on whether start or end is larger.

+  

++---+

+package org.example.app.components;

+

+import org.apache.tapestry.annotation.AfterRender;

+import org.apache.tapestry.annotation.Parameter;

+import org.apache.tapestry.annotation.SetupRender;

+

+public class Count

+{

+    @Parameter

+    private int start = 1;

+

+    @Parameter(required = true)

+    private int end;

+

+    @Parameter

+    private int value;

+

+    private boolean increment;

+

+    @SetupRender

+    void initializeValue()

+    {

+        value = start;

+

+        increment = start < end;

+    }

+

+    @AfterRender

+    boolean next()

+    {

+        if (increment)

+        {

+            int newValue = value + 1;

+

+            if (newValue <= end)

+            {

+                value = newValue;

+                return false; 

+            }

+        }

+        else

+        {

+            int newValue = value - 1;

+

+            if (newValue >= end)

+            {

+                value = newValue;

+                return false; 

+            }

+        }

+

+        return true;

+    }

+}

++---+

+  

+  The name of the parameter is derived from the field name (by stripping leading "_" and "$" characters).

+  Here, the parameter names are "start", "end" and "value".  

+  

+Binding Parameters

+

+  The component above can be referenced in another component or page 

+  {{{templates.html}template}}:

+  

++---+

+<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <p> Merry Christmas: <t:count end="3"> Ho! </t:count>

+    </p>

+</html>

++---+  

+  

+  The end attribute is used to <bind> the end parameter of the

+  Count component.  Here, it is being bound to the string value "3", which is automatically

+  {{{coercion.html}coerced}} by Tapestry into the int value, 3.

+    

+  Any number of parameters may be bound this way.

+  

+  Component parameters may also be bound using the

+  {{{component-classes.html#Embedded Components}Component annotation}} inside the component class.

+  

+  Where conflicts occur, the parameters bound using the Component annotation will

+  take precendence over parameter bindings

+  in the template.

+    

+Binding Expressions

+

+  The value inside the template, "3" in the previous example, is a <binding expression>.

+    

+  By placing a prefix in front of the value, you can change how Tapestry interprets the remainder

+  of the expression (the part after the colon):

+  

+*------------+----------------------------------------------------------------------------------+

+| <<Prefix>> | <<Description>>                                                                  |

+*------------+----------------------------------------------------------------------------------+

+| asset      | The relative path to an asset file (which must exist). |

+*------------+----------------------------------------------------------------------------------+

+| block      | The id of a block within the template. |

+*------------+----------------------------------------------------------------------------------+

+| component  | The id of another component within the same template.                            |

+*------------+----------------------------------------------------------------------------------+

+| literal    | A literal string.                                                                |

+*------------+----------------------------------------------------------------------------------+

+| nullfieldstrategy | Used to locate a pre-defined {{{../../apidocs/org/apache/tapestry/NullFieldStrategy.html}NullFieldStrategy}}|

+*------------+----------------------------------------------------------------------------------+

+| message    | Retrieves a value from the component's {{{localization.html}message catalog}}.   |

+*------------+----------------------------------------------------------------------------------+

+| prop       | The name of a property of the containing component to read or update.            |

+*------------+----------------------------------------------------------------------------------+

+| translate  | The name of a configured translator.                                             |

+*------------+----------------------------------------------------------------------------------+

+| validate   | A <validator specification> used to create some number of field validators.      |

+*------------+----------------------------------------------------------------------------------+

+| var        | Allows a render variable of the component to be read or updated. |      |

+*------------+----------------------------------------------------------------------------------+

+

+  Parameters have a default prefix, usually "prop:", that is used when the prefix is not provided.

+  

+  A <special prefix>, "inherit:", is used to support {{{#Inherited Parameter Bindings}Inherted Parameter Bindings}}.

+

+Render Variables

+

+    Components can have any number of <render variables>.  Render variables are named values with no

+    specific type (they are ultimately stored in a Map).  Render variables are useful

+    for holding simply values, such as a loop index, that needs to be passed from one component to another.

+

+    For example:

+

+---

+  <ul>

+    <li t:type="loop" source="1..10" value="index">${index}</li>

+  </ul>

+---

+

+  And in the Java code:

+

+---

+  @Property

+  private int index;

+---

+

+  ... could be rewritten as just:

+

+---

+  <ul>

+    <li t:type="loop" source="1..10" value="var:index">${var:index}</li>

+  </ul>

+---

+

+  In other words, you don't have to define a property in the Java code.  The disadvantage is that

+  render variables don't work with the property expression syntax, so you can pass around a

+  render variables <value> but you can't reference any of the value's properties.

+

+  Render variables are automatically cleared when a component finishes rendering.

+

+  Render variable names are case insensitive.

+

+Property Bindings

+

+  The "prop:" binding prefix indicates a property binding.

+  

+  The expression for a property binding is a dotted sequence of property names.  Simple

+  property expressions are just the name of a property, "prop:userName".  Complex property

+  expression may do a little navigation before getting to the property to read and/or update:

+  "prop:userData.name".  

+  

+  In addition to property names, you may also invoke arbitrary methods.  The methods must be public,

+  return a non-void value, throw no checked exceptions, and take no parameters.  To differentiate

+  a method name from a property name, you simply append the open and close parenthesis.  Thus

+  the prior examples could be rewritten as "prop:getUserName()" and "prop:getUserData().getName()".

+  Note that when the last term in the expression is a method name, the binding will be read-only,

+  rather than read/write.

+  

+  This feature is most useful for accessing a couple of propertys of standard collection classes

+  that aren't named as proper properties, such as Collection.size(), or Map.keySet().

+      

+  Ever get frustrated, tripping over null pointers inside such an expression?  You may use

+  "?." instead of "." as the separator.  This adds a null check and aborts the expression

+  if the term is null.  Thus "foo?.bar?.baz" will return null if either foo or bar are null.

+  Likewise, updating "foo?.bar?.baz" will turn into a no-op if foo or bar is null.    

+      

+  In addition, a few special cases are also supported. 

+  In most cases, these special values save you the trouble of adding a "literal:" prefix to

+  the value.  These special cases are <alternatives> to property expressions.

+  

+  * "true" and "false" will be converted to booleans. 

+  

+  * "null" will be the  value null. 

+    

+  * "this" will be the component itself.

+  

+  * Simple numeric values are also accepted. These will be parsed into Long or Double objects.

+    Ex: "prop:3.14".

+    

+  * A range of integers separated by two periods. Ex: "1..10".  

+  

+  * Literal strings, inside single quotes.  Ex: "'Hello World'"

+  

+  []

+  

+  In all these cases, excess whitespace is ignored.  For the keywords ("true", "false", "this" and

+  "null"), case is ignored.

+  

+  Such values are read only and invariant.

+  

+Validate Bindings

+

+  The "validate:" binding prefix is highly specialized. It allows a short string to be

+  used to create and configure the objects that perform input validation for 

+  form control components, such as TextField and Checkbox.

+  

+  The string is a comma-separated list of   <validator types>.  These are short aliases

+  that for objects that perform the validation.  In many cases, the validation is configurable

+  in some way: for example, a validator that enforces a minimum string length

+  needs to know what that minimum string length is.  Such values are specified after an equals sign.

+  

+  For example:  <<<validate:required,minLength=5>>> would presumably enforce that a field

+  requires a value, with at least five characters.

+  

+Translate Bindings

+

+  The "translate:" binding prefix is also related to input validator. It is the name

+  of a configured {{{../../apidocs/org/apache/tapestry/Translator.html}Translator}}, responsible

+  for converting between server-side and client-side representations of data (for instance, between

+  client-side strings and server-side numeric values).

+  

+  The list of available translators is configured by the

+  {{{../../apidocs/org/apache/tapestry/services/TranslatorSource.html}TranslatorSource}} service.  

+  

+Informal Parameters

+

+  Some components support <informal parameters>, additional parameters beyond the formally defined parameters.

+  Informal parameters will be rendered into the output as additional attributes on the tag rendered by

+  the component.  Generally speaking, components that have a 1:1 relationship with a particular HTML tag

+  (such as {{{../ref/org/apache/tapestry/corelib/components/TextField.html}TextField}} and 

+  \<input\> will support informal parameters.

+

+  Only components whose class is annotated with

+  {{{../apidocs/org/apache/tapestry/annotation/SupportsInformalParameters.html}SupportsInformalParameters}}

+  will support informal parameters.

+

+  Informal parameters are often used to set the CSS class of an element, or to specify client-side event handlers.

+  

+  The default binding prefix for informal parameters depends on <where> the parameter binding is specified.

+  If the parameter is bound inside a Java class, within the 

+  {{{../../apidocs/org/apache/tapestry/annotation/Component.html}Component}} annotation, then the default binding

+  prefix is "prop:".  If the parameter is bound inside the component template, then the default binding

+  prefix is "literal:".  This reflects the fact that a parameter specified in the Java class, using the annotation, is most likely

+  a computed value, whereas a value in the template should simply be copied, as is, into the result HTML stream.

+

+Supporting Informal Parameters

+

+    <<Only>> components which area annotated with

+    {{{../apidocs/org/apache/tapestry/annotation/SupportsInformalParameters.html}SupportsInformalParameters}}

+    may have informal parameters. Tapestry silently drops informal parameters that are specified for components

+    that do not have this annotation.

+

+    To render informal parameters, inject the

+    {{{../apidocs/org/apache/tapestry/ComponentResources.html}ComponentResources}} for your component

+    and invoke the <<<renderInformalParameters()>>> method.

+

+    

+Parameters Are Bi-Directional

+

+  Parameters are not simply variables; each parameter represents a connection, or <binding>, between

+  a component and a property of its container.  When using the prop: binding prefix,

+  the component can force changes <into> a property of its container, just by assigning a value

+  to its own instance variable.

+  

++---+

+<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <p> Countdown:

+        <t:count start="5" end="1" value="index"> 

+          ${index} ...  

+        </t:count>

+    </p>

+</t:layout>

++---+   

+

+  Because the Count component updates its value parameter (the _value field), the index property

+  of the containing component is updated.  Inside the Count's body, we output the current

+  value of the index property, using the expansion <<<$\{index\}>>>. The resulting output

+  will look something like:

+  

++---+

+  <p> Countdown: 5 ... 4 ... 3 ... 2 ... 1 ... </p>

++---+

+

+  (Though the whitespace will be quite different.)  

+  

+  The relevant part is that components can read fixed values, or <live>

+  properties of their  container, and can <change> properties of their container as well.

+  

+Required Parameters

+

+  Parameters that are required <<must>> be bound.  A runtime exception occurs if a component

+  has unbound required parameters.

+  

+Optional Parameters

+

+  Parameters which are not required, are optional.  

+  

+  You may set a default value for optional parameters as you would for any other field. In the Count component,

+  the min parameter has a default value of 1. That value is used unless the min parameter is bound,

+  in which case, the bound value supercedes the default.

+  

+  

+{Inherited Parameter Bindings}

+

+  A special prefix, "inherit:" is used to identify the name of a parameter of the containing component.

+  If the parameter is bound in the containing component, then it will be bound to the same value

+  in the embedded component.

+  

+  If the parameter is not bound in the containing component, then it will not be bound in the embedded component

+  (and so, the embedded component may use a default binding).

+  

+  Inherited bindings are useful for complex components; they are often used when an inner component

+  has a default value for a parameter, and the outer component wants to make it possible to override that default.

+  

+  More examples on this coming soon.

+    

+Parameter Binding Defaults

+

+  The Parameter annotation's value() attribute can be used to specify a <binding expression> that will be the

+  default binding for the parameter is otherwise left unbound. Typically, this is the name of a property

+  that that will compute the value on the fly.  

+  

+  Example:

+  

++----+

+  @Parameter("defaultMessage")

+  private String message;

+  

+  @Parameter(required=true)

+  private int maxLength;

+  

+  public String getDefaultMessage()

+  {

+    return String.format("Maximum field length is %d.", _maxLength);

+  }

++---+

+

+  As elsewhere, you may use a prefix on the value. A common prefix to use is the "message:" prefix, to access a localized message.  

+  

+Computed Parameter Binding Defaults

+

+  In <rare> cases, you may want to compute the binding to be used as a parameter default. In this case, you will provide

+  a <default binding method>, a method that takes no parameters.  The returned value is used to bind the parameter.  The return value may

+  be a

+  {{{../../apidocs/org/apache/tapestry/Binding.html}Binding}} instance, or it may be a simple value (which is more often the case).  

+  

+  The method name is "default" plus the capitalized name

+  of the parameter.

+  

+  Using this approach, the previous example may be rewritten as:

+    

++----+

+  @Parameter

+  private String message;

+  

+  @Parameter(required=true)

+  private int maxLength;

+  

+  @Inject

+  private ComponentResources resources;

+  

+  @Inject

+  private BindingSource bindingSource;

+  

+  Binding defaultMessage()

+  {

+    return bindingSource.newBinding("default value", resources, "defaultMessage");

+  }

+  

+  public String getDefaultMessage()

+  {

+    return String.format("Maximum field length is %d.", maxLength);

+  }

++---+  

+  

+  In this example, a property expression, "defaultMessage", is used to access the message dynamically.

+  

+  Alternately, the previous example may be written even more succinctly as:

+  

++----+

+  @Parameter

+  private String message;

+  

+  @Parameter(required=true)

+  private int maxLength;

+  

+  @Inject

+  private ComponentResources resources;

+  

+  String defaultMessage()

+  {

+    return String.format("Maximum field length is %d.", _maxLength);

+  }  

++---+  

+  

+  This form is more like using the "literal:" binding prefix, except that the literal value is computed by the defaultMessage() method.

+  

+  Obviously, this is a lot more work than simply specifying a default value as part of the Parameter annotation. In the few

+  real cases where this is approach is used, the default binding method will usually deduce a proper binding, typically in terms of

+  the component's id.  For example, the TextField component will deduce a value parameter that binds to a property of its container with

+  the same name.

+  

+  A default binding method will <only> be invoked if the Parameter annotation does not provide a default value.

+  

+Unbound Parameters

+

+  If a parameter is not bound (and is optional), then the value may be read or <updated> at any time.

+  

+  Updates to unbound parameters cause no side effects.  In the first example, the value parameter of the Count

+  component is not bound, and this is perfectly valid.

+  

+  Note: updates to such fields are temporary; when the component <finishes rendering>, the field

+  will revert to its default value.

+  

+  <<TODO: This seems contradictory. What does it mean to update an unbound component parameter when the component 

+  is not rendering?>>  

+    

+  

+Parameter Caching

+

+  Reading a parameter value can be marginally expensive (because of type coercion). Therefore, it makes sense

+  to cache the parameter value, at least while the component is actively rendering itself.

+  

+  In rare cases, it is desirable to defeat the caching; this can be done by setting the cache() attribute

+  of the Parameter annotation to false.

+  

+Parameter Type Coercion

+

+  Tapestry includes a mechanism for {{{coercion.html}coecing types automatically}}. Most often, this is used to

+  convert literal strings into appropriate values, but in many cases, more complex conversions

+  will occur.

+  

+Parameter Names

+

+  By default, Tapestry converts from the field name to the parameter name, by stripping off leading

+  "$" and "_" characters.

+  

+  This can be overriden using the name() attribute of the Parameter annotation.

+  

+Determining if Bound

+

+  In rare cases, you may want to take different behaviors based on whether a parameter is bound

+  or not. This can be accomplished by querying the component's resources, which can be 

+  {{{inject.html}injected}}  into the component using the

+  {{{../../apidocs/org/apache/tapestry/ioc/annotation/Inject.html}Inject}} annotation:

+  

++---+

+public class MyComponent

+{

+  @Parameter

+  private int myParam;

+  

+  @Inject

+  private ComponentResources resources;

+  

+  @BeginRender

+  void setup()

+  {

+      if (resources.isBound("myParam"))

+      {

+        . . .

+      }

+  }

+}

++---+

+

+  The above sketch illustrates the approach.  Because the parameter type is a primitive type, int,

+  it is hard to distinguish between no binding, and binding explicitly to the value 0.

+  

+  The Inject annotation will inject the

+  {{{../../apidocs/org/apache/tapestry/ComponentResources.html}ComponentResources}} for the component.

+  These resources are the linkage between the Java class you provide, and the infrastructure Tapestry

+  builds around your class.  In any case, once the resources are injected,

+  they can be queried.

+ 

+   
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/persist.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/persist.apt
new file mode 100644
index 0000000..582a086
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/persist.apt
@@ -0,0 +1,106 @@
+ ----

+ Persistent Page Data

+ ----

+ 

+Persistent Page Data

+

+  Most instance variables in Tapestry are automatically cleared at the end of each request.

+  

+  This is important, as it pertains to how Tapestry pages are pooled and shared, over time,

+  by many users.

+  

+  However, you often want to store some persistent data on a page, and have access

+  to it in later requests.

+  

+  This is accomplished with the 

+  {{{../../apidocs/org/apache/tapestry/annotation/Persist.html}Persist annotation}}.

+  

+  This annotation is applied to private instance fields.

+    

++----+

+  @Persist

+  private int value;

++----+

+    

+  Annotated fields will store their state between requests. Generally, speaking, this means

+  that the value is stored into the session (but other approaches are possible).

+  

+  Whenever you make a change to a persistent field, its value is stored.

+  

+  On later requests, the value for such persistent fields is reloaded from storage.

+  

+Persistence Strategies

+

+  The value for each field is the <strategy> used to store the field between requests.

+  

+* session strategy

+

+  The session strategy stores field changes into the session; the session is created as necessary.

+  

+  A suitably long session attribute name is used; it incorporates the

+  name of the page, the nested component id, and the name of the field.

+  

+  Session strategy is the default strategy used unless otherwise overridden.

+  

+* flash strategy

+

+  The flash strategy stores information in the session as well, just for not very long.  Values are

+  stored into the session, but then deleted from the session as they are first used to restore

+  a page's state.

+  

+  The flash is typically used to store temporary messages that should only be displayed to the user

+  once.

+  

+* client strategy

+

+  The field is persisted onto the client; you will see an additional query parameter in each URL

+  (or an extra hidden field in each form).

+  

+  Client persistence is somewhat expensive.  It can bloat the size of the rendered pages by adding hundreds

+  of characters to each link. There is extra processing on each request to de-serialize the 

+  values encoded into the query parameter.

+  

+  Client persistence does not scale very well; as more information is stored into the query parameter, its

+  length can become problematic. In many cases, web browsers, firewalls or other servers may silently

+  truncate the URL which will break the application.

+  

+  Use client persistence with care, and store a minimal amount of data.  Try to store the identity (that is,

+  primary key) of an object, rather than the object itself.

+ 

+  

+Persistence Search

+

+  By default the value for the Persist annotation is the empty string. When this is true,

+  then the actual strategy to be used is determined by a search up the 

+  component hiearchy.

+  

+  For each component, the meta-data property <<<tapestry.persistence-strategy>>> is checked.

+  This can be specified using the 

+  {{{../../apidocs/org/apache/tapestry/annotation/Meta.html}Meta}} annotation.

+  

+  If the value is non-blank, then that strategy is used. This allows a component to control

+  the persistence strategy used inside any sub-components (that don't explicitly use a different

+  strategy).

+  

+  In any case, if no component provides the meta data, then the ultimate default, "session", is used.  

+  

+Default Values

+

+  As with other fields, a default value may be specified inline, or inside a constructor.

+  

+  This value is retained and used to reset the value of the field at the end of each request,

+  before the page is returned to the page pool.

+  

+  Handling of the null value can be a tricky case, due to the limitations of the underlying 

+  Servlet API.  Changing a persistent field's value to null <removes> the

+  field's attribute from the session. On later requests, the field will reset to its

+  default value. Since that is usually null, this is not a problem ... it is only a problem

+  if a field has a non-null default value and may be changed to null.

+

+Clearing Persistent Fields

+

+   If you reach a point where you know that all data for a page can be discarded, you can do exactly that.

+

+   The method <<<discardPersistentFieldChanges()>>> of ComponentResources will discard all persistent fields

+   for the page, regardless of which strategy is used to store the property. This will not affect the

+   page in memory, but takes effect for subsequent requests.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/project-layout.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/project-layout.apt
new file mode 100644
index 0000000..844d5e4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/project-layout.apt
@@ -0,0 +1,63 @@
+ ---
+ Project Layout
+ ---
+
+Project Layout
+
+  This is the <suggested> layout for your Tapestry project; it is the layout of folders and files
+  created by the {{{../../quickstart/}Tapestry Quickstart Archetype}}.  If you are creating your
+  own build using Ant, you may use whatever conventions work for you ... as long as everything gets
+  packaged up into the right place in the target WAR.
+
+  Parts of this project layout mimics the format of an <exploded WAR> (a WAR file unpackaged onto the
+  file system).  This will often enable you to run your application directly from your workspace,
+  without any special build or packaging process, while developing.  Each of the major IDEs has plugins
+  to allow you to accomplish this task ... and its one of the factors (combined with
+  {{{reload.html}live class reloading}}) that makes working with Tapestry a breeze.
+
+  Below is a sample project, whose root package is <<<com.example.myapp>>>:
+
+[../images/projectlayout.png] Project Layout
+
+* Main source files
+
+  Main Java source files, the files that will be compiled into the WAR file, are
+  in <<<src/main/java>>>.  This is <only> Java source files.  You can see
+  the <<<Start.java>>> source file inside the <<<pages>>> subpackage, and
+  the <<<Layout.java>>> source file inside the <<<components>>> subpackage.  The package names
+  demonstrated here are required, dictated by the
+  rules for {{{component-classes.html}component classes}}.
+
+  Compiled Java classes will ultimately be packaged in the WAR inside the
+   <<<WEB-INF/classes>>> folder.
+
+* Classpath Resources
+
+  Resource files are under <<<src/main/resources>>>.  This includes the
+  {{{localization.html}message catalog}} for the Start page (<<<Start.properties>>>),
+  as well as the message catalog and
+  {{{templates.html}component template}} for the Layout component (<<<Layout.tml>>>).  These files will
+  also be packaged into the <<<WEB-INF/classes>>> folder of the WAR.
+
+  Component templates will always be stored in the resources folder.  Templates for pages may be packaged in the WAR proper instead.
+
+* Context Resources
+
+  The WAR is built primarily from the <<<src/main/webapp>>> folder; this is where ordinary files are stored
+  (such as images and stylesheets).  Page templates may also be stored here (<<<Start.tml>>>).  The file <<<src/main/webapp/WEB-INF/web.xml>>>
+  is the servlet container deployment descriptor, which has a very specific
+  {{{conf.html}configuration}} for Tapestry.
+
+  The build tool (usually Maven) will be responsible for putting compiled classes and resources into the <<<WEB-INF/classes>>>
+  folder of the WAR, and for putting the Tapestry library, and its dependencies (as well as any additional libraries defined
+  by your application) into the <<<WEB-INF/lib>>> folder.
+
+* Testing
+
+  The folders <<<src/test/java>>> and <<<src/test/resources>>> are used when compiling and executing tests. Files in these
+  folders are <not> packaged into the final WAR.
+
+  
+
+
+  
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/reload.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/reload.apt
new file mode 100644
index 0000000..5a671cb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/reload.apt
@@ -0,0 +1,69 @@
+ ---

+ Live Class and Template Reloading

+ ---

+ 

+Live Class and Template Reloading

+

+  One of the great new features of Tapestry 5 is automatic reloading of changed classes and templates.

+  

+  In previous versions of Tapestry, reloading of templates was supported in development mode only. Reloading of classes

+  required a restart of the servlet container (or a redeploy of the web application).

+  

+  In Tapestry 5, <page and component> classes will automatically reload when changed.  Likewise, changes to

+  component templates  and other related resources will also be picked up immediately.

+  

+* Template Reloading

+

+  When a template changes, all page instances (as well as the hiearchy of components below them) are discarded and

+  reconstructed with the new template. However, classes are not reloaded in this case.

+  

+  A future version of Tapestry may be more selective, removing only page instances that are affected by the changed

+  file(s).

+  

+* Class Reloading

+

+  On a change to <any> class inside a controlled package (or any sub-package of a controlled package), Tapestry will

+  discard all page instances, and discard the class loader.

+  

+  {{{persist.html}Persistent data}} on the pages will usually not be affected (as it is stored separately, in the session).

+  This allows you to make fairly significant changes to a component class even while the application continues to run.

+  

+Page and Component Packages

+

+  Only page and component classes are subject to reload.

+  

+  Reloading is based on package name; the packages that are reloaded are derived from the {{{conf.html}application configuration}}.

+  

+File System Only

+

+  Reloading of classes and other files applies only to files that are actually on the file system, and not files

+  obtained from JAR files.  This is perfect during development, where the files in question are in your local workspace.

+  In a deployed application, you are somewhat subject to the implementation of your servlet container or application server.  

+  

+Class Loader Issues

+

+  Tapestry uses an extra class loader to load page and component classes.

+  

+  When a change to an underlying Java class file is detected, Tapestry discards the class loader and any pooled page instances.

+  

+  You should be careful to not hold any references to Tapestry pages or components in other code, such as Tapestry IoC services. 

+  Holding such references can cause significant memory leaks, as they can prevent the class loader from being reclaimed by the garbage

+  collector.

+  

+ClassCastExceptions

+

+  Tapestry's class loader architecture can cause minor headaches when you make use of a services layer, or any time that you pass

+  component instances to objects that are not themselves components.

+  

+  You will often see a ClassCastException.  This is because the same class name, say org.example.myapp.pages.Start, exists as two different

+  class instances.  One class instance is loaded by the web application's default class loader.  A second class 

+  instance has been loaded <and transformed> by Tapestry's reloading class loader.

+  

+  Ordinary classes, such as Tapestry IoC Services, will be loaded by the default class loader and expect instances to be

+  loaded by the same class loader (or a parent).

+  

+  The solution to this problem is to introduce an interface; the component class will implement the interface, the service will

+  expect an instance of the interface, rather than a specific type. 

+  

+  It is important that the interface be loaded by the default class loader, it should not be in the pages or components

+  package, but instead be in another package, such as services.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/rendering.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/rendering.apt
new file mode 100644
index 0000000..a5bb9f3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/rendering.apt
@@ -0,0 +1,335 @@
+ ----

+ Component Rendering

+ ----

+

+Component Rendering

+

+* Tapestry 4 Approach

+ 

+ Rendering was a recursive process. Each component implemented a render() method

+ (inherited from an IRender interface).

+ Components would invoke render() on the objects in their template, including

+ other components. 

+ 

+ {{{http://blog.rapidred.com/}Bruce Tate}} has said "if you get veritgo, don't

+ stand at the edge of a JavaServer Faces stack trace and look down". The same applies

+ to Tapestry 4. Once you have heavily nested, looping components, the stack trace

+ can get quite deep. 

+ 

+* Tapestry 5 Approach

+

+ Rendering of components is based on a <state machine> and a <queue> instead of tail recursion.

+ This breaks the rendering process up into tiny pieces that can easily be

+ implemented or overriden.  Don't worry, in practice, it is a breathtakingly

+ small amount of code to write.

+ 

+Rendering Phases

+

+ The rendering of  each component is divided into a number of phases, illustrated

+ below.

+ 

+[../images/component-render-states.png] Component Render States

+

+  Each of the orange phases (SetupRender, BeginRender, BeforeRenderBody, etc.) 

+  corresponds to an annotation you

+  may place on one or more methods of your class.  The annotation directs

+  Tapestry to invoke your method as part of that phase.

+    

+  Methods marked with these annotations are called <<render phase methods>>.

+  

+  Your methods may be void, or return a boolean value. Returning a value can force

+  phases to be skipped, or even be re-visited.  In the diagram, solid lines

+  show the normal processing path.  Dashed lines are alternate flows that are triggered

+  when your render phase methods return false instead of true (or void).

+  

+  Render phase methods may take no parameters, or may take

+  a parameter of type {{{dom.html}MarkupWriter}}.  The methods can have any visibility

+  you like ... typically, package private is used, as this visibility

+  makes it possible to unit test your code (from within the same Java package)

+  without making the methods part of the component's

+  <public> API.

+  

+  These methods are <<optional>>, a default behavior is associated with each phase.

+ 

+  The large number of phases reflects the use of {{{mixin.html}component mixins}} which

+  also plug into the render phases. Several of the phases 

+  exist almost exclusively for mixins.

+  

+  Generally, your code will use the SetupRender, BeginRender, AfterRender and CleanupRender

+  phases ... often just one or two of those.

+ 

+  Here's the source for a looping component that counts up or down between two values,

+  renders its body a number of times,

+  and stores the current index value in a parameter:

+  

++---+

+package org.example.app.components;

+

+import org.apache.tapestry.annotation.Parameter;

+import org.apache.tapestry.annotation.AfterRender;

+import org.apache.tapestry.annotation.SetupRender;

+

+public class Count

+{

+    @Parameter

+    private int start = 1;

+

+    @Parameter(required = true)

+    private int end;

+

+    @Parameter

+    private int value;

+

+    private boolean increment;

+

+    @SetupRender

+    void initializeValue()

+    {

+        value = start;

+

+        increment = start < end;

+    }

+

+    @AfterRender

+    boolean next()

+    {

+        if (increment)

+        {

+            int newValue = value + 1;

+

+            if (newValue <= end)

+            {

+                value = newValue;

+                return false;

+            }

+        }

+        else

+        {

+            int newValue = value - 1;

+

+            if (newValue >= end)

+            {

+                value = newValue;

+                return false; 

+            }

+        }

+

+        return true;

+    }

+}

++---+

+  

+  Returning false from next() causes Tapestry to re-run the BeginRender phase,

+  and from there, re-render the component's body (this component does not have a template).

+  Returning true transitions to the CleanupRender phase.

+  

+  Notice how Tapestry adapts to your methods, as marked with the annotations. It also

+  adapts in terms of parameters; the two annotated methods here did not perform any

+  output, so they did not need a MarkupWriter.

+  

+  What's really mind blowing is that the template and body of a component will

+  often contain ... more components! That means that many different components will

+  be in different phases of their own state machine.

+    

+* {{{../../apidocs/org/apache/tapestry/annotation/SetupRender.html}SetupRender}}

+

+  This is where you can perform any one-time per-render setup for your component.

+  This is a good place to read component parameters and use them to set temporary instance

+  variables.

+  

+* {{{../../apidocs/org/apache/tapestry/annotation/BeginRender.html}BeginRender}}

+

+  For components that render a tag, the start tag is should be rendered here (the close tag

+  should be rendered inside the AfterRender phase). The component

+  can also prevent the template and/or body from being rendered by returning false.

+  

+  Components may or may not have a template.  If a component has a template,

+  and the template includes a \<body\> element, then the BeforeRenderBody phase

+  will be triggered (giving the component the option of rendering its body or not).

+  

+  If a component does not have a \<body\> element in its template, then

+  the BeforeRenderBody phase is not triggered.

+  

+  If a component does not have a template, but does have a body, the BeforeRenderBody

+  phase is still triggered.

+  

+  If no methods are annotated with BeginRender, then no special output occurs during

+  this phase, but the template (if present) or body (if no template is present, but

+  the component has a body) will be rendered.

+  

+* {{{../../apidocs/org/apache/tapestry/annotation/BeforeRenderTemplate.html}BeforeRenderTemplate}}

+

+  This phase exists to allow a component to decorate

+  its template (creating markup around the template generated markup), or to allow a component

+  to skip its template.

+  

+* {{{../../apidocs/org/apache/tapestry/annotation/BeforeRenderBody.html}BeforeRenderBody}}

+

+  Phase associated with a component's body (the portion of its container's template that

+  the component occupies).  The BeforeRenderBody phase allows the component the ability

+  to skip the body, while still rendering the rest of the component's template (if any).

+  

+  If no methods are annotated with BeforeRenderBody, then the body will be rendered by

+  default. Again, this occurs when the \<body\> element of the component's template

+  is reached, or automatically if the component has no template (but the component does

+  have a body).

+

+* {{{../../apidocs/org/apache/tapestry/annotation/AfterRenderBody.html}AfterRenderBody}}

+

+  Phase that is executed after the body is rendered; this only occurs for components with a 

+  body.

+  

+* {{{../../apidocs/org/apache/tapestry/annotation/AfterRender.html}AfterRender}}

+  

+  This phase complements BeginRender, and is often used to render the close tag

+  that matches the start tag rendered in the BeginRender phase.  In any case, the

+  AfterRender phase can continue on to CleanupRender, or revert back to BeginRender (as

+  in our Count component example, above).

+  

+  If no methods are annotated with AfterRender, then no special output occurs, and the

+  CleanupRender phase is triggered.

+   

+* {{{../../apidocs/org/apache/tapestry/annotation/CleanupRender.html}CleanupRender}}

+  

+  The counterpart to SetupRender, this allows final cleanups to occur.

+  

+Using Method Names instead of Annotations

+

+  If you prefer to avoid using annotations on your methods, you may do so by providing specific names for your methods.  

+  The required method name is the annotation name, with the first character decapitalized:  setupRender(), beginRender(), etc.

+  As with annotated render phase methods, Tapestry is flexible about visibility, return type and parameters.

+  

+  Using this mechanism, the earlier example can be rewritten as:

+    

++---+

+package org.example.app.components;

+

+import org.apache.tapestry.annotation.Parameter;

+

+public class Count

+{

+    @Parameter

+    private int start = 1;

+

+    @Parameter(required = true)

+    private int end;

+

+    @Parameter

+    private int value;

+

+    private boolean increment;

+

+    void setupRender()

+    {

+        value = start;

+

+        increment = start < end;

+    }

+

+    boolean afterRender()

+    {

+        if (increment)

+        {

+            int newValue = value + 1;

+

+            if (newValue <= end)

+            {

+                value = newValue;

+                return false;

+            }

+        }

+        else

+        {

+            int newValue = value - 1;

+

+            if (newValue >= end)

+            {

+                value = newValue;

+                return false; 

+            }

+        }

+

+        return true;

+    }

+}

++---+   

+

+  This style is a tradeoff: on the gain side, the code is <even> simpler and shorter, and the method names will, by design, be more consistent from one class to the next.

+  The down side is that the names are very generic, and may in some cases, be less descriptive than using annotated methods (<<<initializeValue()>>> and <<<next()>>> are,

+  to some eyes, more descriptive).

+  

+  You can, of course, mix and match, using specifically named render phase methods in some cases, and annotated render phase methods in other cases. 

+  

+Rendering Components

+

+  Instead of returning true or false, a render phase method may return a component. The component may have been injected via the

+  {{{.../apidocs/org/apache/tapestry/annotation/Component.html}Component}} annotation, or may have been passed to the

+  as a parameter.

+  

+  In any case, returning a component will queue that component to be rendered <<before>> the active component continues rendering.

+  

+  The component to render may even be from a completely different page of the application.

+  

+  Recursive rendering of components is not allowed.

+  

+  This technique allows the rendering of Tapestry pages to be <highly> dynamic.  

+  

+  Returning a component instance does <<not>> short circuit method invocation, the way returning a boolean would.  It is possible

+  that multiple  methods may return components (this is not advised -- insanity may ensue).  

+

+Method Conflicts and Ordering

+

+  It is possible to have multiple methods that are annotated with the

+  same render phase annotation.  This may include methods in the same class, or

+  a mix of method defined in a class and inherited from other classes.

+ 

+* Mixins Before Component

+

+  When a component has {{{mixins.html}mixins}}, then the mixins' render phase methods execute <before>

+  the component's render phase methods.  If a mixin extends from a base class, the mixin's

+  parent class methods execute before the mixin subclass' render phase methods.

+  

+  The order in which the mixins execute is not defined at this time.

+  

+  Exception: Mixins whose class is annotated with

+  {{{../../apidocs/org/apache/tapestry/annotation/MixinAfter.html}MixinAfter}} are ordered

+  <after> the component, not before.

+  

+* Parents before Child

+

+  Ordering is always parent-first.  Methods defined in the parent class are always invoked

+  before methods defined in the child class.

+  

+* Reverse Ordering for AfterXXX and CleanupRender

+

+  The After<XXX> phases exists to balance the Begin<XXX> and Before<XXX> phases.  Often elements will

+  be started inside an earlier phase and then the elements will be ended (closed)

+  inside the correspopnding After<XXX> phase (with the body and template of the component rendering

+  between).

+  

+  In order to ensure that operations occur in the correct, and natural order, the

+  render phase methods for these two stages are invoked in <reverse order>:

+  

+  * Subclass methods 

+  

+  * Parent class methods

+  

+  * Mixin subclass methods

+  

+  * Mixin parent class methods

+  

+* Within a Single Class

+

+  Currently, methods are sorted alphabetically. Methods with the same name are

+  sorted by number of parameters.  Even so, this is not a great idea ... just define

+  one method, and have it call the other methods in the order you desire.

+  

+* Short Circuiting

+

+  If a method returns a true or false value, this will short circuit processing. Other 

+  methods within the phase that would ordinarily be invoked will not be invoked.

+  

+  Most render phase methods should return void, to avoid unintentionally short circuiting

+  other methods for the same phase.

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/request.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/request.apt
new file mode 100644
index 0000000..d4a9adb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/request.apt
@@ -0,0 +1,140 @@
+ ----

+ Request Processing

+ ----

+ 

+Request Processing

+

+  Understanding the request processing pipeline is very important, as it is one of the

+  chief extension points for Tapestry.

+  

+  Much of the early stages of processing are in the form of extensible 

+  {{{../../tapestry-ioc/pipeline.html}pipelines}}.

+  

+Tapestry Filter

+

+  All incoming requests originate with the TapestryFilter, which is configured

+  inside the application's {{{conf.html}web.xml}}.

+  

+  The TapestryFilter is responsible for a number of startup and initialization

+  functions.

+  

+  When it receives a request, the TapestryFilter obtains the

+  {{{../../apidocs/org/apache/tapestry/services/HttpServletRequestHandler.html}HttpServletRequestHandler}} 

+  service, and invokes its service() method. 

+    

+HttpServletRequestHandler Pipeline

+

+  This pipeline performs initial processing of the request. It can be extended

+  by contributing a

+  {{{../../apidocs/org/apache/tapestry/services/HttpServletRequestFilter.html}HttpServletRequestFilter}} into

+  the HttpServletRequestHandler service's configuration.'

+  

+  Tapestry does not contribute any filters into this pipeline of its own

+  

+  The terminator for the pipeline does two things:

+  

+  * It stores the request and response into the {{{../../apidocs/org/apache/tapestry5/services/RequestGlobals.html}RequestGlobals}}

+    service. This is a threaded service that stores per-thread/per-request information.

+    

+  * It wraps the request and response as a

+    {{{../../apidocs/org/apache/tapestry/services/Request.html}Request}} and

+    {{{../../apidocs/org/apache/tapestry/services/Response.html}Response}}, and passes them into the

+    {{{../../apidocs/org/apache/tapestry/services/RequestHandler.html}RequestHandler}} pipeline.

+ 

+  []

+

+  Primarily, this exists to bridge from the Servlet API objects to the corresponding Tapestry objects.  This is the basis

+  for the planned portlet integration for Tapestry.

+     

+RequestHandler Pipeline

+ 

+   This pipeline is where most extensions related to requests take place.  Request represents an abstraction on top of HttpServletRequest; this

+   is necessary to support non-servlet applications, such as portlet applications. Where other code and services within

+   Tapestry require access to information in the request, such as query parameters, that information is obtained from the

+   Request (or Response) objects.

+   

+   The pipeline includes a number of built-in filters:  

+   

+   * CheckForUpdates is responsible for {{{reload.html}class and template reloading}}.

+   

+   * Localization identifies the {{{localization.html}locale for the user}}.

+   

+   * StaticFiles checks for URLs that are for static files (files that exist inside the web context) and aborts

+     the request, so that the servlet container can handle the reuest normally.

+   

+   * ErrorFilter catches uncaught exceptions from the lower levels of Tapestry and presents the exception report page.

+     This involves the {{{../../apidocs/org/apache/tapestry/services/RequestExceptionHandler.html}RequestExceptionHandler}} service,

+     which is responsible for initializing and rendering the

+     {{{../../apidocs/org/apache/tapestry/corelib/pages/ExceptionReport.html}core/ExceptionReport}} page. 

+    

+    

+   []

+      

+   The terminator for this pipeline stores the Request and the Response into RequestGlobals, then requests that the

+   {{{../../apidocs/org/apache/tapestry/services/Dispatcher.html}MasterDispatcher}} service figure out how to

+   handle the request (if it is, indeed, a Tapestry request).

+   

+Master Dispatcher Service

+

+  The MasterDispatcher service is a chain-of-command, aggregating together (in a specific order), several

+  Dispatcher objects.  Each Dispatcher is built to recognize and process a particular kind of URL.

+  

+* RootPath

+

+  As discussed {{{conf.html}elsewhere}}, requests for the context root will instead be treated like render

+  requests for the "start" page.

+

+* Asset

+

+  Requests that being with "/assets/" are references to {{{assets.html}asset resources}} that are stored on the classpath, inside the Tapestry JARs 

+  (or perhaps inside the JAR for a component library).  The contents of the file will be pumped down to the client browser.

+

+* PageRender

+

+  Page render requests are requests to render a particular page.  Such requests may include additional elements on the path, which will be

+  treated as {{{event.html}activation context}} (generally speaking, the primary key of some related entity object), allowing the page to

+  reconstruct the state it will need to succesfully render itself.

+  

+  The event handler method for the activate event may return a value; this is treated the same as the return value from a component action request; typically

+  this will result in a redirect to another page. In this way, the activate event can perform simple validation at the page level ("can the user

+  see this page?").

+  

+  Page render URLs consist of the logical name of the page plus additional path elements for the activation context.  The dispatcher

+  here strips terms off of the path until it finds a known page name. Thus, "/mypage/27" would look first for a page whose name was "mypage/27", then look for 

+  a page name "mypage". Assuming the second search was succesful, the page would be activated with the context "27".  If no logical page name

+  can be identified, control passes to the next dispatcher.

+

+* ComponentEvent

+

+  The component event dispatcher is used to trigger events in components.

+  

+  The URL identifies the name of the page, then a series of component ids (the path from the page down to the specific component), then the name of the event to be

+  triggered on the component. The remaining path elements are used as the context for the <event> (not for the page activation, which

+  does not currently apply). For example, "/griddemo.FOO.BAR/3" would locate page "griddemo", then component "FOO.BAR", and trigger an event named "action" (the default event type,

+  which is omitted from the URL), with

+  the context "3".

+  

+  If the page in question has an activation context, it is supplied as an additional query parameter on the link.

+  

+  In cases where the event type is not the default, "action", it will appear between the nested component id and the event context, preceded by a colon. Example:

+  "/example/foo.bar:magic/99" would trigger an event of type "magic".  This is not common in the vanilla Tapestry framework, but will likely be more common

+  as Ajax features (which would not use the normal request logic) are implemented.

+    

+  The response from a component action request is typically, but not universally, used to send a redirect to the client; the redirect URL is a page render URL

+  to display the response to the event.  This is detailed under {{{pagenav.html}page navigation}}.  

+   

+   

+RequestGlobals Service

+

+  The RequestGlobals service 

+  has a lifecycle of perthread; this means that a seperate instance exists for every thread, and therefore,

+  for every request.  The terminators of the two handler pipelines store the request/response pairs into the RequestGlobals service.

+  

+Request Service

+

+  The Request service is a 

+  {{{http://tapestry.apache.org/tapestry5/tapestry-ioc/shadow.html}shadow}}

+  of the RequestGlobals services' request property. That is, any methods invoked

+  on this service are delegated to the request object stored inside the RequestGlobals.

+   

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/secure.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/secure.apt
new file mode 100644
index 0000000..e91cdb6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/secure.apt
@@ -0,0 +1,139 @@
+ ----
+ Securing the application with HTTPS
+ ----
+
+Securing your application with HTTPS
+
+  Tapestry assumes your application will be primarily deployed as a standard web application, using HTTP
+  (not HTTPS) as the transport mechanism.
+
+  However, many applications will need to have some of their pages secured: only accessible via HTTPS.
+  This could be a login page, or a product ordering wizard, or administrative pages.
+
+  All that is necessary to mark a page as secure is to add
+  the {{{../../apidocs/org/apache/tapestry/annotation/Secure.html}Secure}} annotation to the page class:
+
+----
+@Secure
+public class ProcessOrder
+{
+  . . .
+}
+----
+
+  When a page is marked as secure, Tapestry will ensure that access to that page uses HTTPS.
+  All links to the page will use the "https" protocol.
+
+  If an attempt is made to access a secure page using a non-secure request (a normal HTTP request),
+  Tapestry will send an HTTPS redirect to the client.
+
+  Links to non-secure pages from a secure page will do the reverse: a complete URL with an "http"
+  protocol will be used. In other words, Tapestry manages the transition from insecure to secure and back again.
+
+  Links to other (secure) pages <and to assets> will be based on relative URLs and, therefore, secure.
+
+  The rationale behind using secure links to assets from secure pages is that it prevents
+  the client web browser from reporting a mixed security level.
+
+Securing Multiple Pages
+
+  Rather than placing an @Secure annotation on individual pages, it is possible to
+  enable security for folders of pages.  All pages in or beneath the folder will be secured.
+
+  This is accomplished by making a contribution to the
+  {{{../../apidocs/org/apache/tapestry/services/MetaDataLocator.html}MetaDataLocator}}
+  service configuration.  For example, to secure all pages in the "admin" folder:
+
+----
+public void contributeMetaDataLocator(MappedConfiguration<String,String> configuration)
+{
+  configuration.put("admin:" + TapestryConstants.SECURE_PAGE, "true");
+}
+----
+
+  Here "admin" is the folder name, and the colon is a separator between the folder name
+   and the the meta data key.
+  SECURE_PAGE is a public constant for value "tapestry.secure-page";
+
+  When Tapestry is determining if a page is secure or not, it starts by checking for
+  the @Secure annotation, then it consults the MetaDataLocator service.
+
+  If you want to make your entire application secure:
+
+---
+public void contributeMetaDataLocator(MappedConfiguration<String,String> configuration)
+{
+  configuration.put(TapestryConstants.SECURE_PAGE, "true");
+}
+----
+
+ With no colon, the meta data applies to the entire application (including any component libraries
+ used in the application).
+
+Base URL Support
+
+  When Tapestry switches back and forth between secure and unsecure mode, it must
+  create a full URL (rather than a relative URL) that identifies the protocol, server host name
+  and perhaps even a port number.
+
+  That can be a stumbling point, especially the server host name.  In a cluster, behind a fire wall,
+  the server host name available to Tapestry, via the <<<HttpServletRequest.getServerName()>>> method,
+  is often <not> the server name the client web browser sees ... instead it is the
+  name of the internal server behind the firewall.  The firewall server has the correct name
+  from the web browser's point of view.
+
+  Because of this, Tapestry includes a hook to allow you to override how these default
+  URLs are created: the
+  {{{../../apidocs/org/apache/tapestry/services/BaseURLSource.html}BaseURLSource}} service.
+
+  The default implementation is based on just the getServerName() method; it's often not the
+  correct choice even for development.
+
+  Fortunately, it is very easy to override this implementation.  Here's an example of an override
+  that uses the default port numbers that
+  the {{{http://jetty.mortbay.com}Jetty servlet container}} uses for normal HTTP (port 8080) and for
+  secure HTTPS (port 8443):
+
+----
+    public void contributeAlias(Configuration<AliasContribution> configuration)
+    {
+        BaseURLSource source = new BaseURLSource()
+        {
+            public String getBaseURL(boolean secure)
+            {
+                String protocol = secure ? "https" : "http";
+
+                int port = secure ? 8080 : 8443;
+
+                return String.format("%s://localhost:%d", protocol, port);
+            }
+        };
+
+        configuration.add(AliasContribution.create(BaseURLSource.class, source));
+    }
+----
+
+  This override is hardcoded to generate URLs for localhost; as such you might use it for development
+  but certainly not in production.
+
+  The Alias service exists just for these kinds of overrides; it allows a late-binding
+  to a customized implementation of the BaseURLSource service that hides the built-in
+  Tapestry implementation.
+
+
+Application Server Configuration
+
+   Setting up HTTPS support varies from application server to application server.
+
+   * Jetty:
+
+     * {{{http://docs.codehaus.org/display/JETTY/How+to+configure+SSL}Jetty 6}}
+
+   * Tomcat:
+
+        * {{{http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html}Version 6.0}}
+
+        * {{{http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html}Version 5.5}}
+
+   
+
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/servicestatus.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/servicestatus.apt
new file mode 100644
index 0000000..5126d37
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/servicestatus.apt
@@ -0,0 +1,25 @@
+ ----
+  IoC Services Status
+ ----
+
+IoC Services Status
+
+  Using Tapestry there will often be a large number of services defined in the registry; a mix of the builtin services provided by the framework
+  and your own.
+  
+  Built in to every Tapestry application is a page, ServiceStatus, that can present this information to you.
+  
+  The page "ServiceStatus" presents the list of services within the appication's Registry.
+   
+[../images/servicestatus.png] Service Status Page
+
+  Services may be builtin, defined, virtual or real.
+  
+  Builtin only applies to a few special services that are part of Tapestry IoC.
+  
+  Defined services are defined in some module, but have not yet been referenced in any way.
+  
+  Virtual services have been referenced and have gotten as far as creating a service proxy.
+  
+  Real services have had methods invoked, this forces the <realization> of the service which includes
+  instantiating the service, injecting dependencies, and decorating with any applicable interceptors.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/templates.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/templates.apt
new file mode 100644
index 0000000..4309859
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/templates.apt
@@ -0,0 +1,404 @@
+ ----

+ Component Templates

+ ----

+ 

+Component Templates

+

+  Under Tapestry, component templates are files associated with page or component classes that contain the markup for

+  the component, along with any <embedded components>.

+  

+  In a change from Tapestry 4, under Tapestry 5, component templates are <<well formed XML documents>>. That means

+  that every open tag must have a matching close tag, every attribute must be quoted, and so forth.

+  

+  For the most part, these templates are standard (X)HTML; Tapestry extensions to ordinary markup are provided

+  in the form of a Tapestry namespace.

+  

+  We'll cover the specific content of templates shortly, first a few details about connecting a component to its template.

+    

+Template Location

+

+  Component templates are stored with the component class file.  The files have a ".tml" extension (i.e., <T>apestry <M>arkup

+  <L>anguage), and are stored in

+  the same package as corresponding component class.

+  

+  Under a typical Maven directory structure, the Java class for a component

+  might be <<<src/main/java/org/example/myapp/components/MyComponent.java>>>.

+  The corresponding template will be <<<src/main/resources/org/example/myapp/components/MyComponent.tml>>>.

+  

+  Likewise, the Java class for a page might be <<<src/main/java/org/example/myapp/pages/MyPage.java>>> and

+  the corresponding template will be <<<src/main/resources/org/example/myapp/pages/MyPage.tml>>>.

+  

+  The template and the compiled class will be packaged together in the WEB-INF/classes folder of the application WAR.

+

+  For <pages> (not <components>), a second location will be searched: in the web application context.

+  The location is based on the logical name of the page, in the previous example, the template

+  would be <<<MyPage.tml>>> in the root folder of the web application.

+  

+  In certain cases, Tapestry will simplify the the logical name of a page. For example, the page class

+  org.example.pages.address.CreateAddress will be given a logical name of "address/Create" (the redundant "Address"

+  is removed as a suffix). However, this only affects how the page is referenced in URLs; the template file

+  will still be CreateAddress.tml, whether on the classpath, or as address/CreateAddress.tml (in the web context).

+  

+  A template on the classpath takes precedence over a file in the web application context.

+  

+Template Localization

+

+  Templates are {{{localization.html}localized}} in much the same way as individual files of a component's message

+  catalog: the effective locale is inserted into the name of the file.  Thus a German users will see the content

+  generated from <<<MyPage_de.tml>>> and French users will see content generated from <<<MyPage_fr.tml>>>.  When no

+  specific localization is available, the default location (<<<MyPage.tml>>>) is used.  

+

+Template Inheritance

+

+  If a component does not have a template, but extends from a component class that does have

+  a template, then the parent class' template will be used by the child component.

+

+  This allows a component to extend from a base class but not have to duplicate the base class' template.

+

+Template Doctypes

+

+  As mentioned above, component templates are well-formed XML documents. This means that if you want to use any

+  {{{http://www.w3.org/TR/html401/sgml/entities.html}HTML entities}} (such as &amp; &nbsp; &lt; &gt; or &copy;),

+  you must use an {{{http://www.w3.org/QA/2002/04/valid-dtd-list.html}HTML or XHTML doctype}} in your template. If

+  you choose to use (X)HTML doctypes in your templates, they will be passed on to the client in the resultant (X)HTML.

+  Note that if your pages are composed of multiple components, each with a template, and each template contains a

+  doctype declaration, only the first doctype encountered by the template parser will be passed on to the client.

+

+  It should also be noted that even though XHTML DTDs are valid XML DTDs, HTML DTDs aren't valid XML DTDs. This means

+  that HTML doctypes cannot be used by XML parsers. Tapestry works around this limitation internally by using XHTML DTDs

+  to parse templates that use HTML DTDs. This internal mapping is possible because XHTML 1.0 is nothing more than "a

+  reformulation of the three HTML 4 document types as applications of XML 1.0," {{{http://www.w3.org/TR/xhtml1/#xhtml}as per the W3C}}.

+  Don't worry though -- the original HTML 4 doctype will still be emitted to the client!

+

+ The following doctypes are the most common (X)HTML doctypes:

+

++----+

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

+

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

+

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"

+   "http://www.w3.org/TR/html4/strict.dtd">

+

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

+   "http://www.w3.org/TR/html4/loose.dtd">

++----+

+

+Tapestry Namespace

+

+  Component templates should include the Tapestry namespace, defining it in the root element of the template.

+

++----+

+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <head>

+        <title>Hello World Page</title>

+    </head>

+    <body>

+        <h1>Hello World</h1>

+    </body>

+</html>

++---+

+

+  This defines the namespace using the standard prefix, "t:".  The examples on this page all assume the use of the standard 

+  prefix.

+

+Tapestry Elements

+

+  Tapestry elements are elements defined using the Tapestry namespace prefix.

+  

+  All other elements should be in the default namespace, with no prefix.

+  

+* \<body\>

+

+  In many cases, a component is designed to integrate its template with its container's

+  template.  

+  

+  The \<body\> element is used to identify where, within a component's template, its

+  body (from the container's template) is to be rendered.

+  

+  Components have control over if, and even how often, their body is rendered.

+  

+  The following example is a Layout component, that adds basic HTML elements

+  around the page specific content:

+  

++---+

+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <head>

+        <title>My Tapestry Application</title>

+    </head>

+    <body>

+        <t:body/>

+    </body>

+</html>

++---+  

+

+  A page would use this component as follow:

+  

++---+

+<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+  My Page Specific Content

+

+</t:layout>

++---+

+   

+   When the page renders, the page's template and the Border component's template

+   are merged together:

+   

++---+

+<html>

+  <head>

+    <title>My Tapestry Application</title>

+  </head>

+  <body>

+    My Page Specific Content

+  </body>

+</html>

++---+

+   

+   Tapestry 4 users will recognize the \<body\> element as a replacement for the

+   RenderBody component.

+   

+* \<container\>

+

+   A container element contains markup without being considered part of the template. This is useful for components that render several top level

+   tags, for example, a component that renders several columns within a table row:

+   

++---+

+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+  <td>${label}</td>

+  <td>${value}</td>

+</t:container>

++---+     

+   

+   This component only makes sense when used inside a \<tr\> element of its container's template.

+   

+   Without the \<t:container\> element, there would be no way to create a valid XML document as the template, because XML documents must always

+   have a single root element.

+   

+* \<block\>

+

+  A block is a container of a portion of the component template. A block does not normally render; any component or contents you put inside

+  a block will not ordinarily be rendered.  However, by injected the block, you can have precise control over when and if the content renders.   

+  

+  A block may be anonymous, or it may have an id (specified with the id attribute).  Non-anonymous blocks may be 

+  {{{inject.html}injected}} into the component.

+

+  Ids must be valid Java identifiers: start with a letter, and contain only letters, numbers and underscores.

+

+  Note that the id parameter is <not> placed in the Tapestry namespace (since the element always <is> in the Tapestry namespace).

+

+* \<parameter\>

+

+  A \<parameter\> element is a special kind of block.  It is placed inside the body of an embedded component.  The block defined by the

+  \<parameter\> is passsed to the component.  \<parameter\> includes a mandatory name attribute to identify which parameter of the component

+  to bind.  

+

+  Example:

+    

++---+

+<t:if test="loggedIn">

+  Hello, ${userName}!

+  <t:parameter name="else">

+  Click <a t:type="actionlink" t:id="login">here</a> to log in.

+  </t:parameter>

+</t:if>

++---+

+

+

+Expansions

+

+  Another option when rendering output is the use of  <expansions>.  Expansions

+  are special strings that may be emdedded in template bodies, and borrow some syntax

+  from the {{{http://ant.apache.org}Ant}} build tool.

+  

++---+

+  Welcome, ${userId}!

++---+    

+

+  Here, <<<$\{userId}>>> is the expansion.  In this example, the userId property of the 

+  component is extracted, converted to a string, and streamed into the output.  

+ 

+  Expansions are allowed inside text, and inside attributes of ordinary elements, and component elements.  For example:

+  

++---+

+  <img src="${request.contextPath}/images/catalog/product_${productId}.png"/>

++---+

+

+  In this hypothetical example, the component class is providing a request property and a productId property, and these are being

+  used inside the template to assemble the src attribute of the \<img\> element.  This is component-like behavior without

+  actual components.

+  

+  Under the covers, expansions are the same as

+  {{{parameters.html}parameter bindings}}.  The default

+  binding prefix for expansions is "prop:" (that is, the name of a property), but

+  other binding prefixes are useful, especially "message:" (to access a localized

+  message from the component's message catalog).

+  

+  Tapestry 4 users will note that expansions are a concise, easy replacement for the

+  Insert component, and for the \<span key="..."\> directive.

+  

+Component Elements

+

+  An embedded component is identified within the template as an element in the t: namespace.  Example:

+  

++---+

+  You have ${cartItems.size()} items in your cart.

+  <t:actionlink t:id="clear">Remove All</t:actionlink>.

++---+ 

+  

+  The element name, "actionlink" is used to select the type of component, "ActionLink" (Tapestry is case insensitive when

+  identifying component types).

+  

+  Embedded components may have two Tapestry-specific parameters:

+  

+  * id: A unique id for the component (within its container).

+  

+  * mixins: An optional comma seperated list of mixins for the the component.

+  

+  [] 

+  

+  These attributes are specified inside the t: namespace (i.e., <<<t:id="clear">>>).

+  

+  If the id attribute is ommitted, Tapestry will assign a unique id for the element.

+

+  Ids must be valid Java identifiers: start with a letter, and contain only letters, numbers and underscores.

+  

+  Any other attributes are used to {{{parameters.html}bind parameters of the component}}. These may be formal parameters

+  or informal parameters.  Formal parameters will have a default binding prefix (usually "prop:").  Informal parameters

+  will be assumed to be literals (i.e., the "literal:" binding prefix).

+  

+  Use of the t: prefix is optional for all other attributes.  Some users implement a build process where the Tapestry template

+  files are validated ... in that case, any Tapestry-specific attributes, not defined by the underlying DTD or schema, should be in

+  the Tapestry namespace, to avoid validation errors.

+

+  The open and close tags of a Tapestry component element define the <<body>> of the component. It is quite common for

+  additional components to be <<enclosed>> in the body of another component:

+    

++----+

+<t:form>

+  <t:errors/>

+  <t:label for="userId"/>

+  <t:textfield t:id="userId"/>

+  <br/>

+  <t:table for="password"/>

+  <t:passwordfield t:id="password"/>

+  <br/>

+  <input type="submit" value="Login"/>

+</t:form>

++---+  

+   

+   In some cases, components require some kind of enclosure; for example, all of the field components will throw a runtime exception

+   if not enclosed by a Form component.

+   

+   It is possible to place Tapestry components in subclasses.  For example, your application may have a package org.example.myapp.components.ajax.Dialog.

+   This component's normal type name is "ajax/dialog" (because it is in the ajax subfolder). This name is problematic, as

+   it is not valid to define an XML element with an element name <<<\<t:ajax/dialog\>>>>.  Instead,

+   replace the slashes with periods: <<<\<t:ajax.dialog\>>>>.

+   

+Invisible Instrumentation

+

+  A favorite feature of Tapestry 4 is <invisible instrumentation>, the ability to mark ordinary HTML elements as components. Invisible instrumentation

+  leads to more concise templates that are also more readable.

+  

+  For Tapestry 5, you make use of <namespaced> id or type attributes to mark an arbitrary element as a component, for example:

+  

++---+

+<p>

+    Merry Christmas:

+    <span t:type="Count" end="3">

+        Ho!

+    </span>

+</p>

++---+   

+

+  The id, type and mixins attributes must be placed in the Tapestry namespace.  Any additional attributes may be in the Tapestry namespace

+  or in the default namespace. Placing an attribute in the Tapestry namespace is useful when the attribute is not defined for the

+  element being instrumented.

+    

+  A component <must> have a type, either via the t:type attribute in the template, or by the defining the component in the Java class using the

+  {{{../../apidocs/org/apache/tapestry/annotation/Component.html}Component}} annotation (and using the t:id attribute on the element in the template).

+

+  

+  In <most> cases,it is an aesthetic choice between normal emebedded components, and embedded components via invisible instrumentation.  In a few instances,

+  such as the Loop component, the behavior of the component is influenced by your choice.  The Loop component, when included using invisible instrumentation, will

+  render the tag and any informal parameters, around its body.  Thus, for example:

+  

++---+

+  <table>

+    <tr t:type="loop" source="items" value="item" class="prop:rowClass">

+      <td>${item.id}</td>

+      <td>${item.name}</td>

+      <td>${item.quantity}</td>

+    </tr>

+  </tabel>

++---+

+

+  Here, the loop component "merges into" the \<tr\> element.  It will render out a \<tr\> for each item object in the items list.

+  It will write a dynamic class attribute into each \<tr\>.

+        

+   

+Whitespace in Templates

+

+  Tapestry strips out unnecessary whitespace from templates as they are parsed.

+  Inside any block of text, repeated whitespace is reduced

+  to a single space character.  Blocks of text that are entirely whitespace, such a line break

+  and whitespace between two tags, is eliminated entirely.

+

+  If you do a view source on the rendered output, you'll see that the bulk of the rendered page is one

+  long unbroken line.

+

+  This approach has certain efficiency advantages on both the server (less processing to render the page) and on the client

+  (fewer characters to parse).  Tools such as

+  {{{http://www.getfirebug.com/}FireBug}} are useful for allowing you to view the rendered HTML on the client properly.

+

+  In rare cases, the whitespace in a template <is> significant.  Perhaps you are creating a \<pre\> (preformatted)

+  block of text, or the whitespace interacts with your stylesheet to some desired effect.

+

+  You may use the standard XML attribute <<<xml:space>>> to indicate to Tapestry whether whitespace should

+  be compressed (<<<xml:space="default">>>) or preserved (<<<xml:space="preserve">>>).  Such attributes are stripped

+  out by the template parser; they do not appear in the rendered output.

+

+  The xml: namespace prefix is built into all XML documents, there is no special configuration (as there is with the

+  Tapestry namespace).

+

+  For example:

+

+---

+  <ul class="navmenu" xml:space="preserve">

+    <li t:type="loop" t:source="pages" t:value="var:page">

+      <t:pagelink page="var:page">${var:page}</t:pagelink>

+    </li>

+  </ul>

+---

+

+  This will preserve the whitespace between the \<ul\> and \<li\> elements, and between the

+  (rendered) \<li\> elements and the nested \<a\> elements.  For example, the output may look something like:

+

+---

+  <ul>

+    <li>

+      <a href="showcart>ShowCart</a>

+    </li>

+    <li>

+      <a href="viewaccount">ViewAccount</a>

+    </li>

+  </ul>

+---

+

+  With normal whitespace compression, you would see the following rendered output:

+

+---

+  <ul><li><a href="showcart">ShowCart</a></li><li><a href="viewaccount">ViewAccount</li></ul>

+---

+

+

+  You can even put further <<<xml:space>>> attributes inside nested elements to fine-tune the control over

+  what whitespace is preserved and what is compressed.

+  

+  

+

+  

+  

diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/unit-testing-pages.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/unit-testing-pages.apt
new file mode 100644
index 0000000..ff9b6f0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/unit-testing-pages.apt
@@ -0,0 +1,139 @@
+ ----

+  Unit testing pages or components

+ ----

+

+Unit testing pages or components

+

+  You can easily unit test a certain page or a component. Follow the simple 

+  tasks below.

+ 

+* Setting up a driving environment

+

+  In order to unit test a page, you'll need to create an instance of 

+  {{{../../apidocs/org/apache/tapestry/test/pagelevel/PageTester.html}PageTester}}.

+  It acts as both the browser and the servlet container so that you can

+  use it to drive your page. As it is not a real servlet container, you need 

+  to tell it the same information as you would in web.xml:

+  

+  [[1]] Your application package.

+

+  [[2]] Your filter name. This is used to load your Tapestry IoC module only.

+  If you have none, you can pass an empty string or anything to it.

+  

+  [[3]] The folder acting as your context root. This is used to locate your

+  templates (if they're put there).

+

+  Here is an example (using TestNG, but you're free to use JUnit or anything else):

+

++---+

+public class MyTest extends Assert

+{

+    @Test

+    public void test1()

+    {

+        String appPackage = "org.example.app";

+        String appName = "App1"; // App1Module.java has configured some services.

+        PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

+    }

+}

++---+

+

+* Testing the rendering of a page

+

+  To test if a page renders properly (optionally with context), you can tell

+  the PageTester to render it and then assert against the 

+   {{{../../apidocs/org/apache/tapestry/dom/Document.html}DOM Document}} returned.

+  

+  Here is an example. Let's assuming the page being tested is named "MyPage"

+  and it should return a page containing an HTML element whose id is "id1" 

+  and whose text content should be "hello":

+  

++---+

+public class MyTest extends Assert

+{

+    @Test

+    public void test1()

+    {

+        String appPackage = "org.example.app";

+        String appName = "LocaleApp";

+        PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

+        Document doc = tester.renderPage("MyPage");

+        assertEquals(doc.getElementById("id1").getChildText(), "hello");

+    }

+}

++---+

+

+  If the page requires a context, you can pass it this way:

+  

++---+

+public class MyTest extends Assert

+{

+    @Test

+    public void test1()

+    {

+        String appPackage = "org.example.app";

+        String appName = "LocaleApp";

+        PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

+        Object[] context = new Object[]{ "abc", 123 };

+        Document doc = tester.invoke(new ComponentInvocation(new PageLinkTarget("MyPage"), context));

+        assertEquals(doc.getElementById("id1").getChildText(), "hello");

+    }

+}

++---+

+

+* Testing an action link

+

+  After rendering a page, you may want to "click" on an action link and then

+  assert against the resulting page. You can do it this way:

+

++---+

+public class MyTest extends Assert

+{

+    @Test

+    public void test1()

+    {

+        String appPackage = "org.example.app";

+        String appName = "LocaleApp";

+        PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

+        Document doc = tester.renderPage("MyPage");

+        Element link = doc.getElementById("link1");

+        doc = tester.clickLink(link);

+        assertTrue(doc.toString().contains("abc"));

+    }

+}

++---+

+

+* Testing a form submission

+

+  After rendering a page, you may want to fill out a form, submit it and

+  then inspect the resulting page. You can do it this way:

+

++---+

+public class MyTest extends Assert

+{

+    @Test

+    public void test1()

+    {

+        String appPackage = "org.example.app";

+        String appName = "LocaleApp";

+        PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

+        Document doc = tester.renderPage("MyPage");

+        Element form = doc.getElementById("form1");

+        Map<String, String> fieldValues = new HashMap<String, String>();

+        fieldValues.put("field1", "hello");

+        fieldValues.put("field2", "100");

+        doc = tester.submitForm(form, fieldValues);

+        assertTrue(doc.toString().contains("abc"));

+    }

+}

++---+

+

+  To submit a form by clicking a submit button, call the

+  {{{../../apidocs/org/apache/tapestry/test/pagelevel/PageTester.html#clickSubmit(org.apache.tapestry.dom.Element, java.util.Map)}clickSubmit()}} 

+  method instead.

+

+* Unit testing a component

+

+  To unit test a component, just create a test page containing that component. Then 

+  unit test that page.

+

diff --git a/hlship-20080520/tapestry-core/src/site/apt/guide/validation.apt b/hlship-20080520/tapestry-core/src/site/apt/guide/validation.apt
new file mode 100644
index 0000000..3e63c48
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/guide/validation.apt
@@ -0,0 +1,317 @@
+ ---
+ Form Input and Validation
+ ---
+ 
+Form Input and Validation
+
+  The life's blood of any application is form input; this is the most effective way to gather significant information from the user.
+  Whether it's a search form, a login screen or a multi-page registration wizard, forms are how the user really expresses themselves to the
+  application. 
+  
+  Tapestry excels at creating forms and validating input.  Input validation is declarative, meaning you simply tell Tapestry what validations
+  to apply to a given field, and it takes care of it on the server and (once implemented) on the client as well.
+  
+  Finally, Tapestry is able to not only present the errors back to the user, but to decorate the fields and the labels for the
+  fields, marking them as containing errors (primarily, using CSS effects).
+  
+Form component
+
+  The core of Tapestry's form support is the
+  {{{../ref/org/apache/tapestry/corelib/components/Form.html}Form}} component.  The Form component encloses (wraps around) all the
+  other <field components>  such as
+  {{{../ref/org/apache/tapestry/corelib/components/TextField.html}TextField}},
+  {{{../ref/org/apache/tapestry/corelib/components/TextArea.html}TextArea}},
+  {{{../ref/org/apache/tapestry/corelib/components/Checkbox.html}Checkbox}}, etc.
+  
+  The Form component generates a number of {{{event.html}component events}} that
+  you may provide event handler methods for.
+  
+  When rendering, the Form component emits two notifications: first, "prepareForRender", then "prepare". These
+  allow the Form's container to setup any fields or properties that will be referenced in the form.
+  For example, this is a good chance to create a temporary entity object to be rendered, or
+  to load an entity from a database to be editted.
+  
+  When user submits the form on the client, a series of steps occur on the server.
+  
+  First, the Form emits a "prepareForSubmit" notification,
+  then a "prepare" notification.  These allow the container to ensure that objects are set up
+  and ready to receive information from the form submission.
+  
+  Next, all the fields inside the form are activated to pull values out of the
+  incoming request, validate them and (if valid) store the changes.
+  
+  <For Tapestry 4 Users: > Tapestry 5 does not use the fragile "form rewind" approach
+  from Tapestry 4.  Instead, a hidden field generated during the render stores
+  the information needed to process the form submission.
+  
+  After the fields have done their processing, the Form emits a "validate" event.
+  This is a chance to perform cross-form validation that can't be described declaratively.
+  
+  Next, the Form determines if there have been any validation errors.  If there have been,
+  then the submission is considered a failure, and a "failure" event is emitted.
+  If there have been no validation errors, then a "success" event is emitted.
+  
+  Last, the Form emits a "submit" event (for logic that doesn't care about success or
+  failure).
+  
+Tracking Validation Errors
+
+  Associated with the Form is an
+  {{{../../apidocs/org/apache/tapestry/ValidationTracker.html}ValidationTracker}}
+  that tracks all the provided user input and validation errors for every field in the
+  form.  The tracker can be provided to the Form via the Form's tracker parameter,
+  but this is rarely necessary.
+  
+  The Form includes  methods <<<isValid()>>> and <<<getHasErrors()>>>, which are used to
+  see if the Form's validation tracker contains any errors.
+  
+  In your own logic, it is possible to record your own errors.  Form includes
+  two different versions of method <<<recordError()>>>, one of which specifies a 
+  {{{../../apidocs/org/apache/tapestry/Field.html}Field}} (an interface implemented by
+  all form element components), and one of which is for "global" errors, unassociated
+  with any particular field.
+  
+Storing Data Between Requests
+
+  As with other action requests, the result of a form submission is to send a redirect
+  to the client which re-renders the page.  The ValidationTracker must be
+  stored {{{persist.html}persistently}} between requests, or all the validation
+  information will be lost (the default ValidationTracker provided by the Form is persistent).
+  
+  Likewise, the individual fields updated by the components should also be persistent.
+  
+  For example, a Login page, which collects a user name and a password, might look like:
+  
++---+
+public class Login
+{
+    @Persist
+    private String userName;
+
+    private String password;
+
+    @Inject
+    private UserAuthenticator authenticator;
+
+    @Component(id = "password")
+    private PasswordField passwordField;
+
+    @Component
+    private Form form;
+
+    String onSuccess()
+    {
+        if (!authenticator.isValid(userName, password))
+        {
+            form.recordError(passwordField, "Invalid user name or password.");
+            return null;
+        }
+
+        return "PostLogin";
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        password = password;
+    }
+
+    public String getUserName()
+    {
+        return userName;
+    }
+
+    public void setUserName(String userName)
+    {
+        userName = userName;
+    }
+}
++---+  
+
+	Because of the the fact that a form submission is <two> requests (the submission itself, then a re-render of the page),
+	it is necessary to make the value stored in the _userName field persist between the two requests. This would be necessary
+	for the _password field as well, except that the 
+	{{{../ref/org/apache/tapestry/corelib/components/PasswordField.html}PasswordField}} component never renders a value.
+	
+	Note that the onSuccess() method is not public; event handler methods can have any visibility, even private.  Package private
+	(that is, no modifier) is the typical use, as it allows the component to be tested, from a test case class in the same package.
+	
+	The Form only emits a "success" event if the there are no prior validation errors.  This means it is not necessary to
+	write <<<if (_form.getHasErrors()) return;>>> as the first line of the method.
+	
+	Finally, notice how business logic fits into validation.  The UserAuthenticator service is responsible for ensuring
+	that the userName and (plaintext) password are valid. When it returns false, we ask the Form component
+	to record an error.  We provide the PasswordField instance as the first parameter; this ensures that the
+	password field, and its label, are decorated when the Form is re-rendered, to present the errors to the user.
+
+Configuring Fields and Labels
+
+	The template for page contains a minimal amount of Tapestry instrumentation:
+	
++---+
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Login</title>
+    </head>
+    <body>
+        <h1>Please Login</h1>
+
+        <form t:id="form">
+
+            <t:errors/>
+
+            <t:label for="userName"/>:
+            <input t:type="TextField" t:id="userName" t:validate="required,minlength=3" size="30"/>
+            <br/>
+            <t:label for="password"/>:
+            <input t:type="PasswordField" t:id="password" t:validate="required,minlength=3" size="30"/>
+            <br/>
+            <input type="submit" value="Login"/>
+        </form>
+    </body>
+</html>
++---+
+
+  The Tapestry Form component is responsible for creating the necessary URL for the form submission (this is Tapestry's
+  responsibility, not yours).
+  
+  The 
+  {{{../ref/org/apache/tapestry/corelib/components/Errors.html}Errors}} component must be placed inside a Form, it outputs
+  all of the errors for all the fields within the Form as a single list. It uses some simple styling to make the result more presentable.
+  
+  Each field component, such as the TextField, is paired with a
+  {{{../ref/org/apache/tapestry/corelib/components/Label.html}Label}} component.  The Label will render out
+  a \<label\> element connected to the field. This is very important for useability, especially for users with
+  visual disabilities. It also means you can click on the label text to move the cursor to the corresponding field.
+  
+  The <<<for>>> parameter of the Label is the id of a component.
+  
+  For the TextField, we provide a component id, userName.  We could specify the <<<value>>> parameter, but the default is
+  to match the TextField's id against a property of the container, the Login page, if such a property exists.
+  
+  As a rule of thumb, you should always give your fields a specific id (this id will be used to generate the <<<name>>> and <<<id>>> attributes
+  of the rendered tag).  Being allowed to omit the value parameter helps to keep the template from getting too cluttered.
+  
+  The <<<validate>>> parameter identifies what validations should occur for the field.  This is a list of validator names.  Validators are
+  configured within Tapestry, and the list of available validators is extensible.  "required" is a name of one of the built-in validators,
+  that ensures that the submitted value is not the empty string.  Likewise, "minlen" ensures that the value has the specified minimum length.
+  
+  The <<<validate>>> parameter was placed within the Tapestry namespace using the <<<t:>>> prefix. This is not strictly necessary, as the template
+  is <well formed> either way. However, putting the Tapestry specific values into the Tapestry namespace ensures that the template will itself
+  be <valid>.
+  
+Errors and Decorations
+
+  <<Note: This section has not been updated to reflect the introduction of client-side input validation.>>
+
+  When you first activate the Login page, the fields and forms will render normally, awaiting input:
+  
+[../images/validation_initial.png] Initial form presentation
+
+  Notice how the Label components are displaying the textual names for the fields. Given that we have not done any explicit configuration,
+  what's happened is that the component's ids ("userName" and "password") have been converted to "User Name" and "Password".
+  
+  If you just submit the form as is, the fields will violate the "required" constraint and the page will be redisplayed to present those
+  errors to the user:
+  
+[../images/validation_errors.png] Errors and decorations
+
+  There's a couple of subtle things going on here.  First, Tapestry tracks <all> the errors for <all> the fields.  The
+  Errors component has displayed them at the top of the form.  Further, the <default validation decorator> has added
+  decorations to the labels and the fields, adding "t-error" to the CSS class for the fields and labels. Tapestry provides a default
+  CSS stylesheet that combines with the "t-error" class to make things turn red.
+  
+  Next, we'll fill in the user name but not provide enough characters for password.
+  
+[../images/validation_minlength.png] Minlength error message
+
+  The user name field is OK, but there's an error on just the password field.  The PasswordField component always displays a blank value
+  by default, otherwise we'd see the partial password displayed inside.
+  
+  If you type in enough characters and submit, we see how the logic inside the Login page can attach errors to fields:
+  
+[../images/validation_password.png] Application supplied errors
+
+  This is nice and seamless; the same look and feel and behavior for both the built-in validators, and for errors generated based on
+  application logic.
+
+Overriding the Translator with Events
+
+  The TextField, PasswordField and TextArea components all have a translate parameter, a
+  {{{../../apidocs/org/apache/tapestry/Translator.html}Translator}} object that is used to convert values on the server
+  side to strings on the client side.
+
+  In most cases, the translate parameter is not set explicitly; Tapestry derives an appropriate value
+  based on the type of property being editted by the field.
+
+  In certain cases, you may want to override the translator.  This can be accomplished using two events
+  triggered on the component, "toclient" and "parseclient".
+
+  The "toclient" event is passed the current object value and returns a string, which will be the default
+  value for the field. When there is no event handler, or when the event handler returns null, the default
+  Translator is used to convert the server side value to a string.
+
+  For example, you may have a quantity field that you wish to display as blank, rather than zero,
+  initially:
+
++---+
+  <t:textfield t:id="quantity" size="10"/>
+
+  . . .
+
+  private int quantity;
+
+  String onToClientFromQuantity()
+  {
+    if (quantity == 0) return "";
+
+    return null;
+  }
++---+
+
+  This is good so far, but if the field is optional and the user submits the form,
+  you'll get a validation error, because the empty string is not valid as an integer.
+
+  That's where the "parseclient" event comes in:
+
++---+
+  Object onParseClientFromQuantity(String input)
+  {
+    if ("".equals(input)) return 0;
+
+    return null;
+  }
++---+
+
+  The event handler metohd has precendence over the translator.  Here it checks for the empty string
+  (and note that the input may be null!) and evaluates that as zero.
+
+  Again, returning null lets the normal translator do its work.
+
+  The event handler may also throw
+  {{{../../apidocs/org/apache/tapestry/ValidationException.html}ValidationException}} to indicate a value
+  that can't be parsed.
+
+  Now, what if you want to perform your own custom validation?  That's another event: "validateInput":
+
++---+
+  void onValidateFromCount(Integer value) throws ValidationException
+  {
+    if (value.equals(13)) throw new ValidationException("Thirteen is an unlucky number.");
+  }
++---+
+
+  This event gets fired <<after>> the normal validators. It is passed the <parsed> value (not the string from
+  the client, but the object value from the translator, or from the "parseclient" event handler).
+
+  The method may not return a value, but may throw a ValidationException to indicate a problem with
+  the value.
+
+  <<Caution:>> These events are exclusively on the <server side>.
+  This means that, in certain circumstances,
+  an input value will be rejected on the client side even though it is valid on the server side.
+
diff --git a/hlship-20080520/tapestry-core/src/site/apt/index.apt b/hlship-20080520/tapestry-core/src/site/apt/index.apt
new file mode 100644
index 0000000..3d71ce0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/index.apt
@@ -0,0 +1,175 @@
+ ----

+ tapestry-core

+ ----

+ 

+Tapestry Core

+

+  The tapestry-core module provides the interfaces and annotations that form the Tapestry API.

+  

+  tapestry-core is built upon the {{{../tapestry-ioc/index.html}Tapestry IoC Container}}.

+

+New And Of Note

+

+  * Component methods may be marked with the @Log annotation, to enable debug logging of

+    method entry (with parameters) and exit (with return value, or thrown exception).

+

+  * It is now possible to provide method invocation advice to component methods. This opens up

+    a very powerful Aspect Oriented Programming approach to Tapestry components.

+

+  * The Exception Report page now identifies the version of the Tapestry framework, and lists

+    out System properties (including the Java classpath).

+

+  * The {{{ref/org/apache/tapestry/corelib/components/Grid.html}Grid}} component can now update itself in place,

+    using Ajax, when paging or sorting links are clicked.

+

+  * Added a zone parameter to the  {{{ref/org/apache/tapestry/corelib/components/BeanEditForm.;html}BeanEditForm}}

+    component, to support Ajax updates.

+

+  * The @Cached annotation has been added to allowing the caching of method results.

+

+  * Tapestry can now generate accessor methods for fields automatically via the @Property annotation.

+

+  * It is now possible to override the built-in display and edit blocks for data types.

+

+  * Tapestry now supports "Index" pages at the root or in sub-folders.

+

+  * Tapestry pages may now be {{{guide/secure.html}secured for access only via HTTPS}}.

+

+  * Added the {{{ref/org/apache/tapestry/corelib/components/FormFragment.html}FormFragment}} component

+    to allow for forms that are mutable on the client-side. In addition, the

+    {{{ref/org/apache/tapestry/corelib/components/Form.html}Form}} component may

+    now update a Zone.

+

+  * Form components now trigger a "validateForm" event, not a "validate" event (so as to avoid conflict

+    with the "validate" event triggered by TextFields).

+

+  * Tapestry now understands JDK 1.5 Generics, allowing for simple parameterized types for properties of data objects and components.

+

+  * Tapestry now differentiates between development mode and production mode, primarily in how

+    it reports runtime exceptions.  It defaults to production mode.   

+

+  * Components can now supply an event handler for type "exception" which will be invoked when

+    an exception occurs in a component event handler method. This is useful for handling errors

+    with the context for the "activate" event.

+

+  * Page instances are now cached more efficiently, with Tapestry attempting to control how many instances

+    are created, and culling unused instances periodically.

+

+  * Component templates are stripped of unnecessary whitespace.

+

+  * New Unless component (like an If component, but inverted).

+

+  * Support for "password" and "longtext" data types (for use with the BeanEditor), and a new

+    {{{ref/org/apache/tapestry/corelib/components/TextOutput.html}TextOutput}} component.

+

+  * The new "var:" binding prefix allows for temporary, untyped storage

+    of render-time values without having to define a new component property.

+ 

+Changes from Tapestry 4 to Tapestry 5

+

+  Tapestry 5 represents a significant advance over Tapestry 4.  The goal is to make Tapestry 5

+  <significantly> easier to use than Tapestry 4 (or any other Java web framework).

+  We're keeping the <essence> of Tapestry 4, but starting with a brand new code base designed

+  to provide a stable, powerful, extensible platform for many years to come.

+  

+  Here's a few of the planned and implemented features:

+

+  * Easy to get started using Maven.

+  

+  * Simplified, minimal API based on annotations.

+  

+  * <<No>> base class requirement; components are true, pure Pojos (Plain Old Java Objects).

+  

+  * Abstract classes ... gone!  Classes are normal, concrete classes.

+  

+  * <<No>> XML descriptors for pages and components ... just the annotations.

+  

+  * Less configuration all around.

+  

+  * Automatic reloading of templates and even <Java classes>.

+  

+  * Super-duper Ajax integration built in.

+  

+  * Easy & fast unit testing of individual pages or components.

+    

+Adaptive API

+

+  A key feature of Tapestry 5 is <adaptive API>.

+  

+  In traditional Java frameworks, including Tapestry 4, user code is expected to

+  conform to the framework.  You create classes that extend from framework-provided

+  base classes, or implement framework-provided interfaces.

+  

+  This works well until you upgrade to the next release of the framework: with

+  the new features of the upgrade, you will more often than not experience breaks

+  in backwards compatibility. Interfaces or base classes will have changed and your

+  existing code will need to be changed to match.

+  

+  In Tapestry 5, the framework <adapts to your code>.  You have control over the

+  names of the methods, the parameters they take, and the value that is returned. This

+  is driven by annotations, which tell Tapestry under what circumstances your

+  methods are to be invoked.

+  

+  For example, you may have a login form and have a method that gets invoked

+  when the form is submitted:

+  

++----+

+public class Login

+{

+  @Persist

+  @Property

+  private String userId;

+  

+  @Property

+  private String password;

+  

+  @Component

+  private Form form;

+  

+  @Inject

+  private LoginAuthenticator authenticator;

+  

+  void onValidateForm()

+  {

+    if (! authenticator.isValidLogin(userId, password))

+    {

+      form.recordError("Invalid user name or password.");

+    }

+  }

+

+  Object onSuccess()

+  {

+    return PostLogin.class;

+  }

+

+}

++----+

+

+  This short snippet demonstrates a bit about how Tapestry operates.  Pages and services

+  within the application are injected with the @Inject annotation. The method names, onValidateForm()

+  and onSuccess(),

+  inform Tapestry about when the method is to be invoked.  The two events <validateForm> and <success> occur

+  when a form is submitted; "validateForm" is triggered to perform cross-field validations, and "success" is

+  only triggered when there are no validation errors. The onSuccess() method's 

+  return value directs Tapestry on what to do next: jump to another page within the application

+  (here identified as the class for the page, but many other options exist).  When there are exceptions,

+  the page will be redisplayed to the user.

+

+  This also represents a distinct change from Tapestry 4. In earlier versions of Tapestry, 

+  the Form component's listener parameter would be bound to the method to invoke, by name.  Further,

+  the listener method had to be public.

+  This new approach not only support multiple listeners, but provides an improved separation of

+  view concerns (inside the page's HTML template) and logic concerns, inside the Java class.

+    

+  In many cases, additional information about the event is available, and can be passed

+  into the method by adding parameters to the method. Again, Tapestry will adapt

+  to your parameters, in whatever order you supply them.

+

+  Tapestry also saves you effort:  the @Property annotation marks a field as readable and writable;

+  Tapestry will provide the accessor methods automatically.

+

+  Finally, Tapestry 5 explicitly separates actions (requests that change things) and rendering (requests that

+  render pages) into two separate requests.  Performing an action, such as clicking a link or submitting a form,

+  results in a <client side redirect> to the new page. This is often called "redirect after post". This helps ensure

+  that URLs in the browser are book-markable ... but also requires that a bit more information be stored in the session

+  between requests (using the @Persist annotation).  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/upgrade.apt b/hlship-20080520/tapestry-core/src/site/apt/upgrade.apt
new file mode 100644
index 0000000..d50e81c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/upgrade.apt
@@ -0,0 +1,141 @@
+ ----
+ Upgrade Notes
+ ----
+
+Upgrade Notes
+
+  This is a quick guide to changes between releases of Tapestry.  This is meant to provide information
+  on any additions or changes that developers will face after upgrading to the latest version of Tapestry.
+
+  It is always advised to perform a full and complete build after upgrading.
+
+  You should also check the {{{../release-notes.html}project-wide release notes}} for information
+  about bugs fixes and other improvements.
+
+Release 5.0.12
+
+* {{{https://issues.apache.org/jira/browse/TAPESTRY-2421}TAPESTRY-2421}}
+
+  To enable deployment compatibility between Tapestry 4 and Tapestry 5, a
+  small number of classes
+  had to be renamed or refactored.
+
+  PageRenderSupport has been renamed to just
+  {{{../apidocs/org/apache/tapestry/RenderSupport.html}RenderSupport}}.
+
+  TapestryConstants has been removed, split into a number of new classes (by type), such as
+  {{{../apidocs/org/apache/tapestry/SymbolConstants.html}SymbolConstants}}.
+
+  Likewise, TapestryUtils has been split into
+  {{{../apidocs/org/apache/tapestry/MarkupUtils.html}MarkupUtils}} and
+  {{{../apidocs/org/apache/tapestry/VersionUtils.html}VersionUtils}}.
+
+  Because of naming conflicts, several classes and interfaces were moved under an
+  org.apache.tapestry5 package:
+
+  * {{{../apidocs/org/apache/tapestry5/services/ApplicationInitializer.html}ApplicationInitializer}} and
+    {{{../apidocs/org/apache/tapestry5/services/ApplicationInitializerFilter.html}ApplicationInitializerFilter}}.
+
+  * {{{../apidocs/org/apache/tapestry5/services/ComponentMessagesSource.html}ComponentMessagesSource}}.
+
+  * {{{../apidocs/org/apache/tapestry5/services/RequestGlobals.html}RequestGlobals}}.
+
+  * {{{../apidocs/org/apache/tapestry5/json/JSONObject.html}JSONObject}} (and the other JSON classes).
+
+  []
+
+* TapestryModule
+
+  Many of the internal services of Tapestry have been split off into their own module,
+  {{{../apidocs/org/apache/tapestry/internal/services/InternalModule.html}InternalModule}}.
+  This should not affect any user code.
+
+* Form component
+
+  The default {{{../apidocs/org/apache/tapestry/ValidationTracker.html}ValidationTracker}}
+  built into the Form component now has a persistence strategy of "flash". This means that
+  if you navigate away from a page with validation errors and return, you will lose the errors
+  To support this style of navigation, you will need to bind the Form's tracker parameter
+  to a field that has the correct persistency (most likely, "session", the previous persistence
+  strategy).
+
+* Resource.openStream()
+
+  The methods <<<exists()>>> and <<<openStream()>>> were added to the
+  {{{../apidocs/org/apache/tapestry/ioc/Resource.html}Resource}} interface. The semantics
+  of some of the other methods were slightly alterred.
+
+* Loop element parameter
+
+  The Loop components' elementName parameter was renamed to simply element (to be consistent
+  with element parameters added to the Any and FormInjector components).
+
+Release 5.0.11
+
+* Field.getElementName()
+
+  The method <<<getElementName()>>> on interface {{{../apidocs/org/apache/tapestry/Field.html}Field}}
+  was renamed to <<<getControlName()>>>.  This brings the property in alignment with W3C documentation
+  and terminology, and helps differentiate from the element name (i.e., the tag name used to represent
+  the element in a component template).
+
+  This affects a number of existing components that implement the interface.
+
+  Method <<<allocateElementName()>>> on interface {{{../apidocs/org/apache/tapestry/services/FormSupport.html}FormSupport}}
+  was likewise renamed to <<<allocateControlName()>>>.
+
+* Zone
+
+  The show and hide parameters of the {{{ref/org/apache/tapestry/corelib/components/Zone.html}Zone}}
+  component now have a default binding prefix of "literal".
+
+  In addition, the client-side Tapestry.ZoneEffect object was renamed to Tapestry.ElementEffect to reflect
+  that it can be used with elements that are not explicitly Zones.
+
+* Validator.invokeIfBlank()
+
+  The method <<<invokeIfBlank()>>> on interface {{{../apidocs/org/apache/tapestry/Validator.html}Validator}}
+  was renamed to <<<isRequired()>>>.
+
+* MetaDataLocator
+
+  The <<findMeta()>> method on interface {{{../apidocs/org/apache/tapestry/services/MetaDataLocator.html}MetaDataLocator}}
+  has changed significantly; it now expands symbols and performs type coercion.
+
+* Grid Interfaces
+
+  The {{{../apidocs/org/apache/tapestry/grid/GridModel.html}GridModel}} interface and
+  the <<<prepare()>>> method of 
+  {{{../apidocs/org/apache/tapestry/grid/GridDataSource.html}GridDataSource}} have changed to accommodate
+  the ability to sort using multiple columns.
+
+* PropertyModel
+
+  The <<<getWidth()>>> method was removed from the
+  {{{../apidocs/org/apache/tapestry/beaneditor/PropertyModel.java}PropertyModel}} interface; the logic
+  for deducing the desired field size from the @Width annotation has been moved into AbstractTextField.
+
+* Grid, BeanEditForm, BeanEditor, BeanDisplay
+
+  The data type for boolean values has changed from "checkbox" (reflecting how it is rendered in an edit form) to "boolean"
+  (reflecting what it is). In addition, all numeric types are given the data type "number".
+  This will only affect your application if you provided an overriding contribution
+  to the {{{../apidocs/org/apache/tapestry/services/BeanBlockSource.html}BeanBlockSource}} service.
+
+* ExceptionInfo
+
+  The return type for <<<getStackTrace()>>> on
+  {{{../apidocs/org/apache/tapestry/services/ExceptionInfo.html}ExceptionInfo}}
+  changed from List\<String\> to List\<StackTraceElement\>.
+
+* ApplicationGlobals and RequestGlobals
+
+  The <store> methods on these two interfaces were renamed to be more explicit. These are not methods typically
+  invoked from user code.
+
+* BeanModel
+
+  The <<<remove()>>> method of {{{../apidocs/org/apache/tapestry/beaneditor/BeanModel.html}BeanModel}} was renamed
+  to <<<exclude()>>>, and a new method, <<<include()>>> was added. The <<remove>> parameter of BeanEditForm,
+  BeanEditor, BeanDisplay and Grid were all renamed to <<exclude>> as well (and a new <<include>> parameter was added
+  to each).
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/apt/upgrade4.apt b/hlship-20080520/tapestry-core/src/site/apt/upgrade4.apt
new file mode 100644
index 0000000..319ab44
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/apt/upgrade4.apt
@@ -0,0 +1,20 @@
+  ----

+  Upgrading from Tapestry 4 to Tapestry 5

+  ----

+  

+Upgrading from Tapestry 4 to Tapestry 5

+  

+ There is no simple, direct upgrade path from Tapestry 4 to Tapestry 5.

+

+ Tapestry 5 represents a completely new code base. Although it maintains the <spirit> of

+ Tapestry 4, it is also a quantum leap ahead of Tapestry 4.

+

+ A lot of the familiar aspects of Tapestry are completely different between the two releases.

+ In other cases, core concepts remain, but the details, names, and implementations

+ have changed.

+

+ As part of {{{https://issues.apache.org/jira/browse/TAPESTRY-2421}TAPESTRY-2421}}, we've done

+ some judicous renaming so that Tapestry 4 and Tapestry 5 applications can run inside the same WAR.

+

+

+ More to come ...
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/site/images/component-render-states.graffle b/hlship-20080520/tapestry-core/src/site/images/component-render-states.graffle
new file mode 100644
index 0000000..02083d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/images/component-render-states.graffle
@@ -0,0 +1,2721 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2006-12-19 16:46:40 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{514.496, 485.521}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>76</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>27</integer>
+				<key>Position</key>
+				<real>0.44419869780540466</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{280.166, 648.779}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>61</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>37</integer>
+				<key>Position</key>
+				<real>0.048526979982852936</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{521.666, 890.223}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>57</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+				<key>Position</key>
+				<real>0.50833463668823242</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{416.262, 828.757}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>56</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>41</integer>
+				<key>Position</key>
+				<real>0.024163046851754189</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{486.944, 176.879}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>55</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+				<key>Position</key>
+				<real>0.038560941815376282</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{344.76, 760.704}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>74</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>73</integer>
+				<key>Position</key>
+				<real>0.037935700267553329</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{470.294, 803.739}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>53</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>31</integer>
+				<key>Position</key>
+				<real>0.34824743866920471</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{399.272, 695.173}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>52</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+				<key>Position</key>
+				<real>0.22049112617969513</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{374.611, 645.65}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>51</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>29</integer>
+				<key>Position</key>
+				<real>0.45005011558532715</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{406.172, 500.59}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>49</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>38</integer>
+				<key>Position</key>
+				<real>0.17215704917907715</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{355.24, 573.112}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>48</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>39</integer>
+				<key>Position</key>
+				<real>0.14579181373119354</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{243.006, 351.06}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>46</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>36</integer>
+				<key>Position</key>
+				<real>0.11131267249584198</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{366.154, 349.45}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>45</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>25</integer>
+				<key>Position</key>
+				<real>0.48894369602203369</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{354.693, 261.686}, {31, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>72</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>71</integer>
+				<key>Position</key>
+				<real>0.33751571178436279</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{493.307, 260.272}, {36, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>68</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>67</integer>
+				<key>Position</key>
+				<real>0.056039527058601379</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 false}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{414.858, 187.48}, {35, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>YES</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>70</integer>
+			<key>Line</key>
+			<dict>
+				<key>ID</key>
+				<integer>69</integer>
+				<key>Position</key>
+				<real>0.41089463233947754</real>
+				<key>RotationType</key>
+				<integer>0</integer>
+			</dict>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 true }</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>66</integer>
+			</dict>
+			<key>ID</key>
+			<integer>73</integer>
+			<key>Points</key>
+			<array>
+				<string>{394.959, 775.836}</string>
+				<string>{176, 695.173}</string>
+				<string>{198, 249}</string>
+				<string>{379.306, 241.526}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>12</integer>
+				<key>Info</key>
+				<integer>1</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+			<key>ID</key>
+			<integer>39</integer>
+			<key>Points</key>
+			<array>
+				<string>{379.084, 598.325}</string>
+				<string>{365.685, 539.16}</string>
+				<string>{407.965, 488.708}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>9</integer>
+				<key>Info</key>
+				<integer>2</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>9</integer>
+			</dict>
+			<key>ID</key>
+			<integer>38</integer>
+			<key>Points</key>
+			<array>
+				<string>{424.209, 488.825}</string>
+				<string>{423.997, 597.825}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+			<key>ID</key>
+			<integer>37</integer>
+			<key>Points</key>
+			<array>
+				<string>{298.208, 671.825}</string>
+				<string>{297.959, 568.325}</string>
+				<string>{297.959, 444.325}</string>
+				<string>{323.021, 340.811}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>11</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>11</integer>
+				<key>Info</key>
+				<integer>1</integer>
+			</dict>
+			<key>ID</key>
+			<integer>36</integer>
+			<key>Points</key>
+			<array>
+				<string>{294.969, 340.637}</string>
+				<string>{239.077, 385.325}</string>
+				<string>{239.077, 530.325}</string>
+				<string>{239.98, 672.325}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>12</integer>
+			</dict>
+			<key>ID</key>
+			<integer>67</integer>
+			<key>Points</key>
+			<array>
+				<string>{479.795, 253.125}</string>
+				<string>{604, 329}</string>
+				<string>{625.997, 582}</string>
+				<string>{485.209, 756.836}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>66</integer>
+				<key>Info</key>
+				<integer>3</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>13</integer>
+				<key>Info</key>
+				<integer>4</integer>
+			</dict>
+			<key>ID</key>
+			<integer>34</integer>
+			<key>Points</key>
+			<array>
+				<string>{483.224, 166.21}</string>
+				<string>{626.438, 299.939}</string>
+				<string>{648, 614}</string>
+				<string>{611.203, 841.292}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{488.217, 915.347}, {98, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>1</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>14</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf1 End}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{447.901, 840.502}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>13</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{-0.281146, -0.13158}</string>
+				<string>{0.25, -0.5}</string>
+				<string>{-0.00563669, 0.368422}</string>
+				<string>{0.433564, -0.5}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 CleanupRender}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{394.959, 756.836}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>12</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{-0.5, 0}</string>
+				<string>{0, 0.5}</string>
+				<string>{0, -0.5}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 AfterRender}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{207.959, 672.325}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>11</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{-0.322601, -0.5}</string>
+				<string>{-5.96046e-08, -0.5}</string>
+				<string>{-5.96046e-08, 0.5}</string>
+				<string>{0.292358, -0.5}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 AfterRenderTemplate}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{445.497, 529.727}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>10</integer>
+			<key>Shape</key>
+			<string>Parallelogram</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 Render Body}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{333.959, 598.325}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>9</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{-0.00127089, -0.281658}</string>
+				<string>{-0.25, -0.499999}</string>
+				<string>{-0.00127089, 0.481501}</string>
+				<string>{0.170474, -0.386921}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 AfterRenderBody}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{333.959, 450.325}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>8</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 BeforeRenderBody}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{333.959, 373.29}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>7</integer>
+			<key>Shape</key>
+			<string>Parallelogram</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 Render Template}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{235.205, 302.325}, {180.5, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>6</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{0.0241081, -0.224772}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 BeforeRenderTemplate}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{379.705, 220.345}, {105, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>66</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{0, 0}</string>
+				<string>{-0.5, 0}</string>
+				<string>{0.453242, 0.362622}</string>
+				<string>{0.25, 0.25}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 BeginRender}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{379.705, 137.939}, {105, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>4</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{0.411739, 0.0526314}</string>
+				<string>{0.00221539, 0.368421}</string>
+				<string>{0, -0.5}</string>
+				<string>{-0.445207, 0.0526316}</string>
+			</array>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf0 SetupRender}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{382.2, 67.5615}, {98, 38}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>1</string>
+				</dict>
+				<key>Font</key>
+				<string>TrebuchetMS-Bold</string>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>3</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+					<key>MiddleFraction</key>
+					<real>0.0</real>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>CornerRadius</key>
+					<real>5</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fnil\fcharset77 TrebuchetMS-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\b\fs24 \cf1 Start}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+			<key>ID</key>
+			<integer>41</integer>
+			<key>Points</key>
+			<array>
+				<string>{458.994, 843.755}</string>
+				<string>{153, 728}</string>
+				<string>{146, 242}</string>
+				<string>{379.562, 160.984}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>2</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>13</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>14</integer>
+			</dict>
+			<key>ID</key>
+			<integer>32</integer>
+			<key>Points</key>
+			<array>
+				<string>{537.141, 879.002}</string>
+				<string>{537.19, 914.847}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>13</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>13</integer>
+			</dict>
+			<key>ID</key>
+			<integer>31</integer>
+			<key>Points</key>
+			<array>
+				<string>{485.209, 794.836}</string>
+				<string>{486.889, 840.502}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>12</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>12</integer>
+				<key>Info</key>
+				<integer>3</integer>
+			</dict>
+			<key>ID</key>
+			<integer>30</integer>
+			<key>Points</key>
+			<array>
+				<string>{388.868, 690.479}</string>
+				<string>{463, 726}</string>
+				<string>{485.209, 756.836}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>11</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>11</integer>
+			</dict>
+			<key>ID</key>
+			<integer>29</integer>
+			<key>Points</key>
+			<array>
+				<string>{422.135, 636.55}</string>
+				<string>{350.98, 672.325}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>9</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>9</integer>
+			</dict>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Points</key>
+			<array>
+				<string>{504.428, 567.989}</string>
+				<string>{461.524, 598.038}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>10</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>10</integer>
+			</dict>
+			<key>ID</key>
+			<integer>27</integer>
+			<key>Points</key>
+			<array>
+				<string>{499.152, 486.713}</string>
+				<string>{531.959, 494.325}</string>
+				<string>{534.389, 529.228}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>8</integer>
+			</dict>
+			<key>ID</key>
+			<integer>26</integer>
+			<key>Points</key>
+			<array>
+				<string>{424.209, 411.79}</string>
+				<string>{424.209, 449.825}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>7</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>7</integer>
+			</dict>
+			<key>ID</key>
+			<integer>25</integer>
+			<key>Points</key>
+			<array>
+				<string>{362.89, 340.647}</string>
+				<string>{401.267, 372.968}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>6</integer>
+			</dict>
+			<key>ID</key>
+			<integer>71</integer>
+			<key>Points</key>
+			<array>
+				<string>{393.365, 258.464}</string>
+				<string>{357.74, 276}</string>
+				<string>{338.051, 301.927}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>66</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>66</integer>
+			</dict>
+			<key>ID</key>
+			<integer>69</integer>
+			<key>Points</key>
+			<array>
+				<string>{432.419, 176.439}</string>
+				<string>{432.27, 220.345}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+			<key>ID</key>
+			<integer>22</integer>
+			<key>Points</key>
+			<array>
+				<string>{431.478, 106.061}</string>
+				<string>{432.205, 137.939}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>HopLines</key>
+					<true/>
+					<key>HopType</key>
+					<integer>1</integer>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>3</integer>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>2</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2007-03-06 10:15:03 -0800</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>2</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<string>0</string>
+		<key>DrawerOpen</key>
+		<false/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>324</real>
+		<key>FitInWindow</key>
+		<false/>
+		<key>Frame</key>
+		<string>{{627, 109}, {1534, 1465}}</string>
+		<key>ShowRuler</key>
+		<false/>
+		<key>ShowStatusBar</key>
+		<true/>
+		<key>VisibleRegion</key>
+		<string>{{-180, 0}, {1519, 1351}}</string>
+		<key>Zoom</key>
+		<string>1</string>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/component-render-states.png b/hlship-20080520/tapestry-core/src/site/resources/images/component-render-states.png
new file mode 100644
index 0000000..c778905
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/component-render-states.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/projectlayout.png b/hlship-20080520/tapestry-core/src/site/resources/images/projectlayout.png
new file mode 100644
index 0000000..0328e34
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/projectlayout.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/servicestatus.png b/hlship-20080520/tapestry-core/src/site/resources/images/servicestatus.png
new file mode 100644
index 0000000..7b2281e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/servicestatus.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/validation_errors.png b/hlship-20080520/tapestry-core/src/site/resources/images/validation_errors.png
new file mode 100644
index 0000000..525ab56
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/validation_errors.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/validation_initial.png b/hlship-20080520/tapestry-core/src/site/resources/images/validation_initial.png
new file mode 100644
index 0000000..2da714d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/validation_initial.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/validation_minlength.png b/hlship-20080520/tapestry-core/src/site/resources/images/validation_minlength.png
new file mode 100644
index 0000000..aa21c07
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/validation_minlength.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/resources/images/validation_password.png b/hlship-20080520/tapestry-core/src/site/resources/images/validation_password.png
new file mode 100644
index 0000000..56415e6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/resources/images/validation_password.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/site/site.xml b/hlship-20080520/tapestry-core/src/site/site.xml
new file mode 100644
index 0000000..774d19f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/site/site.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 

+   Copyright 2006, 2007, 2008 The Apache Software Foundation

+

+   Licensed under the Apache License, Version 2.0 (the "License");

+   you may not use this file except in compliance with the License.

+   You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT 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="Tapestry Core">

+    <bannerLeft>

+        <name>Tapestry 5</name>

+        <href>http://tapestry.apache.org/tapestry5/</href>

+        <src>images/tapestry_banner.gif</src>

+    </bannerLeft>

+    <bannerRight>

+        <name>Apache</name>

+        <href>http://www.apache.org</href>

+        <src>images/asf_logo_wide.gif</src>

+    </bannerRight>

+    <skin>

+        <groupId>org.apache.tapestry</groupId>

+        <artifactId>maven-skin</artifactId>

+        <version>1.1</version>

+    </skin>

+

+    <publishDate format="dd MMM yyyy"/>

+

+    <body>

+

+

+        <!--

+

+       This is probably useful but it drives me crazy whenever I reload a page.

+

+                <head>

+                   <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>

+                   <script type="text/javascript">_uacct = "UA-400821-1"; urchinTracker();</script>

+               </head>

+        -->

+        <menu name="Tapestry Core">

+            <item name="Introduction" href="/index.html"/>

+            <item name="Component Reference" href="ref/index.html"/>

+            <item name="Download" href="http://tapestry.apache.org/download.html"/>

+        </menu>

+

+        <menu name="Upgrade Notes">

+            <item name="From Tapestry 5" href="upgrade.html"/>

+            <item name="From Tapestry 4" href="upgrade4.html"/>

+        </menu>

+

+        <menu name="User Guide">

+            <item name="Project Layout" href="guide/project-layout.html"/>

+            <item name="Component Classes" href="guide/component-classes.html"/>

+            <item name="Component Templates" href="guide/templates.html"/>

+            <item name="Component Parameters" href="guide/parameters.html"/>

+            <item name="Page Navigation" href="guide/pagenav.html"/>

+            <item name="Input Validation" href="guide/validation.html"/>

+            <item name="BeanEditForm Guide" href="guide/beaneditform.html"/>

+            <item name="Component Events" href="guide/event.html"/>

+            <item name="Environmental Services" href="guide/env.html"/>

+            <item name="Layout Component" href="guide/layout.html"/>

+            <item name="CSS" href="guide/css.html"/>

+            <item name="Ajax" href="guide/ajax.html"/>

+            <item name="Page Lifecycle" href="guide/lifecycle.html"/>

+            <item name="Component Mixins" href="guide/mixins.html"/>

+            <item name="Localization" href="guide/localization.html"/>

+            <item name="Assets" href="guide/assets.html"/>

+            <item name="Type Coercion" href="guide/coercion.html"/>

+            <item name="Component Rendering" href="guide/rendering.html"/>

+            <item name="Persistent Data" href="guide/persist.html"/>

+            <item name="Application State" href="guide/appstate.html"/>

+            <item name="Injection" href="guide/inject.html"/>

+            <item name="Aliases" href="guide/alias.html"/>

+            <item name="Configuration" href="guide/conf.html"/>

+            <item name="Request Processing" href="guide/request.html"/>

+            <item name="DOM" href="guide/dom.html"/>

+            <item name="Class Reloading" href="guide/reload.html"/>

+            <item name="Unit testing pages/components" href="guide/unit-testing-pages.html"/>

+            <item name="Logging" href="guide/logging.html"/>

+            <item name="Service Status" href="guide/servicestatus.html"/>

+            <item name="HTTPS" href="guide/secure.html"/>

+        </menu>

+

+        <menu ref="reports"/>

+

+    </body>

+</project>

diff --git a/hlship-20080520/tapestry-core/src/tapestry-formatting.xml b/hlship-20080520/tapestry-core/src/tapestry-formatting.xml
new file mode 100644
index 0000000..c9cb154
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/tapestry-formatting.xml
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<profiles version="10">

+<profile name="Tapestry Project" version="10">

+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="48"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>

+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.format_comments" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>

+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>

+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>

+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>

+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>

+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>

+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/>

+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>

+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>

+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>

+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>

+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>

+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>

+</profile>

+</profiles>

diff --git a/hlship-20080520/tapestry-core/src/test/app1/ActionViaLinkDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/ActionViaLinkDemo.tml
new file mode 100644
index 0000000..ac798e4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ActionViaLinkDemo.tml
@@ -0,0 +1,22 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+    <t:if test="message">
+        <p>
+            <strong>
+                <span id="message">${message}</span>
+            </strong>
+        </p>
+    </t:if>
+
+    <p>
+        Update the message:
+
+        <ul>
+            <li>
+                <a href="${actionURL}">via explicit Link creation</a>
+            </li>
+        </ul>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/AddedGridColumnsDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/AddedGridColumnsDemo.tml
new file mode 100644
index 0000000..206ee3e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/AddedGridColumnsDemo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Added Columns Grid Demo</h1>
+
+    <table t:id="grid">
+        <t:parameter name="viewlinkcell">
+            <t:actionlink t:id="view" context="track.title">view</t:actionlink>
+        </t:parameter>
+    </table>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/AttributeExpansionsDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/AttributeExpansionsDemo.tml
new file mode 100644
index 0000000..51eabaa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/AttributeExpansionsDemo.tml
@@ -0,0 +1,25 @@
+<t:border  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  
+  <h1>Expansions in Attributes</h1>
+  
+  <style>
+    DIV.red { font-weight: bold; color: red; }
+    
+    DIV.goober-red { font-style: italic; color: #FF9F2F; }
+ 
+    DIV.goober-green { font-size: x-large; color: green; }
+    
+  </style>
+  
+  <div id="mixed-expansion" style="color: ${colorscheme}">This text is blue, thanks to property colorscheme.</div>
+  
+  <div id="single" class="${styleClass}">This text is red and bold, thanks to the class attribute, set from property styleClass.</div>
+  
+  <div id="consecutive" class="${message:cssclassprefix}${styleClass}">And this text is italic and orange, from a complex CSS class attribute, built from multiple expansions.</div>
+  
+  <div id="trailer" class="${message:cssclassprefix}green">This text is green and large, and tests a trailing literal string within an attribute with an expansion.</div>
+  
+  <div id="formal"><t:echo value="${prefix}${message:alert}"/></div>
+  
+  <!-- A comment! -->
+</t:border>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/AutocompleteDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/AutocompleteDemo.tml
new file mode 100644
index 0000000..9181705
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/AutocompleteDemo.tml
@@ -0,0 +1,20 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Autocomplete Mixin Demo</h1>
+
+    <t:form>
+        <t:errors/>
+
+        <div class="t-beaneditor">
+            <div class="t-beaneditor-row">
+                <t:label for="title"/>
+                <t:textfield t:id="title" t:mixins="autocomplete" tokens=",;" size="100"/>
+            </div>
+
+            <div class="t-beaneditor-row">
+                <input type="submit" value="Show Track"/>
+            </div>
+        </div>
+    </t:form>
+
+
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BeanEditDateDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/BeanEditDateDemo.tml
new file mode 100644
index 0000000..d0cee64
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BeanEditDateDemo.tml
@@ -0,0 +1,13 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>BeanEditor Date Demo</h1>
+
+  <t:beaneditform t:id="reminder" />
+
+  <hr />
+
+  <t:actionlink t:id="clear">clear</t:actionlink>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BeanEditRemoveReorder.tml b/hlship-20080520/tapestry-core/src/test/app1/BeanEditRemoveReorder.tml
new file mode 100644
index 0000000..f5100f4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BeanEditRemoveReorder.tml
@@ -0,0 +1,14 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>${pageTitle}</h1>
+
+  <form t:id="registrationData" submitlabel="Register" exclude="birthYear" reorder="lastname,firstname">
+
+    <t:parameter name="firstName">
+      <t:label for="firstName"/>
+      <input t:type="TextField" t:id="firstName" value="registrationData.firstName" size="40"/>
+      (First Name is Required) </t:parameter>
+
+  </form>
+
+  <p>[<a t:type="ActionLink" t:id="clear">Clear Data</a>]</p>
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BeanEditorDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/BeanEditorDemo.tml
new file mode 100644
index 0000000..eed78a9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BeanEditorDemo.tml
@@ -0,0 +1,14 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>${pageTitle}</h1>
+
+  <form t:id="registrationData" submitlabel="Register">
+
+    <t:parameter name="firstName">
+      <t:label for="firstName"/>
+      <input t:type="TextField" t:id="firstName" value="registrationData.firstName" size="40"/>
+      (First Name is Required) </t:parameter>
+
+  </form>
+
+  <p>[<a t:type="ActionLink" t:id="clear">Clear Data</a>]</p>
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BeanEditorOverride.tml b/hlship-20080520/tapestry-core/src/test/app1/BeanEditorOverride.tml
new file mode 100644
index 0000000..6e7df53
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BeanEditorOverride.tml
@@ -0,0 +1,26 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>BeanEditor Override Demo</h1>
+
+    <p>Demonstrates that the BeanEditor properly supports overrides of its property editors.</p>
+
+    <form t:id="form">
+        <t:errors/>
+
+        <div class="t-beaneditor">
+            <div t:id="editor">
+                <t:parameter name="firstName">
+                    <t:label for="firstName"/>
+                    <t:textfield t:id="firstName" value="registrationData.firstName"/>
+                    [FirstName Property Editor Override]
+                </t:parameter>
+            </div>
+        </div>
+
+        <input type="submit" value="Register"/>
+    </form>
+
+    <p>[<t:actionlink t:id="clear">Clear Data</t:actionlink>]
+    </p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BlockCaller.tml b/hlship-20080520/tapestry-core/src/test/app1/BlockCaller.tml
new file mode 100644
index 0000000..975515c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BlockCaller.tml
@@ -0,0 +1,21 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Block Caller Demo</h1>
+
+    <p>This page demonstrates how action links can work correctly even when located outside the
+        active page.
+    </p>
+
+    <p>
+        Page activation context:
+        <span id="context">${activationContext}</span>
+    </p>
+
+
+    <t:delegate to="block"/>
+
+    <p>
+        [<t:pagelink page="blockcaller">refresh</t:pagelink>]
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BlockDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/BlockDemo.tml
new file mode 100644
index 0000000..7d2e25c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BlockDemo.tml
@@ -0,0 +1,24 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Block Demo</h1>
+
+  <p> This page demonstrates how blocks may be used to contain text and other elements and control
+    when and if they are rendered. </p>
+
+  <t:form>
+    <t:select t:id="blockName" model="',fred,barney'" onchange="this.form.submit();"/>
+    <t:label for="blockName">Block to display</t:label>
+  </t:form>
+
+  <p>The block: [<t:render value="blockToRender"/>]</p>
+
+  <t:block id="fred">Block fred.</t:block>
+  <t:block id="barney">Block barney.</t:block>
+
+<hr/>
+
+  You can also render a block before it is defined: [<t:delegate to="block:wilma"/>].
+  
+  <t:block id="wilma">Block wilma</t:block>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BlockHolder.tml b/hlship-20080520/tapestry-core/src/test/app1/BlockHolder.tml
new file mode 100644
index 0000000..dfb1962
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BlockHolder.tml
@@ -0,0 +1,11 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:block id="links">
+        <ul>
+            <li t:type="loop" t:source="1..3" value="index">
+                <t:actionlink t:id="link" context="index">${index}</t:actionlink>
+            </li>
+        </ul>
+    </t:block>
+
+</t:container>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/BooleanDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/BooleanDemo.tml
new file mode 100644
index 0000000..4e5c434
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/BooleanDemo.tml
@@ -0,0 +1,27 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Boolean Property Access Demo</h1>
+
+    <p>
+        Both
+        <code>is</code>
+        and
+        <code>get</code>
+        prefixes work.
+    </p>
+
+    <dl>
+        <dt>flagUsingGet</dt>
+        <dd id="usingGet">${flagUsingGet}</dd>
+        <dt>flagUsingIs</dt>
+        <dd id="usingIs">${flagUsingIs}</dd>
+    </dl>
+
+    <p>
+        <t:actionlink t:id="set">set</t:actionlink>
+        |
+        <t:actionlink t:id="clear">clear</t:actionlink>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ClassLoaderInspect.tml b/hlship-20080520/tapestry-core/src/test/app1/ClassLoaderInspect.tml
new file mode 100644
index 0000000..253d6b3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ClassLoaderInspect.tml
@@ -0,0 +1,70 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Class Loader Inspection</h1>
+
+
+  <dl>
+    <dt>Context ClassLoader</dt>
+    <dd>${classLoader} [${classLoader.class.name}]</dd>
+
+    <dt> Instance ClassLoader </dt>
+    <dd>${class.classLoader}</dd>
+
+  </dl>
+
+  <h2>Class Loader Hierarchy</h2>
+
+  <ul>
+    <t:loop source="loaders" value="loader">
+      <li>${loader}</li>
+    </t:loop>
+  </ul>
+
+  <h2> Find Resources </h2>
+
+  <form t:id="search">
+    <t:errors/>
+    <t:label for="resource"/>: <input t:id="resource" t:type="TextField" size="50"
+      validate="required"/>
+    <br/>
+    <input type="submit"/>
+  </form>
+
+  <t:if test="showMatches">
+
+    <h3>${listSize} Matches</h3>
+
+    <ul>
+      <t:loop source="URLs" value="URL">
+        <li>${URL} <dl>
+
+            <dt>Connection</dt>
+            <dd>${URLConnection} [${URLConnection.class.name}]</dd>
+            <dt>Content</dt>
+            <dd>${URL.content}</dd>
+
+            <dt>Stream </dt>
+            <dd>
+              <pre>
+${contentStreamContents}
+</pre>
+            </dd>
+
+            <dt> JAR Entries </dt>
+
+            <dd>
+              <ul>
+                <t:loop source="jarEntries" value="jarEntry">
+                  <li>${jarEntry}</li>
+                </t:loop>
+              </ul>
+            </dd>
+
+          </dl>
+        </li>
+      </t:loop>
+    </ul>
+
+  </t:if>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/CleanCacheDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/CleanCacheDemo.tml
new file mode 100644
index 0000000..379ec4e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/CleanCacheDemo.tml
@@ -0,0 +1,24 @@
+<html t:type="border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+    <p>
+        The following two numbers will be identical, due to @Cache:
+    </p>
+
+    <div t:type="zone" t:id="aZone">
+        <ul>
+            <li id="time1">${timeNanos}</li>
+            <li id="time2">${timeNanos}</li>
+        </ul>
+
+
+    </div>
+
+    <p>
+        Clicking
+        <a t:type="actionlink" t:id="updateZone" href="#" t:zone="aZone">update</a>
+        will refresh the numbers.
+    </p>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ClientPersistenceDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/ClientPersistenceDemo.tml
new file mode 100644
index 0000000..ad2b119
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ClientPersistenceDemo.tml
@@ -0,0 +1,27 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+<h1>Client Persistence Demo</h1>
+
+
+  <p>
+    Persisted value: [${persistedValue}]
+  </p>
+  
+  <p>
+    Session: [${sessionExists}]
+  </p>
+  
+  
+  <p>
+    <t:actionlink t:id="storeString">store string</t:actionlink>
+  </p>
+  
+  <p>
+    <t:actionlink t:id="storeBad">store non-serializable</t:actionlink>
+  </p>
+  
+  <p>
+    <t:pagelink page="clientpersistencedemo">refresh</t:pagelink>
+  </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ComponentParameter.tml b/hlship-20080520/tapestry-core/src/test/app1/ComponentParameter.tml
new file mode 100644
index 0000000..f244118
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ComponentParameter.tml
@@ -0,0 +1,17 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Component as Parameter</h1>
+
+    <p>Tests the ability to use a component type as a parameter.</p>
+
+    <t:if test="message">
+        <p>${message}</p>
+    </t:if>
+
+    <t:block>
+        <t:actionlink t:id="blockAction">click me</t:actionlink>
+    </t:block>
+
+    <t:actionlinkindirect component="blockAction"/>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/DateFieldDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/DateFieldDemo.tml
new file mode 100644
index 0000000..1436e9f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/DateFieldDemo.tml
@@ -0,0 +1,41 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>DateField Demo</h1>
+
+    <t:form>
+        <t:errors/>
+
+        <div class="t-beaneditor">
+
+            <div class="t-beaneditor-row">
+                <t:label for="birthday"/>
+                <t:datefield t:id="birthday"/>
+            </div>
+
+            <div class="t-beaneditor-row">
+                <t:label for="asteroidImpact"/>
+                <t:datefield t:id="asteroidImpact"/>
+            </div>
+
+
+            <div class="t-beaneditor-row">
+                <input type="submit" value="Go"/>
+            </div>
+
+        </div>
+    </t:form>
+
+    <t:if test="birthday">
+        <hr/>
+        <p>
+            Birthday: [<t:output value="birthday" format="dateFormat"/>]
+        </p>
+
+        <p>
+            Impact: [<t:output value="asteroidImpact" format="dateFormat"/>]
+        </p>
+    </t:if>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/DeleteFromGridDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/DeleteFromGridDemo.tml
new file mode 100644
index 0000000..b9e667e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/DeleteFromGridDemo.tml
@@ -0,0 +1,15 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>ToDo Listing</h1>
+
+    <t:grid rowsperpage="5" source="items" row="item">
+        <t:parameter name="titlecell">
+            <t:actionlink t:id="delete" context="item.id">${item.title}</t:actionlink>
+        </t:parameter>
+    </t:grid>
+
+    <p>
+        <t:actionlink t:id="setup">setup the database</t:actionlink>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/DisabledFields.tml b/hlship-20080520/tapestry-core/src/test/app1/DisabledFields.tml
new file mode 100644
index 0000000..79d6148
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/DisabledFields.tml
@@ -0,0 +1,43 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+    <h1>Disabled Fields Demo</h1>
+
+    <t:form>
+
+        <t:textfield t:id="textfield" value="stringValue" disabled="true"/>
+        <br/>
+        <t:passwordfield t:id="passwordfield" value="stringValue" disabled="true"/>
+        <br/>
+        <t:textarea t:id="textarea" value="stringValue" disabled="true"/>
+        <br/>
+        <t:checkbox t:id="checkbox" value="flag" disabled="true"/>
+        <br/>
+        <t:select t:id="select" value="stringValue" disabled="true" model="literal:Up,Down,Strange,Charm,Bottom,Top"/>
+        <br/>
+        <t:radiogroup t:id="group1" value="stringValue" disabled="true">
+            <t:radio t:id="radio1" value="literal:Right"/>
+        </t:radiogroup>
+
+        <br/>
+
+        <t:radiogroup t:id="group2" value="stringValue">
+            <t:radio t:id="radio2" disabled="true" value="literal:Left"/>
+        </t:radiogroup>
+
+        <br/>
+
+        <t:datefield t:id="datefield" value="date" disabled="true"/>
+
+        <br/>
+
+        <t:palette t:id="palette" selected="values" disabled="true" encoder="encoder"
+                   model="literal:Fred,Barney,Wilma,Betty"/>
+
+        <br/>
+
+        <t:submit t:id="submit" disabled="true" value="Disabled Submit"/>
+        <input type="submit" value="Continue"/>
+    </t:form>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/EventHandlerDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/EventHandlerDemo.tml
new file mode 100644
index 0000000..632ac5a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/EventHandlerDemo.tml
@@ -0,0 +1,29 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>EventHandler Demo</h1>
+
+  <t:if test="methodNames">
+    <p> Event method names: ${methodNames} </p>
+  </t:if>
+
+
+  <p> [<t:pagelink page="eventhandlerdemo" context="'anything'">clear</t:pagelink>] </p>
+
+
+  <ul>
+    <li>
+      <t:actionlink t:id="wilma">No Context</t:actionlink>
+    </li>
+    <li>
+      <t:actionlink t:id="barney" context="literal:one">Single context value</t:actionlink>
+    </li>
+    <li>
+      <t:actionlink t:id="betty" context="twoContext">Two value context</t:actionlink>
+    </li>
+    <li>
+      <t:actionlink context="'two'" t:id="fred">Two value context (from fred)</t:actionlink>
+    </li>
+  </ul>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/EventMethodTranslate.tml b/hlship-20080520/tapestry-core/src/test/app1/EventMethodTranslate.tml
new file mode 100644
index 0000000..6cd52aa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/EventMethodTranslate.tml
@@ -0,0 +1,28 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Event Handler Method Translate</h1>
+
+    <t:form>
+
+        <t:errors/>
+
+        <div class="t-beaneditor">
+
+            <div class="t-beaneditor-row">
+                <t:label for="count"/>
+                <t:textfield t:id="count"/>
+
+            </div>
+
+            <div class="t-beaneditor-row">
+                <input type="submit" value="Update"/>
+            </div>
+        </div>
+    </t:form>
+
+    <hr/>
+
+    <p>
+        Count: [${count}]
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ExceptionEventDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/ExceptionEventDemo.tml
new file mode 100644
index 0000000..6f2795a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ExceptionEventDemo.tml
@@ -0,0 +1,28 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Exception Event Demo</h1>
+
+    <t:if test="message">
+        <p id="message">
+            ${message}
+        </p>
+    </t:if>
+
+
+    <t:pagelink page="ExceptionEventDemo" context="invalidContext">force invalid activation context</t:pagelink>
+
+    <br/>
+
+    <t:actionlink t:id="fail" context="invalidContext">force invalid event context</t:actionlink>
+
+
+    <br/>
+
+    <p>
+        Exception interception: ${intercept} --
+        <t:actionlink t:id="enable">enable</t:actionlink>
+        /
+        <t:actionlink t:id="disable">disable</t:actionlink>
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/FlashDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/FlashDemo.tml
new file mode 100644
index 0000000..fb25ef5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/FlashDemo.tml
@@ -0,0 +1,18 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Flash Demo</h1>
+
+    <p>
+        The message: [${message}]
+    </p>
+
+    <p>
+        <a t:type="ActionLink" t:id="show">show the message</a>
+    </p>
+
+    <p>
+        <a t:id="refresh" t:type="PageLink" page="FlashDemo">refresh the page</a>
+    </p>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/FormEncodingType.tml b/hlship-20080520/tapestry-core/src/test/app1/FormEncodingType.tml
new file mode 100644
index 0000000..e76a3a1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/FormEncodingType.tml
@@ -0,0 +1,17 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  
+  <h1>Form Encoding Type Demo</h1>
+
+  
+  <t:form>
+
+    <p>
+      Not much to see here, unless you check the DOM.
+    </p>
+
+    <t:delegate to="forceEncodingType"/>
+    
+  </t:form>
+
+  
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/FormFragmentDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/FormFragmentDemo.tml
new file mode 100644
index 0000000..0c39157
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/FormFragmentDemo.tml
@@ -0,0 +1,57 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Form Fragment Demo</h1>
+
+    <form t:id="form">
+
+        <t:errors/>
+
+        <div class="t-beaneditor">
+
+            <div class="t-beaneditor-row">
+                <t:label for="name"/>
+                <t:textfield t:id="name" value="subscribe.name"/>
+            </div>
+
+            <t:checkbox t:id="subscribeToEmail" t:mixins="triggerfragment" fragment="showEmail"/>
+            <t:label for="subscribeToEmail">Subscribe to Email?</t:label>
+
+            <t:formfragment t:id="showEmail" visible="subscribeToEmail" hide="fade">
+                <div class="t-beaneditor-row">
+                    <t:label for="email"/>
+                    <t:textfield t:id="email" value="subscribe.email"/>
+                </div>
+            </t:formfragment>
+
+
+            <br/>
+
+            <t:radiogroup value="codeVisible">
+                <t:radio t:id="on" label="On" value="true" t:mixins="triggerfragment" fragment="codeFragment"/>
+                <t:label for="on"/>
+                <t:radio t:id="off" label="Off" value="false"/>
+                <t:label for="off"/>
+            </t:radiogroup>
+
+
+            <t:formfragment t:id="codeFragment" visible="codeVisible">
+                <div class="t-beaneditor-row">
+                    <t:label for="code"/>
+                    <t:textfield t:id="code" value="subscribe.code"/>
+                </div>
+            </t:formfragment>
+
+
+            <div class="t-beaneditor-row">
+                <input type="submit" value="Subscribe"/>
+            </div>
+
+        </div>
+
+
+        <p>
+            <t:actionlink t:id="clear">Clear</t:actionlink>
+        </p>
+
+    </form>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/FormFragmentOutput.tml b/hlship-20080520/tapestry-core/src/test/app1/FormFragmentOutput.tml
new file mode 100644
index 0000000..0d8b9cb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/FormFragmentOutput.tml
@@ -0,0 +1,19 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Form Fragment Demo</h1>
+
+
+    <dl>
+        <dt>Name</dt>
+        <dd id="name">${subscribe.name}</dd>
+        <dt>Email</dt>
+        <dd id="email">${subscribe.email}</dd>
+        <dt>Code</dt>
+        <dd id="code">${subscribe.code}</dd>
+    </dl>
+
+
+    <p>
+        <t:pagelink page="formfragmentdemo">Back</t:pagelink>
+    </p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/FormInjectorDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/FormInjectorDemo.tml
new file mode 100644
index 0000000..1abe398
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/FormInjectorDemo.tml
@@ -0,0 +1,34 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+    <t:form>
+
+        <t:block id="newRow">
+
+            <div class="t-beaneditor-row">
+                <t:submitnotifier>
+                    <t:textfield t:id="value"/>
+                </t:submitnotifier>
+            </div>
+
+        </t:block>
+
+        <ul>
+            <li t:id="forminjector" class="t-beaneditor-row">
+                <a href="#" id="addnewrow">Add a row</a>
+            </li>
+        </ul>
+
+        <div class="t-beaneditor-row">
+            <input type="submit" value="Sum up the values"/>
+        </div>
+
+    </t:form>
+
+    <p>
+        Current sum:
+        <span id="sum">${sum}</span>
+    </p>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/GridDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/GridDemo.tml
new file mode 100644
index 0000000..05a60f6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/GridDemo.tml
@@ -0,0 +1,18 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Grid Demo</h1>
+
+    <table t:id="grid" source="tracks" row="track">
+        <t:parameter name="ratingheader">
+            <t:actionlink t:id="sortRating">Sort Rating</t:actionlink>
+        </t:parameter>
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+
+    <p>
+        [<t:actionlink t:id="reset">reset the Grid</t:actionlink>]
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/GridEnumDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/GridEnumDemo.tml
new file mode 100644
index 0000000..4d959e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/GridEnumDemo.tml
@@ -0,0 +1,10 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>Grid Enum Demo</h1>
+    
+    <table t:type="Grid" source="database.findAll()"/>
+    
+    <p>
+        [<a t:type="ActionLink" t:id="reset">reset</a>]
+    </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/GridFormDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/GridFormDemo.tml
new file mode 100644
index 0000000..3605b06
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/GridFormDemo.tml
@@ -0,0 +1,35 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Grid Form Demo</h1>
+
+
+  <t:form>
+
+    <t:errors />
+
+    <table t:type="Grid" source="items" row="item" pagerposition="top"
+      rowsperpage="5">
+
+      <t:parameter name="titleCell">
+        <t:textfield t:id="title" value="item.title" />
+      </t:parameter>
+
+      <t:parameter name="urgencyCell">
+        <t:select t:id="urgency" value="item.urgency" />
+      </t:parameter>
+
+    </table>
+
+    <p>
+      <input type="submit" value="Update Items" />
+    </p>
+  </t:form>
+
+
+  <p>
+    [
+    <a t:type="ActionLink" t:id="reset">reset</a>
+    ]
+  </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/GridRemoveReorderDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/GridRemoveReorderDemo.tml
new file mode 100644
index 0000000..7164142
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/GridRemoveReorderDemo.tml
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Grid Remove/Reorder Demo</h1>
+
+    <table t:id="grid" source="tracks" row="track" remove="playCount" reorder="rating,title">
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/GridSetDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/GridSetDemo.tml
new file mode 100644
index 0000000..61fa314
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/GridSetDemo.tml
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Grid Set Demo</h1>
+
+    <table t:type="Grid" source="tracks" row="track" informal="supported">
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/IndirectProtectedFields.tml b/hlship-20080520/tapestry-core/src/test/app1/IndirectProtectedFields.tml
new file mode 100644
index 0000000..c20393a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/IndirectProtectedFields.tml
@@ -0,0 +1,12 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Protected Fields Demo</h1>
+
+    <p>
+        <t:actionlink t:id="go">Trigger the Exception</t:actionlink>
+    </p>
+
+
+</html>
+
diff --git a/hlship-20080520/tapestry-core/src/test/app1/InheritInformalsDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/InheritInformalsDemo.tml
new file mode 100644
index 0000000..bbd650f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/InheritInformalsDemo.tml
@@ -0,0 +1,8 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Inherit Informals Demo</h1>
+
+    <t:outerany id="target" class="inherit">Should be italic</t:outerany>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/InheritedBindingsDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/InheritedBindingsDemo.tml
new file mode 100644
index 0000000..232449b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/InheritedBindingsDemo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>Inherited Bindings Demo</h1>
+  
+  <h1>Bound</h1>
+  
+  Bound: <t:outer outerValue="the-bound-value"/>
+
+  <h1>Unbound</h1>
+  
+  Unbound: <t:outer/>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/InjectComponentDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/InjectComponentDemo.tml
new file mode 100644
index 0000000..cf90957
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/InjectComponentDemo.tml
@@ -0,0 +1,9 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Inject Component Demo</h1>
+
+    <t:form t:id="form"/>
+
+    ${injectComponentId}
+
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/InplaceGridDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/InplaceGridDemo.tml
new file mode 100644
index 0000000..da63033
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/InplaceGridDemo.tml
@@ -0,0 +1,23 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>In-Place Grid Demo</h1>
+
+    <p>
+        Last full page refresh at:
+        <span id="lastupdate">${date}</span>
+    </p>
+
+    <table t:id="grid" source="tracks" row="track" inplace="true">
+        <t:parameter name="ratingheader">
+            <t:actionlink t:id="sortRating">Sort Rating</t:actionlink>
+        </t:parameter>
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+
+    <p>
+        [<t:actionlink t:id="reset">reset the Grid</t:actionlink>]
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Kicker.tml b/hlship-20080520/tapestry-core/src/test/app1/Kicker.tml
new file mode 100644
index 0000000..dff3550
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Kicker.tml
@@ -0,0 +1,8 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+<h1>Kicker</h1>    
+
+[<a t:type="actionlink">kick target</a>]
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/LeanGridDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/LeanGridDemo.tml
new file mode 100644
index 0000000..e605f2c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/LeanGridDemo.tml
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Lean Grid Demo</h1>
+
+    <table t:id="grid" source="tracks" row="track" lean="true">
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ListEventContextDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/ListEventContextDemo.tml
new file mode 100644
index 0000000..a4e5b2c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ListEventContextDemo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>List Event Context</h1>
+
+
+    <ul id="eventcontext">
+        <li t:type="loop" source="eventContext" value="var:value">${var:value}</li>
+    </ul>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/MagicValueEncoder.tml b/hlship-20080520/tapestry-core/src/test/app1/MagicValueEncoder.tml
new file mode 100644
index 0000000..31f0dd3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/MagicValueEncoder.tml
@@ -0,0 +1,23 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Magic Value Encoder</h1>
+
+    <p>Ok, Magic is too strong a word. This is really based on the TypeCoercer, which is not quite magic (but close).
+    </p>
+
+
+    <t:form>
+        <t:select t:id="number" model="options"/>
+        <br/>
+        <input type="submit" value="Update"/>
+    </t:form>
+
+    <hr/>
+
+    <p>
+        Selected number:
+        <span id="selectednumber">${number}</span>
+    </p>
+
+</html>    
diff --git a/hlship-20080520/tapestry-core/src/test/app1/MethodAdviceDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/MethodAdviceDemo.tml
new file mode 100644
index 0000000..e40b1c0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/MethodAdviceDemo.tml
@@ -0,0 +1,33 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Method Advice Demo</h1>
+
+    <p>
+        Greetings and salutations:
+        <span id="message">${message}</span>.
+    </p>
+
+
+    <p>
+        The current Major version of Tapestry is:
+        <span id="version">${version}</span>
+    </p>
+
+
+    <t:beaneditform object="this"/>
+
+    <t:if test="text">
+        <p>
+            Stored text:
+            <span id="output-text">${text}</span>
+        </p>
+    </t:if>
+
+    <p>
+        Cranky:
+        <span id="cranky">${cranky}</span>
+    </p>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/MultiBeanDemoResult.tml b/hlship-20080520/tapestry-core/src/test/app1/MultiBeanDemoResult.tml
new file mode 100644
index 0000000..02cea18
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/MultiBeanDemoResult.tml
@@ -0,0 +1,13 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>MultiBean Edit Demo</h1>
+
+  <ul>
+    <li>First Name: [${credentials.firstName}]</li>
+    <li>Last Name: [${credentials.lastName}]</li>
+    <li>Path: [${rolePath.path}]</li>
+    <li>Role: [${rolePath.role}]</li>
+  </ul>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/MultiBeanEditDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/MultiBeanEditDemo.tml
new file mode 100644
index 0000000..994255f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/MultiBeanEditDemo.tml
@@ -0,0 +1,32 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>MultiBean Edit</h1>
+
+  <form t:id="form">
+
+    <t:errors />
+
+    <div class="t-beaneditor">
+
+      <!--  Demonstrate default object binding from component id -->
+      <t:beaneditor t:id="credentials" />
+      <t:beaneditor t:id="rolePath" />
+
+      <div class="t-beaneditor-row">
+        <input type="submit" value="Set Access" />
+      </div>
+
+
+    </div>
+
+
+  </form>
+
+  <p>
+    [
+    <t:actionlink t:id="clear">Clear Data</t:actionlink>
+    ]
+  </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Music.tml b/hlship-20080520/tapestry-core/src/test/app1/Music.tml
new file mode 100644
index 0000000..cdbe771
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Music.tml
@@ -0,0 +1,14 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Music Library</h1>
+
+    <t:grid source="tracks" row="track" remove="genre,artist,playcount">
+        <t:parameter name="titleCell">
+            <t:pagelink page="music/details" context="track">${track.title}</t:pagelink>
+        </t:parameter>
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </t:grid>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/NullGrid.tml b/hlship-20080520/tapestry-core/src/test/app1/NullGrid.tml
new file mode 100644
index 0000000..bb85b90
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/NullGrid.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>Null Grid Demo</h1>
+    
+    <p>Default behavior for when a Grid is passed null for source.</p>
+    
+    <table t:type="Grid" source="null"/>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/NullStrategyDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/NullStrategyDemo.tml
new file mode 100644
index 0000000..85dd689
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/NullStrategyDemo.tml
@@ -0,0 +1,23 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Null Field Strategy Demo</h1>
+
+    <p>
+        Demonstrates the use of the nulls parameter of TextField to change how null values are treated.
+    </p>
+
+
+    <t:form>
+        <t:textfield t:id="number" nulls="zero"/>
+        <br/>
+        <input type="submit" value="Update"/>
+    </t:form>
+
+    <hr/>
+
+    <p>
+        Number property value:
+        <span id="value">${number}</span>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/NumberBeanDisplayDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/NumberBeanDisplayDemo.tml
new file mode 100644
index 0000000..23c4203
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/NumberBeanDisplayDemo.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:beandisplay object="holder"/>
+
+    <p>
+        <t:pagelink page="numberbeaneditordemo">Back to form</t:pagelink>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/NumberBeanEditorDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/NumberBeanEditorDemo.tml
new file mode 100644
index 0000000..06d7b7a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/NumberBeanEditorDemo.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Number BeanEditor Demo</h1>
+
+    <p>
+        Demonstrates that BeanEditor can handle null properties.
+    </p>
+
+
+    <t:beaneditform t:id="holder"/>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/OverrideValidationDecorator.tml b/hlship-20080520/tapestry-core/src/test/app1/OverrideValidationDecorator.tml
new file mode 100644
index 0000000..04116e1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/OverrideValidationDecorator.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Override Validation Decorator</h1>
+
+    <p>
+        Demonstrates how to override the default Validation Decorator for a page or a component (this is often
+        done inside a layout component). In addition, used to verify that the Label component
+        invokes Validation Decorator methods at the correct time.
+    </p>
+
+    <t:beaneditform t:id="form" object="this"/>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PageContextInForm.tml b/hlship-20080520/tapestry-core/src/test/app1/PageContextInForm.tml
new file mode 100644
index 0000000..1eda2a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PageContextInForm.tml
@@ -0,0 +1,17 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Page Context in Form</h1>
+
+    <h2>Activation Context</h2>
+    <t:if test="activationContext">
+        <ul>
+            <li t:type="loop" source="activationContext" value="object">${object}</li>
+        </ul>
+        <t:parameter name="else">No activation context.</t:parameter>
+    </t:if>
+
+    <t:form>
+        <input type="submit"/>
+    </t:form>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PageLinkContext.tml b/hlship-20080520/tapestry-core/src/test/app1/PageLinkContext.tml
new file mode 100644
index 0000000..a45f82d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PageLinkContext.tml
@@ -0,0 +1,24 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>PageLink Context Demo</h1>
+
+    <p>
+        Demonstrates how to supply explicit context is a page link. This is often used in pages with a master/detail
+        relationship,
+        with the master page providing links to the detail page, configured via the explicit context.
+    </p>
+
+    <a t:type="pagelink" page="target">no context</a>
+    <br/>
+    <a t:type="pagelink" page="target" context="literal:literal context">literal context</a>
+    <br/>
+    <a t:type="pagelink" page="target" context="computedContext">computed context</a>
+    <br/>
+    <a t:type="pagelink" page="target" context="unsafeCharacters">unsafe characters</a>
+    <br/>
+    <a t:type="pagelink" page="target" context="japaneseKanji">japanese kanji</a>
+    <br/>
+    <t:actionlink t:id="nullContext">Null in context</t:actionlink>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PageLoadedDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/PageLoadedDemo.tml
new file mode 100644
index 0000000..a4864e5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PageLoadedDemo.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>Page Loaded Demo</h1>
+
+    <p>
+        The message: [${message}]
+    </p>    
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PaletteDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/PaletteDemo.tml
new file mode 100644
index 0000000..721616a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PaletteDemo.tml
@@ -0,0 +1,26 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Palette Demo</h1>
+
+
+  <t:form>
+    <div>
+      <t:checkbox t:id="reorder" label="Enable Reorder"/>
+      <t:label for="reorder"/>
+    </div>
+
+    <div class="t-beaneditor">
+
+
+      <t:palette t:id="languages" model="languageModel" reorder="reorder" encoder="languageEncoder"/>
+      <br/>
+      <input type="submit"/>
+    </div>
+  </t:form>
+
+  <p> Selected Languages: ${languages} </p>
+  
+  <p>
+    [ <t:actionlink t:id="reset">reset</t:actionlink> ]
+  </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PasswordFieldDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/PasswordFieldDemo.tml
new file mode 100644
index 0000000..242c731
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PasswordFieldDemo.tml
@@ -0,0 +1,30 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Simple Form</h1>
+
+    <p> This is the <em>very early</em> start to Tapestry 5 form support. </p>
+
+    <form t:id="form">
+
+        <t:errors/>
+
+        <t:label  for="userName"/>
+        <input t:type="TextField" t:id="userName" t:validate="required" size="30"/>
+        <br/>
+        <t:label for="password"/>
+        <input t:id="password" t:validate="required" size="30"/>
+        <br/>
+        <input type="submit" value="Login"/>
+    </form>
+
+    <hr/>
+
+    <p> Entered data: </p>
+
+    <ul>
+        <li>userName: [${userName}]</li>
+        <li>password: [${password}]</li>
+    </ul>
+
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PersistentDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/PersistentDemo.tml
new file mode 100644
index 0000000..cb1d77f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PersistentDemo.tml
@@ -0,0 +1,21 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p>
+        Message:
+        <span id="message">${message}</span>
+    </p>
+
+    <ul>
+        <li>
+            <t:actionlink t:id="updateMessage" context="literal:updated">Update the message field</t:actionlink>
+        </li>
+        <li>
+            <t:actionlink t:id="discardChanges">Discard persistent field changes</t:actionlink>
+        </li>
+        <li>
+            <t:pagelink page="persistentdemo">Refresh page</t:pagelink>
+        </li>
+    </ul>
+</html>
+
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PostLogin.tml b/hlship-20080520/tapestry-core/src/test/app1/PostLogin.tml
new file mode 100644
index 0000000..63a72df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PostLogin.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+<h1>Post Login</h1>
+    
+    <p>
+        You have provided the correct user name and password.
+    </p>    
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/PrimitiveArrayParameterDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/PrimitiveArrayParameterDemo.tml
new file mode 100644
index 0000000..4a17e58
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/PrimitiveArrayParameterDemo.tml
@@ -0,0 +1,10 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Primitive Array Parameter Demo</h1>
+
+
+    <t:intarraywriter array="values"/>
+
+</html>
+
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Protected.tml b/hlship-20080520/tapestry-core/src/test/app1/Protected.tml
new file mode 100644
index 0000000..ac6d7c9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Protected.tml
@@ -0,0 +1,8 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+<h1>Protected Page</h1>
+
+<p>It should never be possible to see this, as the onActivate() event handler method prevents it.</p>
+    
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RadioDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RadioDemo.tml
new file mode 100644
index 0000000..f53cd2b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RadioDemo.tml
@@ -0,0 +1,47 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Radio Demo</h1>
+
+  <p>Choose a department and position:</p>
+
+  <t:form>
+    <t:radiogroup t:id="department">
+      <t:loop source="departments" value="loopValue">
+        <p>
+          <t:radio t:id="radio" value="loopValue" label="prop:label" />
+          <t:label for="radio" />
+        </p>
+      </t:loop>
+    </t:radiogroup>
+
+    <br />
+
+    <t:radiogroup t:id="position">
+      <p>
+        <t:radio t:id="radio1" value="literal:TEMP" label="Temp" />
+        <t:label for="radio1" />
+      </p>
+      <p>
+        <t:radio t:id="radio2" value="literal:LIFER" label="Lifer" />
+        <t:label for="radio2" />
+      </p>
+    </t:radiogroup>
+
+    <p>
+      <input type="submit" value="Update" />
+    </p>
+  </t:form>
+
+
+  <t:if test="department">
+    <hr />
+    Selected department: ${department}
+  </t:if>
+
+  <t:if test="position">
+    <hr />
+    Selected position: ${position}
+  </t:if>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RecursiveDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RecursiveDemo.tml
new file mode 100644
index 0000000..ff71df5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RecursiveDemo.tml
@@ -0,0 +1,5 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  This page contains a <t:recursive>Recursive component</t:recursive>, so it will never be able to render itself.
+  
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RegexpDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RegexpDemo.tml
new file mode 100644
index 0000000..acfd914
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RegexpDemo.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Regexp Validation Demo</h1>
+
+    <t:beaneditform object="this"/>
+
+    <hr/>
+
+    <t:if test="zipCode">
+        Zip code: [${zipCode}]
+    </t:if>
+
+</html>  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RenderComponentDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RenderComponentDemo.tml
new file mode 100644
index 0000000..69dbb26
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RenderComponentDemo.tml
@@ -0,0 +1,22 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>Render Component Demo</h1>
+
+  <p> This page demonstrates how a component may return a component instance from one of its render
+    phase methods to allow that object to render. </p>
+
+  <t:block id="optional"> <span>Optional Text</span> </t:block>
+
+  <t:form>
+    <input t:type="Checkbox" t:id="enabled" onchange="this.form.submit();"/>
+    <label t:type="Label" for="enabled">Enable optional text</label>
+  </t:form>
+
+  <t:if test="enabled"> Should now show up: <t:parameter name="else"> Should be blank:
+    </t:parameter>
+  </t:if>
+
+  <span id="container">[<t:render value="thing"/>]</span>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RenderErrorDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RenderErrorDemo.tml
new file mode 100644
index 0000000..0c4b28b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RenderErrorDemo.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Render Error Demo</h1>
+
+    <p>This page will not completely render, it gets an exception.</p>
+
+    <t:Echo value="value"/>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/RenderableDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/RenderableDemo.tml
new file mode 100644
index 0000000..7389b2b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/RenderableDemo.tml
@@ -0,0 +1,10 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  
+  <h1>Renderable Demo</h1>
+  
+  <p>
+    The following text is provided by a Renderable: [<t:delegate to="renderable"/>]
+  </p>
+  
+  
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ReturnTypes.tml b/hlship-20080520/tapestry-core/src/test/app1/ReturnTypes.tml
new file mode 100644
index 0000000..6ae5ab8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ReturnTypes.tml
@@ -0,0 +1,55 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Return Type Tests</h1>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="NullReturnValue">null</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="StringReturnValue">string</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="ClassReturnValue">class</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="PageReturnValue">page</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="LinkReturnValue">link</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="StreamReturnValue">stream</a>
+        return values.
+    </p>
+
+    <p>
+        Test
+        <t:actionlink t:id="url">URL</t:actionlink>
+        return values.
+    </p>
+
+
+    <p>
+        Test
+        <a t:type="ActionLink" t:id="BadReturnValue">bad</a>
+        return values.
+    </p>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/SecurityAlert.tml b/hlship-20080520/tapestry-core/src/test/app1/SecurityAlert.tml
new file mode 100644
index 0000000..7bb0b03
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/SecurityAlert.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1 id="pagetitle">Security Alert</h1>
+
+    <p>
+        Security exception: ${message}
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ShowBirthdayReminder.tml b/hlship-20080520/tapestry-core/src/test/app1/ShowBirthdayReminder.tml
new file mode 100644
index 0000000..cc77281
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ShowBirthdayReminder.tml
@@ -0,0 +1,8 @@
+<html t:type="Border"
+  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <h1>BeanEditor Date Demo</h1>
+
+  <t:beandisplay object="reminder" />
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/SimpleForm.tml b/hlship-20080520/tapestry-core/src/test/app1/SimpleForm.tml
new file mode 100644
index 0000000..fb54f39
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/SimpleForm.tml
@@ -0,0 +1,54 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Simple Form</h1>
+
+    <p>This is the
+        <em>very early</em>
+        start to Tapestry 5 form support.
+    </p>
+
+    <t:form clientvalidation="false">
+
+        <t:errors/>
+        
+        <input t:type="Checkbox" t:id="disabled"/>
+        <t:label for="disabled"/>
+        <br/>
+
+        <div class="t-beaneditor">
+
+            <t:label for="email">User Email</t:label>
+            <input t:type="TextField" t:id="email" value="incident.email" size="50" disabled="disabled"/>
+            <br/>
+            <t:label for="message"/>
+            <input t:type="TextArea" t:id="message" label="Incident Message" value="incident.message"
+                   cols="50" rows="10" disabled="disabled">You can put text here, but it isn't used.
+            </input>
+            <br/>
+            <t:label for="operatingSystem"/>
+            <select t:type="Select" t:id="operatingSystem" value="incident.operatingSystem"
+                    model="message:os-values" disabled="disabled"/>
+            <br/>
+            <t:label for="department"/>
+            <select t:type="Select" t:id="department" value="incident.department" disabled="disabled"/>
+            <br/>
+            <t:label for="urgent"/>
+            <input t:type="Checkbox" t:id="urgent" value="incident.urgent" disabled="disabled"/>
+            <br/>
+            <input type="submit"/>
+        </div>
+    </t:form>
+
+    <hr/>
+
+    <p>Entered data:</p>
+
+    <ul>
+        <li>email: [${incident.email}]</li>
+        <li>message: [${incident.message}]</li>
+        <li>OS: [${incident.operatingSystem}]</li>
+        <li>urgent: [${incident.urgent}]</li>
+        <li>department: [${incident.department}]</li>
+    </ul>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/SimpleTrackGridDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/SimpleTrackGridDemo.tml
new file mode 100644
index 0000000..88a92e7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/SimpleTrackGridDemo.tml
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>Grid Demo</h1>
+    
+    <table t:type="Grid" source="tracks" row="track" model="simpleTrackModel">
+        <t:parameter name="ratingcell">
+            <t:outputRating rating="track.rating"/>
+        </t:parameter>
+    </table>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Start.tml b/hlship-20080520/tapestry-core/src/test/app1/Start.tml
new file mode 100644
index 0000000..a15e703
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Start.tml
@@ -0,0 +1,68 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Tapestry 5 Integration Application 1</h1>
+
+    <p>${items.size()} standard test pages</p>
+
+    <ul>
+        <li t:type="loop" source="items" value="item">
+            <t:pagelink page="prop:item.pageName">${item.label}</t:pagelink>
+            -- ${item.description}
+        </li>
+    </ul>
+
+    <h2>Special Pages</h2>
+
+    <p>These are often pages which can't load due to errors.</p>
+
+    <ul>
+        <li>
+            <a href="BadTemplate">BadTemplate Page</a>
+            -- More exception reporting
+        </li>
+        <li>
+            <t:pagelink page="eventhandlerdemo" context="'clear'">
+                EventHandler Demo
+            </t:pagelink>
+            -- Tests for event handling method order and matching
+        </li>
+
+        <li>
+            <a href="InjectContainerMismatch">
+                InjectContainerMismatch
+            </a>
+            -- check error reporting when @InjectContainer doesn't match
+            the actual field type
+        </li>
+
+        <li>
+            <a href="injectcomponentmismatch">InjectComponentMismatch</a>
+            -- check error reporting when @InjectComponent
+            doesn't match actual field type
+        </li>
+
+        <li>
+            <a href="recursivedemo">Recursive Demo</a>
+            -- check for handling of recursive components
+        </li>
+
+        <li>
+            <t:actionlink t:id="securepage">Secure Page Demo</t:actionlink>
+            -- transition to HTTPS
+        </li>
+
+        <li>
+            <t:pagelink page="listeventcontextdemo" context="demoContext">List Event Context Demo</t:pagelink>
+            -- using a List for catch-all event context parameters
+        </li>
+
+        <li>
+            <a href="datumeditor">Class Transformation Exception Demo</a>
+            -- demo proper reporting of exceptions during class transformation
+        </li>
+
+    </ul>
+
+</html>                      
+
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Target.tml b/hlship-20080520/tapestry-core/src/test/app1/Target.tml
new file mode 100644
index 0000000..1f9b65a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Target.tml
@@ -0,0 +1,33 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Target</h1>
+    <h2>Activation Context</h2>
+    <t:if test="activationContext">
+
+        <ul>
+            <li t:type="loop" source="activationContext" value="object">${object}</li>
+        </ul>
+        <t:parameter name="else">No activation context.</t:parameter>
+    </t:if>
+    <h2>Component Context</h2>
+    <t:if test="componentContext">
+
+        <ul>
+            <li t:type="loop" source="componentContext" value="object">${object}</li>
+        </ul>
+
+        <t:parameter name="else"> No component context. </t:parameter>
+    </t:if>
+    <h2>Setup Component Context</h2> [<a t:type="actionlink" context="contextToEncode">go</a>] 
+    
+    <h2>Navigation</h2>
+    
+    <p>[<a t:type="pagelink" page="pagelinkcontext">PageLink Context Demo</a>]</p>
+    
+  <p>
+    [<t:pagelink t:id="nocontext" page="target" context="null">Target base, no context</t:pagelink>]
+  </p>
+    
+    
+    
+    
+    </html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/TextFieldWrapperTypeDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/TextFieldWrapperTypeDemo.tml
new file mode 100644
index 0000000..f52b831
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/TextFieldWrapperTypeDemo.tml
@@ -0,0 +1,35 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>TextField Wrapper Types Demo</h1>
+
+    <p>
+        Demonstrates the use of wrapper types (i.e. java.lang.Integer) with a TextField.
+    </p>
+
+    <t:form>
+        <t:errors/>
+
+        <t:textfield t:id="count" nulls="default"/>
+
+        <br/>
+
+        <input type="submit" value="Continue"/>
+
+    </t:form>
+
+    <hr/>
+
+    <p>
+        Count:
+        <t:if test="countNull">
+            <em id="value">null</em>
+            <t:parameter name="else">
+                <span id="value">${count}</span>
+            </t:parameter>
+        </t:if>
+
+        [<t:actionlink t:id="clear">clear</t:actionlink>]
+
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ToDoList.tml b/hlship-20080520/tapestry-core/src/test/app1/ToDoList.tml
new file mode 100644
index 0000000..24935f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ToDoList.tml
@@ -0,0 +1,36 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <h1>ToDo List</h1>
+    
+    <form t:id="form">
+        
+        <t:errors/>
+        
+        <table class="t-data-table">
+            <tr>
+                <th> Title </th>
+                <th> Reorder </th>
+            </tr>
+            <tr t:type="Loop" source="items" value="item" encoder="encoder">
+                <td>
+                    <input t:type="TextField" t:id="title" value="item.title" size="30"
+                        validate="required"/>
+                </td>
+                <td> NOT YET </td>            
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <input type="submit" value="Update ToDos"/>
+                    <input t:type="Submit" t:id="addNew" value="Add new ToDo"/>
+                </td>
+            </tr>
+            
+        </table>
+    </form>
+    
+    
+    <p>
+        <a t:type="ActionLink" t:id="reset">reset the database</a>
+    </p>
+    
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ToDoListVolatile.tml b/hlship-20080520/tapestry-core/src/test/app1/ToDoListVolatile.tml
new file mode 100644
index 0000000..1519ca8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ToDoListVolatile.tml
@@ -0,0 +1,36 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>ToDo List</h1>
+
+    <form t:id="form">
+
+        <t:errors/>
+
+        <table class="t-data-table">
+            <tr>
+                <th> Title </th>
+                <th> Reorder </th>
+            </tr>
+            <tr t:type="Loop" source="items" value="item" volatile="true">
+                <td>
+                    <input t:type="TextField" t:id="title" value="item.title" size="30"
+                        validate="required"/>
+                </td>
+                <td> NOT YET </td>            
+            </tr>
+            <tr>
+                <td colspan="2">
+                   <input type="submit" value="Update ToDos"/>
+                   <input t:type="Submit" t:id="addNew" value="Add new ToDo"/>
+                                   </td>
+            </tr>
+ 
+        </table>
+    </form>
+    
+
+    <p>
+        <a t:type="ActionLink" t:id="reset">reset the database</a>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/UnlessDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/UnlessDemo.tml
new file mode 100644
index 0000000..105b2df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/UnlessDemo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p id="false">
+        <t:unless test="false">
+            false is rendered
+        </t:unless>
+    </p>
+
+    <p id="true">
+        <t:unless test="true">true is not rendered</t:unless>
+    </p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/Unreachable.tml b/hlship-20080520/tapestry-core/src/test/app1/Unreachable.tml
new file mode 100644
index 0000000..4a0b0d3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/Unreachable.tml
@@ -0,0 +1,3 @@
+<html>
+    <h1>This page should not be reachable, due to IgnoredPathsFilter.</h1>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ViewRegistration.tml b/hlship-20080520/tapestry-core/src/test/app1/ViewRegistration.tml
new file mode 100644
index 0000000..e6b9856
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ViewRegistration.tml
@@ -0,0 +1,14 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>BeanEdit Component Demo</h1>
+    
+<t:beandisplay t:id="registrationdata">
+  <t:parameter name="citizen">
+    <t:if test="registrationdata.citizen">U.S. Citizen
+      <t:parameter name="else">
+        Resident Alien
+      </t:parameter>
+    </t:if>
+  </t:parameter>
+</t:beandisplay>
+    
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/app.properties b/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/app.properties
new file mode 100644
index 0000000..ac10fe8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/app.properties
@@ -0,0 +1,17 @@
+# Copyright 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+app-catalog-status=Application Catalog Working
+
+viewlink-label=View
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/web.xml b/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/web.xml
new file mode 100644
index 0000000..ecaf9dd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Integration Test App 1</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.apache.tapestry.integration.app1</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/XMLContent.tml b/hlship-20080520/tapestry-core/src/test/app1/XMLContent.tml
new file mode 100644
index 0000000..4a4836d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/XMLContent.tml
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>XML Content</h1>
+
+    <p>
+        <![CDATA[< & >]]>
+    </p>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/ZoneDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/ZoneDemo.tml
new file mode 100644
index 0000000..11c7438
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/ZoneDemo.tml
@@ -0,0 +1,38 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="default">
+    <h1>Zone/Ajax Demo</h1>
+
+
+    <t:zone t:id="output" style="float:right; width: 800px;" update="slidedown">
+        No name has been selected.
+
+        <t:block id="showName">
+            Selected: ${name}
+        </t:block>
+
+    </t:zone>
+
+    <t:block id="registrationForm">
+
+
+        <t:beaneditform t:id="form" object="registration" zone="output"/>
+
+        <t:actionlink t:id="clear" zone="output">clear</t:actionlink>
+
+    </t:block>
+
+    <t:block id="registrationOutput">
+        <t:beandisplay object="registration"/>
+    </t:block>
+
+
+    <ul>
+        <li t:type="loop" source="names" value="name">
+            <t:actionlink t:id="select" context="name" zone="output">Select "${name}"</t:actionlink>
+        </li>
+        <li>
+            <t:actionlink t:id="JSON" zone="output">Direct JSON response</t:actionlink>
+        </li>
+    </ul>
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/css/app.css b/hlship-20080520/tapestry-core/src/test/app1/css/app.css
new file mode 100644
index 0000000..13a916b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/css/app.css
@@ -0,0 +1,40 @@
+SPAN.inherit {
+    font-style: italic;
+}
+
+A.selected {
+    font-size: large;
+    font-weight: bold;
+}
+
+DIV#topspread {
+    padding: 0px 5px;
+}
+
+DIV.menu {
+    margin-bottom: 10px;
+}
+
+/** Copy of "#right h3" */
+
+DIV#left H3 {
+    background: #4A1605 url( ../layout/images/rightbig.gif ) no-repeat;
+    height: 30px;
+    line-height: 30px;
+    color: #fff;
+    padding-left: 10px;
+    font-size: 13px;
+    font-weight: 600;
+}
+
+/* Copy of ".menu h4" */
+DIV.t-env-data-section {
+    background: #4A1605 url( ../layout/images/rightsmall.gif ) no-repeat;
+    height: 20px;
+    line-height: 20px;
+    color: #fff;
+    padding-left: 10px;
+    font-size: 12px;
+    font-weight: 600;
+    width: 170px;
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/images/tapestry_banner.gif b/hlship-20080520/tapestry-core/src/test/app1/images/tapestry_banner.gif
new file mode 100644
index 0000000..42118f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/images/tapestry_banner.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/bg.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/bg.gif
new file mode 100755
index 0000000..aed0647
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/bg.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/bottom.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/bottom.gif
new file mode 100755
index 0000000..faa631b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/bottom.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/footer.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/footer.gif
new file mode 100755
index 0000000..6d820a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/footer.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/header.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/header.gif
new file mode 100755
index 0000000..62133bc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/header.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightbig.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightbig.gif
new file mode 100755
index 0000000..9a378f5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightbig.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightsmall.gif b/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightsmall.gif
new file mode 100755
index 0000000..9766528
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/images/rightsmall.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/index.html b/hlship-20080520/tapestry-core/src/test/app1/layout/index.html
new file mode 100755
index 0000000..f1b2f5e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/index.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

+<html xmlns="http://www.w3.org/1999/xhtml">

+<head>

+    <title>Professional</title>

+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

+    <meta http-equiv="Content-Language" content="English"/>

+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

+    <link rel="stylesheet" type="text/css" href="style.css" media="screen"/>

+</head>

+<body>

+<div id="wrap">

+

+    <div id="header">

+        <h1><a href="#">Your Website Title</a></h1>

+

+        <h2>Slogan of your website - H2</h2>

+    </div>

+

+    <div id="content">

+

+        <div id="intro">

+            Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla imperdiet aliquet orci.

+            Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy. Class aptent taciti sociosqu

+            ad litora torquent per conubia nostra, per inceptos hymenaeos. Phasellus quis ipsum

+            ac mauris vulputate ullamcorper. Praesent nonummy urna a es. Consectetuer adipiscing elit.

+            Mauris ac elit sed velit scelerisque nonummy.Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy.

+            Nulla imperdiet aliquet orci. Sed quis nibh. Mauris ac elit sed velit scelerisque.

+        </div>

+

+        <div id="left">

+

+            <h2><a href="#">Lorem Ipsum dolor sit amet</a></h2>

+

+            <img src="images/pic.gif" alt="Example pic" style="border: 3px solid #eee;"/>

+            <br/>

+            Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla imperdiet aliquet orci.

+            Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy. Class aptent taciti sociosqu

+            ad litora torquent per conubia nostra, per inceptos hymenaeos. Phasellus quis ipsum

+            ac mauris vulputate ullamcorper. Praesent nonummy urna a es. Consectetuer adipiscing elit.

+            Mauris ac elit sed velit scelerisque nonummy.Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy.

+            Nulla imperdiet aliquet orci. Sed quis nibh. Mauris ac elit sed velit scelerisque.

+            <br/><br/>

+            Consectetuer adipiscing elit.

+            Mauris ac elit sed velit scelerisque nonummy.Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy.

+            Nulla imperdiet aliquet orci. Sed quis nibh. Mauris ac elit sed velit scelerisque.

+            Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla imperdiet aliquet orci.

+            Sed quis nibh. Mauris ac elit sed velit scelerisque nonummy. Class aptent taciti sociosqu

+            ad litora torquent per conubia nostra, per inceptos hymenaeos. Phasellus quis ipsum

+            ac mauris vulputate ullamcorper. Praesent nonummy urna a es.

+            <br/><br/>

+            Mauris ac elit sed velit scelerisque.

+            Lorem ipsum dolor sit amet, consectetuer adipiscing.

+

+        </div>

+

+        <div id="right">

+

+            <h3>Advertisments or Latest Articles</h3>

+

+            <div class="rightads">

+                <img src="images/ads.gif" alt="Ads"/>

+            </div>

+

+            <div class="menu">

+                <h4>Categories</h4>

+                <ul>

+                    <li><a href="#">Home</a></li>

+                    <li><a href="#">Art and Humanities</a></li>

+                    <li><a href="#">World Politics</a></li>

+                    <li><a href="#">World Sports</a></li>

+                    <li><a href="#">Categories</a></li>

+                    <li><a href="#">Your Category</a></li>

+                    <li><a href="#">Something Goes Here</a></li>

+                    <li><a href="#">Example Categories</a></li>

+                    <li><a href="#">Surfing</a></li>

+                </ul>

+            </div>

+

+            <div class="menu1">

+                <h4>Archives</h4>

+                <ul>

+                    <li><a href="#">January 2007</a></li>

+                    <li><a href="#">February 2007</a></li>

+                    <li><a href="#">March 2007</a></li>

+                    <li><a href="#">April 2007</a></li>

+                    <li><a href="#">May 2007</a></li>

+                    <li><a href="#">June 2007</a></li>

+                    <li><a href="#">July 2007</a></li>

+                    <li><a href="#">August 2007</a></li>

+                    <li><a href="#">September 2007</a></li>

+                </ul>

+            </div>

+

+        </div>

+

+        <div style="clear: both;"></div>

+    </div>

+

+    <div id="footer">

+        &copy; Copyright by <a href="#">You</a> | Design by <a href="http://www.minimalistic-design.net">Minimalistic

+        Design</a>

+    </div>

+

+    <div id="bottom"></div>

+

+</div>

+</body>

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app1/layout/style.css b/hlship-20080520/tapestry-core/src/test/app1/layout/style.css
new file mode 100755
index 0000000..3d7c449
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/layout/style.css
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/app1/music/MusicDetails.tml b/hlship-20080520/tapestry-core/src/test/app1/music/MusicDetails.tml
new file mode 100644
index 0000000..f4d7d36
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/music/MusicDetails.tml
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Track Details</h1>
+
+    <t:beandisplay object="track"/>
+
+    <p>
+        <t:pagelink page="music">Back to music library</t:pagelink>
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/app1/nested/ActionDemo.tml b/hlship-20080520/tapestry-core/src/test/app1/nested/ActionDemo.tml
new file mode 100644
index 0000000..044c374
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app1/nested/ActionDemo.tml
@@ -0,0 +1,23 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+    <t:if test="number">

+        <p>

+            <strong>

+                <span id="message">Number: ${number}</span>

+            </strong>

+        </p>

+    </t:if>

+

+    <p>

+        Choose a number:

+

+        <ul>

+            <t:loop source="1..3" value="var:currentNumber">

+                <li>

+                    <t:actionlink t:id="actionlink" context="var:currentNumber">${var:currentNumber}</t:actionlink>

+                </li>

+            </t:loop>

+        </ul>

+    </p>

+

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app2/OpaqueResource.txt b/hlship-20080520/tapestry-core/src/test/app2/OpaqueResource.txt
new file mode 100644
index 0000000..525c208
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app2/OpaqueResource.txt
@@ -0,0 +1 @@
+some opaque resource. This file is needed by a unit test. Do not delete it.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app2/TestPageForTemplateInContext.tml b/hlship-20080520/tapestry-core/src/test/app2/TestPageForTemplateInContext.tml
new file mode 100644
index 0000000..72dc401
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app2/TestPageForTemplateInContext.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<p>
+${msg}
+</p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app2/css/test.css b/hlship-20080520/tapestry-core/src/test/app2/css/test.css
new file mode 100644
index 0000000..7fcdff9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app2/css/test.css
@@ -0,0 +1,3 @@
+.foo {
+    display: none;
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app3/BeanDisplayOverrideDemo.tml b/hlship-20080520/tapestry-core/src/test/app3/BeanDisplayOverrideDemo.tml
new file mode 100644
index 0000000..126f2ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app3/BeanDisplayOverrideDemo.tml
@@ -0,0 +1,11 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>BeanDisplay Global Override Demo</title>
+    </head>
+    <body>
+        <h1>BeanDisplay Global Override Demo</h1>
+
+        <t:beandisplay object="this"/>
+
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app3/Index.tml b/hlship-20080520/tapestry-core/src/test/app3/Index.tml
new file mode 100644
index 0000000..f92a651
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app3/Index.tml
@@ -0,0 +1,13 @@
+<html>
+    <head>
+        <title>Index</title>
+    </head>
+    <body>
+        <h1>Index</h1>
+
+        <p>
+            Message:
+            <span id="message">${message}</span>
+        </p>
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app3/Login.tml b/hlship-20080520/tapestry-core/src/test/app3/Login.tml
new file mode 100644
index 0000000..39a9e39
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app3/Login.tml
@@ -0,0 +1,19 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Login</title>
+    </head>
+    <body>
+        <h1>Login Page</h1>
+
+        <p>
+            You have reached this page via a redirect from the Index page's onActivate() event handler method.
+        </p>
+
+        <ul>
+            <li>
+                 <t:pagelink page="beandisplayoverridedemo">BeanDisplay Override Demo</t:pagelink>
+            </li>
+        </ul>
+
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app3/PropertyDisplayBlockOverrides.tml b/hlship-20080520/tapestry-core/src/test/app3/PropertyDisplayBlockOverrides.tml
new file mode 100644
index 0000000..95ef04a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app3/PropertyDisplayBlockOverrides.tml
@@ -0,0 +1,11 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:block id="boolean">
+        <t:if test="context.propertyValue">
+            Yea
+            <t:parameter name="else">
+                Nay
+            </t:parameter>
+        </t:if>
+    </t:block>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app3/WEB-INF/web.xml b/hlship-20080520/tapestry-core/src/test/app3/WEB-INF/web.xml
new file mode 100644
index 0000000..b02474f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app3/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Integration Test App 3</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.apache.tapestry.integration.app3</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
diff --git a/hlship-20080520/tapestry-core/src/test/app4/Destination.tml b/hlship-20080520/tapestry-core/src/test/app4/Destination.tml
new file mode 100644
index 0000000..f46046c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app4/Destination.tml
@@ -0,0 +1,27 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Destination</title>
+    </head>
+
+    <body>
+
+
+        <dl>
+            <dt>message</dt>
+            <dd>${message}</dd>
+
+            <dt>value</dt>
+            <dd>${value}</dd>
+        </dl>
+
+        <hr/>
+
+        <t:pagelink page="destination">refresh page</t:pagelink>
+
+        <hr/>
+
+        <t:actionlink>refresh via action</t:actionlink>
+
+    </body>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app4/Start.tml b/hlship-20080520/tapestry-core/src/test/app4/Start.tml
new file mode 100644
index 0000000..4b6f778
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app4/Start.tml
@@ -0,0 +1,21 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Start</title>
+    </head>
+
+    <body>
+
+        <h1>Start</h1>
+
+        <t:beaneditform object="this"/>
+
+        <hr/>
+
+        <p>
+            Click
+            <t:actionlink t:id="bypass">here</t:actionlink>
+            to bypass the form.
+        </p>
+    </body>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/app4/WEB-INF/web.xml b/hlship-20080520/tapestry-core/src/test/app4/WEB-INF/web.xml
new file mode 100644
index 0000000..fbe58fa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/app4/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Integration Test App 4</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.apache.tapestry.integration.app4</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
diff --git a/hlship-20080520/tapestry-core/src/test/conf/keystore b/hlship-20080520/tapestry-core/src/test/conf/keystore
new file mode 100644
index 0000000..b17e4b0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/conf/keystore
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/conf/keystore-password.txt b/hlship-20080520/tapestry-core/src/test/conf/keystore-password.txt
new file mode 100644
index 0000000..2125b08
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/conf/keystore-password.txt
@@ -0,0 +1 @@
+The password for this keystore is "tapestry".
diff --git a/hlship-20080520/tapestry-core/src/test/conf/testng.xml b/hlship-20080520/tapestry-core/src/test/conf/testng.xml
new file mode 100644
index 0000000..ae33410
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/conf/testng.xml
@@ -0,0 +1,59 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Core" thread-count="10" annotations="1.5" verbose="2" parallel="tests">
+    <test name="Integration Tests">
+        <packages>
+            <package name="org.apache.tapestry.integration"/>
+        </packages>
+    </test>
+    <test name="Components">
+        <packages>
+            <package name="org.apache.tapestry.integration.pagelevel"/>
+            <package name="org.apache.tapestry.corelib.base"/>
+            <package name="org.apache.tapestry.corelib.components"/>
+            <package name="org.apache.tapestry.corelib.internal"/>
+        </packages>
+    </test>
+    <test name="Public APIs">
+        <packages>
+            <package name="org.apache.tapestry"/>
+            <package name="org.apache.tapestry.dom"/>
+            <package name="org.apache.tapestry5.json"/>
+            <package name="org.apache.tapestry.services"/>
+            <package name="org.apache.tapestry.util"/>
+            <package name="org.apache.tapestry.runtime"/>
+            <package name="org.apache.tapestry.validator"/>
+        </packages>
+    </test>
+    <test name="Internal APIs">
+        <packages>
+            <package name="org.apache.internal"/>
+            <package name="org.apache.tapestry.internal"/>
+            <package name="org.apache.tapestry.internal.beaneditor"/>
+            <package name="org.apache.tapestry.internal.grid"/>
+            <package name="org.apache.tapestry.internal.services"/>
+            <package name="org.apache.tapestry.internal.structure"/>
+            <package name="org.apache.tapestry.internal.util"/>
+            <package name="org.apache.tapestry.internal.bindings"/>
+            <package name="org.apache.tapestry.internal.model"/>
+            <package name="org.apache.tapestry.internal.test"/>
+            <package name="org.apache.tapestry.internal.transform"/>
+            <package name="org.apache.tapestry.internal.translator"/>
+        </packages>
+    </test>
+</suite>
diff --git a/hlship-20080520/tapestry-core/src/test/conf/webdefault.xml b/hlship-20080520/tapestry-core/src/test/conf/webdefault.xml
new file mode 100644
index 0000000..fa9e230
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/conf/webdefault.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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">

+

+    <description>

+        Default web.xml file.

+        This file is applied to a Web application before it's own WEB_INF/web.xml file

+    </description>

+

+

+    <!-- ==================================================================== -->

+    <!-- Context params to control Session Cookies                            -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <!-- UNCOMMENT TO ACTIVATE

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>

+      <param-value>127.0.0.1</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>

+      <param-value>/</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>

+      <param-value>-1</param-value>

+    </context-param>

+    -->

+

+

+    <!-- ==================================================================== -->

+    <!-- The default servlet.                                                 -->

+    <!-- This servlet, normally mapped to /, provides the handling for static -->

+    <!-- content, OPTIONS and TRACE methods for the context.                  -->

+    <!-- The following initParameters are supported:                          -->

+    <!--                                                                      -->

+    <!--   acceptRanges     If true, range requests and responses are         -->

+    <!--                    supported                                         -->

+    <!--                                                                      -->

+    <!--   dirAllowed       If true, directory listings are returned if no    -->

+    <!--                    welcome file is found. Else 403 Forbidden.        -->

+    <!--                                                                      -->

+    <!--   putAllowed       If true, the PUT method is allowed                -->

+    <!--                                                                      -->

+    <!--   delAllowed       If true, the DELETE method is allowed             -->

+    <!--                                                                      -->

+    <!--   redirectWelcome  If true, redirect welcome file requests           -->

+    <!--                    else use request dispatcher forwards              -->

+    <!--                                                                      -->

+    <!--   minGzipLength    If set to a positive integer, then static content -->

+    <!--                    larger than this will be served as gzip content   -->

+    <!--                    encoded if a matching resource is found ending    -->

+    <!--                    with ".gz"                                        -->

+    <!--                                                                      -->

+    <!--   resoureBase      Can be set to replace the context resource base   -->

+    <!--                                                                      -->

+    <!--   relativeResourceBase                                               -->

+    <!--                    Set with a pathname relative to the base of the   -->

+    <!--                    servlet context root. Useful for only serving     -->

+    <!--                    static content from only specific subdirectories. -->

+    <!--                                                                      -->

+    <!-- The MOVE method is allowed if PUT and DELETE are allowed             -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <servlet>

+        <servlet-name>default</servlet-name>

+        <servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>

+        <init-param>

+            <param-name>acceptRanges</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>dirAllowed</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>putAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>delAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>redirectWelcome</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>minGzipLength</param-name>

+            <param-value>8192</param-value>

+        </init-param>

+        <load-on-startup>0</load-on-startup>

+    </servlet>

+

+

+    <servlet-mapping>

+        <servlet-name>default</servlet-name>

+        <url-pattern>/</url-pattern>

+    </servlet-mapping>

+

+    <!-- ==================================================================== -->

+    <session-config>

+        <session-timeout>30</session-timeout>

+    </session-config>

+

+

+    <!-- ==================================================================== -->

+    <welcome-file-list>

+        <welcome-file>index.html</welcome-file>

+        <welcome-file>index.htm</welcome-file>

+    </welcome-file-list>

+

+    <!-- ==================================================================== -->

+    <locale-encoding-mapping-list>

+        <locale-encoding-mapping>

+            <locale>ar</locale>

+            <encoding>ISO-8859-6</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>be</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>bg</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ca</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>cs</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>da</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>de</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>el</locale>

+            <encoding>ISO-8859-7</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>en</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>es</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>et</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fi</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fr</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hr</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hu</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>is</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>it</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>iw</locale>

+            <encoding>ISO-8859-8</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ja</locale>

+            <encoding>Shift_JIS</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ko</locale>

+            <encoding>EUC-KR</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lt</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lv</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>mk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>nl</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>no</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pt</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ro</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ru</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sh</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sk</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sq</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sr</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sv</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>tr</locale>

+            <encoding>ISO-8859-9</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>uk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh</locale>

+            <encoding>GB2312</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh_TW</locale>

+            <encoding>Big5</encoding>

+        </locale-encoding-mapping>

+    </locale-encoding-mapping-list>

+

+

+</web-app>

+

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ContentTypeTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ContentTypeTest.java
new file mode 100644
index 0000000..f32797f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ContentTypeTest.java
@@ -0,0 +1,128 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+public class ContentTypeTest extends Assert
+{
+    @Test
+    public void simple_equals()
+    {
+        ContentType master = new ContentType("text/html");
+
+        assertFalse(master.equals(null));
+        assertFalse(master.equals(this));
+        assertTrue(master.equals(master));
+        assertTrue(master.equals(new ContentType("text/html")));
+        assertFalse(master.equals(new ContentType("foo/bar")));
+        assertFalse(master.equals(new ContentType("text/plain")));
+    }
+
+    @Test
+    public void equals_with_parameters()
+    {
+        ContentType master = new ContentType("text/html;charset=utf-8");
+
+        assertFalse(master.equals(new ContentType("text/html")));
+        assertTrue(master.equals(new ContentType("text/html;charset=utf-8")));
+        assertFalse(master.equals(new ContentType("text/html;charset=utf-8;foo=bar")));
+
+        // Check that keys are case insensitive
+
+        assertTrue(master.equals(new ContentType("text/html;Charset=utf-8")));
+
+        master = new ContentType("text/html;foo=bar;biff=bazz");
+
+        assertTrue(master.equals(new ContentType("text/html;foo=bar;biff=bazz")));
+        assertTrue(master.equals(new ContentType("text/html;Foo=bar;Biff=bazz")));
+        assertTrue(master.equals(new ContentType("text/html;biff=bazz;foo=bar")));
+    }
+
+    @Test
+    public void parse_with_parameters() throws Exception
+    {
+        ContentType contentType = new ContentType("text/html;charset=utf-8");
+
+        assertEquals(contentType.getBaseType(), "text");
+
+        assertEquals(contentType.getSubType(), "html");
+
+        assertEquals(contentType.getMimeType(), "text/html");
+
+        List<String> parameterNames = contentType.getParameterNames();
+        assertEquals(parameterNames.size(), 1);
+
+        assertEquals(parameterNames.get(0), "charset");
+
+        String charset = contentType.getParameter("charset");
+        assertEquals(charset, "utf-8");
+
+        String nonexistant = contentType.getParameter("nonexistant");
+        assertTrue(nonexistant == null);
+    }
+
+    @Test
+    public void parse_without_parameters() throws Exception
+    {
+        ContentType contentType = new ContentType("text/html");
+
+        assertEquals(contentType.getBaseType(), "text");
+
+        assertEquals(contentType.getSubType(), "html");
+
+        assertEquals(contentType.getMimeType(), "text/html");
+
+        assertTrue(contentType.getParameterNames().isEmpty());
+    }
+
+    @Test
+    public void unparse_with_parameters() throws Exception
+    {
+        ContentType contentType = new ContentType();
+
+        contentType.setBaseType("text");
+        contentType.setSubType("html");
+        contentType.setParameter("charset", "utf-8");
+
+        assertEquals(contentType.unparse(), "text/html;charset=utf-8");
+    }
+
+    @Test
+    public void unparse_no_parameters() throws Exception
+    {
+        ContentType contentType = new ContentType();
+
+        contentType.setBaseType("text");
+        contentType.setSubType("html");
+
+        assertEquals(contentType.unparse(), "text/html");
+    }
+
+    @Test
+    public void to_string_is_unparse()
+    {
+        ContentType contentType = new ContentType();
+
+        contentType.setBaseType("text");
+        contentType.setSubType("html");
+        contentType.setParameter("charset", "utf-8");
+
+        assertEquals(contentType.toString(), contentType.unparse());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/MarkupUtilsTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/MarkupUtilsTest.java
new file mode 100644
index 0000000..785b2c3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/MarkupUtilsTest.java
@@ -0,0 +1,71 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class MarkupUtilsTest extends Assert
+{
+    @Test(dataProvider = "string_quoting_input")
+    public void string_quoting(String input, String expected)
+    {
+        assertEquals(MarkupUtils.quote(input), expected);
+    }
+
+    @DataProvider(name = "string_quoting_input")
+    public Object[][] string_quoting_input()
+    {
+        return new Object[][]
+                {
+                        { "Suzy said: \"It's not the proper time\".",
+                                "'Suzy said: \\\"It\\'s not the proper time\\\".'" },
+                        { "regexp: \\d{4}", "'regexp: \\\\d{4}'" },
+
+                };
+    }
+
+    @Test(dataProvider = "join_input")
+    public void join_array(String[] inputs, String expected)
+    {
+        assertEquals(MarkupUtils.join(inputs), expected);
+    }
+
+    @Test(dataProvider = "join_input")
+    public void join_list(String[] inputs, String expected)
+    {
+        List<String> list = Arrays.asList(inputs);
+
+        assertEquals(MarkupUtils.join(list), expected);
+    }
+
+    @DataProvider(name = "join_input")
+    public Object[][] join_input()
+    {
+        return new Object[][]
+                {
+                        { new String[0], "" },
+                        { new String[]
+                                { "fred" }, "fred" },
+                        { new String[]
+                                { "fred", "barney", "wilma" }, "barney fred wilma" } };
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/Stooge.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/Stooge.java
new file mode 100644
index 0000000..a137808
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/Stooge.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+public enum Stooge
+{
+    MOE, LARRY, CURLY_JOE
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java
new file mode 100644
index 0000000..4c82fd0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java
@@ -0,0 +1,214 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+
+public class ValidationTrackerImplTest extends TapestryTestCase
+{
+    @Test
+    public void empty_tracker_has_no_errors()
+    {
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        assertTrue(tracker.getErrors().isEmpty());
+        assertFalse(tracker.getHasErrors());
+    }
+
+    @Test
+    public void order_added_is_maintained()
+    {
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
+
+        replay();
+
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        tracker.recordError("one");
+        tracker.recordError(fieldb, "fieldb: two");
+        tracker.recordError("three");
+        tracker.recordError(fielda, "fielda: four");
+
+        assertEquals(tracker.getErrors(), Arrays.asList(
+                "one",
+                "three",
+                "fieldb: two",
+                "fielda: four"));
+
+        verify();
+    }
+
+    @Test
+    public void record_input()
+    {
+        Field field = newFieldWithControlName("field");
+
+        replay();
+
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        assertNull(tracker.getInput(field));
+
+        tracker.recordInput(field, "one");
+
+        assertEquals(tracker.getInput(field), "one");
+
+        tracker.recordInput(field, "two");
+
+        assertEquals(tracker.getInput(field), "two");
+
+        verify();
+    }
+
+    @Test
+    public void record_error_for_field()
+    {
+        Field field = newFieldWithControlName("field");
+
+        replay();
+
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        assertFalse(tracker.getHasErrors());
+        assertFalse(tracker.inError(field));
+        assertNull(tracker.getError(field));
+
+        tracker.recordError(field, "one");
+
+        assertTrue(tracker.getHasErrors());
+        assertTrue(tracker.inError(field));
+        assertEquals(tracker.getError(field), "one");
+
+        tracker.recordError(field, "two");
+        assertEquals(tracker.getError(field), "two");
+
+        verify();
+    }
+
+    @Test
+    public void record_error_for_form()
+    {
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        assertFalse(tracker.getHasErrors());
+
+        assertTrue(tracker.getErrors().isEmpty());
+
+        tracker.recordError("one");
+
+        assertEquals(tracker.getErrors(), Arrays.asList("one"));
+
+        tracker.recordError("two");
+
+        assertEquals(tracker.getErrors(), Arrays.asList("one", "two"));
+    }
+
+    @Test
+    public void data_survives_serialization() throws Exception
+    {
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
+        Field fieldc = newFieldWithControlName("fieldC");
+
+        replay();
+
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        tracker.recordError("one");
+        tracker.recordError(fieldb, "fieldb: two");
+        tracker.recordError("three");
+        tracker.recordError(fielda, "fielda: four");
+
+        ValidationTracker copy = cloneBySerialiation(tracker);
+
+        copy.recordError(fieldc, "fieldc: five");
+
+        assertEquals(copy.getErrors(), Arrays.asList(
+                "one",
+                "three",
+                "fieldb: two",
+                "fielda: four",
+                "fieldc: five"));
+
+        verify();
+    }
+
+    @Test
+    public void clear_removes_all()
+    {
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
+
+        replay();
+
+        ValidationTracker tracker = new ValidationTrackerImpl();
+
+        tracker.recordError("one");
+        tracker.recordInput(fieldb, "input b");
+        tracker.recordError(fieldb, "fieldb: two");
+        tracker.recordError("three");
+        tracker.recordInput(fielda, "input a");
+        tracker.recordError(fielda, "fielda: four");
+
+        tracker.clear();
+
+        assertFalse(tracker.getHasErrors());
+        assertTrue(tracker.getErrors().isEmpty());
+        assertNull(tracker.getInput(fielda));
+        assertNull(tracker.getInput(fieldb));
+
+        verify();
+    }
+
+    private final Field newFieldWithControlName(String controlName)
+    {
+        Field field = mockField();
+
+        // Fields generated this way, for the purposes of this test, do not
+        // ever change their controlName. In real life, elementNames can change.
+
+        expect(field.getControlName()).andReturn(controlName).atLeastOnce();
+
+        return field;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final <T> T cloneBySerialiation(T input) throws Exception
+    {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+
+        oos.writeObject(input);
+
+        oos.close();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bis);
+
+        T result = (T) ois.readObject();
+
+        ois.close();
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/VersionUtilsTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/VersionUtilsTest.java
new file mode 100644
index 0000000..2db2e8d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/VersionUtilsTest.java
@@ -0,0 +1,25 @@
+package org.apache.tapestry;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class VersionUtilsTest extends Assert
+{
+    @Test
+    public void read_version_number_missing()
+    {
+        assertEquals(VersionUtils.readVersionNumber("no-such-file.properties"), "UNKNOWN");
+    }
+
+    @Test
+    public void read_version_number()
+    {
+        assertEquals(VersionUtils.readVersionNumber("org/apache/tapestry/version.properties"), "1.2.3.4");
+    }
+
+    @Test
+    public void read_version_number_no_version_key()
+    {
+        assertEquals(VersionUtils.readVersionNumber("org/apache/tapestry/noversion.properties"), "UNKNOWN");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractLinkTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractLinkTest.java
new file mode 100644
index 0000000..a698379
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractLinkTest.java
@@ -0,0 +1,109 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ComponentInvocation;
+import org.apache.tapestry.internal.services.ComponentInvocationMap;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.test.PageTesterComponentInvocationMap;
+import org.testng.annotations.Test;
+
+public class AbstractLinkTest extends InternalBaseTestCase
+{
+    private final static String LINK_URI = "/foo/bar.baz";
+
+    private final AbstractLink linkFixture = new AbstractLink()
+    {
+    };
+
+    @Test
+    public void no_anchor()
+    {
+        Link link = mockLink();
+        ComponentResources resources = mockComponentResources();
+        ComponentInvocationMap map = new PageTesterComponentInvocationMap();
+        MarkupWriter writer = new MarkupWriterImpl();
+        ComponentInvocation invocation = mockComponentInvocation();
+
+        map.store(link, invocation);
+
+        train_toURI(link, LINK_URI);
+
+        resources.renderInformalParameters(writer);
+
+        replay();
+
+        linkFixture.inject(null, map, resources);
+
+        linkFixture.writeLink(writer, link);
+
+        verify();
+
+        Element e = writer.getElement();
+
+        writer.write("link text");
+        writer.end();
+
+        assertEquals(writer.toString(), "<a href=\"/foo/bar.baz\">link text</a>");
+        assertSame(map.get(e), invocation);
+    }
+
+    @Test
+    public void with_anchor()
+    {
+        Link link = mockLink();
+        ComponentResources resources = mockComponentResources();
+        ComponentInvocationMap map = new PageTesterComponentInvocationMap();
+        MarkupWriter writer = new MarkupWriterImpl();
+        ComponentInvocation invocation = mockComponentInvocation();
+
+        map.store(link, invocation);
+
+        train_toURI(link, LINK_URI);
+
+        resources.renderInformalParameters(writer);
+
+        replay();
+
+        linkFixture.inject("wilma", map, resources);
+
+        linkFixture.writeLink(writer, link);
+
+        verify();
+
+        Element e = writer.getElement();
+
+        writer.write("link text");
+        writer.end();
+
+        assertEquals(writer.toString(), "<a href=\"/foo/bar.baz#wilma\">link text</a>");
+        assertSame(map.get(e), invocation);
+    }
+
+    protected final void train_toURI(Link link, String URI)
+    {
+        expect(link.toURI()).andReturn(URI);
+    }
+
+    protected final ComponentInvocation mockComponentInvocation()
+    {
+        return newMock(ComponentInvocation.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractPropertyOutputTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractPropertyOutputTest.java
new file mode 100644
index 0000000..231fa34
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/base/AbstractPropertyOutputTest.java
@@ -0,0 +1,57 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.base;
+
+import org.testng.annotations.Test;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.PropertyConduit;
+
+public class AbstractPropertyOutputTest extends InternalBaseTestCase
+{
+    private final AbstractPropertyOutput propertyOutputFixture = new AbstractPropertyOutput()
+    {
+    };
+
+    @Test
+    // Tests TAPESTRY-2182.
+    public void test_null_pointer_exception_message()
+    {
+        final PropertyConduit conduit = mockPropertyConduit();
+        final PropertyModel model = mockPropertyModel();
+        final Object object = new Object();
+
+        propertyOutputFixture.inject(model, object);
+
+        expect(model.getConduit()).andReturn(conduit);
+        expect(conduit.get(object)).andThrow(new NullPointerException());
+        expect(model.getPropertyName()).andReturn("wilma.occupation.address");
+
+        replay();
+
+        try
+        {
+            propertyOutputFixture.readPropertyForObject();
+
+            fail("Expected a NullPointerException to be thrown.");
+        }
+        catch (final NullPointerException ex)
+        {
+            assertEquals(ex.getMessage(), "Property 'wilma.occupation.address' contains a null value in the path.");
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/AnyTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/AnyTest.java
new file mode 100644
index 0000000..9c12540
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/AnyTest.java
@@ -0,0 +1,86 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.dom.DefaultMarkupModel;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class AnyTest extends TapestryTestCase
+{
+    @Test
+    public void render_simple()
+    {
+        ComponentResources resources = mockComponentResources();
+        RenderSupport support = mockRenderSupport();
+
+        MarkupWriter writer = new MarkupWriterImpl(new DefaultMarkupModel());
+
+        resources.renderInformalParameters(writer);
+
+        replay();
+
+        Any component = new Any();
+        component.inject(support, resources, "span", "foo");
+
+        component.beginRender(writer);
+        writer.write("content");
+        component.afterRender(writer);
+
+        assertEquals(writer.toString(), "<span>content</span>");
+
+        verify();
+    }
+
+    @Test
+    public void render_with_id()
+    {
+        ComponentResources resources = mockComponentResources();
+        RenderSupport support = mockRenderSupport();
+
+        MarkupWriter writer = new MarkupWriterImpl(new DefaultMarkupModel());
+
+        resources.renderInformalParameters(writer);
+
+        String clientId = "bar";
+        String uniqueId = "bar_0";
+
+        expect(support.allocateClientId(clientId)).andReturn(uniqueId);
+
+        replay();
+
+        Any component = new Any();
+        component.inject(support, resources, "div", clientId);
+
+        component.beginRender(writer);
+        writer.write("content");
+        component.afterRender(writer);
+
+        assertEquals(writer.toString(), "<div>content</div>");
+
+        assertEquals(component.getClientId(), uniqueId);
+
+        assertEquals(writer.toString(), "<div id=\"bar\">content</div>");
+
+        assertEquals(component.getClientId(), uniqueId);
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditorTest.java
new file mode 100644
index 0000000..45cf164
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/BeanEditorTest.java
@@ -0,0 +1,107 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BeanModelSource;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class BeanEditorTest extends TapestryTestCase
+{
+    @Test
+    public void object_created_as_needed()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentResources overrides = mockComponentResources();
+        ComponentResources containerResources = mockComponentResources();
+        BeanModelSource source = mockBeanModelSource();
+        BeanModel model = mockBeanModel();
+        RegistrationData data = new RegistrationData();
+
+        train_getBoundType(resources, "object", RegistrationData.class);
+
+        train_getContainerResources(overrides, containerResources);
+
+        train_create(source, RegistrationData.class, true, containerResources, model);
+
+        expect(model.newInstance()).andReturn(data);
+
+        replay();
+
+        BeanEditor component = new BeanEditor();
+
+        component.inject(resources, overrides, source);
+
+        component.doPrepare();
+
+        assertSame(component.getObject(), data);
+
+        verify();
+    }
+
+
+    @Test
+    public void object_can_not_be_instantiated()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentResources overrides = mockComponentResources();
+        ComponentResources containerResources = mockComponentResources();
+        BeanModelSource source = mockBeanModelSource();
+        BeanModel model = mockBeanModel();
+        Location l = mockLocation();
+        Throwable exception = new RuntimeException("Fall down go boom.");
+
+        train_getBoundType(resources, "object", Runnable.class);
+
+        train_getContainerResources(overrides, containerResources);
+
+        train_create(source, Runnable.class, true, containerResources, model);
+
+        expect(model.newInstance()).andThrow(exception);
+
+        train_getCompleteId(resources, "Foo.bar");
+
+        train_getLocation(resources, l);
+
+        expect(model.getBeanType()).andReturn(Runnable.class);
+
+        replay();
+
+        BeanEditor component = new BeanEditor();
+
+        component.inject(resources, overrides, source);
+
+        try
+        {
+            component.doPrepare();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertMessageContains(
+                    ex,
+                    "Exception instantiating instance of java.lang.Runnable (for component \'Foo.bar\'):");
+
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/FormTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/FormTest.java
new file mode 100644
index 0000000..5cb3d69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/FormTest.java
@@ -0,0 +1,62 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationTracker;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class FormTest extends TapestryTestCase
+{
+    @Test
+    public void record_error()
+    {
+        ValidationTracker tracker = mockValidationTracker();
+        String message = "A recorded message.";
+
+        tracker.recordError(message);
+
+        replay();
+
+        Form form = new Form();
+
+        form.setTracker(tracker);
+
+        form.recordError(message);
+
+        verify();
+    }
+
+    @Test
+    public void record_error_for_field()
+    {
+        ValidationTracker tracker = mockValidationTracker();
+        String message = "A recorded message.";
+        Field field = mockField();
+
+        tracker.recordError(field, message);
+
+        replay();
+
+        Form form = new Form();
+
+        form.setTracker(tracker);
+
+        form.recordError(field, message);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/IfTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/IfTest.java
new file mode 100644
index 0000000..88f0dd4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/IfTest.java
@@ -0,0 +1,61 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class IfTest extends InternalBaseTestCase
+{
+    @Test
+    public void true_test_renders_body()
+    {
+        If component = new If();
+
+        component.setup(true, false, null);
+
+        assertNull(component.beginRender());
+        assertTrue(component.beforeRenderBody());
+    }
+
+    @Test
+    public void false_test_renders_else_block()
+    {
+        Block block = mockBlock();
+
+        replay();
+
+        If component = new If();
+
+        component.setup(false, false, block);
+
+        assertSame(component.beginRender(), block);
+        assertFalse(component.beforeRenderBody());
+
+        verify();
+    }
+
+    @Test
+    public void negate_inverts_test()
+    {
+        If component = new If();
+
+        component.setup(false, true, null);
+
+        assertNull(component.beginRender());
+        assertTrue(component.beforeRenderBody());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/LoopTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/LoopTest.java
new file mode 100644
index 0000000..4ec6106
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/LoopTest.java
@@ -0,0 +1,89 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Heartbeat;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class LoopTest extends InternalBaseTestCase
+{
+    @Test
+    public void non_empty_iterator()
+    {
+        Heartbeat hb = mockHeartbeat();
+
+        // Really hard to test the exact timing of all this; it will have to
+        // be "proven" by integration tests.
+
+        hb.begin();
+        getMocksControl().times(3);
+
+        hb.end();
+        getMocksControl().times(3);
+
+        replay();
+
+        Loop loop = new Loop();
+
+        loop.setHeartbeat(hb);
+
+        loop.setSource(Arrays.asList("alpha", "beta", "gamma"));
+
+        assertTrue(loop.setup());
+        assertEquals(loop.getIndex(), 0);
+
+        loop.begin();
+        assertEquals(loop.getValue(), "alpha");
+        assertEquals(loop.getIndex(), 0);
+
+        assertFalse(loop.after());
+        loop.begin();
+        assertEquals(loop.getValue(), "beta");
+        assertEquals(loop.getIndex(), 1);
+
+        assertFalse(loop.after());
+        loop.begin();
+        assertEquals(loop.getValue(), "gamma");
+        assertEquals(loop.getIndex(), 2);
+
+        assertTrue(loop.after());
+
+        verify();
+    }
+
+    @Test
+    public void iterator_is_null()
+    {
+        Loop loop = new Loop();
+
+        loop.setSource(null);
+
+        assertFalse(loop.setup());
+    }
+
+    @Test
+    public void iterator_is_empty()
+    {
+        Loop loop = new Loop();
+
+        loop.setSource(Collections.EMPTY_LIST);
+
+        assertFalse(loop.setup());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputRawTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputRawTest.java
new file mode 100644
index 0000000..c05c6af
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputRawTest.java
@@ -0,0 +1,72 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class OutputRawTest extends TapestryTestCase
+{
+    @Test
+    public void value_is_null()
+    {
+        MarkupWriter writer = mockMarkupWriter();
+
+        replay();
+
+        OutputRaw component = new OutputRaw();
+
+        assertFalse(component.beginRender(writer));
+
+        verify();
+    }
+
+    @Test
+    public void value_is_empty_string()
+    {
+        MarkupWriter writer = mockMarkupWriter();
+
+        replay();
+
+        OutputRaw component = new OutputRaw();
+
+        component.setValue("");
+
+        assertFalse(component.beginRender(writer));
+
+        verify();
+    }
+
+    @Test
+    public void value_is_non_blank()
+    {
+        String value = "&nbsp;";
+
+        MarkupWriter writer = mockMarkupWriter();
+
+        writer.writeRaw(value);
+
+        replay();
+
+        OutputRaw component = new OutputRaw();
+
+        component.setValue(value);
+
+        assertFalse(component.beginRender(writer));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputTest.java
new file mode 100644
index 0000000..0e9e1a8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/OutputTest.java
@@ -0,0 +1,194 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+public class OutputTest extends TapestryTestCase
+{
+    private final Number value = 22.7d;
+
+    private final DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+
+    private final DecimalFormat filterFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+
+    @BeforeClass
+    public void setup()
+    {
+        format.applyPattern("0.00");
+        filterFormat.applyPattern("<0.00>");
+    }
+
+    @Test
+    public void simple_output()
+    {
+        MarkupWriter writer = createMarkupWriter();
+        ComponentResources resources = mockComponentResources();
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(value, format, true, null, resources);
+
+        writer.element("root");
+        assertFalse(component.beginRender(writer));
+        writer.end();
+
+        verify();
+
+        assertEquals(writer.toString(), "<root>22.70</root>");
+    }
+
+    @Test
+    public void simple_output_with_filter()
+    {
+        MarkupWriter writer = createMarkupWriter();
+        ComponentResources resources = mockComponentResources();
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(value, filterFormat, true, null, resources);
+
+        writer.element("root");
+        assertFalse(component.beginRender(writer));
+        writer.end();
+
+        verify();
+
+        assertEquals(writer.toString(), "<root>&lt;22.70&gt;</root>");
+    }
+
+    @Test
+    public void simple_output_with_filter_disabled()
+    {
+        MarkupWriter writer = createMarkupWriter();
+        ComponentResources resources = mockComponentResources();
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(value, filterFormat, false, null, resources);
+
+        writer.element("root");
+        assertFalse(component.beginRender(writer));
+        writer.end();
+
+        verify();
+
+        // It's not valid XML output, but that's why it's called programmer error :-)
+
+        assertEquals(writer.toString(), "<root><22.70></root>");
+    }
+
+    @Test
+    public void null_output()
+    {
+        MarkupWriter writer = createMarkupWriter();
+        ComponentResources resources = mockComponentResources();
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(null, format, true, null, resources);
+
+        writer.element("root");
+        assertFalse(component.beginRender(writer));
+        writer.end();
+
+        verify();
+
+        assertEquals(writer.toString(), "<root></root>");
+    }
+
+    @Test
+    public void output_with_element_and_informals()
+    {
+        String elementName = "span";
+
+        MarkupWriter writer = createMarkupWriter();
+
+        ComponentResources resources = mockComponentResources();
+
+        train_renderInformalParameters(resources, writer, "foo", "bar");
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(value, format, true, elementName, resources);
+
+        assertFalse(component.beginRender(writer));
+
+        verify();
+
+        assertEquals(writer.toString(), "<span foo=\"bar\">22.70</span>");
+    }
+
+    @Test
+    public void null_format_is_a_noop()
+    {
+        String elementName = "span";
+
+        MarkupWriter writer = createMarkupWriter();
+
+        ComponentResources resources = mockComponentResources();
+
+        Format format = new Format()
+        {
+            private static final long serialVersionUID = -4360045992642727894L;
+
+            @Override
+            public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
+            {
+                return toAppendTo;
+            }
+
+            @Override
+            public Object parseObject(String source, ParsePosition pos)
+            {
+                return null;
+            }
+        };
+
+        replay();
+
+        Output component = new Output();
+
+        component.setup(value, format, true, elementName, resources);
+
+        writer.element("root");
+        assertFalse(component.beginRender(writer));
+        writer.end();
+
+        verify();
+
+        assertEquals(writer.toString(), "<root></root>");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
new file mode 100644
index 0000000..54a7fcf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/PropertyEditorTest.java
@@ -0,0 +1,81 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * Tests an error case for the PropertyEditor component. The success cases are mixed into the
+ * BeanEditForm component's integration tests.
+ */
+public class PropertyEditorTest extends TapestryTestCase
+{
+    @Test
+    public void no_editor_block_available()
+    {
+        PropertyModel model = mockPropertyModel();
+        ComponentResources overrides = mockComponentResources();
+        ComponentResources resources = mockComponentResources();
+        BeanBlockSource source = newMock(BeanBlockSource.class);
+        RuntimeException exception = new RuntimeException("Simulated failure.");
+        Messages messages = mockMessages();
+        Location l = mockLocation();
+
+        String propertyId = "foo";
+        String dataType = "unk";
+        String propertyName = "fooProp";
+        Object object = "[OBJECT]";
+        String formattedMessage = "formatted-message";
+
+        expect(model.getId()).andReturn(propertyId);
+
+        expect(overrides.getBlockParameter(propertyId)).andReturn(null);
+
+        expect(model.getDataType()).andReturn(dataType);
+
+        expect(source.getEditBlock(dataType)).andThrow(exception);
+        expect(model.getPropertyName()).andReturn(propertyName);
+
+        train_getLocation(resources, l);
+
+        expect(messages.format("block-error", propertyName, dataType, object, exception))
+                .andReturn(formattedMessage);
+
+        replay();
+
+        PropertyEditor pe = new PropertyEditor();
+
+        pe.inject(resources, overrides, model, source, messages, object);
+
+        try
+        {
+            pe.beginRender();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(), formattedMessage);
+            assertSame(ex.getLocation(), l);
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java
new file mode 100644
index 0000000..74daead
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SelectTest.java
@@ -0,0 +1,382 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.corelib.data.BlankOption;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.OptionGroupModelImpl;
+import org.apache.tapestry.internal.OptionModelImpl;
+import org.apache.tapestry.internal.SelectModelImpl;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.internal.services.StringValueEncoder;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.testng.annotations.Test;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Mostly, this is about how the Select component renders its {@link SelectModel}. The real nuts and bolts are tested in
+ * the integration tests.
+ */
+public class SelectTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void empty_model()
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+
+        select.setModel(new SelectModelImpl(null, null));
+        select.setValidationTracker(tracker);
+
+        select.options(null);
+
+        verify();
+    }
+
+    private String read(String file) throws Exception
+    {
+        InputStream is = getClass().getResourceAsStream(file);
+        Reader reader = new InputStreamReader(new BufferedInputStream(is));
+
+        StringBuilder builder = new StringBuilder();
+        char[] buffer = new char[1000];
+
+        while (true)
+        {
+            int length = reader.read(buffer);
+
+            if (length < 0) break;
+
+            builder.append(buffer, 0, length);
+        }
+
+        reader.close();
+
+        return builder.toString();
+    }
+
+    @Test
+    public void just_options() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        List<OptionModel> options = TapestryInternalUtils
+                .toOptionModels("fred=Fred Flintstone,barney=Barney Rubble");
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("just_options.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void just_options_with_blank_label_enabled() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        List<OptionModel> options = TapestryInternalUtils
+                .toOptionModels("fred=Fred Flintstone,barney=Barney Rubble");
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+        select.setBlankOption(BlankOption.ALWAYS, "Make a selection");
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("blank_label.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void current_selection_from_validation_tracker() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        List<OptionModel> options = TapestryInternalUtils
+                .toOptionModels("fred=Fred Flintstone,barney=Barney Rubble");
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, "fred");
+
+        replay();
+
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        // fred will be selected, not barney, because the validation tracker
+        // takes precendence.
+
+        assertEquals(writer.toString(), read("current_selection_from_validation_tracker.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void option_attributes() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        // Extra cast needed for Sun compiler, not Eclipse compiler.
+
+        List<OptionModel> options = Arrays.asList(
+                (OptionModel) new OptionModelImpl("Fred", "fred")
+                {
+                    @Override
+                    public Map<String, String> getAttributes()
+                    {
+                        return Collections.singletonMap("class", "pixie");
+                    }
+                });
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("option_attributes.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void disabled_option() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        // Extra cast needed for Sun compiler, not Eclipse compiler.
+
+        List<OptionModel> options = Arrays.asList(
+                (OptionModel) new OptionModelImpl("Fred", "fred")
+                {
+                    @Override
+                    public boolean isDisabled()
+                    {
+                        return true;
+                    }
+
+                    @Override
+                    public Map<String, String> getAttributes()
+                    {
+                        return Collections.singletonMap("class", "pixie");
+                    }
+                });
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+        select.setModel(new SelectModelImpl(null, options));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("barney");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("disabled_option.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void option_groups() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        OptionGroupModel husbands = new OptionGroupModelImpl("Husbands", false,
+                                                             TapestryInternalUtils.toOptionModels("Fred,Barney"));
+        OptionGroupModel wives = new OptionGroupModelImpl("Wives", true, TapestryInternalUtils
+                .toOptionModels("Wilma,Betty"));
+        List<OptionGroupModel> groupModels = CollectionFactory.newList(husbands, wives);
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+        select.setModel(new SelectModelImpl(groupModels, null));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("Fred");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("option_groups.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void option_groups_precede_ungroup_options() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        OptionGroupModel husbands = new OptionGroupModelImpl("Husbands", false,
+                                                             TapestryInternalUtils.toOptionModels("Fred,Barney"));
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+        select.setModel(new SelectModelImpl(Collections.singletonList(husbands),
+                                            TapestryInternalUtils.toOptionModels("Wilma,Betty")));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("Fred");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("option_groups_precede_ungroup_options.txt"));
+
+        verify();
+    }
+
+    @Test
+    public void option_group_attributes() throws Exception
+    {
+        ValidationTracker tracker = mockValidationTracker();
+
+        Map<String, String> attributes = Collections.singletonMap("class", "pixie");
+
+        OptionGroupModel husbands = new OptionGroupModelImpl("Husbands", false,
+                                                             TapestryInternalUtils.toOptionModels("Fred,Barney"),
+                                                             attributes);
+
+        Select select = new Select();
+
+        train_getInput(tracker, select, null);
+
+        replay();
+
+        select.setModel(new SelectModelImpl(Collections.singletonList(husbands), null));
+        select.setValueEncoder(new StringValueEncoder());
+        select.setValue("Fred");
+        select.setValidationTracker(tracker);
+
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        writer.element("select");
+
+        select.options(writer);
+
+        writer.end();
+
+        assertEquals(writer.toString(), read("option_group_attributes.txt"));
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SubmitTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SubmitTest.java
new file mode 100644
index 0000000..faa6bb4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/SubmitTest.java
@@ -0,0 +1,109 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.corelib.internal.FormSupportImpl;
+import org.apache.tapestry.internal.services.HeartbeatImpl;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Heartbeat;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.Test;
+
+public class SubmitTest extends InternalBaseTestCase
+{
+    @Test
+    public void not_trigger_of_submission()
+    {
+        Request request = mockRequest();
+
+        String elementName = "myname";
+
+        train_getParameter(request, elementName, null);
+
+        replay();
+
+        Submit submit = new Submit(request);
+
+        submit.processSubmission(elementName);
+
+        verify();
+    }
+
+    @Test
+    public void trigger_deferred()
+    {
+        Request request = mockRequest();
+        ComponentResources resources = mockComponentResources();
+        FormSupportImpl support = new FormSupportImpl();
+
+        String elementName = "myname";
+
+        train_getParameter(request, elementName, "login");
+
+        replay();
+
+        Submit submit = new Submit(request);
+
+        submit.setup(resources, support, null);
+
+        submit.processSubmission(elementName);
+
+        verify();
+
+        expect(resources.triggerEvent(Submit.SELECTED_EVENT, null, null)).andReturn(false);
+
+        replay();
+
+        support.executeDeferred();
+
+        verify();
+    }
+
+    @Test
+    public void trigger_immediate()
+    {
+        FormSupport support = mockFormSupport();
+        ComponentResources resources = mockComponentResources();
+        Heartbeat heartbeat = new HeartbeatImpl();
+        Request request = mockRequest();
+
+        String elementName = "myname";
+
+        train_getParameter(request, elementName, "login");
+
+        replay();
+
+        heartbeat.begin();
+
+        Submit submit = new Submit(request);
+
+        submit.setup(resources, support, heartbeat);
+        submit.setDefer(false);
+
+        submit.processSubmission(elementName);
+
+        verify();
+
+        expect(resources.triggerEvent(Submit.SELECTED_EVENT, null, null)).andReturn(false);
+
+        replay();
+
+        heartbeat.end();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/TextOutputTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/TextOutputTest.java
new file mode 100644
index 0000000..28920dd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/TextOutputTest.java
@@ -0,0 +1,55 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class TextOutputTest extends InternalBaseTestCase
+{
+    @Test
+    public void null_value_is_noop()
+    {
+        MarkupWriter writer = mockMarkupWriter();
+
+        replay();
+
+        TextOutput component = new TextOutput();
+
+        component.beginRender(writer);
+
+        verify();
+    }
+
+    @Test
+    public void normal_output()
+    {
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+
+        TextOutput component = new TextOutput();
+
+        component.injectValue("Fred\nBarney\rWilma\r\nBetty\nBam-Bam\n");
+
+        writer.element("div");
+        component.beginRender(writer);
+        writer.end();
+
+        assertEquals(writer.toString(),
+                     "<?xml version=\"1.0\"?>\n" + "<div><p>Fred</p><p>Barney</p><p>Wilma</p><p>Betty</p><p>Bam-Bam</p></div>");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/UnlessTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/UnlessTest.java
new file mode 100644
index 0000000..e7f490b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/components/UnlessTest.java
@@ -0,0 +1,50 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.testng.annotations.Test;
+import org.apache.tapestry.Block;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+
+public class UnlessTest extends InternalBaseTestCase
+{
+    @Test
+    public void false_test_renders_body()
+    {
+        Unless component = new Unless();
+
+        component.setup(false, null);
+
+        assertNull(component.beginRender());
+        assertTrue(component.beforeRenderBody());
+    }
+
+    @Test
+    public void true_test_renders_else_block()
+    {
+        Block block = mockBlock();
+
+        replay();
+
+        Unless component = new Unless();
+
+        component.setup(true, block);
+
+        assertSame(component.beginRender(), block);
+        assertFalse(component.beforeRenderBody());
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/internal/FormSupportImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/internal/FormSupportImplTest.java
new file mode 100644
index 0000000..0ad9a7c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/corelib/internal/FormSupportImplTest.java
@@ -0,0 +1,167 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.internal;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class FormSupportImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void execute_deferred_with_no_commands()
+    {
+        FormSupportImpl support = new FormSupportImpl();
+
+        support.executeDeferred();
+    }
+
+    @Test
+    public void execute_deferred_execute_in_added_order()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        getMocksControl().checkOrder(true);
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        FormSupportImpl support = new FormSupportImpl();
+
+        support.defer(r1);
+        support.defer(r2);
+
+        support.executeDeferred();
+
+        verify();
+    }
+
+    @Test
+    public void deferred_commands_execute_once()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+        Runnable r3 = mockRunnable();
+
+        getMocksControl().checkOrder(true);
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        FormSupportImpl support = new FormSupportImpl();
+
+        support.defer(r1);
+        support.defer(r2);
+
+        support.executeDeferred();
+
+        verify();
+
+        r3.run();
+
+        replay();
+
+        support.defer(r3);
+
+        support.executeDeferred();
+
+        verify();
+    }
+
+    @Test
+    public void set_encoding_type()
+    {
+        FormSupportImpl support = new FormSupportImpl();
+
+        String encodingType = "foo/bar";
+
+        support.setEncodingType(encodingType);
+
+        assertSame(support.getEncodingType(), encodingType);
+    }
+
+    @Test
+    public void set_encoding_type_to_same_value_is_allowed()
+    {
+        FormSupportImpl support = new FormSupportImpl();
+
+        String encodingType = "foo/bar";
+
+        support.setEncodingType(encodingType);
+        support.setEncodingType(new String(encodingType));
+
+        assertEquals(support.getEncodingType(), encodingType);
+    }
+
+    @Test
+    public void set_encoding_type_conflict()
+    {
+
+        FormSupportImpl support = new FormSupportImpl();
+
+        support.setEncodingType("foo");
+        try
+        {
+            support.setEncodingType("bar");
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Encoding type of form has already been set to \'foo\' and may not be changed to \'bar\'.");
+        }
+
+    }
+
+    @Test
+    public void add_validations()
+    {
+        Field barney = mockField();
+        ClientBehaviorSupport clientBehaviorSupport = mockClientBehaviorSupport();
+
+        clientBehaviorSupport.addValidation(barney, "required", "Who can live without Barney?", null);
+
+        replay();
+
+        FormSupportImpl support = new FormSupportImpl(null, null, clientBehaviorSupport, true);
+
+        support.addValidation(barney, "required", "Who can live without Barney?", null);
+
+        verify();
+    }
+
+    @Test
+    public void add_validation_when_client_validation_is_disabled()
+    {
+        Field barney = mockField();
+        ClientBehaviorSupport clientBehaviorSupport = mockClientBehaviorSupport();
+
+        replay();
+
+        FormSupportImpl support = new FormSupportImpl(null, null, clientBehaviorSupport, false);
+
+        support.addValidation(barney, "required", "Who can live without Barney?", null);
+
+        verify();
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java
new file mode 100644
index 0000000..e81fedc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java
@@ -0,0 +1,468 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.dom;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for a number of DOM node classes, including {@link org.apache.tapestry.dom.Element} and
+ * {@link org.apache.tapestry.dom.Document}.
+ */
+public class DOMTest extends InternalBaseTestCase
+{
+    @Test
+    public void document_with_empty_root_element()
+    {
+        Document d = new Document();
+
+        d.newRootElement("empty");
+
+        assertEquals(d.toString(), "<empty></empty>");
+    }
+
+    @Test
+    public void xml_style_empty_element()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        d.newRootElement("empty");
+
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<empty/>");
+    }
+
+    @Test
+    public void namespaced_elements() throws Exception
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("fredns", "root");
+
+        root.defineNamespace("fredns", "f");
+        root.defineNamespace("barneyns", "b");
+
+        Element nested = root.elementNS("fredns", "nested");
+
+        Element deepest = nested.elementNS("barneyns", "deepest");
+
+        assertEquals(d.toString(), readFile("namespaced_elements.txt"));
+    }
+
+    @Test
+    public void namespace_element_without_a_prefix()
+    {
+
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("fredns", "root");
+
+        try
+        {
+            d.toString();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Namespace prefix for URI 'fredns' is not defined.");
+        }
+    }
+
+    @Test
+    public void default_namespace()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        String namespaceURI = "http://foo.com";
+
+        Element root = d.newRootElement(namespaceURI, "root");
+
+        root.defineNamespace(namespaceURI, "");
+        root.attribute(namespaceURI, "gnip", "gnop");
+
+
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<root gnip=\"gnop\" xmlns=\"http://foo.com\"/>");
+    }
+
+    /**
+     * Also demonstrates that attributes are provided in alphabetical order.
+     */
+    @Test
+    public void document_with_root_element_and_attributes() throws Exception
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("has-attributes");
+
+        e.attribute("fred", "flintstone");
+        e.attribute("barney", "rubble");
+
+        assertEquals(d.toString(), readFile("document_with_root_element_and_attributes.txt"));
+    }
+
+    @Test
+    public void nested_elements() throws Exception
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("population");
+
+        Element p = e.element("person");
+        p.attribute("first-name", "Fred");
+        p.attribute("last-name", "Flintstone");
+
+        assertSame(p.getParent(), e);
+
+        p = e.element("person");
+        p.attribute("first-name", "Barney");
+        p.attribute("last-name", "Rubble");
+
+        assertSame(p.getParent(), e);
+
+        assertEquals(d.toString(), readFile("nested_elements.txt"));
+    }
+
+    @Test
+    public void to_string_on_empty_document()
+    {
+        Document d = new Document();
+
+        assertEquals(d.toString(), "[empty Document]");
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void attribute_names_may_not_be_blank()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("fred");
+
+        e.attribute("", "value");
+    }
+
+    @Test
+    public void element_name_may_not_be_blank()
+    {
+        Document d = new Document();
+
+        d.newRootElement("");
+    }
+
+    @Test
+    public void attribute_value_null_is_no_op()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("root");
+
+        e.attribute("foo", "bar");
+
+        final String expected = "<root foo=\"bar\"></root>";
+
+        assertEquals(d.toString(), expected);
+
+        e.attribute("foo", null);
+
+        assertEquals(d.toString(), expected);
+
+        e.attribute("gnip", null);
+
+        assertEquals(d.toString(), expected);
+    }
+
+    @Test
+    public void comments() throws Exception
+    {
+        Document d = new Document();
+
+        // Can't add comments to the document, not yet.
+
+        Element e = d.newRootElement("html");
+
+        e.comment("Created by Tapestry 5.0");
+
+        assertEquals(d.toString(), "<html><!-- Created by Tapestry 5.0 --></html>");
+    }
+
+    @Test
+    public void text()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("body");
+
+        e.text("Tapestry does DOM.");
+
+        assertEquals(d.toString(), "<body>Tapestry does DOM.</body>");
+    }
+
+    @Test
+    public void text_with_control_characters()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("root");
+
+        e.text("<this> & <that>");
+
+        assertEquals(d.toString(), "<root>&lt;this&gt; &amp; &lt;that&gt;</root>");
+    }
+
+    @Test
+    public void specify_attributes_with_new_element()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("root");
+
+        e.element("foo", "alpha", "legion");
+
+        assertEquals(d.toString(), "<root><foo alpha=\"legion\"></foo></root>");
+    }
+
+    @Test
+    public void writef_with_text()
+    {
+        Document d = new Document();
+
+        Element e = d.newRootElement("root");
+
+        Text t = e.text("Start: ");
+
+        t.writef("** %s: %d **", "foo", 5);
+
+        assertEquals(d.toString(), "<root>Start: ** foo: 5 **</root>");
+    }
+
+    @Test
+    public void get_element_by_id()
+    {
+        Document d = new Document();
+        Element e = d.newRootElement("root");
+        Element e1 = e.element("e1", "id", "x");
+        Element e2 = e.element("e2", "id", "y");
+        assertSame(e1.getElementById("x"), e1);
+        assertSame(e.getElementById("y"), e2);
+        assertNull(e.getElementById("z"));
+    }
+
+    @Test
+    public void get_child_markup()
+    {
+        Document d = new Document();
+        Element e0 = d.newRootElement("root");
+        Element e1 = e0.element("e1");
+        e1.text("123");
+        assertEquals(e1.getChildMarkup(), "123");
+        assertEquals(e0.getChildMarkup(), "<e1>123</e1>");
+    }
+
+    @Test
+    public void document_find_no_root_element()
+    {
+        Document d = new Document();
+
+        assertNull(d.find("does/not/matter"));
+    }
+
+    @Test
+    public void document_find_not_a_match()
+    {
+        Document d = new Document();
+
+        d.newRootElement("fred");
+
+        assertNull(d.find("barney"));
+        assertNull(d.find("wilma/betty"));
+    }
+
+    @Test
+    public void document_find_root_is_match()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("fred");
+
+        assertSame(d.find("fred"), root);
+    }
+
+    @Test
+    public void document_find_match()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("fred");
+
+        root.text("text");
+        Element barney = root.element("barney");
+        Element bambam = barney.element("bambam");
+
+        assertSame(d.find("fred/barney/bambam"), bambam);
+        assertSame(root.find("barney/bambam"), bambam);
+    }
+
+    @Test
+    public void document_find_no_match()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("fred");
+
+        root.text("text");
+        Element barney = root.element("barney");
+        barney.element("bambam");
+
+        assertNull(d.find("fred/barney/pebbles"));
+        assertNull(root.find("barney/pebbles"));
+    }
+
+    @Test
+    public void insert_element_at()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("fred");
+
+        root.element("start");
+        root.element("end");
+
+        root.elementAt(1, "one").element("tiny");
+        root.elementAt(2, "two").element("bubbles");
+
+        assertEquals(d.toString(),
+                     "<?xml version=\"1.0\"?>\n<fred><start/><one><tiny/></one><two><bubbles/></two><end/></fred>");
+    }
+
+    @Test
+    public void force_attributes_overrides_existing()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("fred");
+
+        root.attributes("hi", "ho", "gnip", "gnop");
+
+        assertEquals(root.toString(), "<fred gnip=\"gnop\" hi=\"ho\"/>");
+
+        root.forceAttributes("hi", "bit", "gnip", null);
+
+        assertEquals(root.toString(), "<fred hi=\"bit\"/>");
+    }
+
+    @Test
+    public void raw_output()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("fred");
+
+        Element em = root.element("em");
+
+        em.text("<");
+        em.raw("&nbsp;");
+        em.text(">");
+
+        // The '<' and '>' are filtered into entities, but the '&' in &nbsp; is left alone (left
+        // raw).
+
+        assertEquals(root.toString(), "<fred><em>&lt;&nbsp;&gt;</em></fred>");
+    }
+
+    @Test
+    public void dtd_with_markup()
+    {
+        Document d = new Document(new XMLMarkupModel());
+        Element root = d.newRootElement("prime");
+        root.element("slag");
+        d.dtd("prime", "-//TF", "tf");
+        String expected = "<?xml version=\"1.0\"?>\n<!DOCTYPE prime PUBLIC \"-//TF\" \"tf\"><prime><slag/></prime>";
+        assertEquals(d.toString(), expected);
+    }
+
+    @Test
+    public void dtd_with_nullids()
+    {
+        Document d = new Document(new XMLMarkupModel());
+        d.newRootElement("prime");
+        d.dtd("prime", null, null);
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<prime/>");
+        d.dtd("prime", "-//TF", null);
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<!DOCTYPE prime PUBLIC \"-//TF\"><prime/>");
+
+        d.dtd("prime", null, "tf");
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<!DOCTYPE prime SYSTEM \"tf\"><prime/>");
+    }
+
+    @Test
+    public void markup_characters_inside_attributes_are_escaped()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("prime");
+
+        root.attribute("alpha-only", "abcdef");
+        root.attribute("entities", "\"<>&");
+
+        assertEquals(root.toString(), "<prime alpha-only=\"abcdef\" entities=\"&quot;&lt;&gt;&amp;\"/>");
+    }
+
+    @Test
+    public void add_class_names()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        Element root = d.newRootElement("div");
+
+        assertSame(root.addClassName("fred"), root);
+
+        assertEquals(root.toString(), "<div class=\"fred\"/>");
+
+        assertSame(root.addClassName("barney", "wilma"), root);
+
+        assertEquals(root.toString(), "<div class=\"fred barney wilma\"/>");
+    }
+
+    @Test
+    public void cdata_in_HTML_document()
+    {
+        Document d = new Document();
+
+        d.newRootElement("root").cdata("This & That");
+
+        // The '&' is expanded to an entity:
+
+        assertEquals(d.toString(), "<root>This &amp; That</root>");
+    }
+
+    @Test
+    public void cdata_in_XML_document()
+    {
+        Document d = new Document(new XMLMarkupModel());
+
+        d.newRootElement("root").cdata("This & That");
+
+        // The '&' is expanded to an entity:
+
+        assertEquals(d.toString(), "<?xml version=\"1.0\"?>\n<root><![CDATA[This & That]]></root>");
+    }
+
+    @Test
+    public void encoding_specified()
+    {
+        Document d = new Document(new XMLMarkupModel(), "utf-8");
+        d.newRootElement("root");
+
+        assertEquals(d.toString(), "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root/>");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/AdditionalIntegrationTests.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/AdditionalIntegrationTests.java
new file mode 100644
index 0000000..7b9bfbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/AdditionalIntegrationTests.java
@@ -0,0 +1,68 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration;
+
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Additional integration tests that do not fit with the main group due to the need for special configuration.
+ */
+@Test(timeOut = 50000, sequential = true, groups = { "integration" })
+public class AdditionalIntegrationTests extends AbstractIntegrationTestSuite
+{
+
+    public AdditionalIntegrationTests()
+    {
+        super("src/test/app3");
+    }
+
+
+    /**
+     * Test to prove that a redirect from the start page works correctly.
+     *
+     * @see https://issues.apache.org/jira/browse/TAPESTRY-1627
+     */
+    @Test
+    public void redirect_for_root() throws Exception
+    {
+        open(BASE_URL);
+
+        assertText("//h1", "Login Page");
+    }
+
+    @Test
+    public void bean_block_overrides()
+    {
+        start("BeanDisplay Override Demo");
+
+        assertText("//div[@class='t-beandisplay-value no']", "Nay");
+        assertText("//div[@class='t-beandisplay-value yes']", "Yea");
+    }
+
+    /**
+     * TAPESTRY-2226
+     */
+    @Test
+    public void activation_context_for_root_index_page()
+    {
+        open(BASE_URL + "it worked");
+
+        assertText("//h1", "Index");
+
+        assertText("message", "it worked");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/ImmediateModeTests.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/ImmediateModeTests.java
new file mode 100644
index 0000000..7cb1544
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/ImmediateModeTests.java
@@ -0,0 +1,76 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration;
+
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for immediate mode (aka T4 mode, aka {@linkplain org.apache.tapestry.SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS
+ * redirects suppressed} mode).
+ */
+@Test(timeOut = 50000, sequential = true, groups = { "integration" })
+public class ImmediateModeTests extends AbstractIntegrationTestSuite
+{
+    public ImmediateModeTests()
+    {
+        super("src/test/app4");
+    }
+
+    @Test
+    public void action_link()
+    {
+        start("here");
+
+        assertTextSeries("//dd[%d]", 1, "onActivate() invoked", "automatic value");
+
+        clickAndWait("link=refresh page");
+
+        assertTextSeries("//dd[%d]", 1, "onActivate(String) invoked - onActivate() invoked", "automatic value");
+
+        clickAndWait("link=refresh via action");
+
+        // The last onActivate() is due to the "default" rendering of the page for the action link (on the same page).
+
+        assertTextSeries("//dd[%d]", 1, "onActivate(String) invoked - onActivate() invoked - onActivate() invoked",
+                         "automatic value");
+    }
+
+    @Test
+    public void form_submission()
+    {
+        open(BASE_URL);
+
+        type("input", "immediate mode");
+
+        clickAndWait(SUBMIT);
+
+        assertTextSeries("//dd[%d]", 1, "onActivate() invoked", "immediate mode");
+
+        clickAndWait("link=refresh page");
+
+        assertTextSeries("//dd[%d]", 1, "onActivate(String) invoked - onActivate() invoked", "immediate mode");
+
+        clickAndWait("link=refresh via action");
+
+        // The last onActivate() is due to the "default" rendering of the page for the action link (on the same page).
+
+        assertTextSeries("//dd[%d]", 1, "onActivate(String) invoked - onActivate() invoked - onActivate() invoked",
+                         "immediate mode");
+
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
new file mode 100644
index 0000000..1676594
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
@@ -0,0 +1,2032 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration;
+
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.integration.app1.pages.RenderErrorDemo;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Note: If these tests fail with BindException when starting Jetty, it could be Skype. At least on my system, Skype is
+ * listening on localhost:80.
+ */
+@Test(timeOut = 50000, sequential = true, groups = { "integration" })
+public class IntegrationTests extends AbstractIntegrationTestSuite
+{
+    public IntegrationTests()
+    {
+        super("src/test/app1");
+    }
+
+    @Test
+    public void assets() throws Exception
+    {
+        start("AssetDemo");
+
+        // Test for https://issues.apache.org/jira/browse/TAPESTRY-1935
+
+        assertSourcePresent("<link href=\"/css/app.css\" rel=\"stylesheet\" type=\"text/css\">");
+
+        assertAttribute("//img[@id='icon']/@src", "/images/tapestry_banner.gif");
+
+        // doesn't prove that the image shows up in the client browser (it does, but
+        // it could just as easily be a broken image). Haven't figured out how Selenium
+        // allows to be verified. Note that the path below represents some aliasing
+        // of the raw classpath resource path.
+
+        assertAttribute("//img[@id='button']/@src", "/assets/app1/pages/nested/tapestry-button.png");
+
+        // Read the byte stream for the asset and compare to the real copy.
+
+        URL url = new URL("http", "localhost", JETTY_PORT, "/assets/app1/pages/nested/tapestry-button.png");
+
+        byte[] downloaded = readContent(url);
+
+        Resource classpathResource = new ClasspathResource(
+                "org/apache/tapestry/integration/app1/pages/nested/tapestry-button.png");
+
+        byte[] actual = readContent(classpathResource.toURL());
+
+        assertEquals(downloaded, actual);
+    }
+
+    /**
+     * Tests the ability to inject a Block, and the ability to use the block to control rendering.
+     */
+    @Test
+    public void block_rendering() throws Exception
+    {
+        start("BlockDemo");
+
+        assertTextPresent("[]");
+
+        select("//select[@id='blockName']", "fred");
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+        assertTextPresent("[Block fred.]");
+
+        select("//select[@id='blockName']", "barney");
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+        assertTextPresent("[Block barney.]");
+
+        // TAPESETRY-1583
+
+        assertTextPresent("before it is defined: [Block wilma].");
+    }
+
+    @Test
+    public void component_parameter_default_from_method() throws Exception
+    {
+        start("ParameterDefault");
+
+        assertTextPresent("Echo component default: [ParameterDefault:echo]");
+    }
+
+    @Test
+    public void embedded_components()
+    {
+        start("Countdown Page");
+
+        assertTextPresent("regexp:\\s+5\\s+4\\s+3\\s+2\\s+1\\s+");
+
+        assertTextPresent("Brought to you by the org.apache.tapestry.integration.app1.components.Count");
+    }
+
+    @Test
+    public void encoded_loop_inside_a_form()
+    {
+        test_loop_inside_form("ToDo List");
+    }
+
+    @Test
+    public void environmental()
+    {
+        start("Environmental Annotation Usage");
+
+        assertSourcePresent("[<strong>A message provided by the RenderableProvider component.</strong>]");
+    }
+
+    @Test
+    public void exception_report()
+    {
+        start("BadTemplate Page");
+
+        assertTextPresent("org.apache.tapestry.ioc.internal.util.TapestryException",
+                          "Failure parsing template classpath:org/apache/tapestry/integration/app1/pages/BadTemplate.tml, line 7, column 15",
+                          "<t:foobar>content from template</t:foobar>",
+                          "Element <t:foobar> is in the Tapestry namespace, but is not a recognized Tapestry template element.");
+    }
+
+    @Test
+    public void expansion()
+    {
+        start("Expansion Page");
+
+        assertTextPresent("[value provided by a template expansion]");
+    }
+
+    /**
+     * {@link org.apache.tapestry.internal.transform.InjectContainerWorker} is largely tested by the forms tests ({@link
+     * RenderDisabled} is built on it). test is for the failure case, where a mixin class is used with the wrong type of
+     * component.
+     */
+    @Test
+    public void inject_container_failure() throws Exception
+    {
+        start("InjectContainerMismatch");
+
+        // And exception message:
+
+        assertTextPresent(
+                "Component InjectContainerMismatch is not assignable to field org.apache.tapestry.corelib.mixins.RenderDisabled.field (of type org.apache.tapestry.Field).");
+    }
+
+    @Test
+    public void inject_component_failure() throws Exception
+    {
+        start("InjectComponentMismatch");
+
+        assertTextPresent(
+                "Unable to inject component 'form' into field form of component InjectComponentMismatch. Class org.apache.tapestry.corelib.components.BeanEditForm is not assignable to a field of type org.apache.tapestry.corelib.components.Form.",
+                "ClassCastException");
+    }
+
+    @Test
+    public void injection() throws Exception
+    {
+        start("Inject Demo");
+
+        // is a test for a named @Inject:
+        assertTextPresent("<Proxy for Request(org.apache.tapestry.services.Request)>");
+
+        // is a test for an anonymous @Inject and ComponentResourcesInjectionProvider
+        assertTextPresent("ComponentResources[InjectDemo]");
+
+        // Another test, DefaultInjectionProvider
+        assertTextPresent("<Proxy for BindingSource(org.apache.tapestry.services.BindingSource)>");
+
+        // Prove that injection using a marker annotation (to match against a marked service) works.
+
+        assertTextPresent("Injection via Marker: Bonjour!");
+    }
+
+    @Test
+    public void instance_mixin()
+    {
+        start("InstanceMixin");
+
+        final String[] dates = { "Jun 13, 1999", "Jul 15, 2001", "Dec 4, 2005" };
+
+        for (String date : dates)
+        {
+            String snippet = String.format("[%s]", date);
+
+            assertSourcePresent(snippet);
+        }
+
+        clickAndWait("link=Toggle emphasis");
+
+        for (String date : dates)
+        {
+            String snippet = String.format("[<em>%s</em>]", date);
+            assertSourcePresent(snippet);
+        }
+    }
+
+    @Test
+    public void localization()
+    {
+        start("Localization");
+
+        assertTextPresent("Via injected Messages property: [Accessed via injected Messages]");
+        assertTextPresent("Via message: binding prefix: [Accessed via message: binding prefix]");
+        assertTextPresent("From Application Message Catalog: [Application Catalog Working]");
+        assertTextPresent("Page locale: [en]");
+        clickAndWait("link=French");
+        assertTextPresent("Page locale: [fr]");
+        clickAndWait("link=English");
+        assertTextPresent("Page locale: [en]");
+    }
+
+    @Test
+    public void page_injection() throws Exception
+    {
+        start("Inject Demo");
+
+        clickAndWait("link=Fred");
+
+        assertTextPresent("You clicked Fred.");
+
+        clickAndWait("link=Back");
+        clickAndWait("link=Barney");
+
+        assertTextPresent("You clicked Barney.");
+
+        clickAndWait("link=Back");
+        clickAndWait("link=Wilma");
+        assertTextPresent("You clicked Wilma.");
+    }
+
+    @Test
+    public void passivate_activate() throws Exception
+    {
+        start("NumberSelect");
+
+        clickAndWait("link=5");
+
+        assertTextPresent("You chose 5.");
+    }
+
+    @Test
+    public void password_field()
+    {
+        start("PasswordFieldDemo");
+
+        type("userName", "howard");
+        type("password", "wrong-password");
+
+        clickAndWait(SUBMIT);
+
+        assertFieldValue("userName", "howard");
+        // Verify that password fields do not render a non-blank password, even when it is known.
+        assertFieldValue("password", "");
+
+        assertTextPresent("[howard]");
+        assertTextPresent("[wrong-password]");
+
+        type("password", "tapestry");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("You have provided the correct user name and password.");
+    }
+
+    @Test
+    public void render_phase_method_returns_a_component() throws Exception
+    {
+        start("RenderComponentDemo");
+
+        assertText("//span[@id='container']", "[]");
+
+        // Sneak in a little test for If and parameter else:
+
+        assertTextPresent("Should be blank:");
+
+        clickAndWait("enabled");
+
+        // After clicking the link (which submits the form), the page re-renders and shows us
+        // the optional component from inside the NeverRender, resurrected to render on the page
+        // after all.
+
+        assertText("//span[@id='container']/span", "Optional Text");
+
+        assertTextPresent("Should now show up:");
+    }
+
+    @Test
+    public void render_phase_order()
+    {
+        start("RenderPhaseOrder");
+
+
+        assertTextPresent(
+                "[BEGIN-TRACER-MIXIN BEGIN-ABSTRACT-TRACER BEGIN-TRACER BODY AFTER-TRACER AFTER-ABSTRACT-TRACER AFTER-TRACER-MIXIN]");
+    }
+
+    @Test
+    public void server_side_validation_for_textfield_and_textarea() throws Exception
+    {
+        start("ValidForm");
+
+        clickAndWait(SUBMIT);
+        assertTextPresent("You must provide a value for Email.");
+        // is an overridden validation error message:
+        assertTextPresent("Please provide a detailed description of the incident.");
+
+        // Check on decorations via the default validation decorator:
+
+        assertAttribute("//label[1]/@class", "t-error");
+        assertAttribute("//label[2]/@class", "t-error");
+        assertAttribute("//input[@id='email']/@class", "t-error");
+        assertAttribute("//textarea[@id='message']/@class", "t-error");
+
+        type("email", "foo@bar.baz");
+        type("message", "Show me the money!");
+        type("hours", "foo");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("[false]");
+        assertTextPresent("The input value 'foo' is not parseable as an integer value.");
+
+        assertAttribute("//input[@id='hours']/@value", "foo");
+
+        type("hours", " 19 ");
+        click("//input[@id='urgent']");
+        clickAndWait(SUBMIT);
+
+        // Make sure the decoration went away.
+
+        // Sorry, not sure how to do that, since the attributes don't exist, we get xpath errors.
+
+        // assertText("//label[1]/@class", "");
+        // assertText("//label[2]/@class", "");
+        // assertText("//input[@id='email']/@class", "");
+        // assertText("//textarea[@id='message']/@class", "");
+
+        assertTextPresent("[foo@bar.baz]");
+        assertTextPresent("[Show me the money!]");
+        assertTextPresent("[true]");
+        assertTextPresent("[19]");
+    }
+
+    @Test
+    public void simple_component_event()
+    {
+        final String YOU_CHOSE = "You chose: ";
+
+        start("Action Page");
+
+        assertFalse(isTextPresent(YOU_CHOSE));
+
+        for (int i = 2; i < 5; i++)
+        {
+            clickAndWait("link=" + i);
+
+            assertTextPresent(YOU_CHOSE + i);
+        }
+    }
+
+    /**
+     * Tests for forms and form submissions and basic form control components. also tests a few other things, such as
+     * computed default bindings and invisible instrumentation.
+     */
+    @Test
+    public void simple_form()
+    {
+        start("SimpleForm");
+
+        assertText("//label[@id='disabled:label']", "Disabled");
+
+        // This demonstrates TAPESTRY-1642:
+        assertText("//label[@id='email:label']", "User Email");
+
+        assertText("//label[@id='message:label']", "Incident Message");
+        assertText("//label[@id='operatingSystem:label']", "Operating System");
+        assertText("//label[@id='department:label']", "Department");
+        assertText("//label[@id='urgent:label']", "Urgent Processing Requested");
+
+        assertFieldValue("email", "");
+        assertFieldValue("message", "");
+        assertFieldValue("operatingSystem", "osx");
+        assertFieldValue("department", "");
+        assertFieldValue("urgent", "on");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("department: []");
+
+        type("email", "foo@bar.baz");
+        type("message", "Message for you, sir!");
+        select("operatingSystem", "Windows NT");
+        select("department", "R&D");
+        click("urgent");
+
+        clickAndWait(SUBMIT);
+
+        assertFieldValue("email", "foo@bar.baz");
+        assertFieldValue("message", "Message for you, sir!");
+        assertFieldValue("urgent", "off");
+
+        // Tried to use "email:" and "exact:email:" but Selenium 0.8.1 doesn't seem to accept that.
+
+        assertTextPresent("[foo@bar.baz]", "[Message for you, sir!]", "[false]", "[winnt]", "[RESEARCH_AND_DESIGN]");
+
+        // Haven't figured out how to get selenium to check that fields are disabled.
+    }
+
+    @Test
+    public void subclass_inherits_parent_template()
+    {
+        start("ExpansionSubclass");
+
+        assertTextPresent("[value provided, in the subclass, via a template expansion]");
+    }
+
+    @Test
+    public void template_overridden()
+    {
+        start("Template Overridden by Class Page");
+
+        assertTextPresent("Output: ClassValue");
+    }
+
+    @Test
+    public void volatile_loop_inside_a_form()
+    {
+        test_loop_inside_form("ToDo List (Volatile)");
+    }
+
+    /**
+     * also verifies the use of meta data to set the default strategy.
+     */
+    @Test
+    public void flash_persistence()
+    {
+        start("FlashDemo");
+
+        assertTextPresent("[]");
+
+        clickAndWait("link=show the message");
+
+        assertTextPresent("[You clicked the link!]");
+
+        clickAndWait("link=refresh the page");
+
+        assertTextPresent("[]");
+    }
+
+    private byte[] readContent(URL url) throws Exception
+    {
+        InputStream is = new BufferedInputStream(url.openStream());
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+        byte[] buffer = new byte[10000];
+
+        while (true)
+        {
+            int length = is.read(buffer);
+
+            if (length < 0) break;
+
+            os.write(buffer, 0, length);
+        }
+
+        os.close();
+        is.close();
+
+        return os.toByteArray();
+    }
+
+    private void test_loop_inside_form(String linkLabel)
+    {
+        start(linkLabel);
+
+        clickAndWait("link=reset the database");
+
+        assertFieldValue("title", "End World Hunger");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel");
+        assertFieldValue("title_1", "Cure Common Cold");
+
+        type("title", "End World Hunger - today");
+        type("title_0", "Develop Faster-Than-Light Travel - immediately");
+        type("title_1", "Cure Common Cold - post haste");
+
+        clickAndWait("//input[@value='Update ToDos']");
+
+        assertFieldValue("title", "End World Hunger - today");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel - immediately");
+        assertFieldValue("title_1", "Cure Common Cold - post haste");
+
+        clickAndWait("//input[@value='Add new ToDo']");
+
+        type("title_2", "Conquer World");
+
+        clickAndWait("//input[@value='Update ToDos']");
+
+        assertFieldValue("title", "End World Hunger - today");
+        assertFieldValue("title_0", "Develop Faster-Than-Light Travel - immediately");
+        assertFieldValue("title_1", "Cure Common Cold - post haste");
+        assertFieldValue("title_2", "Conquer World");
+    }
+
+    /**
+     * Tests the bean editor. Along the way, tests a bunch about validation, loops, blocks, and application state
+     * objects.
+     */
+    @Test
+    public void bean_editor()
+    {
+        start("BeanEditor Demo", "Clear Data");
+        clickAndWait(SUBMIT);
+
+        // Part of the override for the firstName property
+
+        assertAttribute("//input[@id='firstName']/@size", "40");
+
+        // Check that the @Width annotation works
+
+        assertAttribute("//input[@id='birthYear']/@size", "4");
+
+        // Check override of the submit label
+
+        assertAttribute("//input[@type='submit']/@value", "Register");
+
+
+        type("firstName", "a");
+        type("lastName", "b");
+        type("birthYear", "");
+        select("sex", "label=Martian");
+        click("citizen");
+        type("password", "abracadabra");
+        type("notes", "line1\nline2\nline3");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("You must provide at least 3 characters for First Name.",
+                          "You must provide at least 5 characters for Last Name.",
+                          "You must provide a value for Year of Birth.");
+
+        type("firstName", "Howard");
+        type("lastName", "Lewis Ship");
+        type("birthYear", "1966");
+        type("password", "supersecret");
+
+        clickAndWait(SUBMIT);
+
+        // The XPath support is too weak for //div[@class='t-beandisplay-value'][%d], so we
+        // just look for the text itself.
+
+        assertTextPresent("Howard", "Lewis Ship", "1966", "Martian", "U. S. Citizen", "***********", "line1", "line2",
+                          "line3");
+
+    }
+
+    @Test
+    public void bean_editor_property_reorder_remove()
+    {
+        start("BeanEdit Remove/Reorder", "Clear Data");
+
+        // Looks like a bug in Selenium; we can see //label[1] but not //label[2].
+        // assertTextSeries("//label[%d]", 1, "Last Name", "First Name", "Sex", "U.S. Citizen");
+
+        type("firstName", "Howard");
+        type("lastName", "Lewis Ship");
+        type("password", "supersecret");
+
+        clickAndWait("//input[@type=\'submit\']");
+
+        assertTextPresent("Howard", "Lewis Ship", "0", "100% He-Man", "U. S. Citizen");
+    }
+
+    @Test
+    public void pageloaded_lifecycle_method_invoked()
+    {
+        start("PageLoaded Demo");
+
+        assertTextPresent("[pageLoaded() was invoked.]");
+    }
+
+
+    /**
+     * Basic Grid rendering, with a column render override. Also tests sorting.
+     */
+    @Test
+    public void basic_grid()
+    {
+        start("Grid Demo");
+
+        // "Sort Rating" via the header cell override (TAPESTRY-2081)
+
+        assertTextSeries("//th[%d]", 1, "Title", "Album", "Artist", "Genre", "Play Count", "Sort Rating");
+
+        // Strange: I thought tr[1] was the header row ???
+
+        assertTextSeries("//tr[1]/td[%d]", 1, "Bug Juice", "Late Lounge (2 of 2)", "45 Dip", "Electronica", "4", "-");
+
+        // Here were checking that the page splits are correct
+
+        clickAndWait("link=3");
+
+        // Last on page 3:
+        assertText("//tr[25]/td[1]", "Blood Red River");
+
+        clickAndWait("link=4");
+        assertText("//tr[1]/td[1]", "Devil Song");
+
+        clickAndWait("link=7");
+        clickAndWait("link=10");
+
+        // Here's one with a customized rating cell
+
+        assertTextSeries("//tr[25]/td[%d]", 1, "Smoked", "London (Original Motion Picture Soundtrack)",
+                         "The Crystal Method", "Soundtrack", "30", "****");
+
+        clickAndWait("link=69");
+
+        assertText("//tr[22]/td[1]", "radioioAmbient");
+
+        // Sort ascending (and we're on the last page, with the highest ratings).
+
+        clickAndWait("link=Sort Rating");
+
+
+        assertTextSeries("//tr[22]/td[%d]", 1, "Mona Lisa Overdrive", "Labyrinth", "Juno Reactor", "Dance", "31",
+                         "*****");
+
+        // Toggle to sort descending
+
+        clickAndWait("link=Sort Rating");
+
+        assertTextSeries("//tr[1]/td[%d]", 1, "Hey Blondie", "Out from Out Where");
+
+        clickAndWait("link=Title");
+
+        // The lack of a leading slash indicates that the path was optimized, see TAPESTRY-1502
+
+        assertAttribute("//img[@id='title:sort']/@src", "assets/tapestry/UNKNOWN/corelib/components/sort-asc.png");
+        assertAttribute("//img[@id='title:sort']/@alt", "[Asc]");
+
+        clickAndWait("link=1");
+
+        assertText("//tr[1]/td[1]", "(untitled hidden track)");
+
+        clickAndWait("link=Title");
+
+        assertAttribute("//img[@id='title:sort']/@src", "assets/tapestry/UNKNOWN/corelib/components/sort-desc.png");
+        assertAttribute("//img[@id='title:sort']/@alt", "[Desc]");
+
+        clickAndWait("link=reset the Grid");
+
+        // Back to where we started.
+
+        assertTextSeries("//tr[1]/td[%d]", 1, "Bug Juice", "Late Lounge (2 of 2)", "45 Dip", "Electronica", "4", "-");
+    }
+
+    @Test
+    public void grid_remove_reorder()
+    {
+        start("Grid Remove/Reorder Demo");
+
+        assertTextSeries("//th[%d]", 1, "Rating", "Title", "Album", "Artist", "Genre");
+    }
+
+    @Test
+    public void grid_from_explicit_interface_model()
+    {
+        start("SimpleTrack Grid Demo");
+
+        assertTextSeries("//th[%d]", 1, "Title", "Album", "Rating");
+
+        assertTextSeries("//tr[1]/td[%d]", 1, "Bug Juice", "Late Lounge (2 of 2)", "-");
+    }
+
+    @Test
+    public void grid_enum_display()
+    {
+        start("Grid Enum Demo", "reset");
+
+        assertTextSeries("//tr[1]/td[%d]", 1, "End World Hunger", "Medium");
+        assertTextSeries("//tr[2]/td[%d]", 1, "Develop Faster-Than-Light Travel", "Ultra Important");
+        assertTextSeries("//tr[3]/td[%d]", 1, "Cure Common Cold", "Low");
+    }
+
+    @Test
+    public void null_grid() throws Exception
+    {
+        start("Null Grid");
+
+        assertTextPresent("There is no data to display.");
+    }
+
+    @Test
+    public void grid_set() throws Exception
+    {
+        start("Grid Set Demo");
+
+        assertFalse(isTextPresent("Exception"));
+
+        // Also check for TAPESTRY-2228
+
+        assertAttribute("//table/@informal", "supported");
+    }
+
+    @Test
+    public void navigation_response_from_page_activate() throws Exception
+    {
+        start("Protected Page");
+
+        assertText("pagetitle", "Security Alert");
+
+        // The message is set by Protected, but is rendered by SecurityAlert.
+
+        assertTextPresent("Access to Protected page is denied");
+    }
+
+    @Test
+    public void mixed_page_activation_context_and_component_context()
+    {
+        start("Kicker");
+
+        clickAndWait("link=kick target");
+
+        assertTextSeries("//li[%d]", 1, "betty", "wilma", "betty/wilma", "\u82B1\u5B50");
+        assertTextPresent("No component context.");
+
+        clickAndWait("link=go");
+
+        assertTextSeries("//li[%d]", 1, "betty", "wilma", "betty/wilma", "\u82B1\u5B50");
+        assertTextSeries("//ul[2]/li[%d]", 1, "fred", "barney", "clark kent", "fred/barney", "\u592A\u90CE");
+    }
+
+    @Test
+    public void page_link_with_explicit_empty_context()
+    {
+        start("Kicker");
+
+        clickAndWait("link=kick target");
+
+        assertTextSeries("//li[%d]", 1, "betty", "wilma", "betty/wilma", "\u82B1\u5B50");
+
+        clickAndWait("link=Target base, no context");
+
+        assertTextPresent("No activation context.");
+    }
+
+    @Test
+    public void page_link_with_explicit_activation_context()
+    {
+        start("PageLink Context Demo", "no context");
+
+        assertTextPresent("No activation context.");
+
+        clickAndWait("link=PageLink Context Demo");
+
+        clickAndWait("link=literal context");
+
+        assertText("//li[1]", "literal context");
+
+        clickAndWait("link=PageLink Context Demo");
+
+        clickAndWait("link=computed context");
+
+        assertTextSeries("//li[%d]", 1, "fred", "7", "true");
+
+        clickAndWait("link=PageLink Context Demo");
+
+        clickAndWait("link=unsafe characters");
+
+        assertText("//li[1]", "unsafe characters: !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
+
+        clickAndWait("link=PageLink Context Demo");
+
+        clickAndWait("link=japanese kanji");
+
+        assertText("//li[1]", "japanese kanji: \u65E5\u672C\u8A9E");
+
+        // TAPESTRY-2221
+
+        clickAndWait("link=PageLink Context Demo");
+
+        clickAndWait("link=Null in context");
+
+        assertTextPresent("Context values (which are added to the request URL) may not be null or blank.");
+    }
+
+    @Test
+    public void page_context_in_form()
+    {
+        start("Page Context in Form");
+
+        assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
+        assertFieldValue("t:ac", "betty/wilma/context with spaces/context%2Fwith%2Fslashes");
+
+        clickAndWait(SUBMIT);
+
+        assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
+        assertFieldValue("t:ac", "betty/wilma/context with spaces/context%2Fwith%2Fslashes");
+    }
+
+    @Test
+    public void client_side_validation()
+    {
+        start("Client Validation Demo");
+
+        // The lack of a leading slash indicates that the path was optimized, see TAPESTRY-1502
+
+        assertAttributeSeries("//script[%d]/@src", 1, "assets/scriptaculous/UNKNOWN/prototype.js",
+                              "assets/scriptaculous/UNKNOWN/scriptaculous.js");
+
+        clickAndWait("link=Clear Data");
+
+        // Notice: click, not click and wait.
+
+        click(SUBMIT);
+
+        // Looks like more weaknesses in Selenium, can only manage the first match not the others.
+        assertTextSeries("//div[@class='t-error-popup'][%d]/span", 1, "You must provide a value for First Name."
+                         //, "Everyone has to have a last name!",
+                         //       "Year of Birth requires a value of at least 1900."
+        );
+
+        type("firstName", "Howard");
+        type("lastName", "Lewis Ship");
+        type("birthYear", "1000");
+        type("password", "supersecret");
+
+        click(SUBMIT);
+
+        type("birthYear", "1966");
+        click("citizen");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Howard", "Lewis Ship", "1966", "U. S. Citizen");
+    }
+
+    @Test
+    public void recursive_components_are_identified_as_errors()
+    {
+        start("Recursive Demo");
+
+        assertTextPresent("An unexpected application exception has occurred.",
+                          "The template for component org.apache.tapestry.integration.app1.components.Recursive is recursive (contains another direct or indirect reference to component org.apache.tapestry.integration.app1.components.Recursive). is not supported (components may not contain themselves).",
+                          "component is <t:recursive>recursive</t:recursive>, so we\'ll see a failure.");
+    }
+
+    @Test
+    public void render_phase_method_may_return_renderable()
+    {
+        start("Renderable Demo");
+
+        assertTextPresent("Renderable Demo", "[proves it works.]");
+    }
+
+    @Test
+    public void verify_event_handler_invocation_order_and_circumstance()
+    {
+        String clear = "link=clear";
+
+        start("EventHandler Demo");
+
+        clickAndWait(clear);
+
+        clickAndWait("link=No Context");
+        assertTextPresent(
+                "[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild(), child.onAction()]");
+
+        clickAndWait(clear);
+        clickAndWait("link=Single context value");
+
+        assertTextPresent(
+                "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction()]");
+
+        clickAndWait(clear);
+        clickAndWait("link=Two value context");
+        assertTextPresent(
+                "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction()]");
+
+        clickAndWait(clear);
+        clickAndWait("link=Two value context (from fred)");
+
+        assertTextPresent(
+                "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerForFred(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction(), child.onActionFromFred(String), child.onActionFromFred()]");
+    }
+
+    @Test
+    public void inherited_bindings()
+    {
+        start("Inherited Bindings Demo");
+
+        assertTextPresent("Bound: [ value: the-bound-value, bound: true ]", "Unbound: [ value: null, bound: false ]");
+    }
+
+    @Test
+    public void client_persistence()
+    {
+        start("Client Persistence Demo");
+
+        assertTextPresent("Persisted value: []", "Session: [false]");
+
+        clickAndWait("link=store string");
+
+        assertTextPresent("Persisted value: [A String]", "Session: [false]");
+    }
+
+    @Test
+    public void attribute_expansions()
+    {
+        start("Attribute Expansions Demo");
+
+        assertAttribute("//div[@id='mixed-expansion']/@style", "color: blue;");
+        assertAttribute("//div[@id='single']/@class", "red");
+        assertAttribute("//div[@id='consecutive']/@class", "goober-red");
+        assertAttribute("//div[@id='trailer']/@class", "goober-green");
+        assertText("//div[@id='formal']", "ALERT-expansions work inside formal component parameters as well");
+
+        // An unrelated test, but fills in a bunch of minor gaps.
+
+        assertSourcePresent("<!-- A comment! -->");
+    }
+
+    @Test
+    public void palette_component()
+    {
+        start("Palette Demo", "reset");
+
+        addSelection("languages:avail", "label=Haskell");
+        addSelection("languages:avail", "label=Javascript");
+        click("languages:select");
+
+        clickAndWait(SUBMIT);
+        assertTextPresent("Selected Languages: [HASKELL, JAVASCRIPT]");
+
+        addSelection("languages", "label=Javascript");
+        click("languages:deselect");
+
+        addSelection("languages:avail", "label=Perl");
+        removeSelection("languages:avail", "label=Javascript");
+        addSelection("languages:avail", "label=Erlang");
+        addSelection("languages:avail", "label=Java");
+        addSelection("languages:avail", "label=Lisp");
+        addSelection("languages:avail", "label=Ml");
+        addSelection("languages:avail", "label=Python");
+        addSelection("languages:avail", "label=Ruby");
+
+        click("languages:select");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("[ERLANG, HASKELL, JAVA, LISP, ML, PERL, PYTHON, RUBY]");
+
+        check("reorder");
+        clickAndWait(SUBMIT);
+
+        addSelection("languages", "label=Ruby");
+
+        for (int i = 0; i < 6; i++)
+            click("languages:up");
+
+        removeSelection("languages", "label=Ruby");
+        addSelection("languages", "label=Perl");
+
+        click("languages:down");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("[ERLANG, RUBY, HASKELL, JAVA, LISP, ML, PYTHON, PERL]");
+    }
+
+    @Test
+    public void event_handler_return_types()
+    {
+
+        open(BASE_URL);
+
+        assertTextPresent("Tapestry 5 Integration Application 1");
+
+        clickAndWait("link=Return Types");
+        assertTextPresent("Return Type Tests");
+
+        clickAndWait("link=null");
+        assertTextPresent("Return Type Tests");
+
+        clickAndWait("link=string");
+        assertTextPresent("Tapestry 5 Integration Application 1");
+        goBack();
+        waitForPageToLoad();
+
+        clickAndWait("link=class");
+        assertTextPresent("Tapestry 5 Integration Application 1");
+        goBack();
+        waitForPageToLoad();
+
+        clickAndWait("link=page");
+        assertTextPresent("Tapestry 5 Integration Application 1");
+        goBack();
+        waitForPageToLoad();
+
+        clickAndWait("link=link");
+        assertTextPresent("Tapestry 5 Integration Application 1");
+        goBack();
+        waitForPageToLoad();
+
+        clickAndWait("link=stream");
+        assertTextPresent("Success!");
+        goBack();
+        waitForPageToLoad();
+
+        // This has been failing?  Why?
+
+        // clickAndWait("link=URL");
+        // assertTextPresent("Google");
+        // goBack();
+        // waitForPageToLoad();
+
+        clickAndWait("link=bad");
+        assertTextPresent("An unexpected application exception has occurred.",
+                          "An event handler for component org.apache.tapestry.integration.app1.pages.Start returned the value 20 (from method org.apache.tapestry.integration.app1.pages.Start.onActionFromBadReturnType() (at Start.java:34)). Return type java.lang.Integer can not be handled.");
+
+    }
+
+    @Test
+    public void access_to_page_name()
+    {
+        open(BASE_URL);
+
+        assertText("activePageName", "Start");
+
+        clickAndWait("link=Grid Demo");
+
+        assertText("activePageName", "GridDemo");
+    }
+
+    @Test
+    public void form_encoding_type()
+    {
+        start("Form Encoding Type");
+
+        assertAttribute("//form/@enctype", "x-override");
+    }
+
+    @Test
+    public void radio_button_and_group()
+    {
+        start("RadioDemo");
+
+        String update = SUBMIT;
+
+        // in a loop ...
+        click("//label[.='Accounting']");
+        clickAndWait(update);
+        assertTextPresent("Selected department: ACCOUNTING");
+
+        click("//label[.='Sales And Marketing']");
+        clickAndWait(update);
+        assertTextPresent("Selected department: SALES_AND_MARKETING");
+
+        // not in a loop ...
+        click("//label[.='Temp']");
+        clickAndWait(update);
+        assertTextPresent("Selected position: TEMP");
+
+        click("//label[.='Lifer']");
+        clickAndWait(update);
+        assertTextPresent("Selected position: LIFER");
+    }
+
+    @Test
+    public void regexp_validator()
+    {
+        start("Regexp Demo");
+
+        String update = SUBMIT;
+
+        type("zipCode", "abc");
+
+        click(update); // but don't wait
+
+        assertTextPresent("A zip code consists of five or nine digits, eg: 02134 or 90125-4472.");
+
+        type("zipCode", "12345");
+
+        clickAndWait(update);
+
+        assertTextPresent("Zip code: [12345]");
+
+        type("zipCode", "12345-9876");
+
+        clickAndWait(update);
+
+        assertTextPresent("Zip code: [12345-9876]");
+    }
+
+    @Test
+    public void multiple_beaneditor_components()
+    {
+        start("MultiBeanEdit Demo", "Clear Data");
+
+        type("firstName", "Howard");
+        type("lastName", "Lewis Ship");
+        type("path", "/var/www");
+        clickAndWait("//input[@value='Set Access']");
+
+        waitForPageToLoad("30000");
+
+        assertTextSeries("//li[%d]", 1, "First Name: [Howard]", "Last Name: [Lewis Ship]", "Path: [/var/www]",
+                         "Role: [GRANT]");
+    }
+
+    @Test
+    public void grid_inside_form()
+    {
+        start("Grid Form Demo", "reset", "2");
+
+        // The first input field is the form's hidden field.
+
+        assertFieldValue("title", "ToDo # 6");
+        assertFieldValueSeries("title_%d", 0, "ToDo # 7", "ToDo # 8", "ToDo # 9", "ToDo # 10");
+
+        type("title_0", "Cure Cancer");
+        select("urgency_0", "Top Priority");
+
+        type("title_1", "Pay Phone Bill");
+        select("urgency_1", "Low");
+
+        clickAndWait(SUBMIT);
+
+        assertFieldValueSeries("title_%d", 0, "Cure Cancer", "Pay Phone Bill");
+        assertFieldValueSeries("urgency_%d", 0, "HIGH", "LOW");
+    }
+
+    @Test
+    public void missing_template_for_page()
+    {
+        start("Missing Template Demo");
+
+        assertTextPresent(
+                "Page MissingTemplate did not generate any markup when rendered. This could be because its template file could not be located, or because a render phase method in the page prevented rendering.");
+    }
+
+    /**
+     * This can test some output and parsing capability of the DateField component, but not the interesting client-side
+     * behavior.
+     */
+    @Test
+    public void basic_datefield()
+    {
+        start("DateField Demo");
+
+        type("birthday", "12/24/66");
+        type("asteroidImpact", "05/28/2046");
+
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Birthday: [12/24/1966]");
+        assertTextPresent("Impact: [05/28/2046]");
+
+        assertFieldValue("birthday", "12/24/1966");
+        assertFieldValue("asteroidImpact", "05/28/2046");
+    }
+
+    /**
+     * This also checks that the date type is displayed correctly by BeanDisplay and Grid.
+     */
+    @Test
+    public void date_field_inside_bean_editor()
+    {
+        start("BeanEditor / Date Demo", "clear");
+
+        type("name", "Howard Lewis Ship");
+        type("date", "12/24/66");
+
+        clickAndWait(SUBMIT);
+
+        // Notice the date output format; that is controlled by the date Block on the
+        // PropertyDisplayBlocks page.
+
+        assertTextPresent("Howard Lewis Ship", "Dec 24, 1966");
+    }
+
+    /**
+     * This basically checks that the services status page does not error.
+     */
+    @Test
+    public void services_status()
+    {
+        open(BASE_URL + "servicestatus");
+
+        assertTextPresent("Tapestry IoC Services Status");
+    }
+
+    @Test
+    public void event_based_translate() throws Exception
+    {
+        start("EventMethod Translator");
+
+        type("count", "123");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Count: [123]");
+
+        type("count", "0");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Count: [0]");
+
+        assertFieldValue("count", "zero");
+
+        type("count", "456");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Count: [456]");
+
+        assertFieldValue("count", "456");
+
+        type("count", "ZERO");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Count: [0]");
+
+        assertFieldValue("count", "zero");
+
+        // Try the server-side custom exception reporting.
+
+        type("count", "13");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Event Handler Method Translate", "Thirteen is an unlucky number.");
+
+        type("count", "i");
+        clickAndWait(SUBMIT);
+
+        assertTextPresent("Event Handler Method Translate", "Rational numbers only, please.");
+    }
+
+    @Test
+    public void autocomplete_mixin()
+    {
+        start("Autocomplete Mixin Demo");
+
+        // And that's as far as we can go currently, because
+        // of limitations in Selenium 0.8.3 and bugs in Selenium 0.9.2.
+    }
+
+    @Test
+    public void zone_updates()
+    {
+        start("Zone Demo");
+
+        assertTextPresent("No name has been selected.");
+
+        // Hate doing this, but selecting by the text isn't working, perhaps because of the
+        // HTML entities.
+        click("select_0");
+
+        // And that's as far as we can go currently, because
+        // of limitations in Selenium 0.8.3 and bugs in Selenium 0.9.2.
+
+        // assertTextPresent("Selected: Mr. &lt;Roboto&gt;");
+
+        click("link=Direct JSON response");
+    }
+
+    /**
+     * Tests TAPESTRY-1934.
+     */
+    @Test
+    public void base_class_must_be_in_controlled_package() throws Exception
+    {
+        open(BASE_URL + "invalidsuperclass");
+
+        assertTextPresent(
+                "Base class org.apache.tapestry.integration.app1.WrongPackageForBaseClass (super class of org.apache.tapestry.integration.app1.pages.InvalidSuperClass) is not in a controlled package and is therefore not valid. You should try moving the class to package org.apache.tapestry.integration.app1.base.");
+    }
+
+    @Test
+    public void xml_content() throws Exception
+    {
+        open(BASE_URL + "xmlcontent");
+
+        // Commented out ... Selenium can't seem to handle an XML response.
+
+        // assertSourcePresent("<![CDATA[< & >]]>");
+    }
+
+    /**
+     * Tests TAPESTRY-2005.
+     */
+    @Test
+    public void components_passed_as_parameters() throws Exception
+    {
+        start("ComponentParameter Demo");
+
+        // This component is inside a block, and is only rendered because it is passed as a parameter, of type ActionLink,
+        // to an ActionLinkIndirect component.
+
+        clickAndWait("link=click me");
+
+        assertTextPresent("Link was clicked.");
+    }
+
+    /**
+     * Tests TAPESTRY-1546
+     */
+    @Test
+    public void inherit_informals() throws Exception
+    {
+        start("Inherit Informal Parameters Demo");
+
+        assertAttribute("//span[@id='target']/@class", "inherit");
+    }
+
+    @Test
+    public void disabled_fields() throws Exception
+    {
+        start("Disabled Fields");
+
+        String[] paths = new String[] { "//input[@id='textfield']",
+
+                "//input[@id='passwordfield']",
+
+                "//textarea[@id='textarea']",
+
+                "//input[@id='checkbox']",
+
+                "//select[@id='select']",
+
+                "//input[@id='radio1']",
+
+                "//input[@id='radio2']",
+
+                "//input[@id='datefield']",
+
+                "//select[@id='palette:avail']",
+
+                "//button[@id='palette:select']",
+
+                "//button[@id='palette:deselect']",
+
+                "//select[@id='palette']",
+
+                "//input[@id='submit']" };
+
+        for (String path : paths)
+        {
+            String locator = String.format("%s/@disabled", path);
+
+            assertAttribute(locator, "disabled");
+        }
+    }
+
+    /**
+     * TAPESTRY-2013
+     */
+    @Test
+    public void bean_editor_overrides()
+    {
+        start("BeanEditor Override", "Clear Data");
+
+        assertTextPresent("[FirstName Property Editor Override]");
+    }
+
+    /**
+     * TAPESTRY-1830
+     */
+    @Test
+    public void var_binding()
+    {
+        start("Var Binding Demo");
+
+        assertTextSeries("//li[%d]", 1, "1", "2", "3");
+    }
+
+    /**
+     * TAPESTRY-2021
+     */
+    @Test
+    public void lean_grid()
+    {
+        start("Lean Grid Demo");
+
+        assertTextSeries("//th[%d]", 1, "Title", "Album", "Artist", "Genre", "Play Count", "Rating");
+
+        // Selenium makes it pretty hard to check for a missing class.
+
+        // assertText("//th[1]/@class", "");
+    }
+
+    @Test
+    public void unless_component()
+    {
+        start("Unless Demo");
+
+        assertText("//p[@id='false']", "false is rendered");
+
+        assertText("//p[@id='true']", "");
+    }
+
+    /**
+     * TAPESTRY-2044
+     */
+    @Test
+    public void action_links_on_non_active_page()
+    {
+        start("Action Links off of Active Page");
+
+        String contextSpan = "//span[@id='context']";
+
+        assertText(contextSpan, "0");
+
+        clickAndWait("link=3");
+
+        assertText(contextSpan, "3");
+
+        clickAndWait("link=refresh");
+
+        assertText(contextSpan, "3");
+
+        clickAndWait("link=1");
+
+        assertText(contextSpan, "1");
+
+        clickAndWait("link=refresh");
+
+        assertText(contextSpan, "1");
+    }
+
+    /**
+     * TAPESTRY-2333
+     */
+    @Test
+    public void action_links_on_custom_url()
+    {
+        open(BASE_URL + "nested/actiondemo/");
+
+        clickAndWait("link=2");
+
+        assertTextPresent("Number: 2");
+    }
+
+    /**
+     * TAPESTRY-1598
+     */
+    @Test
+    public void value_encoder_via_type_coercer()
+    {
+        start("Magic ValueEncoder Demo");
+
+        select("number", "25");
+
+        clickAndWait(SUBMIT);
+
+        String locator = "//span[@id='selectednumber']";
+
+        assertText(locator, "25");
+
+        select("number", "100");
+        clickAndWait(SUBMIT);
+
+        assertText(locator, "100");
+    }
+
+    /**
+     * TAPESTRY-2056
+     */
+    @Test
+    public void null_field_strategy()
+    {
+        start("Null Field Strategy Demo");
+
+        String locator = "//span[@id='value']";
+
+        assertText(locator, "");
+
+        assertAttribute("//input[@id='number']/@value", "0");
+
+        type("number", "");
+
+        clickAndWait(SUBMIT);
+
+        assertText(locator, "0");
+    }
+
+    /**
+     * TAPESTRY-1647
+     */
+    @Test
+    public void label_invokes_validation_decorator_at_correct_time()
+    {
+        start("Override Validation Decorator");
+
+        // This is sub-optimal, as it doesn't esnure that the before/after field values really do wrap around
+        // the field (they do, but that's hard to prove!).
+
+        // Along the way we are also testing:
+        // - primitive types are automatically required
+        // - AbstractTextField.isRequired() and the logic inside ComponentFieldValidator.isRequired()
+
+        assertSourcePresent(
+                "[Before label for Value]<label for=\"value\" id=\"value:label\">Value</label>[After label for Value]",
+                "[Before field Value]", "[After field Value (optional)]",
+                "[Before label for Required Value]<label for=\"requiredValue\" id=\"requiredValue:label\">Required Value</label>[After label for Required Value]",
+                "[Before field Required Value]", "[After field Required Value (required)]");
+    }
+
+    /**
+     * TAPESTRY-1724
+     */
+    @Test
+    public void component_event_errors()
+    {
+        start("Exception Event Demo", "enable", "force invalid activation context");
+
+        assertTextPresent(
+                "Exception: Exception in method org.apache.tapestry.integration.app1.pages.ExceptionEventDemo.onActivate(float)");
+
+        clickAndWait("link=force invalid event context");
+
+        assertTextPresent(
+                "Exception: Exception in method org.apache.tapestry.integration.app1.pages.ExceptionEventDemo.onActionFromFail(float)");
+
+        // Revert to normal handling: return null from the onException() event handler method.
+
+        clickAndWait("link=disable");
+
+        clickAndWait("link=force invalid event context");
+
+        assertTextPresent("An unexpected application exception has occurred.",
+                          "org.apache.tapestry.ioc.internal.util.TapestryException", "java.lang.NumberFormatException");
+
+    }
+
+    /**
+     * TAPESTRY-1416
+     */
+
+    @Test
+    public void adding_new_columns_to_grid_programattically()
+    {
+        start("Added Grid Columns Demo", "Title Length");
+
+        assertTextSeries("//th[%d]", 1, "Title", "View", "Title Length", "Dummy");
+
+        // The rendered &nbsp; becomes just a blank string.
+        assertTextSeries("//tr[1]/td[%d]", 1, "7", "view", "1", "");
+    }
+
+    /**
+     * TAPESTRY-1518
+     */
+    @Test
+    public void generic_page_type()
+    {
+        start("Generic Page Class Demo");
+
+        assertTextPresent("Editor for org.apache.tapestry.integration.app1.data.Track");
+
+        assertSourcePresent("<label for=\"title\" id=\"title:label\">Title</label>");
+    }
+
+    /**
+     * TAPESTRY-2088
+     */
+    @Test
+    public void primitive_array_as_parameter_type()
+    {
+        start("Primitive Array Parameter Demo");
+
+        assertSourcePresent("<ul><li>1</li><li>3</li><li>5</li><li>7</li><li>9</li></ul>");
+    }
+
+    /**
+     * TAPESTRY-2097
+     */
+    @Test
+    public void render_queue_exception()
+    {
+        start("Render Error Demo");
+
+        assertTextPresent("An unexpected application exception has occurred");
+
+        // Just sample a smattering of the vast amount of data in the exception report.
+
+        assertTextPresent("RenderErrorDemo", "class " + RenderErrorDemo.class.getName(), "RenderErrorDemo:border",
+                          "RenderErrorDemo:echo");
+    }
+
+    /**
+     * TAPESTRY-1594
+     */
+    @Test
+    public void ignored_paths_filter()
+    {
+        start("Unreachable Page");
+
+        assertTextPresent("HTTP ERROR: 404");
+    }
+
+    /**
+     * TAPESTRY-2085
+     */
+    @Test
+    public void render_phase_methods_may_throw_checked_exceptions()
+    {
+        start("Render Phase Method Exception Demo");
+
+        assertTextPresent(
+                "Render queue error in BeginRender[RenderPhaseMethodExceptionDemo]: java.sql.SQLException: Simulated JDBC exception while rendering.");
+    }
+
+    /**
+     * TAPESTRY-2085
+     */
+    @Test
+    public void wrapper_types_with_text_field()
+    {
+        start("TextField Wrapper Types", "clear");
+
+        assertFieldValue("count", "");
+        assertText("value", "null");
+
+        type("count", "0");
+        clickAndWait(SUBMIT);
+
+        assertFieldValue("count", "0");
+        assertText("value", "0");
+
+        type("count", "1");
+        clickAndWait(SUBMIT);
+
+        assertFieldValue("count", "1");
+        assertText("value", "1");
+
+        clickAndWait("link=clear");
+
+        assertFieldValue("count", "");
+        assertText("value", "null");
+    }
+
+    /**
+     * TAPESTRY-1901
+     */
+    @Test
+    public void delete_rows_from_grid()
+    {
+        start("Delete From Grid", "setup the database", "2");
+
+        for (int i = 6; i <= 10; i++)
+            clickAndWait("link=ToDo #" + i);
+
+        // A rather clumsy way to ensure we're back on the first page.
+
+        for (int i = 1; i <= 5; i++)
+            assertTextPresent("ToDo #" + i);
+    }
+
+    /**
+     * TAPESTRY-2114
+     */
+    @Test
+    public void boolean_properties_can_use_get_or_is_as_method_name_prefix()
+    {
+        start("Boolean Property Demo", "clear");
+
+        assertText("usingGet", "false");
+        assertText("usingIs", "false");
+
+        clickAndWait("link=set");
+
+        assertText("usingGet", "true");
+        assertText("usingIs", "true");
+    }
+
+    @Test
+    public void form_fragment()
+    {
+        start("Form Fragment Demo", "Clear");
+
+        type("name", "Fred");
+        // Really, you can't type in the field because it is not visible, but
+        // this checks that invisible fields are not processed.
+        type("email", "this field is ignored");
+
+        clickAndWait(SUBMIT);
+
+        assertText("name", "Fred");
+        assertText("email", "");
+
+        clickAndWait("link=Back");
+        clickAndWait("link=Clear");
+
+        click("subscribeToEmail");
+        click("on");
+        type("name", "Barney");
+        type("email", "rubble@bedrock.gov");
+        type("code", "ABC123");
+
+        click("off");
+        sleep(1000);
+
+        clickAndWait(SUBMIT);
+
+        assertText("name", "Barney");
+        assertText("email", "rubble@bedrock.gov");
+        assertText("code", "");
+    }
+
+    @Test
+    public void zone_inject_component_from_template()
+    {
+        start("Inject Component Demo");
+
+        assertTextPresent(Form.class.getName() + "[form--form]");
+    }
+
+
+    /**
+     * This may need to be disabled or dropped from the test suite, I don't know that Selenium, especially Selenium
+     * running headless on the CI server, can handle the transition to HTTPS: there's warnings that pop up about
+     * certificates.
+     * <p/>
+     * <p/>
+     * Verified: Selenium can't handle this, even with a user manually OK-ing the certificate warning dialogs.
+     */
+    @Test(enabled = false)
+    public void secure_page_access()
+    {
+        start("Secure Page Demo");
+
+        assertText("secure", "secure");
+
+        assertText("message", "Triggered from Start");
+
+        clickAndWait("link=click");
+
+        assertText("secure", "secure");
+
+        assertText("message", "Link clicked");
+
+        clickAndWait(SUBMIT);
+
+        assertText("secure", "secure");
+        assertText("message", "Form submitted");
+
+        clickAndWait("link=Back to index");
+
+        // Back to the insecure home page.
+
+        assertText("//h1", "Tapestry 5 Integration Application 1");
+    }
+
+    /**
+     * TAPESTRY-2184
+     */
+    @Test
+    public void create_action_link_while_not_rendering()
+    {
+        start("Action via Link Demo", "via explicit Link creation");
+
+        assertText("message", "from getActionURL()");
+    }
+
+    /**
+     * TAPESTRY-1475
+     */
+    @Test
+    public void discard_persistent_field_changes()
+    {
+        start("Persistent Demo");
+
+        assertText("message", "");
+
+        clickAndWait("link=Update the message field");
+
+        assertText("message", "updated");
+
+        clickAndWait("link=Refresh page");
+
+        assertText("message", "updated");
+
+        clickAndWait("link=Discard persistent field changes");
+
+        assertText("message", "");
+    }
+
+    /**
+     * TAPESTRY-2150.  Also demonstrates how to add a ValueEncoder for an entity object, to allow seamless encoding of
+     * the entity's id into the URL.
+     */
+    @Test
+    public void nested_page_names()
+    {
+        start("Music Page", "2");
+
+        assertText("activePageName", "Music");
+
+        clickAndWait("link=The Gift");
+
+        assertText("activePageName", "music/Details");
+    }
+
+    /**
+     * TAPESTRY-1869
+     */
+    @Test
+    public void null_fields_and_bean_editor()
+    {
+        start("Number BeanEditor Demo");
+
+        clickAndWait(SUBMIT);
+
+        // Hard to check for anything here.
+
+        clickAndWait("link=Back to form");
+
+        type("value", "237");
+
+        clickAndWait(SUBMIT);
+
+        assertText("//div[@class='t-beandisplay-value value']", "237");
+    }
+
+    /**
+     * TAPESTRY-1999
+     */
+    @Test
+    public void list_as_event_context()
+    {
+        start("List Event Context Demo");
+
+        assertTextSeries("//ul[@id='eventcontext']/li[%d]", 1, "1", "2", "3");
+    }
+
+    @Test
+    public void form_injector()
+    {
+        start("FormInjector Demo");
+
+        assertText("sum", "0.0");
+
+        click("link=Add a row");
+
+        sleep(1000);
+
+        type("//input[@type='text'][1]", "5.1");
+
+        // I wanted to add two rows, but Selenium didn't want to play.
+
+        clickAndWait(SUBMIT);
+
+        assertText("sum", "5.1");
+    }
+
+    /**
+     * TAPESTRY-2196
+     */
+    @Test
+    public void protected_field_in_page_class()
+    {
+        start("Protected Fields Demo", "Trigger the Exception");
+
+        assertTextPresent("An unexpected application exception has occurred.",
+                          "Class org.apache.tapestry.integration.app1.pages.ProtectedFields contains field(s) (_field) that are not private. You should change these fields to private, and add accessor methods if needed.");
+    }
+
+
+    /**
+     * TAPESTRY-2078
+     */
+    @Test
+    public void noclassdeffound_exception_is_linked_to_underlying_cause()
+    {
+        start("Class Transformation Exception Demo");
+
+        assertTextPresent(
+                "Class org.apache.tapestry.integration.app1.pages.Datum contains field(s) (_value) that are not private. You should change these fields to private, and add accessor methods if needed.");
+    }
+
+    /**
+     * TAPESTRY-2244
+     */
+    @Test
+    public void cached()
+    {
+        start("Cached Annotation");
+
+        assertText("value", "000");
+        assertText("value2size", "111");
+
+        assertText("//span[@class='watch'][1]", "0");
+        assertText("//span[@class='watch'][2]", "0");
+        assertText("//span[@class='watch'][3]", "1");
+
+        clickAndWait("link=Back to index");
+
+        // TAPESTRY-2338: Make sure the data is cleared.
+
+        clickAndWait("link=Cached Annotation");
+
+        assertText("value", "000");
+        assertText("value2size", "111");
+
+        assertText("//span[@class='watch'][1]", "0");
+        assertText("//span[@class='watch'][2]", "0");
+        assertText("//span[@class='watch'][3]", "1");
+
+    }
+
+    /**
+     * TAPESTRY-2244
+     */
+    @Test
+    public void override_method_with_cached()
+    {
+        start("Cached Annotation2");
+
+        assertText("value", "111");
+
+        clickAndWait("link=Back to index");
+
+        // TAPESTRY-2338: Make sure the data is cleared.
+
+        clickAndWait("link=Cached Annotation2");
+
+        assertText("value", "111");
+    }
+
+    private void sleep(long timeout)
+    {
+        try
+        {
+            Thread.sleep(timeout);
+        }
+        catch (InterruptedException ex)
+        {
+        }
+    }
+
+    /**
+     * TAPESTRY-2338
+     */
+    @Test
+    public void cached_properties_cleared_at_end_of_request()
+    {
+        start("Clean Cache Demo");
+
+        String time1_1 = getText("time1");
+        String time1_2 = getText("time1");
+
+        // Don't know what they are but they should be the same.
+
+        assertEquals(time1_2, time1_1);
+
+        click("link=update");
+
+        sleep(250);
+
+        String time2_1 = getText("time1");
+        String time2_2 = getText("time1");
+
+        // Check that @Cache is still working
+
+        assertEquals(time2_2, time2_1);
+
+        assertFalse(time2_1.equals(time1_1),
+                    "After update the nanoseconds time did not change, meaning @Cache was broken.");
+
+    }
+
+    @Test
+    public void inplace_grid()
+    {
+        start("In-Place Grid Demo");
+
+        String timestamp = getText("lastupdate");
+
+        click("link=2");
+        sleep(100);
+        click("link=Album");
+        sleep(100);
+
+        assertEquals(getText("lastupdate"), timestamp,
+                     "Timestamp should not have changed because updates are in-place.");
+    }
+
+
+    @Test
+    public void method_advice()
+    {
+        start("Method Advice Demo");
+
+        // @ReverseStrings intercepted and reversed the result:
+        assertText("message", "!olleH");
+
+        // @ReverseStrings doesn't do anything for non-Strings
+        assertText("version", "5");
+
+        // @ReverseStrings filtered the checked exception to a string result
+        assertText("cranky",
+                   "Invocation of method getCranky() failed with org.apache.tapestry.integration.app1.services.DearGodWhyMeException.");
+
+        // Now to check advice on a setter that manipulates parameters
+
+        type("text", "Tapestry");
+        clickAndWait(SUBMIT);
+
+        assertText("output-text", "yrtsepaT");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/RunJetty.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/RunJetty.java
new file mode 100644
index 0000000..41cef5c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/RunJetty.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration;
+
+import org.apache.tapestry.test.JettyRunner;
+
+import java.io.File;
+
+/**
+ * A "shim" to run Demo App #1 inside IntelliJ.  I still haven't found a way to get IntelliJ to
+ * export test classes and resources into a web facet.
+ */
+public class RunJetty
+{
+    public static void main(String[] args) throws InterruptedException
+    {
+        String contextName = args[0];
+        String path = args[1];
+
+        File workingDir = new File(System.getProperty("user.dir"));
+
+        new JettyRunner(workingDir, contextName, 8080, path);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app0/services/FooModule.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app0/services/FooModule.java
new file mode 100644
index 0000000..e53e956
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app0/services/FooModule.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app0.services;
+
+import org.apache.tapestry.util.Transformer;
+import org.apache.tapestry.util.UppercaseTransformer;
+
+public class FooModule
+{
+    public static Transformer buildService1()
+    {
+        return new UppercaseTransformer();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/ChattyValidationDecorator.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/ChattyValidationDecorator.java
new file mode 100644
index 0000000..09a778b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/ChattyValidationDecorator.java
@@ -0,0 +1,69 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationDecorator;
+import org.apache.tapestry.dom.Element;
+
+public class ChattyValidationDecorator implements ValidationDecorator
+{
+    private final MarkupWriter writer;
+
+    private final ValidationDecorator delegate;
+
+    public ChattyValidationDecorator(MarkupWriter writer, ValidationDecorator delegate)
+    {
+        this.writer = writer;
+        this.delegate = delegate;
+    }
+
+    public void beforeLabel(Field field)
+    {
+        writer.writef("[Before label for %s]", field.getLabel());
+    }
+
+    public void afterLabel(Field field)
+    {
+        writer.writef("[After label for %s]", field.getLabel());
+    }
+
+    public void beforeField(Field field)
+    {
+        writer.writef("[Before field %s]", field.getLabel());
+
+        delegate.beforeField(field);
+    }
+
+    public void insideField(Field field)
+    {
+        delegate.insideField(field);
+    }
+
+    public void afterField(Field field)
+    {
+        delegate.afterField(field);
+
+        writer.writef("[After field %s (%s)]", field.getLabel(),
+                      field.isRequired() ? "required" : "optional"
+        );
+    }
+
+    public void insideLabel(Field field, Element labelElement)
+    {
+        delegate.insideLabel(field, labelElement);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java
new file mode 100644
index 0000000..215cd57
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java
@@ -0,0 +1,22 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1;
+
+/**
+ * Used in a test for TAPESTRY-1934; base classes should be in the .base package.
+ */
+public class WrongPackageForBaseClass
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseComponent.java
new file mode 100644
index 0000000..92dc49d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseComponent.java
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.base;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.integration.app1.data.IncidentData;
+
+public class BaseComponent
+{
+    @ApplicationState
+    @Property
+    private IncidentData incidentData;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseEventHandlerDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseEventHandlerDemo.java
new file mode 100644
index 0000000..85eeb21
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/BaseEventHandlerDemo.java
@@ -0,0 +1,71 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.base;
+
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+public abstract class BaseEventHandlerDemo
+{
+    @Persist
+    @Property
+    private List<String> methodNames;
+
+    protected final void addMethodName(String name)
+    {
+        List<String> methodNames = this.methodNames;
+
+        if (methodNames == null) methodNames = CollectionFactory.newList();
+
+        methodNames.add(name);
+
+        this.methodNames = methodNames;
+    }
+
+    void onActivate(String placeholder)
+    {
+        methodNames = null;
+    }
+
+    @SuppressWarnings("unused")
+    private void onAction()
+    {
+        addMethodName("parent.onAction()");
+    }
+
+    @SuppressWarnings("unused")
+    private void onAction(String value)
+    {
+        addMethodName("parent.onAction(String)");
+
+    }
+
+    @OnEvent("action")
+    void eventHandlerZero()
+    {
+        addMethodName("parent.eventHandlerZero()");
+    }
+
+    @OnEvent(value = "action")
+    void eventHandlerOne(String value)
+    {
+        addMethodName("parent.eventHandlerOne(String)");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/GenericEditor.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/GenericEditor.java
new file mode 100644
index 0000000..ef09ed8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/base/GenericEditor.java
@@ -0,0 +1,65 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.base;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.corelib.components.BeanEditForm;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.PropertyConduitSource;
+
+/**
+ * For testing TAPESTRY-1518.
+ */
+public class GenericEditor<T>
+{
+    @Persist
+    private T bean;
+
+    @Component(parameters = { "object=bean" })
+    private BeanEditForm form;
+
+    @Inject
+    private PropertyConduitSource conduit;
+
+    @Retain
+    private String beanType;
+
+    {
+        // Use getClass(), not GenericEditor.class, to determine the correct type for the bean.
+        // Otherwise, it would be Object.
+
+        PropertyConduit conduit = this.conduit.create(getClass(), "bean");
+
+        beanType = conduit.getPropertyType().getName();
+    }
+
+    public String getBeanType()
+    {
+        return beanType;
+    }
+
+    public T getBean()
+    {
+        return bean;
+    }
+
+    public void setBean(T bean)
+    {
+        this.bean = bean;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/AbstractTracer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/AbstractTracer.java
new file mode 100644
index 0000000..da30b9c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/AbstractTracer.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.components;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.annotation.AfterRender;

+import org.apache.tapestry.annotation.BeginRender;

+

+public abstract class AbstractTracer

+{

+    @BeginRender

+    void begin(MarkupWriter writer)

+    {

+        writer.write("BEGIN-ABSTRACT-TRACER ");

+    }

+

+    @AfterRender

+    void after(MarkupWriter writer)

+    {

+        writer.write("AFTER-ABSTRACT-TRACER ");

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/ActionLinkIndirect.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/ActionLinkIndirect.java
new file mode 100644
index 0000000..d3fe0b8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/ActionLinkIndirect.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.corelib.components.ActionLink;
+
+public class ActionLinkIndirect
+{
+    /**
+     * The component to be rendered.
+     */
+    @Parameter(required = true, defaultPrefix = "component")
+    private ActionLink component;
+
+    Object beginRender(MarkupWriter writer)
+    {
+        writer.element("p");
+
+        return component;
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // p
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java
new file mode 100644
index 0000000..6d11ab3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Border.java
@@ -0,0 +1,62 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotation.IncludeStylesheet;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.services.ComponentLayer;
+import org.apache.tapestry.services.Request;
+
+/**
+ * Here's a component with a template, including a t:body element.   Really should rename this to "Layout" as that's the
+ * T5 naming.
+ */
+@IncludeStylesheet({ "context:layout/style.css", "context:css/app.css" })
+public class Border
+{
+    @Inject
+    @Builtin
+    private ClassFactory iocClassFactory;
+
+    @Inject
+    @ComponentLayer
+    private ClassFactory componentClassFactory;
+
+    @Inject
+    private Request request;
+
+    public ClassFactory getComponentClassFactory()
+    {
+        return componentClassFactory;
+    }
+
+    public ClassFactory getIocClassFactory()
+    {
+        return iocClassFactory;
+    }
+
+    public Request getRequest()
+    {
+        return request;
+    }
+
+    public String getSecure()
+    {
+        return request.isSecure() ? "secure" : "insecure";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Count.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Count.java
new file mode 100644
index 0000000..62d6325
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Count.java
@@ -0,0 +1,75 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotation.AfterRender;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.annotation.SetupRender;
+import org.apache.tapestry.internal.util.IntegerRange;
+
+/**
+ * A component that can count up or count down.
+ * <p/>
+ * This is useful as a demonstration; now that the prop binding supports {@link IntegerRange integer ranges}, it's much
+ * less necessary.
+ */
+public class Count
+{
+    @Parameter
+    private int start = 1;
+
+    @Parameter(required = true)
+    private int end;
+
+    @Parameter
+    private int value;
+
+    private boolean increment;
+
+    @SetupRender
+    void initializeValue()
+    {
+        value = start;
+
+        increment = start < end;
+    }
+
+    @AfterRender
+    boolean next()
+    {
+        if (increment)
+        {
+            int newValue = value + 1;
+
+            if (newValue <= end)
+            {
+                value = newValue;
+                return false; // re-render body
+            }
+        }
+        else
+        {
+            int newValue = value - 1;
+
+            if (newValue >= end)
+            {
+                value = newValue;
+                return false; // re-render body
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Echo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Echo.java
new file mode 100644
index 0000000..460333b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Echo.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.BeginRender;
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * Echos out its value parameter. Uused to test parameter overrides between component annoation and template. Also, used
+ * to test parameter defaulter methods.
+ */
+public class Echo
+{
+    @Parameter("componentResources.completeId")
+    private String value;
+
+    @BeginRender
+    void render(MarkupWriter writer)
+    {
+        writer.write(value);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/HelloWorld.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/HelloWorld.java
new file mode 100644
index 0000000..e7318d3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/HelloWorld.java
@@ -0,0 +1,28 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.BeginRender;
+
+public class HelloWorld
+{
+    @BeginRender
+    void renderMessage(MarkupWriter writer)
+    {
+        writer.write("Why wait?  Make changes here and see them immediately!");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java
new file mode 100644
index 0000000..1b0de16
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class Inner
+{
+    @Parameter
+    private String innerValue;
+
+    @Inject
+    private ComponentResources resources;
+
+    void beginRender(MarkupWriter writer)
+    {
+        writer.writef("[ value: %s, bound: %s ]", innerValue, resources.isBound("innerValue"));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/IntArrayWriter.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/IntArrayWriter.java
new file mode 100644
index 0000000..ebe6e21
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/IntArrayWriter.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+
+public class IntArrayWriter
+{
+    @Parameter
+    private int[] array;
+
+    boolean beginRender(MarkupWriter writer)
+    {
+        writer.element("ul");
+
+        for (int x : array)
+        {
+            writer.element("li");
+            writer.write(String.valueOf(x));
+            writer.end();
+        }
+
+        writer.end();
+
+        return false; // don't render body, etc.
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java
new file mode 100644
index 0000000..324a562
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.annotation.Parameter;
+
+public class Outer
+{
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = BindingConstants.LITERAL)
+    private String outerValue;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OuterAny.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OuterAny.java
new file mode 100644
index 0000000..48c87f5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OuterAny.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.corelib.components.Any;
+
+@SupportsInformalParameters
+public class OuterAny
+{
+    // Also, leave a few parameters here and there in the old naming style, with a
+    // leading underscore.
+
+    @Component(inheritInformalParameters = true)
+    private Any innerAny;
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Output.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Output.java
new file mode 100644
index 0000000..4edc1f3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Output.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+
+import java.text.Format;
+
+/**
+ * component that formats a value and outputs it.
+ */
+public class Output
+{
+    @Parameter(required = true)
+    private Object value;
+
+    @Parameter(required = true)
+    private Format format;
+
+    void beginRender(MarkupWriter writer)
+    {
+        String formatted = format.format(value);
+
+        writer.write(formatted);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OutputRating.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OutputRating.java
new file mode 100644
index 0000000..9e4d021
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/OutputRating.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.Parameter;
+
+public class OutputRating
+{
+    @Parameter
+    private int rating;
+
+    void beginRender(MarkupWriter writer)
+    {
+        if (rating <= 0)
+        {
+            writer.write("-");
+            return;
+        }
+
+        // Want 1 - 5 stars
+        int stars = ((rating - 1) / 20) + 1;
+
+        for (int i = 0; i < stars; i++)
+            writer.write("*");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Recursive.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Recursive.java
new file mode 100644
index 0000000..be6e451
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Recursive.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+public class Recursive
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Render.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Render.java
new file mode 100644
index 0000000..b9d5787
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Render.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotation.Parameter;
+
+public class Render
+{
+    @Parameter(required = true)
+    private Object value;
+
+    /**
+     * Returns the value parameter, which allows another object (presumably, a component) to render first.
+     *
+     * @return
+     */
+    Object beginRender()
+    {
+        return value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java
new file mode 100644
index 0000000..0f5da2f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotation.CleanupRender;
+import org.apache.tapestry.annotation.SetupRender;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.Environment;
+
+public class RenderableProvider
+{
+    @Inject
+    private Environment environment;
+
+    @SetupRender
+    void setup()
+    {
+        Renderable r = new Renderable()
+        {
+            public void render(MarkupWriter writer)
+            {
+                writer.element("strong");
+                writer.write("A message provided by the RenderableProvider component.");
+                writer.end();
+            }
+        };
+
+        environment.push(Renderable.class, r);
+    }
+
+    @CleanupRender
+    void cleanup()
+    {
+        environment.pop(Renderable.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java
new file mode 100644
index 0000000..4f90d6f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotation.BeginRender;
+import org.apache.tapestry.annotation.Environmental;
+
+/**
+ * Used, with {@link RenderableProvider}, to test the {@link Environmental} annotation.
+ */
+public class RenderableUser
+{
+    @Environmental
+    private Renderable renderable;
+
+    @BeginRender
+    void render(MarkupWriter writer)
+    {
+        renderable.render(writer);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Strong.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Strong.java
new file mode 100644
index 0000000..f3333da
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Strong.java
@@ -0,0 +1,30 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+
+public class Strong
+{
+    void beginRender(MarkupWriter writer)
+    {
+        writer.element("strong");
+    }
+
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Tracer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Tracer.java
new file mode 100644
index 0000000..3a056fd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Tracer.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.components;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.annotation.AfterRender;

+import org.apache.tapestry.annotation.BeginRender;

+

+public class Tracer extends AbstractTracer

+{

+    @BeginRender

+    void beginChild(MarkupWriter writer)

+    {

+        writer.write("BEGIN-TRACER ");

+    }

+

+    @AfterRender

+    void afterChild(MarkupWriter writer)

+    {

+        writer.write("AFTER-TRACER ");

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/BirthdayReminder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/BirthdayReminder.java
new file mode 100644
index 0000000..947eb4f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/BirthdayReminder.java
@@ -0,0 +1,49 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+import java.util.Date;
+
+public class BirthdayReminder
+{
+    private String name;
+
+    private Date date;
+
+    @Validate("required")
+    public String getName()
+    {
+        return name;
+    }
+
+    @Validate("required")
+    public Date getDate()
+    {
+        return date;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public void setDate(Date date)
+    {
+        this.date = date;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Department.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Department.java
new file mode 100644
index 0000000..27b5d67
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Department.java
@@ -0,0 +1,21 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public enum Department
+{
+
+    ACCOUNTING, RESEARCH_AND_DESIGN, IT, SALES_AND_MARKETING
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IncidentData.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IncidentData.java
new file mode 100644
index 0000000..bb46ee8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IncidentData.java
@@ -0,0 +1,98 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+import java.io.Serializable;
+
+public class IncidentData implements Serializable
+{
+    private static final long serialVersionUID = -321606932140181054L;
+
+    private String email;
+
+    private String message;
+
+    private boolean urgent;
+
+    private String operatingSystem;
+
+    private int hours;
+
+    private Department department;
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    @Validate("required")
+    public void setMessage(String message)
+    {
+        this.message = message;
+    }
+
+    public boolean isUrgent()
+    {
+        return urgent;
+    }
+
+    public void setUrgent(boolean urgent)
+    {
+        this.urgent = urgent;
+    }
+
+    public String getOperatingSystem()
+    {
+        return operatingSystem;
+    }
+
+    public void setOperatingSystem(String os)
+    {
+        operatingSystem = os;
+    }
+
+    public int getHours()
+    {
+        return hours;
+    }
+
+    public void setHours(int hours)
+    {
+        this.hours = hours;
+    }
+
+    public Department getDepartment()
+    {
+        return department;
+    }
+
+    public void setDepartment(Department department)
+    {
+        this.department = department;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IntegerHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IntegerHolder.java
new file mode 100644
index 0000000..c12f78a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/IntegerHolder.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public class IntegerHolder
+{
+    private Integer value;
+
+    public Integer getValue()
+    {
+        return value;
+    }
+
+    public void setValue(Integer value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
new file mode 100644
index 0000000..49bb1f3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ProgrammingLanguage.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public enum ProgrammingLanguage
+{
+    ADA, ASSEMBLY, C, ERLANG, HASKELL, JAVA, JAVASCRIPT, LISP, ML, PERL, PYTHON, RUBY, SCALA, SCHEME
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java
new file mode 100644
index 0000000..5303e84
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RegistrationData.java
@@ -0,0 +1,115 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.*;
+
+public class RegistrationData
+{
+    private String lastName;
+
+    private String firstName;
+
+    private int birthYear;
+
+    private Sex sex = Sex.MALE;
+
+    private boolean citizen;
+
+    private String password;
+
+    private String notes;
+
+    @OrderAfter("lastName")
+    @Validate("min=1900,max=2007")
+    @Width(4)
+    public int getBirthYear()
+    {
+        return birthYear;
+    }
+
+    @OrderAfter("lastname,birthyear")
+    public Sex getSex()
+    {
+        return sex;
+    }
+
+    @OrderBefore("lastname")
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    @Validate("required,minlength=5")
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    @Validate("required,minlength=6")
+    @DataType("password")
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public boolean isCitizen()
+    {
+        return citizen;
+    }
+
+    public void setBirthYear(int birthYear)
+    {
+        this.birthYear = birthYear;
+    }
+
+    @Validate("required,minlength=3")
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    public void setSex(Sex sex)
+    {
+        this.sex = sex;
+    }
+
+    public void setCitizen(boolean citizen)
+    {
+        this.citizen = citizen;
+    }
+
+    @DataType("longtext")
+    @Width(50)
+    public String getNotes()
+    {
+        return notes;
+    }
+
+    public void setNotes(String notes)
+    {
+        this.notes = notes;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RoleAccess.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RoleAccess.java
new file mode 100644
index 0000000..6394213
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RoleAccess.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public enum RoleAccess
+{
+    GRANT, DENY;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RolePath.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RolePath.java
new file mode 100644
index 0000000..3f3ec76
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/RolePath.java
@@ -0,0 +1,47 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+public class RolePath
+{
+    private String path;
+
+    private RoleAccess role = RoleAccess.GRANT;
+
+    @Validate("required")
+    public String getPath()
+    {
+        return path;
+    }
+
+    @Validate("required")
+    public RoleAccess getRole()
+    {
+        return role;
+    }
+
+    public void setPath(String path)
+    {
+        this.path = path;
+    }
+
+    public void setRole(RoleAccess role)
+    {
+        this.role = role;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Sex.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Sex.java
new file mode 100644
index 0000000..77ed539
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Sex.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public enum Sex
+{
+    MALE, FEMALE, TRANSGENDERED, MARTIAN
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java
new file mode 100644
index 0000000..273eb4e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SimpleTrack.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.OrderBefore;
+
+public interface SimpleTrack
+{
+    @OrderBefore("album")
+    String getTitle();
+
+    @OrderBefore("rating")
+    String getAlbum();
+
+    int getRating();
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java
new file mode 100644
index 0000000..d3cd7c5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java
@@ -0,0 +1,56 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+public class SubscribeData
+{
+    private String name, email, code;
+
+    @Validate("required")
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    // Only really required if visible!
+    @Validate("required")
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    @Validate("required")
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(String code)
+    {
+        this.code = code;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ToDoItem.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ToDoItem.java
new file mode 100644
index 0000000..c63c41d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/ToDoItem.java
@@ -0,0 +1,96 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.NonVisual;
+import org.apache.tapestry.beaneditor.Validate;
+
+import java.io.Serializable;
+
+public class ToDoItem implements Serializable, Cloneable
+{
+    private static final long serialVersionUID = 329624498668043734L;
+
+    private long id;
+
+    private String title;
+
+    private int order;
+
+    private Urgency urgency = Urgency.MEDIUM;
+
+    @Override
+    public String toString()
+    {
+        return String.format("ToDoItem[%d %s]", id, title);
+    }
+
+    @Override
+    public ToDoItem clone()
+    {
+        try
+        {
+            return (ToDoItem) super.clone();
+        }
+        catch (CloneNotSupportedException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @NonVisual
+    public long getId()
+    {
+        return id;
+    }
+
+    public void setId(long id)
+    {
+        this.id = id;
+    }
+
+    @Validate("required")
+    public String getTitle()
+    {
+        return title;
+    }
+
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    public Urgency getUrgency()
+    {
+        return urgency;
+    }
+
+    public void setUrgency(Urgency urgency)
+    {
+        this.urgency = urgency;
+    }
+
+    @NonVisual
+    public int getOrder()
+    {
+        return order;
+    }
+
+    public void setOrder(int order)
+    {
+        this.order = order;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Track.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Track.java
new file mode 100644
index 0000000..f846f50
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Track.java
@@ -0,0 +1,104 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.NonVisual;
+
+/**
+ * One track from a music library.
+ */
+public class Track implements SimpleTrack
+{
+    private Long id;
+
+    private String album, artist, genre, title;
+
+    private int playCount, rating;
+
+    @NonVisual
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public String getTitle()
+    {
+        return title;
+    }
+
+    public String getAlbum()
+    {
+        return album;
+    }
+
+    public String getArtist()
+    {
+        return artist;
+    }
+
+    public String getGenre()
+    {
+        return genre;
+    }
+
+    public int getPlayCount()
+    {
+        return playCount;
+    }
+
+    /**
+     * Rating as a value between 0 and 100.
+     */
+    public int getRating()
+    {
+        return rating;
+    }
+
+    public void setAlbum(String album)
+    {
+        this.album = album;
+    }
+
+    public void setArtist(String artist)
+    {
+        this.artist = artist;
+    }
+
+    public void setGenre(String genre)
+    {
+        this.genre = genre;
+    }
+
+    public void setPlayCount(int playCount)
+    {
+        this.playCount = playCount;
+    }
+
+    public void setRating(int rating)
+    {
+        this.rating = rating;
+    }
+
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Urgency.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Urgency.java
new file mode 100644
index 0000000..810dadb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/Urgency.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+public enum Urgency
+{
+    LOW, MEDIUM, HIGH
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/UserCredentials.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/UserCredentials.java
new file mode 100644
index 0000000..caa2724
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/UserCredentials.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+public class UserCredentials
+{
+    private String lastName, firstName;
+
+    @Validate("required")
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    @Validate("required")
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/Emphasis.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/Emphasis.java
new file mode 100644
index 0000000..8878070
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/Emphasis.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.mixins;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.AfterRender;
+import org.apache.tapestry.annotation.BeginRender;
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * Mixin that adds emphasis to a component if a test is true.
+ */
+public class Emphasis
+{
+    @Parameter(required = true)
+    private boolean test;
+
+    @BeginRender
+    void begin(MarkupWriter writer)
+    {
+        if (test)
+            writer.element("em");
+    }
+
+    @AfterRender
+    void after(MarkupWriter writer)
+    {
+        if (test)
+            writer.end();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/TracerMixin.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/TracerMixin.java
new file mode 100644
index 0000000..1af7ea1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/mixins/TracerMixin.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.mixins;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.annotation.AfterRender;

+import org.apache.tapestry.annotation.BeginRender;

+

+public class TracerMixin

+{

+    @BeginRender

+    void begin(MarkupWriter writer)

+    {

+        writer.write("BEGIN-TRACER-MIXIN ");

+    }

+

+    @AfterRender

+    void after(MarkupWriter writer)

+    {

+        writer.write("AFTER-TRACER-MIXIN");

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionPage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionPage.java
new file mode 100644
index 0000000..026c6c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionPage.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class ActionPage
+{
+    private int index;
+
+    // Must be persistent, to survive from one request to the next.
+    // An action request is always followed by a redirect request.
+    @Persist
+    private int value;
+
+    void onActionFromChoose(int value)
+    {
+        this.value = value;
+    }
+
+    public int getIndex()
+    {
+        return index;
+    }
+
+    public void setIndex(int index)
+    {
+        this.index = index;
+    }
+
+    public int getValue()
+    {
+        return value;
+    }
+
+    public String getLinkClass()
+    {
+        return index == value ? "selected" : null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionViaLinkDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionViaLinkDemo.java
new file mode 100644
index 0000000..2eaf15c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ActionViaLinkDemo.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class ActionViaLinkDemo
+{
+    @Persist("flash")
+    private String message;
+
+    @Inject
+    private ComponentResources resources;
+
+    Object[]
+    onPassivate()
+    {
+        return new Object[] { };
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    void onUpdateMessage(String message)
+    {
+        getActionURL();
+
+        this.message = message;
+    }
+
+    public String getActionURL()
+    {
+        Link link = resources.createActionLink("UpdateMessage", false, "from getActionURL()");
+
+        return link.toURI();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AddedGridColumnsDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AddedGridColumnsDemo.java
new file mode 100644
index 0000000..5dd6e5a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AddedGridColumnsDemo.java
@@ -0,0 +1,79 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanModelSource;
+
+import java.util.List;
+
+public class AddedGridColumnsDemo
+{
+    @Component(parameters = { "source=tracks", "row=track", "model=model" })
+    private Grid grid;
+
+    @Inject
+    private MusicLibrary library;
+
+    private Track track;
+
+    @Inject
+    private BeanModelSource source;
+
+    private final BeanModel model;
+
+    @Inject
+    private ComponentResources resources;
+
+    {
+        model = source.create(Track.class, true, resources);
+
+        model.exclude("album", "artist", "genre", "playcount", "rating");
+
+        model.add("viewlink", null);
+
+        model.add("title.length()").label("Title Length");
+
+        // This is to test the case where there's no property conduit or override block.
+
+        model.add("dummy", null);
+    }
+
+    public Track getTrack()
+    {
+        return track;
+    }
+
+    public void setTrack(Track track)
+    {
+        this.track = track;
+    }
+
+    public List<Track> getTracks()
+    {
+        return library.getTracks();
+    }
+
+    public BeanModel getModel()
+    {
+        return model;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.java
new file mode 100644
index 0000000..94edb77
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class AttributeExpansionsDemo
+{
+    public String getColorScheme()
+    {
+        return "blue";
+    }
+
+    public String getStyleClass()
+    {
+        return "red";
+    }
+
+    public String getPrefix()
+    {
+        return "ALERT-";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java
new file mode 100644
index 0000000..bac5a08
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/AutocompleteDemo.java
@@ -0,0 +1,59 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.List;
+
+public class AutocompleteDemo
+{
+    @Inject
+    private MusicLibrary library;
+
+    @Persist
+    private String title;
+
+    List onProvideCompletionsFromTitle(String partialTitle) throws Exception
+    {
+        List<Track> matches = library.findByMatchingTitle(partialTitle);
+
+        List<String> result = CollectionFactory.newList();
+
+        for (Track t : matches)
+            result.add(t.getTitle());
+
+        Collections.sort(result);
+
+        // Thread.sleep(1000);
+
+        return result;
+    }
+
+    public String getTitle()
+    {
+        return title;
+    }
+
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BadTemplate.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BadTemplate.java
new file mode 100644
index 0000000..d1141f1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BadTemplate.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class BadTemplate
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Barney.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Barney.java
new file mode 100644
index 0000000..25220f8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Barney.java
@@ -0,0 +1,23 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class Barney implements Runnable
+{
+    public void run()
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditDateDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditDateDemo.java
new file mode 100644
index 0000000..76e9a53
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditDateDemo.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.integration.app1.data.BirthdayReminder;
+
+public class BeanEditDateDemo
+{
+    @ApplicationState
+    private BirthdayReminder reminder;
+
+    public BirthdayReminder getReminder()
+    {
+        return reminder;
+    }
+
+    void onActionFromClear()
+    {
+        reminder = null;
+    }
+
+    Object onSuccess()
+    {
+        return ShowBirthdayReminder.class;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java
new file mode 100644
index 0000000..e7fbe71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditRemoveReorder.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class BeanEditRemoveReorder extends BeanEditorDemo
+{
+
+    @Override
+    public boolean getClientValidation()
+    {
+        return true;
+    }
+
+    @Override
+    public String getPageTitle()
+    {
+        return "BeanEditForm: Remove and Reorder";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java
new file mode 100644
index 0000000..a0a188c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.java
@@ -0,0 +1,53 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.corelib.components.BeanEditForm;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+
+public class BeanEditorDemo
+{
+    @Component(id = "registrationData", parameters =
+            { "clientValidation=clientValidation" })
+    private BeanEditForm form;
+
+    @ApplicationState
+    @Property
+    private RegistrationData registrationData;
+
+    Object onSuccess()
+    {
+        return ViewRegistration.class;
+    }
+
+    void onActionFromClear()
+    {
+        registrationData = null;
+        form.clearErrors();
+    }
+
+    public boolean getClientValidation()
+    {
+        return false;
+    }
+
+    public String getPageTitle()
+    {
+        return "BeanEditor Component Demo";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorOverride.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorOverride.java
new file mode 100644
index 0000000..4613bf9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BeanEditorOverride.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.corelib.components.BeanEditor;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+
+public class BeanEditorOverride
+{
+    @Component
+    private Form form;
+
+    @Component(parameters = { "object=registrationData" })
+    private BeanEditor editor;
+
+    @ApplicationState
+    private RegistrationData data;
+
+    public RegistrationData getRegistrationData()
+    {
+        return data;
+    }
+
+    Object onSuccess()
+    {
+        return ViewRegistration.class;
+    }
+
+    void onActionFromClear()
+    {
+        data = null;
+        form.clearErrors();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockCaller.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockCaller.java
new file mode 100644
index 0000000..4b44700
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockCaller.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.InjectPage;
+
+/**
+ * Part of testing for TAPESTRY-2044
+ */
+public class BlockCaller
+{
+    @InjectPage
+    private BlockHolder blockHolder;
+
+    private int activationContext;
+
+    public void setActivationContext(int value)
+    {
+        activationContext = value;
+    }
+
+    public int getActivationContext()
+    {
+        return activationContext;
+    }
+
+    void onActivate(int activationContext)
+    {
+        this.activationContext = activationContext;
+    }
+
+    int onPassivate()
+    {
+        return activationContext;
+    }
+
+    public Block getBlock()
+    {
+        return blockHolder.getLinks();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java
new file mode 100644
index 0000000..deff507
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockDemo.java
@@ -0,0 +1,62 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Map;
+
+public class BlockDemo
+{
+    @Inject
+    private Block fred;
+
+    @Inject
+    private Block barney;
+
+    // Blocks not injected until page load, so must lazily initialize the map.
+    @Retain
+    private Map<String, Block> blocks = null;
+
+    @Persist
+    private String blockName;
+
+    public Block getBlockToRender()
+    {
+        if (blocks == null)
+        {
+            blocks = CollectionFactory.newMap();
+            blocks.put("fred", fred);
+            blocks.put("barney", barney);
+        }
+
+        return blocks.get(blockName);
+    }
+
+    public String getBlockName()
+    {
+        return blockName;
+    }
+
+    public void setBlockName(String blockName)
+    {
+        this.blockName = blockName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockHolder.java
new file mode 100644
index 0000000..3170a23
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BlockHolder.java
@@ -0,0 +1,51 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class BlockHolder
+{
+    @InjectPage
+    private BlockCaller blockCaller;
+
+
+    @Inject
+    private Block links;
+
+    private int index;
+
+    public int getIndex()
+    {
+        return index;
+    }
+
+    public void setIndex(int index)
+    {
+        this.index = index;
+    }
+
+    void onActionFromLink(int eventContext)
+    {
+        blockCaller.setActivationContext(eventContext);
+    }
+
+    Block getLinks()
+    {
+        return links;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BooleanDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BooleanDemo.java
new file mode 100644
index 0000000..5105a52
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/BooleanDemo.java
@@ -0,0 +1,44 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class BooleanDemo
+{
+    @Persist
+    private boolean flag;
+
+    public boolean getFlagUsingGet()
+    {
+        return flag;
+    }
+
+    public boolean isFlagUsingIs()
+    {
+        return flag;
+    }
+
+    public void onActionFromSet()
+    {
+        flag = true;
+    }
+
+    public void onActionFromClear()
+    {
+        flag = false;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage.java
new file mode 100644
index 0000000..46a5a1e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage.java
@@ -0,0 +1,58 @@
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Cached;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CachedPage
+{
+    private int value;
+    private List<String> value2;
+    private int value3;
+
+    private Integer watchValue;
+
+    void beginRender()
+    {
+        value = 0;
+        value2 = new ArrayList<String>();
+        value3 = 0;
+        watchValue = 0;
+    }
+
+    @Cached
+    public int getValue()
+    {
+        return value++;
+    }
+
+    @Cached
+    public List<String> getValue2()
+    {
+        value2.add("a");
+        return value2;
+    }
+
+    @Cached(watch = "watchValue")
+    public int getValue3()
+    {
+        return value3++;
+    }
+
+    public Integer getWatchValue()
+    {
+        return watchValue;
+    }
+
+    public void setWatchValue(Integer watchValue)
+    {
+        this.watchValue = watchValue;
+    }
+
+    public Object incrWatchValue()
+    {
+        watchValue++;
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage2.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage2.java
new file mode 100644
index 0000000..402c2c4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CachedPage2.java
@@ -0,0 +1,24 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class CachedPage2 extends CachedPage {
+
+	@Override
+	public int getValue() {
+		return super.getValue()+1;
+	}
+	
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClassLoaderInspect.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClassLoaderInspect.java
new file mode 100644
index 0000000..b03c28c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClassLoaderInspect.java
@@ -0,0 +1,242 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+
+public class ClassLoaderInspect
+{
+    private static final ClassLoader CLASS_LOADER = Thread.currentThread().getContextClassLoader();
+
+    private ClassLoader loader;
+
+    @Persist
+    private String resource;
+
+    @Component
+    private Form search;
+
+    @Persist
+    private List<URL> URLs;
+
+    @Persist
+    private boolean showMatches;
+
+    private URL URL;
+
+    private JarEntry jarEntry;
+
+    public URL getURL()
+    {
+        return URL;
+    }
+
+    public void setURL(URL url)
+    {
+        URL = url;
+    }
+
+    public ClassLoader getClassLoader()
+    {
+        return CLASS_LOADER;
+    }
+
+    public ClassLoader getLoader()
+    {
+        return loader;
+    }
+
+    public void setLoader(ClassLoader loader)
+    {
+        this.loader = loader;
+    }
+
+    public List<ClassLoader> getLoaders()
+    {
+        List<ClassLoader> result = CollectionFactory.newList();
+
+        ClassLoader current = getClass().getClassLoader();
+
+        while (current != null)
+        {
+            result.add(0, current);
+
+            current = current.getParent();
+        }
+
+        return result;
+    }
+
+    public int getListSize()
+    {
+        return URLs == null ? 0 : URLs.size();
+    }
+
+    void onFailure()
+    {
+        showMatches = false;
+        URLs = null;
+    }
+
+    void onSuccess()
+    {
+        showMatches = false;
+
+        URLs = null;
+
+        try
+        {
+            List<URL> urls = CollectionFactory.newList();
+
+            Enumeration<URL> e = CLASS_LOADER.getResources(resource);
+
+            while (e.hasMoreElements())
+                urls.add(e.nextElement());
+
+            URLs = urls;
+
+            showMatches = true;
+        }
+        catch (Exception ex)
+        {
+            String message = ex.getMessage();
+
+            if (InternalUtils.isBlank(message))
+                message = ex.getClass().getName();
+
+            search.recordError(message);
+        }
+    }
+
+    public String getResource()
+    {
+        return resource;
+    }
+
+    public void setResource(String resource)
+    {
+        this.resource = resource;
+    }
+
+    public List<URL> getURLs()
+    {
+        return URLs;
+    }
+
+    public boolean getShowMatches()
+    {
+        return showMatches;
+    }
+
+    public String getContentStreamContents()
+    {
+        StringBuilder builder = new StringBuilder();
+
+        try
+        {
+            InputStream is = URL.openStream();
+            InputStreamReader reader = new InputStreamReader(is);
+
+            char[] buffer = new char[1000];
+
+            while (true)
+            {
+                int length = reader.read(buffer);
+
+                if (length < 0)
+                    break;
+
+                builder.append(buffer, 0, length);
+            }
+
+            reader.close();
+
+            return builder.toString();
+        }
+        catch (Exception ex)
+        {
+            return ex.getMessage();
+        }
+    }
+
+    public List<JarEntry> getJarEntries()
+    {
+        try
+        {
+            URLConnection rawConnection = URL.openConnection();
+
+            JarURLConnection jarConnection = (JarURLConnection) rawConnection;
+
+            JarEntry rootEntry = jarConnection.getJarEntry();
+
+            List<JarEntry> result = CollectionFactory.newList();
+
+            if (rootEntry.isDirectory())
+            {
+                Enumeration<JarEntry> e = jarConnection.getJarFile().entries();
+
+                while (e.hasMoreElements())
+                    result.add(e.nextElement());
+            }
+            else
+            {
+                result.add(rootEntry);
+            }
+
+            return result;
+        }
+        catch (Exception ex)
+        {
+            return null;
+        }
+
+    }
+
+    public URLConnection getURLConnection()
+    {
+        try
+        {
+            return URL.openConnection();
+        }
+        catch (IOException ex)
+        {
+            return null;
+        }
+    }
+
+    public JarEntry getJarEntry()
+    {
+        return jarEntry;
+    }
+
+    public void setJarEntry(JarEntry jarEntry)
+    {
+        this.jarEntry = jarEntry;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CleanCacheDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CleanCacheDemo.java
new file mode 100644
index 0000000..d12de6a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/CleanCacheDemo.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Cached;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.corelib.components.Zone;
+
+public class CleanCacheDemo
+{
+    @Component
+    private Zone aZone;
+
+    Object onActionFromUpdateZone()
+    {
+        return aZone;
+    }
+
+    @Cached
+    public long getTimeNanos()
+    {
+        return System.nanoTime();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClientPersistenceDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClientPersistenceDemo.java
new file mode 100644
index 0000000..80cbe78
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ClientPersistenceDemo.java
@@ -0,0 +1,53 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.Request;
+
+public class ClientPersistenceDemo
+{
+    @Persist("client")
+    private Object persistedValue;
+
+    @Inject
+    private Request request;
+
+    public Object getPersistedValue()
+    {
+        return persistedValue;
+    }
+
+    public boolean getSessionExists()
+    {
+        return request.getSession(false) != null;
+    }
+
+    void onActionFromStoreString()
+    {
+        persistedValue = "A String";
+    }
+
+    void onActionFromStoreBad()
+    {
+        persistedValue = new Runnable()
+        {
+            public void run()
+            {
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ComponentParameter.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ComponentParameter.java
new file mode 100644
index 0000000..64efd14
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ComponentParameter.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class ComponentParameter
+{
+    @Persist("flash")
+    private String message;
+
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    void onActionFromBlockAction()
+    {
+        message = "Link was clicked.";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java
new file mode 100644
index 0000000..fda9a05
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java
@@ -0,0 +1,38 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.integration.app1.components.Count;
+
+public class Countdown
+{
+    @SuppressWarnings("unused")
+    @Component(parameters =
+            { "start=10", "end=1", "value=countValue" })
+    private Count count;
+
+    private int countValue;
+
+    public int getCountValue()
+    {
+        return countValue;
+    }
+
+    public void setCountValue(int countValue)
+    {
+        this.countValue = countValue;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DateFieldDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DateFieldDemo.java
new file mode 100644
index 0000000..d999382
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DateFieldDemo.java
@@ -0,0 +1,58 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.beaneditor.Validate;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateFieldDemo
+{
+    @Persist
+    private Date birthday;
+
+    @Persist
+    private Date asteroidImpact;
+
+    @Validate("required")
+    public Date getBirthday()
+    {
+        return birthday;
+    }
+
+    public void setBirthday(Date birthday)
+    {
+        this.birthday = birthday;
+    }
+
+    public DateFormat getDateFormat()
+    {
+        return new SimpleDateFormat("MM/dd/yyyy");
+    }
+
+    @Validate("required")
+    public Date getAsteroidImpact()
+    {
+        return asteroidImpact;
+    }
+
+    public void setAsteroidImpact(Date asteroidImpact)
+    {
+        this.asteroidImpact = asteroidImpact;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Datum.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Datum.java
new file mode 100644
index 0000000..c0d963b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Datum.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+/**
+ * This isn't a page class and doesn't belong here.
+ */
+public class Datum
+{
+    protected int _value;
+
+    public int getValue()
+    {
+        return _value;
+    }
+
+    public void setValue(int value)
+    {
+        _value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DatumEditor.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DatumEditor.java
new file mode 100644
index 0000000..7aefb01
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DatumEditor.java
@@ -0,0 +1,27 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.annotation.Retain;
+
+public class DatumEditor
+{
+    @Retain
+    @Property(write = false)
+    private Datum datum = new Datum();
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DeleteFromGridDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DeleteFromGridDemo.java
new file mode 100644
index 0000000..41a145a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DeleteFromGridDemo.java
@@ -0,0 +1,64 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+import org.apache.tapestry.integration.app1.services.ToDoDatabase;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+public class DeleteFromGridDemo
+{
+    @Inject
+    private ToDoDatabase database;
+
+    private ToDoItem item;
+
+    void onActionFromSetup()
+    {
+        database.clear();
+
+        for (int i = 1; i <= 10; i++)
+        {
+            ToDoItem item = new ToDoItem();
+            item.setTitle(String.format("ToDo #%d", i));
+            item.setOrder(i);
+
+            database.add(item);
+        }
+    }
+
+    void onActionFromDelete(long id)
+    {
+        database.remove(id);
+    }
+
+    public List<ToDoItem> getItems()
+    {
+        return database.findAll();
+    }
+
+    public ToDoItem getItem()
+    {
+        return item;
+    }
+
+    public void setItem(ToDoItem item)
+    {
+        this.item = item;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DisabledFields.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DisabledFields.java
new file mode 100644
index 0000000..aa435f6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/DisabledFields.java
@@ -0,0 +1,79 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.internal.services.StringValueEncoder;
+
+import java.util.Date;
+import java.util.List;
+
+public class DisabledFields
+{
+    private String stringValue;
+
+    private boolean flag;
+
+    private Date date;
+
+    private List<String> values;
+
+    @Validate("required")
+    public String getStringValue()
+    {
+        return stringValue;
+    }
+
+    public void setStringValue(String stringValue)
+    {
+        this.stringValue = stringValue;
+    }
+
+    public boolean isFlag()
+    {
+        return flag;
+    }
+
+    public void setFlag(boolean flag)
+    {
+        this.flag = flag;
+    }
+
+    public Date getDate()
+    {
+        return date;
+    }
+
+    public void setDate(Date date)
+    {
+        this.date = date;
+    }
+
+    public List<String> getValues()
+    {
+        return values;
+    }
+
+    public void setValues(List<String> values)
+    {
+        this.values = values;
+    }
+
+    public ValueEncoder getEncoder()
+    {
+        return new StringValueEncoder();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java
new file mode 100644
index 0000000..eb68bcc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class EnvironmentalDemo
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventHandlerDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventHandlerDemo.java
new file mode 100644
index 0000000..52f393f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventHandlerDemo.java
@@ -0,0 +1,68 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.integration.app1.base.BaseEventHandlerDemo;
+
+public class EventHandlerDemo extends BaseEventHandlerDemo
+{
+    @SuppressWarnings("unused")
+    private void onAction()
+    {
+        addMethodName("child.onAction()");
+    }
+
+    @SuppressWarnings("unused")
+    private void onAction(String value)
+    {
+        addMethodName("child.onAction(String)");
+    }
+
+    @SuppressWarnings("unused")
+    private void onActionFromFred()
+    {
+        addMethodName("child.onActionFromFred()");
+    }
+
+    @SuppressWarnings("unused")
+    private void onActionFromFred(String value)
+    {
+        addMethodName("child.onActionFromFred(String)");
+    }
+
+    @OnEvent(value = "action")
+    void eventHandlerZeroChild()
+    {
+        addMethodName("child.eventHandlerZeroChild()");
+    }
+
+    @OnEvent(value = "action")
+    void eventHandlerOneChild(String value)
+    {
+        addMethodName("child.eventHandlerOneChild()");
+    }
+
+    @OnEvent(component = "fred")
+    void eventHandlerForFred()
+    {
+        addMethodName("child.eventHandlerForFred()");
+    }
+
+    public Object[] getTwoContext()
+    {
+        return new Object[] { 1, 2 };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventMethodTranslate.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventMethodTranslate.java
new file mode 100644
index 0000000..7df6f69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/EventMethodTranslate.java
@@ -0,0 +1,65 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.annotation.Persist;
+
+public class EventMethodTranslate
+{
+    @Persist
+    private int count;
+
+    public int getCount()
+    {
+        return count;
+    }
+
+    public void setCount(int count)
+    {
+        this.count = count;
+    }
+
+    String onToClientFromCount()
+    {
+        if (count == 0) return "zero";
+
+        // Get the default behavior
+        return null;
+    }
+
+    Object onParseClientFromCount(String input) throws ValidationException
+    {
+        if (input == null || input.equals("")) return null;
+
+        // And it gets tricky because we probably should trim spaces!
+
+        if (input.equalsIgnoreCase("zero")) return 0;
+
+        if (input.equalsIgnoreCase("i")) throw new ValidationException("Rational numbers only, please.");
+
+        // Get the default behavior.
+
+        return null;
+    }
+
+    void onValidateFromCount(Integer count) throws ValidationException
+    {
+        // count may be null
+        if (count == null) return;
+
+        if (count.equals(13)) throw new ValidationException("Thirteen is an unlucky number.");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExceptionEventDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExceptionEventDemo.java
new file mode 100644
index 0000000..e7515a6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExceptionEventDemo.java
@@ -0,0 +1,71 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class ExceptionEventDemo
+{
+    @Persist("flash")
+    private String message;
+
+    @Persist
+    private boolean intercept = true;
+
+    public Object getInvalidContext()
+    {
+        return "abc";
+    }
+
+    void onActivate(float context)
+    {
+        message = "Activation context: " + context;
+    }
+
+    void onActionFromFail(float context)
+    {
+        message = "Event context: " + context;
+    }
+
+    Object onException(Throwable exception)
+    {
+        if (!intercept) return null;
+
+        message = "Exception: " + exception.getMessage();
+
+        return this;
+    }
+
+
+    void onActionFromEnable()
+    {
+        intercept = true;
+    }
+
+    void onActionFromDisable()
+    {
+        intercept = false;
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public boolean isIntercept()
+    {
+        return intercept;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Expansion.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Expansion.java
new file mode 100644
index 0000000..69d8130
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Expansion.java
@@ -0,0 +1,23 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class Expansion
+{
+    public String getExpansionValue()
+    {
+        return "value provided by a template expansion";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExpansionSubclass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExpansionSubclass.java
new file mode 100644
index 0000000..a1623cc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ExpansionSubclass.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class ExpansionSubclass extends Expansion
+{
+    @Override
+    public String getExpansionValue()
+    {
+        return "value provided, in the subclass, via a template expansion";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FlashDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FlashDemo.java
new file mode 100644
index 0000000..04f7d63
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FlashDemo.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.base.BaseComponent;
+
+@Meta("tapestry.persistence-strategy=flash")
+public class FlashDemo extends BaseComponent
+{
+    @Persist
+    private String message;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    void onAction()
+    {
+        message = "You clicked the link!";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormEncodingType.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormEncodingType.java
new file mode 100644
index 0000000..4c0b478
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormEncodingType.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.services.FormSupport;
+
+public class FormEncodingType
+{
+    @Environmental
+    private FormSupport support;
+
+    public Renderable getForceEncodingType()
+    {
+        return new Renderable()
+        {
+            public void render(MarkupWriter writer)
+            {
+                support.setEncodingType("x-override");
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java
new file mode 100644
index 0000000..dbc4a1b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java
@@ -0,0 +1,64 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.SubscribeData;
+
+public class FormFragmentDemo
+{
+    @Property
+    private SubscribeData subscribe;
+
+    @Property
+    private boolean subscribeToEmail;
+
+    @Property
+    private boolean codeVisible;
+
+    @Component
+    private Form form;
+
+    @InjectPage
+    private FormFragmentOutput outputPage;
+
+    public SubscribeData getSubscribe()
+    {
+        return subscribe;
+    }
+
+    void onPrepare()
+    {
+        subscribe = new SubscribeData();
+    }
+
+    void onActionFromClear()
+    {
+        form.clearErrors();
+    }
+
+    Object onFailure()
+    {
+        throw new RuntimeException("Show me the Request!");
+    }
+
+    Object onSuccess()
+    {
+        return outputPage.initialize(subscribe);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java
new file mode 100644
index 0000000..313f6bb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.SubscribeData;
+
+public class FormFragmentOutput
+{
+    @Persist
+    private SubscribeData subscribe;
+
+    FormFragmentOutput initialize(SubscribeData subscribe)
+    {
+        this.subscribe = subscribe;
+        return this;
+    }
+
+    public SubscribeData getSubscribe()
+    {
+        return subscribe;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormInjectorDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormInjectorDemo.java
new file mode 100644
index 0000000..6c87eb9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormInjectorDemo.java
@@ -0,0 +1,77 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.corelib.components.FormInjector;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class FormInjectorDemo
+{
+    @Persist
+    private double sum;
+
+    private double value;
+
+    @Inject
+    private Block newRow;
+
+    @Inject
+    private RenderSupport renderSupport;
+
+    @Component
+    private FormInjector formInjector;
+
+    public double getSum()
+    {
+        return sum;
+    }
+
+    public double getValue()
+    {
+        return value;
+    }
+
+    public void setValue(double value)
+    {
+        this.value = value;
+    }
+
+    void onPrepareForSubmit()
+    {
+        sum = 0;
+    }
+
+    void onAfterSubmit()
+    {
+        sum += value;
+    }
+
+
+    void afterRender()
+    {
+        renderSupport.addScript(
+                "$('addnewrow').observe('click', function() { $('%s').trigger(); return false; });",
+                formInjector.getClientId());
+    }
+
+    Object onActionFromFormInjector()
+    {
+        return newRow;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Fred.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Fred.java
new file mode 100644
index 0000000..b2c12b2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Fred.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class Fred
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridDemo.java
new file mode 100644
index 0000000..371baad
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridDemo.java
@@ -0,0 +1,59 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+public class GridDemo
+{
+    @Inject
+    private MusicLibrary library;
+
+    private Track track;
+
+    @Component
+    private Grid grid;
+
+    public Track getTrack()
+    {
+        return track;
+    }
+
+    public void setTrack(Track track)
+    {
+        this.track = track;
+    }
+
+    public List<Track> getTracks()
+    {
+        return library.getTracks();
+    }
+
+    void onActionFromSortRating()
+    {
+        grid.getSortModel().updateSort("rating");
+    }
+
+    void onActionFromReset()
+    {
+        grid.reset();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridEnumDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridEnumDemo.java
new file mode 100644
index 0000000..6abbf1a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridEnumDemo.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.services.ToDoDatabase;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+/**
+ * Used to demonstrate the built-in support for enum types.
+ */
+public class GridEnumDemo
+{
+    @Inject
+    private ToDoDatabase database;
+
+    void onActionFromReset()
+    {
+        database.reset();
+    }
+
+    public ToDoDatabase getDatabase()
+    {
+        return database;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridFormDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridFormDemo.java
new file mode 100644
index 0000000..b00c839
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridFormDemo.java
@@ -0,0 +1,76 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+import org.apache.tapestry.integration.app1.services.ToDoDatabase;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+public class GridFormDemo
+{
+    @Inject
+    private ToDoDatabase database;
+
+    private ToDoItem item;
+
+    private List<ToDoItem> items;
+
+    void onPrepare()
+    {
+        items = database.findAll();
+    }
+
+    void onSuccess()
+    {
+        // Here's the down side: we don't have a good way of identifying just what changed.
+        // If we provided our own GridDataSource, we would be able to update just the items
+        // currently visible. But as is, we have to update each one!
+
+        for (ToDoItem item : items)
+            database.update(item);
+    }
+
+    public List<ToDoItem> getItems()
+    {
+        return items;
+    }
+
+    public ToDoItem getItem()
+    {
+        return item;
+    }
+
+    public void setItem(ToDoItem item)
+    {
+        this.item = item;
+    }
+
+    void onActionFromReset()
+    {
+        database.clear();
+
+        for (int i = 0; i < 20; i++)
+        {
+            ToDoItem item = new ToDoItem();
+            item.setTitle("ToDo # " + (i + 1));
+            item.setOrder(i);
+
+            database.add(item);
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridRemoveReorderDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridRemoveReorderDemo.java
new file mode 100644
index 0000000..5c3899a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridRemoveReorderDemo.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class GridRemoveReorderDemo extends GridDemo
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridSetDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridSetDemo.java
new file mode 100644
index 0000000..9646e1c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/GridSetDemo.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Set;
+
+public class GridSetDemo
+{
+    @Inject
+    private MusicLibrary library;
+
+    private Track track;
+
+    public Track getTrack()
+    {
+        return track;
+    }
+
+    public void setTrack(Track track)
+    {
+        this.track = track;
+    }
+
+    public Set<Track> getTracks()
+    {
+        return CollectionFactory.newSet(library.getTracks());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/IndirectProtectedFields.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/IndirectProtectedFields.java
new file mode 100644
index 0000000..29a2051
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/IndirectProtectedFields.java
@@ -0,0 +1,28 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class IndirectProtectedFields
+{
+    @InjectPage
+    private ProtectedFields protectedFields;
+
+    Object onActionFromGo()
+    {
+        return protectedFields;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritInformalsDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritInformalsDemo.java
new file mode 100644
index 0000000..41962c3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritInformalsDemo.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class InheritInformalsDemo
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java
new file mode 100644
index 0000000..89f82b4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class InheritedBindingsDemo
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java
new file mode 100644
index 0000000..81a3d2d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectComponent;
+import org.apache.tapestry.corelib.components.Form;
+
+public class InjectComponentDemo
+{
+
+    @InjectComponent
+    private Form form;
+
+    @InjectComponent("form")
+    private Form form2;
+
+    public String getInjectComponentId()
+    {
+        return Form.class.getName() + "[" + form.getClientId() + "--" + form2.getClientId() + "]";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java
new file mode 100644
index 0000000..4e665a2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java
@@ -0,0 +1,24 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectComponent;
+import org.apache.tapestry.corelib.components.Form;
+
+public class InjectComponentMismatch
+{
+    @InjectComponent
+    private Form form;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.java
new file mode 100644
index 0000000..b691d3d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.java
@@ -0,0 +1,29 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+
+public class InjectContainerMismatch
+{
+    /**
+     * This mixin only works with components of type {@link Field}. That's the mismatch right there.
+     */
+    @SuppressWarnings("unused")
+    @Mixin
+    private RenderDisabled renderDisabled;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java
new file mode 100644
index 0000000..50b49b8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectDemo.java
@@ -0,0 +1,100 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.integration.app1.services.French;
+import org.apache.tapestry.integration.app1.services.Greeter;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.Request;
+
+public class InjectDemo
+{
+    // Named --- now demonstrating case insensitivity
+    // Now vestigial!
+    @Inject
+    private Request request;
+
+    @Inject
+    @Symbol("app.injected-symbol")
+    private String injectedSymbol;
+
+    // Via ComponentResourcesInjectionProvider
+    @Inject
+    private ComponentResources resources;
+
+    // Via ??? -- have to ensure that BindingSource
+    // stays unique.
+    @Inject
+    private BindingSource bindingSource;
+
+    @InjectPage
+    private Fred fred;
+
+    // Again, demonstrates case insensitivity
+    @InjectPage("barney")
+    private Runnable barney;
+
+    @Inject
+    @French
+    private Greeter greeter;
+
+    public String getGreeting()
+    {
+        return greeter.getGreeting();
+    }
+
+    public BindingSource getBindingSource()
+    {
+        return bindingSource;
+    }
+
+    public Request getRequest()
+    {
+        return request;
+    }
+
+    public ComponentResources getResources()
+    {
+        return resources;
+    }
+
+    @OnEvent(component = "fred")
+    Object clickFred()
+    {
+        return fred;
+    }
+
+    @OnEvent(component = "barney")
+    Object clickBarney()
+    {
+        return barney;
+    }
+
+    @OnEvent(component = "wilma")
+    String clickWilma()
+    {
+        return "Wilma";
+    }
+
+    public String getInjectedSymbol()
+    {
+        return injectedSymbol;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InplaceGridDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InplaceGridDemo.java
new file mode 100644
index 0000000..165cf7d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InplaceGridDemo.java
@@ -0,0 +1,25 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import java.util.Date;
+
+public class InplaceGridDemo extends GridDemo
+{
+    public Date getDate()
+    {
+        return new Date();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InstanceMixin.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InstanceMixin.java
new file mode 100644
index 0000000..ee1346f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InstanceMixin.java
@@ -0,0 +1,92 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.*;
+import org.apache.tapestry.integration.app1.components.Output;
+import org.apache.tapestry.integration.app1.mixins.Emphasis;
+
+import java.sql.Date;
+import java.text.DateFormat;
+import java.text.Format;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+public class InstanceMixin
+{
+    @SuppressWarnings("unused")
+    @Component(parameters =
+            { "value=date2", "format=format", "test=showEmphasis" })
+    @Mixins("Emphasis")
+    private Output output2;
+
+    @SuppressWarnings("unused")
+    @Component(parameters =
+            { "value=date3", "format=format", "test=showEmphasis" })
+    @MixinClasses(Emphasis.class)
+    private Output output3;
+
+    @Retain
+    private final Format format = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US);
+
+    @Retain
+    private final Date date1 = newDate(99, Calendar.JUNE, 13);
+
+    @Retain
+    private final Date date2 = newDate(101, Calendar.JULY, 15);
+
+    @Retain
+    private final Date date3 = newDate(105, Calendar.DECEMBER, 4);
+
+    @Persist
+    private boolean showEmphasis;
+
+    public Format getFormat()
+    {
+        return format;
+    }
+
+    private static Date newDate(int yearSince1900, int month, int day)
+    {
+        return new Date(new GregorianCalendar(1900 + yearSince1900, month, day).getTimeInMillis());
+    }
+
+    public Date getDate1()
+    {
+        return date1;
+    }
+
+    public Date getDate2()
+    {
+        return date2;
+    }
+
+    public Date getDate3()
+    {
+        return date3;
+    }
+
+    public boolean getShowEmphasis()
+    {
+        return showEmphasis;
+    }
+
+    @OnEvent(component = "toggle")
+    void toggle()
+    {
+        showEmphasis = !showEmphasis;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java
new file mode 100644
index 0000000..c167ce7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java
@@ -0,0 +1,24 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.WrongPackageForBaseClass;
+
+/**
+ * TAPESTRY-1934: Check for invalid base classes.
+ */
+public class InvalidSuperClass extends WrongPackageForBaseClass
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Kicker.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Kicker.java
new file mode 100644
index 0000000..b6dedef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Kicker.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class Kicker
+{
+    @InjectPage
+    private Target target;
+
+    Object onAction()
+    {
+        target.setActivationContext(new String[] { "betty", "wilma", "betty/wilma", "\u82B1\u5B50" });
+
+        return target;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/LeanGridDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/LeanGridDemo.java
new file mode 100644
index 0000000..048cd2d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/LeanGridDemo.java
@@ -0,0 +1,20 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// package org.apache.tapestry.integration.app1.pages;
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class LeanGridDemo extends GridDemo
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ListEventContextDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ListEventContextDemo.java
new file mode 100644
index 0000000..b6666be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ListEventContextDemo.java
@@ -0,0 +1,32 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import java.util.List;
+
+public class ListEventContextDemo
+{
+    private List eventContext;
+
+    public List getEventContext()
+    {
+        return eventContext;
+    }
+
+    void onActivate(List context)
+    {
+        eventContext = context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Localization.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Localization.java
new file mode 100644
index 0000000..1164750
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Localization.java
@@ -0,0 +1,65 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.PersistentLocale;
+import org.apache.tapestry.services.Request;
+
+import java.util.Locale;
+
+public class Localization
+{
+    @Inject
+    private Messages messages;
+
+
+    @Inject
+    private Locale locale;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    private PersistentLocale persistentLocale;
+
+    public Locale getLocale()
+    {
+        return locale;
+    }
+
+    public Request getRequest()
+    {
+        return request;
+    }
+
+    public String getInjectedMessage()
+    {
+        return messages.get("via-inject");
+    }
+
+
+    public void onActionFromFrench()
+    {
+        persistentLocale.set(Locale.FRENCH);
+    }
+
+    public void onActionFromEnglish()
+    {
+        persistentLocale.set(Locale.ENGLISH);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MagicValueEncoder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MagicValueEncoder.java
new file mode 100644
index 0000000..f9faedf
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MagicValueEncoder.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class MagicValueEncoder
+{
+    @Persist("flash")
+    private int number;
+
+    private static final int[] OPTIONS = { 5, 10, 25, 100 };
+
+    public int getNumber()
+    {
+        return number;
+    }
+
+    public void setNumber(int number)
+    {
+        this.number = number;
+    }
+
+    public int[] getOptions()
+    {
+        return OPTIONS;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MethodAdviceDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MethodAdviceDemo.java
new file mode 100644
index 0000000..3e3ea9a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MethodAdviceDemo.java
@@ -0,0 +1,79 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.integration.app1.services.DearGodWhyMeException;
+import org.apache.tapestry.integration.app1.services.ReverseStrings;
+
+public class MethodAdviceDemo
+{
+    @Persist
+    private String text;
+
+    @Validate("required")
+    public String getText()
+    {
+        return text;
+    }
+
+    @ReverseStrings
+    public void setText(String text)
+    {
+        this.text = text;
+    }
+
+    @ReverseStrings
+    public String getMessage()
+    {
+        return "Hello!";
+    }
+
+    @ReverseStrings
+    public int getVersion()
+    {
+        return 5;
+    }
+
+    @ReverseStrings
+    public int[] getIntArray()
+    {
+        return null;
+    }
+
+    @ReverseStrings
+    public void setIntArray(int[] array)
+    {
+    }
+
+    @ReverseStrings
+    public String[] getStringArray()
+    {
+        return null;
+    }
+
+    @ReverseStrings
+    public void setStringArray(String[] array)
+    {
+    }
+
+    @ReverseStrings
+    public String getCranky() throws DearGodWhyMeException
+    {
+        throw new DearGodWhyMeException();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MissingTemplate.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MissingTemplate.java
new file mode 100644
index 0000000..76dbac8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MissingTemplate.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+/**
+ * A page that simple doesn't have a template.
+ */
+public class MissingTemplate
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanDemoResult.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanDemoResult.java
new file mode 100644
index 0000000..18ecdf5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanDemoResult.java
@@ -0,0 +1,39 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.integration.app1.data.RolePath;
+import org.apache.tapestry.integration.app1.data.UserCredentials;
+
+public class MultiBeanDemoResult
+{
+    @ApplicationState
+    private UserCredentials credentials;
+
+    @ApplicationState
+    private RolePath rolePath;
+
+    public UserCredentials getCredentials()
+    {
+        return credentials;
+    }
+
+    public RolePath getRolePath()
+    {
+        return rolePath;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanEditDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanEditDemo.java
new file mode 100644
index 0000000..66a8da5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/MultiBeanEditDemo.java
@@ -0,0 +1,71 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.RolePath;
+import org.apache.tapestry.integration.app1.data.UserCredentials;
+
+public class MultiBeanEditDemo
+{
+    @ApplicationState
+    private UserCredentials credentials;
+
+    @ApplicationState
+    private RolePath rolePath;
+
+    @InjectPage
+    private MultiBeanDemoResult resultPage;
+
+    @Component
+    private Form form;
+
+    public UserCredentials getCredentials()
+    {
+        return credentials;
+    }
+
+    public RolePath getRolePath()
+    {
+        return rolePath;
+    }
+
+    public void setCredentials(UserCredentials credentials)
+    {
+        this.credentials = credentials;
+    }
+
+    public void setRolePath(RolePath rolePath)
+    {
+        this.rolePath = rolePath;
+    }
+
+    Object onSuccess()
+    {
+        return resultPage;
+    }
+
+    void onActionFromClear()
+    {
+        // Force these to be re-created.
+        credentials = null;
+        rolePath = null;
+
+        form.clearErrors();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Music.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Music.java
new file mode 100644
index 0000000..d93865a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Music.java
@@ -0,0 +1,44 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+public class Music
+{
+    @Inject
+    private MusicLibrary library;
+
+    private Track track;
+
+    public List<Track> getTracks()
+    {
+        return library.getTracks();
+    }
+
+    public Track getTrack()
+    {
+        return track;
+    }
+
+    public void setTrack(Track track)
+    {
+        this.track = track;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullGrid.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullGrid.java
new file mode 100644
index 0000000..e5eac07
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullGrid.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class NullGrid
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullStrategyDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullStrategyDemo.java
new file mode 100644
index 0000000..c901a85
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NullStrategyDemo.java
@@ -0,0 +1,33 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class NullStrategyDemo
+{
+    @Persist
+    private Long number;
+
+    public Long getNumber()
+    {
+        return number;
+    }
+
+    public void setNumber(Long number)
+    {
+        this.number = number;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanDisplayDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanDisplayDemo.java
new file mode 100644
index 0000000..4deebda
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanDisplayDemo.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.IntegerHolder;
+
+public class NumberBeanDisplayDemo
+{
+    @Persist
+    private IntegerHolder holder;
+
+    Object initialize(IntegerHolder holder)
+    {
+        this.holder = holder;
+
+        return this;
+    }
+
+    public IntegerHolder getHolder()
+    {
+        return holder;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanEditorDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanEditorDemo.java
new file mode 100644
index 0000000..1091539
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberBeanEditorDemo.java
@@ -0,0 +1,41 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.integration.app1.data.IntegerHolder;
+
+public class NumberBeanEditorDemo
+{
+    private IntegerHolder holder;
+
+    @InjectPage
+    private NumberBeanDisplayDemo page;
+
+    public IntegerHolder getHolder()
+    {
+        return holder;
+    }
+
+    public void setHolder(IntegerHolder holder)
+    {
+        this.holder = holder;
+    }
+
+    Object onSuccess()
+    {
+        return page.initialize(holder);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java
new file mode 100644
index 0000000..d14eebe
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/NumberSelect.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class NumberSelect
+{
+    private int index;
+
+    @InjectPage
+    private ShowSelection showSelection;
+
+    public int getIndex()
+    {
+        return index;
+    }
+
+    public void setIndex(int index)
+    {
+        this.index = index;
+    }
+
+    public boolean isNotFirst()
+    {
+        return index != 1;
+    }
+
+    Object onActionFromSelect(int index)
+    {
+        showSelection.setSelected(index);
+
+        return showSelection;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OverrideValidationDecorator.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OverrideValidationDecorator.java
new file mode 100644
index 0000000..e3472ac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/OverrideValidationDecorator.java
@@ -0,0 +1,64 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationDecorator;
+import org.apache.tapestry.integration.app1.ChattyValidationDecorator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.Environment;
+
+public class OverrideValidationDecorator
+{
+    private String value;
+
+    private long requiredValue;
+
+    @Inject
+    private Environment environment;
+
+    void beginRender(MarkupWriter writer)
+    {
+        ValidationDecorator existing = environment.peekRequired(ValidationDecorator.class);
+
+        environment.push(ValidationDecorator.class, new ChattyValidationDecorator(writer, existing));
+    }
+
+    void afterRender()
+    {
+        environment.pop(ValidationDecorator.class);
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public long getRequiredValue()
+    {
+        return requiredValue;
+    }
+
+    public void setRequiredValue(long requiredValue)
+    {
+        this.requiredValue = requiredValue;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageContextInForm.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageContextInForm.java
new file mode 100644
index 0000000..b3d1976
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageContextInForm.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class PageContextInForm
+{
+    private Object[] activationContext;
+
+    private Object object;
+
+    void onActivate(Object[] context)
+    {
+        activationContext = context;
+    }
+
+    Object[] onPassivate()
+    {
+        if (activationContext != null)
+        {
+            return activationContext;
+        }
+        else
+        {
+            return new Object[] { "betty", "wilma", "context with spaces", "context/with/slashes" };
+        }
+    }
+
+    public Object[] getActivationContext()
+    {
+        return activationContext;
+    }
+
+    public Object getObject()
+    {
+        return object;
+    }
+
+    public void setObject(Object object)
+    {
+        this.object = object;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLinkContext.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLinkContext.java
new file mode 100644
index 0000000..d84a732
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLinkContext.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class PageLinkContext
+{
+    @Inject
+    private ComponentResources resources;
+
+    public Object[] getComputedContext()
+    {
+        return new Object[] { "fred", 7, true };
+    }
+
+    public String getUnsafeCharacters()
+    {
+        return "unsafe characters: !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
+    }
+
+    public String getJapaneseKanji()
+    {
+        return "japanese kanji: \u65E5\u672C\u8A9E";
+    }
+
+    Object onActionFromNullContext()
+    {
+        return resources.createPageLink("target", true, new Object[] { null });
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLoadedDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLoadedDemo.java
new file mode 100644
index 0000000..f781471
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PageLoadedDemo.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Retain;
+
+public class PageLoadedDemo
+{
+    @Retain
+    private String message;
+
+    void pageLoaded()
+    {
+        message = "pageLoaded() was invoked.";
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java
new file mode 100644
index 0000000..787c2aa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PaletteDemo.java
@@ -0,0 +1,75 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.ProgrammingLanguage;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.util.EnumSelectModel;
+import org.apache.tapestry.util.EnumValueEncoder;
+
+import java.util.List;
+
+public class PaletteDemo
+{
+    @Inject
+    private ComponentResources resources;
+
+    @Persist
+    private List<ProgrammingLanguage> languages;
+
+    @Persist
+    private boolean reorder;
+
+    public boolean isReorder()
+    {
+        return reorder;
+    }
+
+    public void setReorder(boolean reorder)
+    {
+        this.reorder = reorder;
+    }
+
+    public List<ProgrammingLanguage> getLanguages()
+    {
+        return languages;
+    }
+
+    public void setLanguages(List<ProgrammingLanguage> selected)
+    {
+        languages = selected;
+    }
+
+    public SelectModel getLanguageModel()
+    {
+        return new EnumSelectModel(ProgrammingLanguage.class, resources.getMessages());
+    }
+
+    @SuppressWarnings("unchecked")
+    public ValueEncoder getLanguageEncoder()
+    {
+        return new EnumValueEncoder(ProgrammingLanguage.class);
+    }
+
+    void onActionFromReset()
+    {
+        reorder = false;
+        languages = null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterConflict.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterConflict.java
new file mode 100644
index 0000000..542940f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterConflict.java
@@ -0,0 +1,25 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.pages;

+

+import org.apache.tapestry.annotation.Component;

+import org.apache.tapestry.integration.app1.components.Echo;

+

+public class ParameterConflict

+{

+    @SuppressWarnings("unused")

+    @Component(parameters = "value=literal:ClassValue")

+    private Echo echo;

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterDefault.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterDefault.java
new file mode 100644
index 0000000..c535264
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ParameterDefault.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class ParameterDefault
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PasswordFieldDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PasswordFieldDemo.java
new file mode 100644
index 0000000..853d44e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PasswordFieldDemo.java
@@ -0,0 +1,73 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.corelib.components.PasswordField;
+import org.apache.tapestry.integration.app1.services.UserAuthenticator;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class PasswordFieldDemo
+{
+    @Retain
+    private String userName;
+
+    // Normally not retained, just want to prove that the output value is always the blank string.
+    @Retain
+    private String password;
+
+    @Inject
+    private UserAuthenticator authenticator;
+
+    @Component(id = "password")
+    private PasswordField passwordField;
+
+    @Component
+    private Form form;
+
+    String onSuccess()
+    {
+        if (!authenticator.isValid(userName, password))
+        {
+            form.recordError(passwordField, "Invalid user name or password.");
+            return null;
+        }
+
+        return "PostLogin";
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public String getUserName()
+    {
+        return userName;
+    }
+
+    public void setUserName(String userName)
+    {
+        this.userName = userName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java
new file mode 100644
index 0000000..bdf1bfd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PersistentDemo.java
@@ -0,0 +1,43 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class PersistentDemo
+{
+    @Persist
+    private String message;
+
+    @Inject
+    private ComponentResources resources;
+
+    void onActionFromUpdateMessage(String message)
+    {
+        this.message = message;
+    }
+
+    void onActionFromDiscardChanges()
+    {
+        resources.discardPersistentFieldChanges();
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PostLogin.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PostLogin.java
new file mode 100644
index 0000000..501b1f0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PostLogin.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class PostLogin
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PrimitiveArrayParameterDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PrimitiveArrayParameterDemo.java
new file mode 100644
index 0000000..c548624
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/PrimitiveArrayParameterDemo.java
@@ -0,0 +1,24 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.package org.apache.tapestry.integration.app1.pages;
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class PrimitiveArrayParameterDemo
+{
+
+    public int[] getValues()
+    {
+        return new int[]{1, 3, 5, 7, 9};
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java
new file mode 100644
index 0000000..0283e8c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Protected.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class Protected
+{
+    @InjectPage
+    private SecurityAlert alertPage;
+
+    Object onActivate()
+    {
+        alertPage.setMessage("Access to Protected page is denied.");
+
+        return alertPage;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ProtectedFields.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ProtectedFields.java
new file mode 100644
index 0000000..f5aed8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ProtectedFields.java
@@ -0,0 +1,33 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+/**
+ * TAPESTRY-2196
+ */
+public class ProtectedFields
+{
+    protected String _field;
+
+    public String getField()
+    {
+        return _field;
+    }
+
+    public void setField(String field)
+    {
+        _field = field;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RadioDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RadioDemo.java
new file mode 100644
index 0000000..e1e31cb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RadioDemo.java
@@ -0,0 +1,75 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.Department;
+import org.apache.tapestry.internal.TapestryInternalUtils;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class RadioDemo
+{
+    @Persist
+    private Department department;
+
+    @Persist
+    private String position;
+
+    private Department loopValue;
+
+    @Inject
+    private Messages messages;
+
+    public Department[] getDepartments()
+    {
+        return Department.values();
+    }
+
+    public Department getDepartment()
+    {
+        return department;
+    }
+
+    public String getPosition()
+    {
+        return position;
+    }
+
+    public Department getLoopValue()
+    {
+        return loopValue;
+    }
+
+    public void setDepartment(Department department)
+    {
+        this.department = department;
+    }
+
+    public void setPosition(String position)
+    {
+        this.position = position;
+    }
+
+    public void setLoopValue(Department loopValue)
+    {
+        this.loopValue = loopValue;
+    }
+
+    public String getLabel()
+    {
+        return TapestryInternalUtils.getLabelForEnum(messages, loopValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RecursiveDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RecursiveDemo.java
new file mode 100644
index 0000000..90f2ee5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RecursiveDemo.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class RecursiveDemo
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RegexpDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RegexpDemo.java
new file mode 100644
index 0000000..93bcb70
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RegexpDemo.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.beaneditor.Validate;
+
+public class RegexpDemo
+{
+    @Persist
+    private String zipCode;
+
+    // regexp requires a constraint, that'll come from the message catalog
+    @Validate("required,regexp")
+    public String getZipCode()
+    {
+        return zipCode;
+    }
+
+    public void setZipCode(String zipCode)
+    {
+        this.zipCode = zipCode;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java
new file mode 100644
index 0000000..d4b4cd1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java
@@ -0,0 +1,43 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class RenderComponentDemo
+{
+    @Persist
+    private boolean enabled;
+
+    @Inject
+    private Block optional;
+
+    public boolean isEnabled()
+    {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enable)
+    {
+        enabled = enable;
+    }
+
+    public Object getThing()
+    {
+        return enabled ? optional : null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java
new file mode 100644
index 0000000..5e91ef7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderErrorDemo.java
@@ -0,0 +1,24 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class RenderErrorDemo
+{
+    public Object getValue()
+    {
+        throw new RuntimeException("Exception thrown from getValue().");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseMethodExceptionDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseMethodExceptionDemo.java
new file mode 100644
index 0000000..26bbd58
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseMethodExceptionDemo.java
@@ -0,0 +1,25 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import java.sql.SQLException;
+
+public class RenderPhaseMethodExceptionDemo
+{
+    void beginRender() throws SQLException
+    {
+        throw new SQLException("Simulated JDBC exception while rendering.");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.java
new file mode 100644
index 0000000..3c393e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class RenderPhaseOrder
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderableDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderableDemo.java
new file mode 100644
index 0000000..60da376
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/RenderableDemo.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+
+public class RenderableDemo
+{
+    public Renderable getRenderable()
+    {
+        return new Renderable()
+        {
+            public void render(MarkupWriter writer)
+            {
+                writer.write("This proves it works.");
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ReturnTypes.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ReturnTypes.java
new file mode 100644
index 0000000..cbab7bd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ReturnTypes.java
@@ -0,0 +1,80 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.pages;

+

+import org.apache.tapestry.ComponentResources;

+import org.apache.tapestry.annotation.InjectPage;

+import org.apache.tapestry.ioc.annotation.Inject;

+import org.apache.tapestry.services.ComponentEventResultProcessor;

+import org.apache.tapestry.util.TextStreamResponse;

+

+import java.net.MalformedURLException;

+import java.net.URL;

+

+/**

+ * Tests the various event handler method return types.

+ *

+ * @see ComponentEventResultProcessor

+ */

+public class ReturnTypes

+{

+    @InjectPage

+    private Start start;

+

+    @Inject

+    private ComponentResources resources;

+

+    Object onActionFromNullReturnValue()

+    {

+        return null;

+    }

+

+    Object onActionFromStringReturnValue()

+    {

+        return "start";

+    }

+

+    Object onActionFromClassReturnValue()

+    {

+        return Start.class;

+    }

+

+    Object onActionFromPageReturnValue()

+    {

+        return start;

+    }

+

+    Object onActionFromLinkReturnValue()

+    {

+        return resources.createPageLink("start", false);

+    }

+

+    Object onActionFromStreamReturnValue()

+    {

+        String text = "<html><body>Success!</body></html>";

+        return new TextStreamResponse("text/html", text);

+    }

+

+    Object onActionFromBadReturnValue()

+    {

+        // What is Tapestry supposed to do with this? Let's see that Exception Report page.

+        return 20;

+    }

+

+    Object onActionFromURL() throws MalformedURLException

+    {

+        return new URL("http://google.com");

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurePage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurePage.java
new file mode 100644
index 0000000..7530ab3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurePage.java
@@ -0,0 +1,73 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Secure;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.Request;
+
+@Secure
+public class SecurePage
+{
+
+    @Persist("flash")
+    private String message;
+
+    @Inject
+    private Request request;
+
+    @Inject
+    @Path("context:images/tapestry_banner.gif")
+    private Asset icon;
+
+    @Inject
+    @Path("nested/tapestry-button.png")
+    private Asset button;
+
+    public Asset getIcon()
+    {
+        return icon;
+    }
+
+    public Asset getButton()
+    {
+        return button;
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    void onActionFromSecureLink()
+    {
+        message = "Link clicked";
+    }
+
+    void onSubmit()
+    {
+        message = "Form submitted";
+    }
+
+    SecurePage initialize(String message)
+    {
+        this.message = message;
+
+        return this;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java
new file mode 100644
index 0000000..c367bb6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SecurityAlert.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class SecurityAlert
+{
+    @Persist("flash")
+    private String message;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public void setMessage(String mesasge)
+    {
+        message = mesasge;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowBirthdayReminder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowBirthdayReminder.java
new file mode 100644
index 0000000..38a1fe1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowBirthdayReminder.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.integration.app1.data.BirthdayReminder;
+
+public class ShowBirthdayReminder
+{
+    @ApplicationState
+    private BirthdayReminder reminder;
+
+    public BirthdayReminder getReminder()
+    {
+        return reminder;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java
new file mode 100644
index 0000000..3ebe6f0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ShowSelection.java
@@ -0,0 +1,44 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+
+public class ShowSelection
+{
+    private int selected;
+
+    public int getSelected()
+    {
+        return selected;
+    }
+
+    public void setSelected(int selected)
+    {
+        this.selected = selected;
+    }
+
+    @OnEvent("passivate")
+    int passivate()
+    {
+        return selected;
+    }
+
+    @OnEvent("activate")
+    void activate(int selected)
+    {
+        this.selected = selected;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleForm.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleForm.java
new file mode 100644
index 0000000..b082405
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleForm.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.IncidentData;
+
+public class SimpleForm
+{
+    @Persist
+    private IncidentData incident;
+
+    @Persist
+    private boolean disabled;
+
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    public void setDisabled(boolean disable)
+    {
+        disabled = disable;
+    }
+
+    public IncidentData getIncident()
+    {
+        return incident;
+    }
+
+    void onPrepare()
+    {
+        if (incident == null)
+        {
+            incident = new IncidentData();
+            incident.setUrgent(true);
+            incident.setOperatingSystem("osx");
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleTrackGridDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleTrackGridDemo.java
new file mode 100644
index 0000000..6618f18
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/SimpleTrackGridDemo.java
@@ -0,0 +1,59 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.integration.app1.data.SimpleTrack;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.integration.app1.services.MusicLibrary;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanModelSource;
+
+import java.util.List;
+
+public class SimpleTrackGridDemo
+{
+    @Inject
+    private MusicLibrary library;
+
+    @Inject
+    private BeanModelSource beanModelSource;
+
+    @Inject
+    private ComponentResources resources;
+
+    private SimpleTrack track;
+
+    public SimpleTrack getTrack()
+    {
+        return track;
+    }
+
+    public void setTrack(SimpleTrack track)
+    {
+        this.track = track;
+    }
+
+    public List<Track> getTracks()
+    {
+        return library.getTracks();
+    }
+
+    public BeanModel getSimpleTrackModel()
+    {
+        return beanModelSource.create(SimpleTrack.class, false, resources);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
new file mode 100644
index 0000000..79462fb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
@@ -0,0 +1,301 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Have to start somewhere!
+ */
+public class Start
+{
+    public static class Item implements Comparable<Item>
+    {
+        private final String pageName;
+        private final String label;
+        private final String description;
+
+        public Item(String pageName, String label, String description)
+        {
+            this.pageName = pageName;
+            this.label = label;
+            this.description = description;
+        }
+
+        public String getPageName()
+        {
+            return pageName;
+        }
+
+        public String getLabel()
+        {
+            return label;
+        }
+
+        public String getDescription()
+        {
+            return description;
+        }
+
+        public int compareTo(Item o)
+        {
+            return label.compareTo(o.label);
+        }
+    }
+
+    private static final List<Item> ITEMS = CollectionFactory.newList(
+            new Item("actionpage", "Action Page", "tests fixture for ActionLink component"),
+
+            new Item("cleancachedemo", "Clean Cache Demo", "cache cleared properly during Ajax calls"),
+
+            new Item("numberbeaneditordemo", "Number BeanEditor Demo",
+                     "use of nulls and wrapper types with BeanEditor"),
+
+            new Item("forminjectordemo", "FormInjector Demo", "extending a form dynamically via Ajax"),
+
+            new Item("music", "Music Page", "demo handling of edge cases of page naming"),
+
+            new Item("PersistentDemo", "Persistent Demo", "storing and clearing persistent properties"),
+
+            new Item("ActionViaLinkDemo", "Action via Link Demo", "tests creating an action link explicitly"),
+
+            new Item("FormFragmentDemo", "Form Fragment Demo", "page with dynamic form sections"),
+
+            new Item("BooleanDemo", "Boolean Property Demo", "demo boolean properties using both is and get prefixes"),
+
+            new Item("DeleteFromGridDemo", "Delete From Grid", "demo deleting items form a Grid"),
+
+            new Item("RenderErrorDemo", "Render Error Demo", "reporting of errors while rendering"),
+
+            new Item("nested/AssetDemo", "AssetDemo", "declaring an image using Assets"),
+
+            new Item("nested/ActionDemo", "Action With Context Demo",
+                     "using action links with context on page with activation context"),
+
+            new Item("blockdemo", "BlockDemo", "use of blocks to control rendering"),
+
+            new Item("countdown", "Countdown Page", "defining component using @Component annotation"),
+
+            new Item("injectdemo", "Inject Demo", "use of various kinds of injection"),
+
+            new Item("instancemixin", "InstanceMixin", "mixin added to a particular component instance"),
+
+            new Item("TextFieldWrapperTypeDemo", "TextField Wrapper Types",
+                     "use of TextField to edit numeric wrapper types (not primitives) "),
+
+            new Item("EnvironmentalDemo", "Environmental Annotation Usage",
+                     "Storing and retrieving Environmental values"),
+
+            new Item("Expansion", "Expansion Page", "Use of expansions in templates"),
+
+            new Item("ExpansionSubclass", "ExpansionSubclass", "components can inherit templates from base classes"),
+
+            new Item("Localization", "Localization", "access localized messages from the component catalog"),
+
+            new Item("NumberSelect", "NumberSelect", "passivate/activate page context demo"),
+
+            new Item("ParameterConflict", "Template Overridden by Class Page",
+                     "Parameters in the class override those in the template"),
+
+            new Item("ParameterDefault", "ParameterDefault", "defaulter methods for component parameters"),
+
+            new Item("passwordfielddemo", "PasswordFieldDemo", "test for the PasswordField component"),
+
+            new Item("rendercomponentdemo", "RenderComponentDemo",
+                     "components that \"nominate\" other components to render"),
+
+            new Item("renderphaseorder", "RenderPhaseOrder", "order of operations when invoking render phase methods"),
+
+            new Item("simpleform", "SimpleForm", "first pass at writing Form and TextField components"),
+
+            new Item("validform", "ValidForm", "server-side input validation"),
+
+            new Item("ToDoListVolatile", "ToDo List (Volatile)", "Loops and Submit inside Form, volatile mode"),
+
+            new Item("MissingTemplate", "Missing Template Demo",
+                     "Demo for what happens when a template is not found for a page"),
+
+            new Item("zonedemo", "Zone Demo", "dynamic updates within a page"),
+
+            new Item("todolist", "ToDo List", "Loops and Submit inside Form using primary key encoder"),
+
+            new Item("flashdemo", "FlashDemo", "demonstrate 'flash' persistence"),
+
+            new Item("beaneditordemo", "BeanEditor Demo", "demonstrate the BeanEditor mega-component"),
+
+            new Item("pageloadeddemo", "PageLoaded Demo", "shows that page lifecycle methods are invoked"),
+
+            new Item("griddemo", "Grid Demo", "default Grid component"),
+
+            new Item("nullgrid", "Null Grid", "handling of null source for Grid"),
+
+            new Item("gridsetdemo", "Grid Set Demo", "handling of Set sources for Grid"),
+
+            new Item("gridenumdemo", "Grid Enum Demo", "handling of enum types in the Grid"),
+
+            new Item("GridRemoveReorderDemo", "Grid Remove/Reorder Demo", "handling of remove and reorder parameters"),
+
+            new Item("protected", "Protected Page",
+                     "Demonstrate result of non-void return from a page's activate method"),
+
+            new Item("Kicker", "Kicker", "demos complex page and component context in links"),
+
+            new Item("simpletrackgriddemo", "SimpleTrack Grid Demo",
+                     "customizing the model for a Grid around an interface"),
+
+            new Item("pagelinkcontext", "PageLink Context Demo", "passing explicit context in a page render link"),
+
+            new Item("pagecontextinform", "Page Context in Form", "passivate/activate page context in Form"),
+
+            new Item("ValidBeanEditorDemo", "Client Validation Demo", "BeanEditor with validation enabled"),
+
+            new Item("Unreachable", "Unreachable Page", "page not reachable due to IgnoredPathsFilter"),
+
+            new Item("renderabledemo", "Renderable Demo", "shows that render phase methods can return a Renderable"),
+
+            new Item("inheritedbindingsdemo", "Inherited Bindings Demo",
+                     "Tests for components that inherit bindings from containing components"),
+
+            new Item("ClientPersistenceDemo", "Client Persistence Demo",
+                     "component field values persisted on the client side"),
+
+            new Item("attributeExpansionsDemo", "Attribute Expansions Demo",
+                     "use expansions inside attributes of ordinary elements"),
+
+            new Item("PaletteDemo", "Palette Demo", "multiple selection component"),
+
+            new Item("ReturnTypes", "Return Types", "tests various event handler return types"),
+
+            new Item("FormEncodingType", "Form Encoding Type", "Test ability to set an encoding type for a Form"),
+
+            new Item("RadioDemo", "RadioDemo", "Use of the RadioGroup and Radio components"),
+
+            new Item("RegexpDemo", "Regexp Demo", "Use of the Regexp validator"),
+
+            new Item("BeanEditRemoveReorder", "BeanEdit Remove/Reorder",
+                     "Use of the remove and reorder parameters with BeanEditForm"),
+
+            new Item("MultiBeanEditDemo", "MultiBeanEdit Demo", "Multiple BeanEditor components in a single form"),
+
+            new Item("GridFormDemo", "Grid Form Demo", "Grid operating inside a Form"),
+
+            new Item("DateFieldDemo", "DateField Demo", "using DateField by itself on a page"),
+
+            new Item("BeanEditDateDemo", "BeanEditor / Date Demo",
+                     "Use of date properties inside BeanEditor and BeanDisplay"),
+
+            new Item("eventmethodtranslate", "EventMethod Translator",
+                     "Demo ability to provide toclient and parseclient event handler methods"),
+
+            new Item("autocompletedemo", "Autocomplete Mixin Demo", "Demo the autocomplete mixin for text fields"),
+
+            new Item("componentparameter", "ComponentParameter Demo",
+                     " Demo using a component type as a parameter type and succesfuly passing a component"),
+
+            new Item("inheritinformalsdemo", "Inherit Informal Parameters Demo",
+                     "Demo a component which inherits informal parameters from its container"),
+
+            new Item("disabledfields", "Disabled Fields",
+                     "Demonstrate a bunch of disabled fields, to verify that the RenderDisabled mixin works and is being used properly"),
+
+            new Item("BeanEditorOverride", "BeanEditor Override",
+                     "Property editor overrides work for the BeanEditor component itself (not just the BeanEditForm component)"),
+
+            new Item("varbindingdemo", "Var Binding Demo", "use of the var: binding prefix"),
+
+            new Item("leangriddemo", "Lean Grid Demo",
+                     "Grid component with lean parameter turned on, to eliminate CSS class attributes in TD and TH elements"),
+
+            new Item("blockcaller", "Action Links off of Active Page",
+                     "Actions can exist on pages other than the active page, via Blocks."),
+
+            new Item("unlessdemo", "Unless Demo", "use of the Unless component"),
+
+            new Item("MagicValueEncoder", "Magic ValueEncoder Demo",
+                     "Automatic creation of ValueEncoder using the TypeCoercer"),
+
+            new Item("NullStrategyDemo", "Null Field Strategy Demo", "use of the nulls parameter of TextField"),
+
+            new Item("OverrideValidationDecorator", "Override Validation Decorator",
+                     "override the default validation decorator"),
+
+            new Item("ExceptionEventDemo", "Exception Event Demo", "handling component event exceptions"),
+
+            new Item("AddedGridColumnsDemo", "Added Grid Columns Demo", "programatically adding grid columns"),
+
+            new Item("PrimitiveArrayParameterDemo", "Primitive Array Parameter Demo",
+                     "use primitive array as parameter type"),
+
+            new Item("RenderPhaseMethodExceptionDemo", "Render Phase Method Exception Demo",
+                     "render phase methods may throw checked exceptions"),
+
+            new Item("TrackEditor", "Generic Page Class Demo",
+                     "demo use of generics with component classes and, particularily, with property types"),
+
+            new Item("IndirectProtectedFields", "Protected Fields Demo",
+                     "demo exception when component class contains protected fields"),
+
+            new Item("injectcomponentdemo", "Inject Component Demo",
+                     "inject component defined in template"),
+
+            new Item("cachedpage", "Cached Annotation", "Caching method return values"),
+
+            new Item("cachedpage2", "Cached Annotation2", "Caching method return values w/ inheritence"),
+
+            new Item("inplacegriddemo", "In-Place Grid Demo", "Grid that updates in-place using Ajax"),
+
+            new Item("methodadvicedemo", "Method Advice Demo", "Advising component methods.")
+    );
+
+    static
+    {
+        Collections.sort(ITEMS);
+    }
+
+    private Item item;
+
+    @InjectPage
+    private SecurePage securePage;
+
+    public List<Item> getItems()
+    {
+        return ITEMS;
+    }
+
+    public Item getItem()
+    {
+        return item;
+    }
+
+    public void setItem(Item item)
+    {
+        this.item = item;
+    }
+
+    Object onActionFromSecurePage()
+    {
+        return securePage.initialize("Triggered from Start");
+    }
+
+    public List getDemoContext()
+    {
+        return Arrays.asList(1, 2, 3);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Target.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Target.java
new file mode 100644
index 0000000..7d19899
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Target.java
@@ -0,0 +1,65 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.annotation.Persist;
+
+public class Target
+{
+    private Object[] activationContext;
+
+    @Persist("flash")
+    private Object[] componentContext;
+
+    private Object object;
+
+    @OnEvent("passivate")
+    public Object[] getActivationContext()
+    {
+        return activationContext;
+    }
+
+    public Object[] getComponentContext()
+    {
+        return componentContext;
+    }
+
+    @OnEvent("activate")
+    public void setActivationContext(Object[] activationContext)
+    {
+        this.activationContext = activationContext;
+    }
+
+    void onAction(Object[] componentContext)
+    {
+        this.componentContext = componentContext;
+    }
+
+    public Object[] getContextToEncode()
+    {
+        return new Object[] { "fred", "barney", "clark kent", "fred/barney", "\u592A\u90CE" };
+    }
+
+    public Object getObject()
+    {
+        return object;
+    }
+
+    public void setObject(Object object)
+    {
+        this.object = object;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TextFieldWrapperTypeDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TextFieldWrapperTypeDemo.java
new file mode 100644
index 0000000..a25299f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TextFieldWrapperTypeDemo.java
@@ -0,0 +1,43 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class TextFieldWrapperTypeDemo
+{
+    @Persist
+    private Integer count;
+
+    public Integer getCount()
+    {
+        return count;
+    }
+
+    public void setCount(Integer count)
+    {
+        this.count = count;
+    }
+
+    public boolean isCountNull()
+    {
+        return count == null;
+    }
+
+    void onActionFromClear()
+    {
+        count = null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoList.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoList.java
new file mode 100644
index 0000000..ace2c10
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoList.java
@@ -0,0 +1,103 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.PrimaryKeyEncoder;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+import org.apache.tapestry.integration.app1.services.ToDoDatabase;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.util.DefaultPrimaryKeyEncoder;
+
+import java.util.List;
+
+public class ToDoList
+{
+    @Inject
+    private ToDoDatabase database;
+
+    private ToDoItem item;
+
+    private DefaultPrimaryKeyEncoder<Long, ToDoItem> encoder;
+
+    @Component
+    private Form form;
+
+    public List<ToDoItem> getItems()
+    {
+        return encoder.getValues();
+    }
+
+    public ToDoItem getItem()
+    {
+        return item;
+    }
+
+    public void setItem(ToDoItem item)
+    {
+        this.item = item;
+    }
+
+    public ToDoDatabase getDatabase()
+    {
+        return database;
+    }
+
+    public PrimaryKeyEncoder getEncoder()
+    {
+        return encoder;
+    }
+
+    void onPrepare()
+    {
+        List<ToDoItem> items = database.findAll();
+
+        encoder = new DefaultPrimaryKeyEncoder<Long, ToDoItem>();
+
+        for (ToDoItem item : items)
+        {
+            encoder.add(item.getId(), item);
+        }
+    }
+
+    void onSuccess()
+    {
+        int order = 0;
+
+        for (ToDoItem item : encoder.getValues())
+        {
+            item.setOrder(order++);
+            database.update(item);
+        }
+    }
+
+    void onSelectedFromAddNew()
+    {
+        if (form.isValid())
+        {
+            ToDoItem item = new ToDoItem();
+            item.setTitle("<New To Do>");
+            item.setOrder(encoder.getValues().size());
+
+            database.add(item);
+        }
+    }
+
+    void onActionFromReset()
+    {
+        database.reset();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoListVolatile.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoListVolatile.java
new file mode 100644
index 0000000..eeea805
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ToDoListVolatile.java
@@ -0,0 +1,89 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+import org.apache.tapestry.integration.app1.services.ToDoDatabase;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+import java.util.List;
+
+public class ToDoListVolatile
+{
+    @Inject
+    private ToDoDatabase database;
+
+    private ToDoItem item;
+
+    private List<ToDoItem> items;
+
+    @Component
+    private Form form;
+
+    public List<ToDoItem> getItems()
+    {
+        return items;
+    }
+
+    public ToDoItem getItem()
+    {
+        return item;
+    }
+
+    public void setItem(ToDoItem item)
+    {
+        this.item = item;
+    }
+
+    public ToDoDatabase getDatabase()
+    {
+        return database;
+    }
+
+    void onPrepare()
+    {
+        items = database.findAll();
+    }
+
+    void onSuccess()
+    {
+        int order = 0;
+
+        for (ToDoItem item : items)
+        {
+            item.setOrder(order++);
+            database.update(item);
+        }
+    }
+
+    void onSelectedFromAddNew()
+    {
+        if (form.isValid())
+        {
+            ToDoItem item = new ToDoItem();
+            item.setTitle("<New To Do>");
+            item.setOrder(items.size());
+
+            database.add(item);
+        }
+    }
+
+    void onActionFromReset()
+    {
+        database.reset();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TrackEditor.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TrackEditor.java
new file mode 100644
index 0000000..7cd8038
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/TrackEditor.java
@@ -0,0 +1,22 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.base.GenericEditor;
+import org.apache.tapestry.integration.app1.data.Track;
+
+public class TrackEditor extends GenericEditor<Track>
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/UnlessDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/UnlessDemo.java
new file mode 100644
index 0000000..13dfadd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/UnlessDemo.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class UnlessDemo
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Unreachable.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Unreachable.java
new file mode 100644
index 0000000..43a0635
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Unreachable.java
@@ -0,0 +1,19 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class Unreachable
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidBeanEditorDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidBeanEditorDemo.java
new file mode 100644
index 0000000..9c226ca
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidBeanEditorDemo.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class ValidBeanEditorDemo extends BeanEditorDemo
+{
+
+    @Override
+    public boolean getClientValidation()
+    {
+        return true;
+    }
+
+    @Override
+    public String getPageTitle()
+    {
+        return "Client Validation / BeanEditor Demo";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidForm.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidForm.java
new file mode 100644
index 0000000..1692eba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ValidForm.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.integration.app1.data.IncidentData;
+
+public class ValidForm
+{
+    @Persist
+    private IncidentData incident;
+
+    public IncidentData getIncident()
+    {
+        return incident;
+    }
+
+    void onPrepare()
+    {
+        if (incident == null)
+            incident = new IncidentData();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/VarBindingDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/VarBindingDemo.java
new file mode 100644
index 0000000..bbfff11
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/VarBindingDemo.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class VarBindingDemo
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java
new file mode 100644
index 0000000..5820e6a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ViewRegistration.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+
+public class ViewRegistration
+{
+    @ApplicationState
+    private RegistrationData data;
+
+    public RegistrationData getRegistrationData()
+    {
+        return data;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java
new file mode 100644
index 0000000..de99abe
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Wilma.java
@@ -0,0 +1,20 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class Wilma
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/XMLContent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/XMLContent.java
new file mode 100644
index 0000000..3f4fa71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/XMLContent.java
@@ -0,0 +1,22 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotation.Meta;
+
+@Meta("tapestry.response-content-type=text/xml")
+public class XMLContent
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java
new file mode 100644
index 0000000..d0c900b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java
@@ -0,0 +1,99 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Log;
+import org.apache.tapestry.corelib.components.BeanEditForm;
+import org.apache.tapestry.integration.app1.data.RegistrationData;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry5.json.JSONObject;
+
+public class ZoneDemo
+{
+    @Component
+    private BeanEditForm form;
+
+    private String name;
+
+    @ApplicationState
+    private RegistrationData registration;
+
+    private static final String[] NAMES = { "Fred & Wilma", "Mr. <Roboto>", "Grim Fandango", "Registration" };
+
+    @Inject
+    private Block showName;
+
+    @Inject
+    private Block registrationForm;
+
+    @Inject
+    private Block registrationOutput;
+
+    public String[] getNames()
+    {
+        return NAMES;
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    @Log
+    Object onActionFromSelect(String name)
+    {
+        this.name = name;
+
+        if (name.equals("Registration")) return registrationForm;
+
+        return showName;
+    }
+
+    Object onSuccess()
+    {
+        return registrationOutput;
+    }
+
+    Object onActionFromClear()
+    {
+        form.clearErrors();
+        registration = null;
+
+        return registrationForm;
+    }
+
+    public RegistrationData getRegistration()
+    {
+        return registration;
+    }
+
+    Object onActionFromJSON()
+    {
+        JSONObject response = new JSONObject();
+
+        response.put("content", "Directly coded JSON content");
+
+        return response;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/music/MusicDetails.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/music/MusicDetails.java
new file mode 100644
index 0000000..970adb6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/music/MusicDetails.java
@@ -0,0 +1,37 @@
+// Copyright  2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages.music;
+
+import org.apache.tapestry.integration.app1.data.Track;
+
+public class MusicDetails
+{
+    private Track track;
+
+    void onActivate(Track track)
+    {
+        this.track = track;
+    }
+
+    Object onPassivate()
+    {
+        return track;
+    }
+
+    public Track getTrack()
+    {
+        return track;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/ActionDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/ActionDemo.java
new file mode 100644
index 0000000..9ea6f56
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/ActionDemo.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.app1.pages.nested;

+

+import org.apache.tapestry.annotation.OnEvent;

+import org.apache.tapestry.annotation.Property;

+

+public class ActionDemo

+{

+    @Property

+    private Long number;

+

+    @OnEvent(component = "actionlink", value = "action")

+    public void onAction(Long number)

+    {

+        this.number = number;

+    }

+

+    public void onActivate(Long number)

+    {

+        this.number = number;

+    }

+

+    public Long onPassivate()

+    {

+        return number;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.java
new file mode 100644
index 0000000..b944218
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages.nested;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class AssetDemo
+{
+    @Inject
+    @Path("context:images/tapestry_banner.gif")
+    private Asset icon;
+
+    @Inject
+    @Path("tapestry-button.png")
+    private Asset button;
+
+    public Asset getIcon()
+    {
+        return icon;
+    }
+
+    public Asset getButton()
+    {
+        return button;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
new file mode 100644
index 0000000..4b9c356
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/AppModule.java
@@ -0,0 +1,241 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.internal.services.GenericValueEncoderFactory;
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.annotation.Marker;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.*;
+import org.apache.tapestry.test.JettyRunner;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * I was just dying to see how fast requests are!
+ */
+public class AppModule
+{
+    /**
+     * Used to disambiguate services in this module from services in other modules that share the same service
+     * interface.
+     */
+    @Target(
+            { PARAMETER, FIELD })
+    @Retention(RUNTIME)
+    @Documented
+    public @interface Local
+    {
+
+    }
+
+    public void contributeAlias(Configuration<AliasContribution> configuration)
+    {
+        BaseURLSource source = new BaseURLSource()
+        {
+            public String getBaseURL(boolean secure)
+            {
+                String protocol = secure ? "https" : "http";
+
+                // This is all a bit jury-rigged together.  This is for running the app
+                // interactively; Selenium doesn't seem to handle the transition to https.
+                int port = secure ? JettyRunner.DEFAULT_SECURE_PORT : JettyRunner.DEFAULT_PORT;
+
+                return String.format("%s://localhost:%d", protocol, port);
+            }
+        };
+
+        configuration.add(AliasContribution.create(BaseURLSource.class, source));
+    }
+
+    @Marker(Local.class)
+    public RequestFilter buildTimingFilter(final Logger log)
+    {
+        return new RequestFilter()
+        {
+            public boolean service(Request request, Response response, RequestHandler handler) throws IOException
+            {
+                long startTime = System.currentTimeMillis();
+
+                try
+                {
+                    return handler.service(request, response);
+                }
+                finally
+                {
+                    long elapsed = System.currentTimeMillis() - startTime;
+
+                    log.info(String.format("Request time: %d ms", elapsed));
+                }
+            }
+        };
+    }
+
+    public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
+
+                                         @Local RequestFilter filter)
+    {
+        configuration.add("Timing", filter);
+    }
+
+    public void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("app1/", "org/apache/tapestry/integration/app1/");
+    }
+
+    public UserAuthenticator buildUserAuthenticator()
+    {
+        return new UserAuthenticator()
+        {
+            public boolean isValid(String userName, String plaintextPassword)
+            {
+                return plaintextPassword.equals("tapestry");
+            }
+        };
+    }
+
+    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,fr");
+        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
+        configuration.add(SymbolConstants.COMPRESS_WHITESPACE, "false");
+
+        configuration.add("app.injected-symbol", "Symbol contributed to ApplicationDefaults");
+    }
+
+    public static void contributeIgnoredPathsFilter(Configuration<String> configuration)
+    {
+        configuration.add("/unreachable");
+    }
+
+    public ToDoDatabase buildToDoDatabase()
+    {
+        return new ToDoDatabaseImpl();
+    }
+
+    public MusicLibrary buildMusicLibrary(Logger log)
+    {
+        URL library = getClass().getResource("iTunes.xml");
+
+        final List<Track> tracks = new MusicLibraryParser(log).parseTracks(library);
+
+        final Map<Long, Track> idToTrack = CollectionFactory.newMap();
+
+        for (Track t : tracks)
+        {
+            idToTrack.put(t.getId(), t);
+        }
+
+        return new MusicLibrary()
+        {
+            public Track getById(long id)
+            {
+                Track result = idToTrack.get(id);
+
+                if (result != null) return result;
+
+                throw new IllegalArgumentException(String.format("No track with id #%d.", id));
+            }
+
+            public List<Track> getTracks()
+            {
+                return tracks;
+            }
+
+            public List<Track> findByMatchingTitle(String title)
+            {
+                String titleLower = title.toLowerCase();
+
+                List<Track> result = CollectionFactory.newList();
+
+                for (Track t : tracks)
+                {
+                    if (t.getTitle().toLowerCase().contains(titleLower)) result.add(t);
+                }
+
+                return result;
+            }
+        };
+    }
+
+    @Marker(French.class)
+    public Greeter buildFrenchGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+
+            {
+                return "Bonjour!";
+            }
+        };
+    }
+
+    public Greeter buildDefaultGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+
+            {
+                return "Hello";
+            }
+        };
+    }
+
+    public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
+                                                    final MusicLibrary library)
+    {
+        ValueEncoder<Track> encoder = new ValueEncoder<Track>()
+        {
+            public String toClient(Track value)
+            {
+                return Long.toString(value.getId());
+            }
+
+            public Track toValue(String clientValue)
+            {
+                long id = Long.parseLong(clientValue);
+
+                return library.getById(id);
+            }
+        };
+
+
+        configuration.add(Track.class, GenericValueEncoderFactory.create(encoder));
+    }
+
+
+    public static void contributeComponentClassTransformWorker(
+            OrderedConfiguration<ComponentClassTransformWorker> configuration)
+    {
+        configuration.add("ReverseStringsWorker", new ReverseStringsWorker());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/DearGodWhyMeException.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/DearGodWhyMeException.java
new file mode 100644
index 0000000..433d1d5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/DearGodWhyMeException.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+public class DearGodWhyMeException extends Exception
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/French.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/French.java
new file mode 100644
index 0000000..ea3fa46
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/French.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker interface.
+ */
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface French
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/Greeter.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/Greeter.java
new file mode 100644
index 0000000..2033519
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/Greeter.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+public interface Greeter
+{
+    String getGreeting();
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java
new file mode 100644
index 0000000..69333e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibrary.java
@@ -0,0 +1,44 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.integration.app1.data.Track;
+
+import java.util.List;
+
+public interface MusicLibrary
+{
+    /**
+     * Gets a track by its unique id.
+     *
+     * @param id of track to retrieve
+     * @return the Track
+     * @throws IllegalArgumentException if no such track exists
+     */
+    Track getById(long id);
+
+    /**
+     * Provides a list of all tracks in an indeterminate order.
+     */
+    List<Track> getTracks();
+
+    /**
+     * Performs a case-insensitive search, finding all tracks whose title contains the input string (ignoring case).
+     *
+     * @param title a partial title
+     * @return a list of all matches
+     */
+    List<Track> findByMatchingTitle(String title);
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibraryParser.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibraryParser.java
new file mode 100644
index 0000000..e3d78a8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/MusicLibraryParser.java
@@ -0,0 +1,394 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.integration.app1.data.Track;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.util.Stack;
+import org.slf4j.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import static java.lang.String.format;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * Reads an iTunes music library file into a list of {@link org.apache.tapestry.integration.app1.data.Track} elements.
+ */
+public class MusicLibraryParser
+{
+    private final Logger logger;
+
+    private static final int STATE_START = 0;
+
+    private static final int STATE_PLIST = 1;
+
+    private static final int STATE_DICT1 = 2;
+
+    private static final int STATE_IGNORE = 3;
+
+    private static final int STATE_DICT2 = 4;
+
+    private static final int STATE_DICT_TRACK = 5;
+
+    private static final int STATE_COLLECT_KEY = 6;
+
+    private static final int STATE_COLLECT_VALUE = 7;
+
+    private static class Item
+    {
+        StringBuilder _buffer;
+
+        boolean _ignoreCharacterData;
+
+        int _priorState;
+
+        void addContent(char buffer[], int start, int length)
+        {
+            if (_ignoreCharacterData) return;
+
+            if (_buffer == null) _buffer = new StringBuilder(length);
+
+            _buffer.append(buffer, start, length);
+        }
+
+        String getContent()
+        {
+            if (_buffer != null)
+                return _buffer.toString().trim();
+            else
+                return null;
+        }
+
+        Item(int priorState, boolean ignoreCharacterData)
+        {
+            _priorState = priorState;
+            _ignoreCharacterData = ignoreCharacterData;
+        }
+    }
+
+    private class Handler extends DefaultHandler
+    {
+        private final List<Track> tracks = CollectionFactory.newList();
+
+        private Stack<Item> stack = CollectionFactory.newStack();
+
+        private int state = STATE_START;
+
+        /**
+         * Most recently seen key.
+         */
+        private String key;
+
+        /**
+         * Currently building Track.
+         */
+        private Track track;
+
+        public List<Track> getTracks()
+        {
+            return tracks;
+        }
+
+        private Item peek()
+        {
+            return stack.peek();
+        }
+
+        private void pop()
+        {
+            state = stack.pop()._priorState;
+        }
+
+        private void push(int newState)
+        {
+            push(newState, true);
+        }
+
+        protected void push(int newState, boolean ignoreCharacterData)
+        {
+            Item item = new Item(state, ignoreCharacterData);
+
+            stack.push(item);
+
+            state = newState;
+        }
+
+        @Override
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            end(getElementName(localName, qName));
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes attributes)
+                throws SAXException
+        {
+            String elementName = getElementName(localName, qName);
+            begin(elementName);
+        }
+
+        private String getElementName(String localName, String qName)
+        {
+            return qName == null ? localName : qName;
+        }
+
+        @Override
+        public void characters(char ch[], int start, int length) throws SAXException
+        {
+            peek().addContent(ch, start, length);
+        }
+
+        private void begin(String element)
+        {
+            switch (state)
+            {
+                case STATE_START:
+                    enterStart(element);
+                    return;
+
+                case STATE_PLIST:
+                    enterPlist(element);
+                    return;
+
+                case STATE_DICT1:
+                    enterDict1(element);
+                    return;
+
+                case STATE_DICT2:
+                    enterDict2(element);
+                    return;
+
+                case STATE_IGNORE:
+                    push(STATE_IGNORE);
+                    return;
+
+                case STATE_DICT_TRACK:
+                    enterDictTrack(element);
+                    return;
+            }
+        }
+
+        private void enterStart(String element)
+        {
+            if (element.equals("plist"))
+            {
+                push(STATE_PLIST);
+                return;
+            }
+        }
+
+        private void enterPlist(String element)
+        {
+            if (element.equals("dict"))
+            {
+                push(STATE_DICT1);
+                return;
+            }
+
+            push(STATE_IGNORE);
+        }
+
+        private void enterDict1(String element)
+        {
+            if (element.equals("dict"))
+            {
+                push(STATE_DICT2);
+                return;
+            }
+
+            push(STATE_IGNORE);
+        }
+
+        private void enterDict2(String element)
+        {
+            if (element.equals("dict"))
+            {
+                beginDictTrack(element);
+                return;
+            }
+
+            push(STATE_IGNORE);
+        }
+
+        private void beginDictTrack(String element)
+        {
+            track = new Track();
+
+            tracks.add(track);
+
+            push(STATE_DICT_TRACK);
+        }
+
+        private void enterDictTrack(String element)
+        {
+            if (element.equals("key"))
+            {
+                beginCollectKey(element);
+                return;
+            }
+
+            beginCollectValue(element);
+        }
+
+        private void beginCollectKey(String element)
+        {
+            push(STATE_COLLECT_KEY, false);
+        }
+
+        private void beginCollectValue(String element)
+        {
+            push(STATE_COLLECT_VALUE, false);
+
+        }
+
+        private void end(String element)
+        {
+            switch (state)
+            {
+                case STATE_COLLECT_KEY:
+
+                    endCollectKey(element);
+                    return;
+
+                case STATE_COLLECT_VALUE:
+                    endCollectValue(element);
+                    return;
+
+                default:
+                    pop();
+            }
+        }
+
+        private void endCollectKey(String element)
+        {
+            key = peek().getContent();
+
+            pop();
+        }
+
+        private void endCollectValue(String element)
+        {
+            String value = peek().getContent();
+
+            pop();
+
+            if (key.equals("Track ID"))
+            {
+                track.setId(Long.parseLong(value));
+            }
+
+            if (key.equals("Name"))
+            {
+                track.setTitle(value);
+                return;
+            }
+
+            if (key.equals("Artist"))
+            {
+                track.setArtist(value);
+                return;
+            }
+
+            if (key.equals("Album"))
+            {
+                track.setAlbum(value);
+                return;
+            }
+
+            if (key.equals("Genre"))
+            {
+                track.setGenre(value);
+                return;
+            }
+
+            if (key.equals("Play Count"))
+            {
+                track.setPlayCount(Integer.parseInt(value));
+                return;
+            }
+
+            if (key.equals("Rating"))
+            {
+                track.setRating(Integer.parseInt(value));
+                return;
+            }
+
+            // Many other keys are just ignored.
+        }
+
+        @Override
+        public InputSource resolveEntity(String publicId, String systemId) throws SAXException
+        {
+            if (publicId.equals("-//Apple Computer//DTD PLIST 1.0//EN"))
+            {
+                InputStream local = new BufferedInputStream(getClass().getResourceAsStream(
+                        "PropertyList-1.0.dtd"));
+
+                return new InputSource(local);
+            }
+
+            // Perform normal processing, such as accessing via system id. That's
+            // what we want to avoid, since presentations are often given when there
+            // is no Internet connection.
+
+            return null;
+        }
+    }
+
+    public MusicLibraryParser(final Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    public List<Track> parseTracks(URL resource)
+    {
+        logger.info(format("Parsing music library %s", resource));
+
+        long start = System.currentTimeMillis();
+
+        Handler handler = new Handler();
+
+        try
+        {
+            XMLReader reader = XMLReaderFactory.createXMLReader();
+
+            reader.setContentHandler(handler);
+            reader.setEntityResolver(handler);
+
+            InputSource source = new InputSource(resource.openStream());
+
+            reader.parse(source);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        List<Track> result = handler.getTracks();
+        long elapsed = System.currentTimeMillis() - start;
+
+        logger.info(format("Parsed %d tracks in %d ms", result.size(), elapsed));
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStrings.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStrings.java
new file mode 100644
index 0000000..2917b40
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStrings.java
@@ -0,0 +1,31 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation used with {@link org.apache.tapestry.integration.app1.services.StringReversalAdvice}.
+ */
+@Target(METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ReverseStrings
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStringsWorker.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStringsWorker.java
new file mode 100644
index 0000000..f17a77d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ReverseStringsWorker.java
@@ -0,0 +1,79 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+public class ReverseStringsWorker implements ComponentClassTransformWorker
+{
+    private final ComponentMethodAdvice advice = new ComponentMethodAdvice()
+    {
+        public void advise(ComponentMethodInvocation invocation)
+        {
+            for (int i = 0; i < invocation.getParameterCount(); i++)
+            {
+                if (invocation.getParameterType(i).equals(String.class))
+                {
+                    String value = (String) invocation.getParameter(i);
+
+                    invocation.override(i, reverse(value));
+                }
+            }
+
+            invocation.proceed();
+
+            if (invocation.getResultType().equals(String.class))
+            {
+                if (invocation.isFail())
+                {
+                    Exception thrown = invocation.getThrown(Exception.class);
+
+                    invocation.overrideResult(
+                            String.format("Invocation of method %s() failed with %s.",
+                                          invocation.getMethodName(),
+                                          thrown.getClass().getName()));
+
+                    return;
+                }
+
+                String value = (String) invocation.getResult();
+
+                invocation.overrideResult(reverse(value));
+            }
+        }
+
+        private String reverse(String input)
+        {
+            char[] inputArray = input.toCharArray();
+            char[] outputArray = new char[inputArray.length];
+
+            for (int i = 0; i < inputArray.length; i++)
+            {
+                outputArray[inputArray.length - i - 1] = inputArray[i];
+            }
+
+            return new String(outputArray);
+        }
+    };
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (TransformMethodSignature sig : transformation.findMethodsWithAnnotation(ReverseStrings.class))
+        {
+            transformation.advise(sig, advice);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabase.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabase.java
new file mode 100644
index 0000000..7cd8d92
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabase.java
@@ -0,0 +1,58 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+
+import java.util.List;
+
+public interface ToDoDatabase
+{
+    /**
+     * Adds an item to the database, first assigning a unique id to the item.
+     */
+    void add(ToDoItem item);
+
+    /**
+     * Finds all items, sorted ascending by each item's order property.
+     */
+    List<ToDoItem> findAll();
+
+    /**
+     * Updates an existing item.
+     *
+     * @param item
+     * @throws RuntimeException if the item does not exist
+     */
+    void update(ToDoItem item);
+
+    /**
+     * Resets the database, clearing out all data, re-adding base data.
+     */
+    void reset();
+
+    /**
+     * Deletes all items from the database.
+     */
+    void clear();
+
+    /**
+     * Removes an existing item
+     *
+     * @param itemId item to remove
+     * @throws RuntimeException if the item does not exist
+     */
+    void remove(long itemId);
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabaseImpl.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabaseImpl.java
new file mode 100644
index 0000000..b2117dc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/ToDoDatabaseImpl.java
@@ -0,0 +1,118 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+import org.apache.tapestry.integration.app1.data.ToDoItem;
+import org.apache.tapestry.integration.app1.data.Urgency;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * We clone everything that comes in or goes out. This does a reasonable job of simulating an external database. We just
+ * use cloned copies of objects to represent data that's been marshalled into tables and columns.
+ */
+public class ToDoDatabaseImpl implements ToDoDatabase
+{
+    private long nextId = 1000;
+
+    private final Map<Long, ToDoItem> items = CollectionFactory.newMap();
+
+    public ToDoDatabaseImpl()
+    {
+        // A couple of items to get us started:
+
+        reset();
+    }
+
+    public void clear()
+    {
+        items.clear();
+    }
+
+
+    public void reset()
+    {
+        items.clear();
+
+        add("End World Hunger", Urgency.MEDIUM, 1);
+        add("Develop Faster-Than-Light Travel", Urgency.HIGH, 2);
+        add("Cure Common Cold", Urgency.LOW, 3);
+    }
+
+    private void add(String title, Urgency urgency, int order)
+    {
+        ToDoItem item = new ToDoItem();
+
+        item.setTitle(title);
+        item.setUrgency(urgency);
+        item.setOrder(order);
+
+        add(item);
+    }
+
+    public void add(ToDoItem item)
+    {
+        long id = nextId++;
+
+        item.setId(id);
+
+        items.put(id, item.clone());
+    }
+
+    public List<ToDoItem> findAll()
+    {
+        List<ToDoItem> result = newList();
+
+        for (ToDoItem item : items.values())
+            result.add(item.clone());
+
+        Comparator<ToDoItem> comparator = new Comparator<ToDoItem>()
+        {
+            public int compare(ToDoItem o1, ToDoItem o2)
+            {
+                return o1.getOrder() - o2.getOrder();
+            }
+        };
+
+        Collections.sort(result, comparator);
+
+        return result;
+    }
+
+    public void update(ToDoItem item)
+    {
+        long id = item.getId();
+
+        if (!items.containsKey(id))
+            throw new RuntimeException(String.format("ToDoItem #%d not found.", id));
+
+        items.put(id, item.clone());
+    }
+
+    public void remove(long itemId)
+    {
+        ToDoItem item = items.remove(itemId);
+
+        if (item == null)
+            throw new RuntimeException(String.format("ToDoItem #%d not found.", itemId));
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/UserAuthenticator.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/UserAuthenticator.java
new file mode 100644
index 0000000..94ffc3a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/services/UserAuthenticator.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.services;
+
+public interface UserAuthenticator
+{
+    boolean isValid(String userName, String plaintextPassword);
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/FortyTwo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/FortyTwo.java
new file mode 100644
index 0000000..e534d5e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/FortyTwo.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a method should return the answer to life, the universe, and everything.
+ * Used for testing.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface FortyTwo
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/PlusOne.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/PlusOne.java
new file mode 100644
index 0000000..4b41ea9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/PlusOne.java
@@ -0,0 +1,32 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Adds 1 to a method result. Testing only.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface PlusOne
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/SimpleASO.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/SimpleASO.java
new file mode 100644
index 0000000..4075fb2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/SimpleASO.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2;
+
+public class SimpleASO
+{
+    private String foo = "bar";
+
+    public void setFoo(String foo)
+    {
+        this.foo = foo;
+    }
+
+    public String getFoo()
+    {
+        return foo;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/components/SimpleLayout.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/components/SimpleLayout.java
new file mode 100644
index 0000000..62ce416
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/components/SimpleLayout.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.components;
+
+public class SimpleLayout
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/mixins/ForceId.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/mixins/ForceId.java
new file mode 100644
index 0000000..0a0d7dd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/mixins/ForceId.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.mixins;
+
+import org.apache.tapestry.ClientElement;
+import org.apache.tapestry.annotation.InjectContainer;
+
+public class ForceId
+{
+    @InjectContainer
+    private ClientElement container;
+
+    void afterRender()
+    {
+        container.getClientId();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromComponent.java
new file mode 100644
index 0000000..749a34a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromComponent.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class DTDFromComponent
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromPage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromPage.java
new file mode 100644
index 0000000..c85a84b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/DTDFromPage.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class DTDFromPage
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/MultipleDTD.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/MultipleDTD.java
new file mode 100644
index 0000000..4851566
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/MultipleDTD.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class MultipleDTD
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/NoDTD.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/NoDTD.java
new file mode 100644
index 0000000..2a698a0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/NoDTD.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class NoDTD
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.java
new file mode 100644
index 0000000..2ebc849
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+
+public class ResultPageForActionLink
+{
+    private int number;
+
+    @OnEvent("passivate")
+    public int getNumber()
+    {
+        return number;
+    }
+
+    @OnEvent("activate")
+    public void setNumber(int number)
+    {
+        this.number = number;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForASO.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForASO.java
new file mode 100644
index 0000000..d35743d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForASO.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.integration.app2.SimpleASO;
+
+public class TestPageForASO
+{
+    @ApplicationState
+    private SimpleASO aso;
+
+    public String getFooString()
+    {
+        return aso.getFoo();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.java
new file mode 100644
index 0000000..ea3d8c3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.java
@@ -0,0 +1,31 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.OnEvent;
+
+public class TestPageForActionLink
+{
+    @InjectPage("ResultPageForActionLink")
+    private ResultPageForActionLink resultPage;
+
+    @OnEvent(component = "link1")
+    public ResultPageForActionLink onClick(int number)
+    {
+        resultPage.setNumber(number);
+        return resultPage;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForAsset.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForAsset.java
new file mode 100644
index 0000000..389f21b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForAsset.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class TestPageForAsset
+{
+    @Inject
+    @Path("context:css/test.css")
+    private Asset asset;
+
+    public String getStylePath()
+    {
+        return asset.toClientURL();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForForm.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForForm.java
new file mode 100644
index 0000000..7845fd1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForForm.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.Persist;
+
+public class TestPageForForm
+{
+    @Persist
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForHead.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForHead.java
new file mode 100644
index 0000000..634a580
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForHead.java
@@ -0,0 +1,21 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+
+public class TestPageForHead
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForIf.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForIf.java
new file mode 100644
index 0000000..e904fea
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForIf.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class TestPageForIf
+{
+    private boolean property1 = true;
+
+    private boolean property2 = false;
+
+    public boolean isProperty1()
+    {
+        return property1;
+    }
+
+    public boolean isProperty2()
+    {
+        return property2;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLocale.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLocale.java
new file mode 100644
index 0000000..520fa8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLocale.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.PersistentLocale;
+
+import java.util.Locale;
+
+public class TestPageForLocale
+{
+    @Inject
+    private PersistentLocale persistentLocale;
+
+    @OnEvent(component = "changeLocale")
+    public void changeLocaleToFrench()
+    {
+        persistentLocale.set(Locale.FRENCH);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLoop.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLoop.java
new file mode 100644
index 0000000..1a3009c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForLoop.java
@@ -0,0 +1,38 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class TestPageForLoop
+{
+    private String[] array =
+            { "x", "y", "z" };
+
+    private String value;
+
+    public String[] getArray()
+    {
+        return array;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.java
new file mode 100644
index 0000000..8365269
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.java
@@ -0,0 +1,72 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.annotation.Component;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.corelib.components.Submit;
+import org.apache.tapestry.corelib.components.TextField;
+
+public class TestPageForSubmit
+{
+    @SuppressWarnings("unused")
+    @Component
+    private Form form1;
+
+    @SuppressWarnings("unused")
+    @Component
+    private Form form2;
+
+    @SuppressWarnings("unused")
+    @Component
+    private Submit capitalize1;
+
+    @SuppressWarnings("unused")
+    @Component
+    private Submit capitalize2;
+
+    @SuppressWarnings("unused")
+    @Component(parameters = "value=value")
+    private TextField t1;
+
+    @SuppressWarnings("unused")
+    @Component(parameters = "value=value")
+    private TextField t2;
+
+    @Persist
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    void onSelectedFromCapitalize1()
+    {
+        value = value.toUpperCase();
+    }
+
+    void onSelectedFromCapitalize2()
+    {
+        onSelectedFromCapitalize1();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForTemplateInContext.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForTemplateInContext.java
new file mode 100644
index 0000000..f4c2252
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForTemplateInContext.java
@@ -0,0 +1,24 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class TestPageForTemplateInContext
+{
+    public String getMsg()
+    {
+        return "How are you?";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForUnless.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForUnless.java
new file mode 100644
index 0000000..495b5f7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPageForUnless.java
@@ -0,0 +1,32 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class TestPageForUnless
+{
+    private boolean property1 = true;
+
+    private boolean property2 = false;
+
+    public boolean isProperty1()
+    {
+        return property1;
+    }
+
+    public boolean isProperty2()
+    {
+        return property2;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.java
new file mode 100644
index 0000000..b348456
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.java
@@ -0,0 +1,56 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.integration.app2.FortyTwo;
+import org.apache.tapestry.integration.app2.PlusOne;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.services.BeanModelSource;
+
+public class TestPrefixMethod
+{
+    @FortyTwo
+    public int getValue()
+    {
+        return 0;
+    }
+
+    @Inject
+    private ComponentResources resources;
+
+    @Inject
+    private BeanModelSource modelSource;
+
+    @InjectPage
+    private TestPrefixMethod2 otherPage;
+
+    private int foo;
+
+    @FortyTwo
+    public int getValue2()
+    {
+        foo = modelSource.hashCode();
+        return foo;
+    }
+
+    @PlusOne
+    public int getValue3()
+    {
+        int value = otherPage.hashCode();
+        return value * 0;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod2.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod2.java
new file mode 100644
index 0000000..21fc56d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/pages/TestPrefixMethod2.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.pages;
+
+public class TestPrefixMethod2 extends TestPrefixMethod
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/services/LocaleAppModule.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/services/LocaleAppModule.java
new file mode 100644
index 0000000..1c830eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app2/services/LocaleAppModule.java
@@ -0,0 +1,63 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app2.services;
+
+import org.apache.tapestry.integration.app2.FortyTwo;
+import org.apache.tapestry.integration.app2.PlusOne;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformMethodSignature;
+
+public class LocaleAppModule
+{
+    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("tapestry.supported-locales", "en,fr,de");
+    }
+
+    public static void contributeComponentClassTransformWorker(
+            OrderedConfiguration<ComponentClassTransformWorker> configuration)
+    {
+        configuration.add("FortyTwo", new FortyTwoWorker());
+        configuration.add("PlusOne", new PlusOneWorker());
+    }
+
+    private static final class FortyTwoWorker implements ComponentClassTransformWorker
+    {
+
+        public void transform(ClassTransformation transformation, MutableComponentModel model)
+        {
+            for (TransformMethodSignature sig : transformation.findMethodsWithAnnotation(FortyTwo.class))
+            {
+                transformation.prefixMethod(sig, "return 42;");
+            }
+        }
+
+    }
+
+    private static final class PlusOneWorker implements ComponentClassTransformWorker
+    {
+        public void transform(ClassTransformation transformation, MutableComponentModel model)
+        {
+            for (TransformMethodSignature method : transformation.findMethodsWithAnnotation(PlusOne.class))
+            {
+                transformation.extendExistingMethod(method, "return $_ + 1;");
+            }
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/BeanDisplayOverrideDemo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/BeanDisplayOverrideDemo.java
new file mode 100644
index 0000000..8ad6c3e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/BeanDisplayOverrideDemo.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app3.pages;
+
+public class BeanDisplayOverrideDemo
+{
+    public boolean getYes()
+    {
+        return true;
+    }
+
+    public boolean getNo()
+    {
+        return false;
+    }
+    
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Index.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Index.java
new file mode 100644
index 0000000..6c30d32
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Index.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app3.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+
+public class Index
+{
+    @InjectPage
+    private Login login;
+
+    @Persist
+    @Property
+    private String message;
+
+    boolean onActivate(String message)
+    {
+        this.message = message;
+
+        // Terminate the event before it gets to the no-args onActivate().
+
+        return true;
+    }
+
+    Object onActivate()
+    {
+
+        // Perform a redirect to the login page.
+        return login;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Login.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Login.java
new file mode 100644
index 0000000..27885da
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/Login.java
@@ -0,0 +1,19 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app3.pages;
+
+public class Login
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/PropertyDisplayBlockOverrides.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/PropertyDisplayBlockOverrides.java
new file mode 100644
index 0000000..cd51a0c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/pages/PropertyDisplayBlockOverrides.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app3.pages;
+
+import org.apache.tapestry.annotation.Environmental;
+import org.apache.tapestry.services.PropertyOutputContext;
+
+public class PropertyDisplayBlockOverrides
+{
+    @Environmental
+    private PropertyOutputContext context;
+
+    public PropertyOutputContext getContext()
+    {
+        return context;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/services/AppModule.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/services/AppModule.java
new file mode 100644
index 0000000..5a009e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app3/services/AppModule.java
@@ -0,0 +1,26 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app3.services;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.services.BeanBlockContribution;
+
+public class AppModule
+{
+    public void contributeBeanBlockOverrideSource(Configuration<BeanBlockContribution> configuration)
+    {
+        configuration.add(new BeanBlockContribution("boolean", "PropertyDisplayBlockOverrides", "boolean", false));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Destination.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Destination.java
new file mode 100644
index 0000000..817980a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Destination.java
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app4.pages;
+
+public class Destination
+{
+    private String message;
+
+    private String value;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    String onPassivate()
+    {
+        return value;
+    }
+
+    void onActivate(String value)
+    {
+        addMessage("onActivate(String) invoked");
+
+        this.value = value;
+    }
+
+    void onActivate()
+    {
+        addMessage("onActivate() invoked");
+    }
+
+    private void addMessage(String text)
+    {
+        if (message == null)
+        {
+            message = text;
+            return;
+        }
+
+        message += " - " + text;
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Start.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Start.java
new file mode 100644
index 0000000..127043c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/pages/Start.java
@@ -0,0 +1,49 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app4.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class Start
+{
+    @InjectPage
+    private Destination destination;
+
+    private String input;
+
+    public String getInput()
+    {
+        return input;
+    }
+
+    public void setInput(String input)
+    {
+        this.input = input;
+    }
+
+    Object onSuccess()
+    {
+        destination.setValue(input);
+
+        return destination;
+    }
+
+    Object onActionFromBypass()
+    {
+        destination.setValue("automatic value");
+
+        return destination;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/services/AppModule.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/services/AppModule.java
new file mode 100644
index 0000000..f2dc304
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/app4/services/AppModule.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app4.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.ioc.MappedConfiguration;
+
+/**
+ * A module that exists for testing the immediate response mode: sending markup in response to action requests, rather
+ * than sending a redirect.
+ */
+public class AppModule
+{
+    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add(SymbolConstants.SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS, "true");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ASOTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ASOTest.java
new file mode 100644
index 0000000..9a30579
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ASOTest.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+public class ASOTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void submit_aso()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName);
+        Document doc = tester.renderPage("TestPageForASO");
+        assertTrue(doc.toString().contains("bar"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ActionLinkTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ActionLinkTest.java
new file mode 100644
index 0000000..d7d9b98
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/ActionLinkTest.java
@@ -0,0 +1,48 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.pagelevel;

+

+import org.apache.tapestry.dom.Document;

+import org.apache.tapestry.dom.Element;

+import org.apache.tapestry.test.PageTester;

+import org.testng.Assert;

+import org.testng.annotations.AfterMethod;

+import org.testng.annotations.Test;

+

+public class ActionLinkTest extends Assert

+{

+    private PageTester tester;

+

+    @Test

+    public void click_link()

+    {

+        String appPackage = "org.apache.tapestry.integration.app2";

+        String appName = "";

+        tester = new PageTester(appPackage, appName);

+        Document doc = tester.renderPage("TestPageForActionLink");

+        Element link = doc.getElementById("link1");

+        doc = tester.clickLink(link);

+        assertTrue(doc.toString().contains("You chose: 123"));

+    }

+

+    @AfterMethod

+    public void after()

+    {

+        if (tester != null)

+        {

+            tester.shutdown();

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/AssetTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/AssetTest.java
new file mode 100644
index 0000000..2fd9506
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/AssetTest.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+public class AssetTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void submit_context_asset()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName, "src/test/app2");
+        Document doc = tester.renderPage("TestPageForAsset");
+        assertTrue(doc.toString().contains("test.css"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/DTDTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/DTDTest.java
new file mode 100644
index 0000000..fbad8ba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/DTDTest.java
@@ -0,0 +1,93 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class DTDTest extends Assert
+{
+    private static final String FRAMESET = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">";
+
+    private static final String TRANSITIONAL = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
+
+    private static final String STRICT = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
+
+    @DataProvider(name = "dtd_page_provider")
+    public Object[][] dtd_page_provider()
+    {
+        return new Object[][]
+                {
+                        {"DTDFromPage", FRAMESET, "slagheap",},
+                        {"DTDFromComponent", TRANSITIONAL, "flubber",},
+                        {"MultipleDTD", STRICT, "blubber",},
+                        {"NoDTD", "", "no_dtd_loser",}};
+    }
+
+    @Test(dataProvider = "dtd_page_provider")
+    public void verify_correct_dtds(String pageName, String expectedDTD, String checkText)
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        PageTester tester = new PageTester(appPackage, appName);
+        Document doc = tester.renderPage(pageName);
+        String txt = doc.toString();
+        // use startsWith to make sure the DTD is getting into the right spot.
+        assertTrue(txt.startsWith(expectedDTD));
+        // we should also make sure that the other DTD's don't appear anywhere else...
+        checkOtherDTD(txt, expectedDTD);
+        // spot check the body of the pages to make sure they correctly rendered...
+        // they should have, based on the unit tests for template rendering, but...
+        assertTrue(txt.contains(checkText));
+
+    }
+
+    private void checkOtherDTD(String txt, String expected)
+    {
+        if (expected.equals(TRANSITIONAL))
+        {
+            check(txt, FRAMESET, STRICT);
+        }
+        else if (expected.equals(FRAMESET))
+        {
+            check(txt, STRICT, TRANSITIONAL);
+            ;
+        }
+        else if (expected.equals(STRICT))
+        {
+            check(txt, FRAMESET, TRANSITIONAL);
+        }
+        else if (expected.equals(""))
+        {
+            check(txt, FRAMESET, STRICT, TRANSITIONAL);
+        }
+        else
+        {
+            throw new RuntimeException("Unknown expected string: " + expected);
+        }
+    }
+
+    private void check(String txt, String... invalids)
+    {
+        for (String invalid : invalids)
+        {
+            assertFalse(txt.contains(invalid));
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/FormTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/FormTest.java
new file mode 100644
index 0000000..88bca2e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/FormTest.java
@@ -0,0 +1,53 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class FormTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void submit_form()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName);
+        Document doc = tester.renderPage("TestPageForForm");
+        Element form = doc.getElementById("form1");
+        Map<String, String> fieldValues = CollectionFactory.newMap();
+        fieldValues.put("t1", "hello");
+        doc = tester.submitForm(form, fieldValues);
+        assertTrue(doc.toString().contains("You entered: hello"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/HeadTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/HeadTest.java
new file mode 100644
index 0000000..6f7a9ba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/HeadTest.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+public class HeadTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void display()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName);
+        Document doc = tester.renderPage("TestPageForHead");
+        assertTrue(doc.toString().contains("OK"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/IfTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/IfTest.java
new file mode 100644
index 0000000..6195802
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/IfTest.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.pagelevel;

+

+import org.apache.tapestry.dom.Document;

+import org.apache.tapestry.test.PageTester;

+import org.testng.Assert;

+import org.testng.annotations.AfterMethod;

+import org.testng.annotations.Test;

+

+public class IfTest extends Assert

+{

+    private PageTester tester;

+

+    @Test

+    public void render()

+    {

+        String appPackage = "org.apache.tapestry.integration.app2";

+        String appName = "";

+        tester = new PageTester(appPackage, appName);

+        Document doc = tester.renderPage("TestPageForIf");

+        assertNotNull(doc.getElementById("1"));

+        assertNotNull(doc.getElementById("3"));

+        assertNotNull(doc.getElementById("5"));

+        assertNotNull(doc.getElementById("8"));

+        assertNull(doc.getElementById("2"));

+        assertNull(doc.getElementById("4"));

+        assertNull(doc.getElementById("6"));

+        assertNull(doc.getElementById("7"));

+    }

+

+    @AfterMethod

+    public void after()

+    {

+        if (tester != null)

+        {

+            tester.shutdown();

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java
new file mode 100644
index 0000000..580055a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LocaleTest.java
@@ -0,0 +1,80 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class LocaleTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void no_preferred_language()
+    {
+        Document doc = tester.renderPage("TestPageForLocale");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "English page");
+    }
+
+    @Test
+    public void prefer_canada_french()
+    {
+        tester.setPreferedLanguage(Locale.CANADA_FRENCH);
+        Document doc = tester.renderPage("TestPageForLocale");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
+    }
+
+    @Test
+    public void change_language_in_browser()
+    {
+        Document doc = tester.renderPage("TestPageForLocale");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "English page");
+        tester.setPreferedLanguage(Locale.CANADA_FRENCH);
+        doc = tester.renderPage("TestPageForLocale");
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
+    }
+
+    @Test
+    public void persist_locale()
+    {
+        Document doc = tester.renderPage("TestPageForLocale");
+        doc = tester.clickLink(doc.getElementById("changeLocale"));
+        assertEquals(doc.getElementById("id1").getChildMarkup(), "French page");
+    }
+
+    @BeforeMethod
+    public void before()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        // LocaleAppModule.java has configured support for a certain locales.
+        String appName = "LocaleApp";
+        tester = new PageTester(appPackage, appName);
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java
new file mode 100644
index 0000000..a3f734d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/LoopTest.java
@@ -0,0 +1,46 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.integration.pagelevel;

+

+import org.apache.tapestry.dom.Document;

+import org.apache.tapestry.test.PageTester;

+import org.testng.Assert;

+import org.testng.annotations.AfterMethod;

+import org.testng.annotations.Test;

+

+public class LoopTest extends Assert

+{

+    private PageTester tester;

+

+    @Test

+    public void render()

+    {

+        String appPackage = "org.apache.tapestry.integration.app2";

+        String appName = "";

+        tester = new PageTester(appPackage, appName);

+        Document doc = tester.renderPage("TestPageForLoop");

+        assertTrue(doc.toString().contains("abcabcabc"));

+        assertEquals(doc.getElementById("1").getChildMarkup(), "xyz");

+    }

+

+    @AfterMethod

+    public void after()

+    {

+        if (tester != null)

+        {

+            tester.shutdown();

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java
new file mode 100644
index 0000000..94ebb07
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/PrefixMethodTest.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.integration.app2.services.LocaleAppModule;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class PrefixMethodTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void prefix_method() throws Exception
+    {
+        // REFACTOR this happens in a bunch of places
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName, PageTester.DEFAULT_CONTEXT_PATH, LocaleAppModule.class);
+        Document doc = tester.renderPage("TestPrefixMethod");
+
+        // make sure you can use on methods that have injected fields
+        assertEquals(doc.getElementById("value2").getChildMarkup(), "42");
+        assertEquals(doc.getElementById("value3").getChildMarkup(), "1");
+
+        // should override the method in the superclass
+        doc = tester.renderPage("TestPrefixMethod2");
+        assertEquals(doc.getElementById("value").getChildMarkup(), "42");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/SubmitTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/SubmitTest.java
new file mode 100644
index 0000000..fd3ff69
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/SubmitTest.java
@@ -0,0 +1,86 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class SubmitTest extends Assert
+{
+    private PageTester tester;
+
+    private Document doc;
+
+    private Map<String, String> fieldValues;
+
+    @Test
+    public void submit_form()
+    {
+        Element submitButton = doc.getElementById("capitalize1");
+        fieldValues.put("t1", "hello");
+        doc = tester.clickSubmit(submitButton, fieldValues);
+        assertTrue(doc.toString().contains("Value is: HELLO"));
+    }
+
+    @Test
+    public void access_following_fields()
+    {
+        Element submitButton = doc.getElementById("capitalize2");
+        fieldValues.put("t2", "world");
+        doc = tester.clickSubmit(submitButton, fieldValues);
+        assertTrue(doc.toString().contains("Value is: WORLD"));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void not_a_submit()
+    {
+        Element submitButton = doc.getElementById("t1");
+        tester.clickSubmit(submitButton, fieldValues);
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void not_in_form()
+    {
+        Element submitButton = doc.getElementById("orphanedSubmit");
+        tester.clickSubmit(submitButton, fieldValues);
+    }
+
+    @BeforeMethod
+    public void before()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName);
+        doc = tester.renderPage("TestPageForSubmit");
+        fieldValues = CollectionFactory.newMap();
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/TemplateInContextTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/TemplateInContextTest.java
new file mode 100644
index 0000000..3546b54
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/TemplateInContextTest.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+public class TemplateInContextTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void template_in_web_context()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName, "src/test/app2");
+        Document doc = tester.renderPage("TestPageForTemplateInContext");
+        assertTrue(doc.toString().contains("How are you?"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/UnlessTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/UnlessTest.java
new file mode 100644
index 0000000..7574a61
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/integration/pagelevel/UnlessTest.java
@@ -0,0 +1,52 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.pagelevel;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.test.PageTester;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+public class UnlessTest extends Assert
+{
+    private PageTester tester;
+
+    @Test
+    public void render()
+    {
+        String appPackage = "org.apache.tapestry.integration.app2";
+        String appName = "";
+        tester = new PageTester(appPackage, appName);
+        Document doc = tester.renderPage("TestPageForUnless");
+        assertNotNull(doc.getElementById("2"));
+        assertNotNull(doc.getElementById("4"));
+        assertNotNull(doc.getElementById("6"));
+        assertNotNull(doc.getElementById("7"));
+        assertNull(doc.getElementById("1"));
+        assertNull(doc.getElementById("3"));
+        assertNull(doc.getElementById("5"));
+        assertNull(doc.getElementById("8"));
+    }
+
+    @AfterMethod
+    public void after()
+    {
+        if (tester != null)
+        {
+            tester.shutdown();
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBean.java
new file mode 100644
index 0000000..99e4a81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBean.java
@@ -0,0 +1,60 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+/**
+ * Used as test when setting the order of properties via {@link TapestryInternalUtils#orderProperties(org.apache.tapestry.ioc.services.ClassPropertyAdapter,
+ * ClassFactory, java.util.List)}.
+ */
+public class DataBean
+{
+    private String firstName;
+
+    private String lastName;
+
+    private int age;
+
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    public int getAge()
+    {
+        return age;
+    }
+
+    public void setAge(int age)
+    {
+        this.age = age;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBeanSubclass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBeanSubclass.java
new file mode 100644
index 0000000..1da44a0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DataBeanSubclass.java
@@ -0,0 +1,67 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+public class DataBeanSubclass extends DataBean
+{
+    private String street;
+
+    private String city;
+
+    private String state;
+
+    private String zip;
+
+    public String getStreet()
+    {
+        return street;
+    }
+
+    public String getCity()
+    {
+        return city;
+    }
+
+    public String getState()
+    {
+        return state;
+    }
+
+    public String getZip()
+    {
+        return zip;
+    }
+
+    public void setCity(String city)
+    {
+        this.city = city;
+    }
+
+    public void setStreet(String street)
+    {
+        this.street = street;
+    }
+
+    public void setState(String state)
+    {
+        this.state = state;
+    }
+
+    public void setZip(String zip)
+    {
+        this.zip = zip;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DefaultValidationDecoratorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DefaultValidationDecoratorTest.java
new file mode 100644
index 0000000..bdac862
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/DefaultValidationDecoratorTest.java
@@ -0,0 +1,154 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.ValidationDecorator;
+import org.apache.tapestry.ValidationTracker;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class DefaultValidationDecoratorTest extends TapestryTestCase
+{
+    @Test
+    public void label_has_no_field()
+    {
+        Environment env = mockEnvironment();
+
+        replay();
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, null);
+
+        decorator.insideLabel(null, null);
+
+        verify();
+    }
+
+    @Test
+    public void label_error_no_existing_class_attribute()
+    {
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+        Environment env = mockEnvironment();
+        Field field = mockField();
+        ValidationTracker tracker = mockValidationTracker();
+
+        train_peekRequired(env, ValidationTracker.class, tracker);
+        train_inError(tracker, field, true);
+
+        replay();
+
+        Element e = writer.element("label", "accesskey", "f");
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, null);
+
+        decorator.insideLabel(field, e);
+
+        assertEquals(writer.toString(), "<?xml version=\"1.0\"?>\n<label accesskey=\"f\" class=\"t-error\"/>");
+
+        verify();
+    }
+
+    @Test
+    public void label_error_with_existing_class_attribute()
+    {
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+        Environment env = mockEnvironment();
+        Field field = mockField();
+        ValidationTracker tracker = mockValidationTracker();
+
+        train_peekRequired(env, ValidationTracker.class, tracker);
+        train_inError(tracker, field, true);
+
+        replay();
+
+        Element e = writer.element("label", "accesskey", "f", "class", "foo");
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, null);
+
+        decorator.insideLabel(field, e);
+
+        assertEquals(writer.toString(), "<?xml version=\"1.0\"?>\n<label accesskey=\"f\" class=\"foo t-error\"/>");
+
+        verify();
+    }
+
+    @Test
+    public void field_error()
+    {
+        MarkupWriter writer = new MarkupWriterImpl(new XMLMarkupModel());
+        Environment env = mockEnvironment();
+        Field field = mockField();
+        ValidationTracker tracker = mockValidationTracker();
+
+        train_peekRequired(env, ValidationTracker.class, tracker);
+        train_inError(tracker, field, true);
+
+        replay();
+
+        writer.element("input", "type", "text", "name", "ex", "class", "foo", "value", "freddy", "size", "30");
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, writer);
+
+        decorator.insideField(field);
+
+        assertEquals(writer.toString(),
+                     "<?xml version=\"1.0\"?>\n<input class=\"foo t-error\" name=\"ex\" size=\"30\" type=\"text\" value=\"freddy\"/>");
+
+        verify();
+    }
+
+    @Test
+    public void field_ok()
+    {
+        Environment env = mockEnvironment();
+        Field field = mockField();
+        ValidationTracker tracker = mockValidationTracker();
+
+        train_peekRequired(env, ValidationTracker.class, tracker);
+        train_inError(tracker, field, false);
+
+        replay();
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, null);
+
+        decorator.insideField(field);
+
+        verify();
+    }
+
+    @Test
+    public void label_when_field_not_in_error()
+    {
+        Environment env = mockEnvironment();
+        Field field = mockField();
+        ValidationTracker tracker = mockValidationTracker();
+
+        train_peekRequired(env, ValidationTracker.class, tracker);
+        train_inError(tracker, field, false);
+
+        replay();
+
+        ValidationDecorator decorator = new DefaultValidationDecorator(env, null, null, null);
+
+        decorator.insideLabel(field, null);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionGroupModelImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionGroupModelImplTest.java
new file mode 100644
index 0000000..cec9f5a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionGroupModelImplTest.java
@@ -0,0 +1,66 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.OptionGroupModel;
+import org.apache.tapestry.OptionModel;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class OptionGroupModelImplTest extends Assert
+{
+    @Test
+    public void basics()
+    {
+        List<OptionModel> options = Collections.emptyList();
+
+        OptionGroupModel group = new OptionGroupModelImpl("Label", true, options);
+
+        assertEquals(group.toString(), "OptionGroupModel[Label]");
+        assertTrue(group.isDisabled());
+        assertNull(group.getAttributes());
+        assertSame(group.getOptions(), options);
+    }
+
+    @Test
+    public void map_contructor_retains_map()
+    {
+        List<OptionModel> options = Collections.emptyList();
+        Map<String, String> attributes = Collections.emptyMap();
+
+        OptionGroupModel group = new OptionGroupModelImpl("Label", true, options, attributes);
+
+        assertSame(group.getAttributes(), attributes);
+    }
+
+    @Test
+    public void strings_contructor_builds_map()
+    {
+        List<OptionModel> options = Collections.emptyList();
+
+        OptionGroupModel group = new OptionGroupModelImpl("Label", true, options, "fred",
+                                                          "flintstone", "barney", "rubble");
+
+        Map<String, String> attributes = group.getAttributes();
+
+        assertEquals(attributes.size(), 2);
+        assertEquals(attributes.get("fred"), "flintstone");
+        assertEquals(attributes.get("barney"), "rubble");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionModelImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionModelImplTest.java
new file mode 100644
index 0000000..da8200c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/OptionModelImplTest.java
@@ -0,0 +1,38 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.OptionModel;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class OptionModelImplTest extends Assert
+{
+    @Test
+    public void basics()
+    {
+        OptionModel model = new OptionModelImpl("Label", this);
+
+        assertEquals(model.getLabel(), "Label");
+        assertFalse(model.isDisabled());
+        assertSame(model.getValue(), this);
+        assertNull(model.getAttributes());
+
+        model = new OptionModelImpl("Fred", "fred");
+
+
+        assertEquals(model.toString(), "OptionModel[Fred fred]");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java
new file mode 100644
index 0000000..12a6c3d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/PropertyOrderBean.java
@@ -0,0 +1,57 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.beaneditor.OrderBefore;
+
+public class PropertyOrderBean
+{
+    private String first;
+
+    private String second;
+
+    private String third;
+
+    public String getFirst()
+    {
+        return first;
+    }
+
+    public String getSecond()
+    {
+        return second;
+    }
+
+    @OrderBefore("first")
+    public String getThird()
+    {
+        return third;
+    }
+
+    public void setFirst(String first)
+    {
+        this.first = first;
+    }
+
+    public void setSecond(String second)
+    {
+        this.second = second;
+    }
+
+    public void setThird(String third)
+    {
+        this.third = third;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/ServletContextSymbolProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/ServletContextSymbolProviderTest.java
new file mode 100644
index 0000000..cd871ab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/ServletContextSymbolProviderTest.java
@@ -0,0 +1,64 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+import javax.servlet.ServletContext;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+
+public class ServletContextSymbolProviderTest extends TestBase
+{
+    @Test
+    public void access_of_keys_is_case_insensitive()
+    {
+        ServletContext context = newMock(ServletContext.class);
+
+        String key1 = "fred";
+        String value1 = "Fred Flintstone";
+        String key2 = "barney";
+        String value2 = "Barney Rubble";
+
+        expect(context.getInitParameterNames()).andReturn(toEnumeration(key1, key2));
+
+        expect(context.getInitParameter(key1)).andReturn(value1);
+        expect(context.getInitParameter(key2)).andReturn(value2);
+
+        replay();
+
+        SymbolProvider p = new ServletContextSymbolProvider(context);
+
+        assertEquals(p.valueForSymbol(key1), value1);
+        assertEquals(p.valueForSymbol(key2), value2);
+
+        // Not in config is null
+        assertNull(p.valueForSymbol("wilma"));
+
+        // Check for case insensitivity
+        assertEquals(p.valueForSymbol("FRED"), value1);
+
+        verify();
+    }
+
+    protected final <T> Enumeration<T> toEnumeration(T... values)
+    {
+        return Collections.enumeration(Arrays.asList(values));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/SingleKeySymbolProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/SingleKeySymbolProviderTest.java
new file mode 100644
index 0000000..454908c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/SingleKeySymbolProviderTest.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class SingleKeySymbolProviderTest extends Assert
+{
+    private final SymbolProvider provider = new SingleKeySymbolProvider("fred", "flintstone");
+
+    @Test
+    public void exact_match()
+    {
+        assertEquals(provider.valueForSymbol("fred"), "flintstone");
+    }
+
+    @Test
+    public void case_insensitive()
+    {
+        assertEquals(provider.valueForSymbol("FRED"), "flintstone");
+    }
+
+    @Test
+    public void non_match()
+    {
+        assertNull(provider.valueForSymbol("barney"));
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryAppInitializerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryAppInitializerTest.java
new file mode 100644
index 0000000..8ad2e58
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryAppInitializerTest.java
@@ -0,0 +1,44 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.util.Transformer;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+@Test
+public class TapestryAppInitializerTest extends Assert
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testLoadAppModule()
+    {
+        Registry registry = new TapestryAppInitializer("org.apache.tapestry.integration.app0",
+                                                       "foo", "").getRegistry();
+
+        Transformer<String> s1 = registry.getService("Service1", Transformer.class);
+        assertEquals(s1.transform("a"), "A");
+    }
+
+    @Test
+    public void testNoAppModule()
+    {
+        // Apparently just checking to see that it doesn't fail.
+
+        new TapestryAppInitializer("non_existing.package", "foo", "").getRegistry();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
new file mode 100644
index 0000000..4691052
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/TapestryInternalUtilsTest.java
@@ -0,0 +1,455 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.ComponentResourcesAware;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+public class TapestryInternalUtilsTest extends InternalBaseTestCase
+{
+    private ClassFactory classFactory;
+
+    private PropertyAccess access;
+
+    @BeforeClass
+    public void setup()
+    {
+        classFactory = getService("ClassFactory", ClassFactory.class);
+        access = getService("PropertyAccess", PropertyAccess.class);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        access = null;
+        classFactory = null;
+    }
+
+
+    @Test(dataProvider = "to_user_presentable")
+    public void to_user_presentable(String input, String expected)
+    {
+        assertEquals(TapestryInternalUtils.toUserPresentable(input), expected);
+    }
+
+    @DataProvider(name = "to_user_presentable")
+    public Object[][] to_user_presentable_data()
+    {
+        return new Object[][] { { "hello", "Hello" }, { "userId", "User Id" }, { "useHTML", "Use HTML" },
+                { "underscored_name", "Underscored Name" }, };
+    }
+
+    @Test
+    public void map_from_keys_and_values()
+    {
+        Map<String, String> map = TapestryInternalUtils.mapFromKeysAndValues("fred", "flintstone", "barney", "rubble");
+
+        assertEquals(map.size(), 2);
+        assertEquals(map.get("fred"), "flintstone");
+        assertEquals(map.get("barney"), "rubble");
+    }
+
+    @Test
+    public void string_to_option_model_just_label()
+    {
+        OptionModel model = TapestryInternalUtils.toOptionModel("Just A Label");
+
+        assertEquals(model.getLabel(), "Just A Label");
+        assertEquals(model.getValue(), "Just A Label");
+    }
+
+    @Test
+    public void string_to_option_model()
+    {
+        OptionModel model = TapestryInternalUtils.toOptionModel("my-value=Some Label");
+
+        assertEquals(model.getLabel(), "Some Label");
+        assertEquals(model.getValue(), "my-value");
+    }
+
+    @Test
+    public void string_to_option_models()
+    {
+        List<OptionModel> options = TapestryInternalUtils.toOptionModels("UK,USA,DE=Germany");
+
+        assertEquals(options.size(), 3);
+
+        assertEquals(options.get(0).getLabel(), "UK");
+        assertEquals(options.get(0).getValue(), "UK");
+
+        assertEquals(options.get(1).getLabel(), "USA");
+        assertEquals(options.get(1).getValue(), "USA");
+
+        assertEquals(options.get(2).getLabel(), "Germany");
+        assertEquals(options.get(2).getValue(), "DE");
+    }
+
+    @Test
+    public void map_entry_to_option_model()
+    {
+        Map<String, String> map = Collections.singletonMap("key", "value");
+        Map.Entry entry = map.entrySet().iterator().next();
+        OptionModel model = TapestryInternalUtils.toOptionModel(entry);
+
+        assertEquals(model.getLabel(), "value");
+        assertEquals(model.getValue(), "key");
+    }
+
+    @Test
+    public void map_to_option_models()
+    {
+        Map<Integer, String> map = new TreeMap<Integer, String>();
+        map.put(1, "A");
+        map.put(2, null);
+        map.put(3, "C");
+
+        List<OptionModel> options = TapestryInternalUtils.toOptionModels(map);
+
+        assertEquals(options.size(), 3);
+
+        assertEquals(options.get(0).getLabel(), "A");
+        assertEquals(options.get(0).getValue(), 1);
+
+        assertEquals(options.get(1).getLabel(), "");
+        assertEquals(options.get(1).getValue(), 2);
+
+        assertEquals(options.get(2).getLabel(), "C");
+        assertEquals(options.get(2).getValue(), 3);
+    }
+
+    @Test
+    public void null_map_key_is_null_option_value()
+    {
+
+        Map<Integer, String> map = new HashMap<Integer, String>();
+        map.put(null, "Label");
+
+        List<OptionModel> options = TapestryInternalUtils.toOptionModels(map);
+
+        assertEquals(options.size(), 1);
+
+        assertEquals(options.get(0).getLabel(), "Label");
+        assertEquals(options.get(0).getValue(), null);
+    }
+
+    @Test
+    public void object_to_option_model()
+    {
+        Object object = new Integer(27);
+        OptionModel model = TapestryInternalUtils.toOptionModel(object);
+
+        assertEquals(model.getLabel(), "27");
+        assertEquals(model.getValue(), object);
+    }
+
+    @Test
+    public void list_to_option_models()
+    {
+        List<String> list = new ArrayList<String>();
+        list.add("A");
+        list.add(null);
+        list.add("C");
+
+        List<OptionModel> options = TapestryInternalUtils.toOptionModels(list);
+
+        assertEquals(options.size(), 3);
+
+        assertEquals(options.get(0).getLabel(), "A");
+        assertEquals(options.get(0).getValue(), "A");
+
+        assertEquals(options.get(1).getLabel(), "");
+        assertEquals(options.get(1).getValue(), null);
+
+        assertEquals(options.get(2).getLabel(), "C");
+        assertEquals(options.get(2).getValue(), "C");
+    }
+
+    @Test
+    public void whitespace_around_terms_is_trimmed()
+    {
+        List<OptionModel> options = TapestryInternalUtils.toOptionModels(" UK , USA , DE=Germany ");
+
+        assertEquals(options.size(), 3);
+
+        assertEquals(options.get(0).getLabel(), "UK");
+        assertEquals(options.get(0).getValue(), "UK");
+
+        assertEquals(options.get(1).getLabel(), "USA");
+        assertEquals(options.get(1).getValue(), "USA");
+
+        assertEquals(options.get(2).getLabel(), "Germany");
+        assertEquals(options.get(2).getValue(), "DE");
+    }
+
+    @Test
+    public void string_to_select_model_type_coercion_integration()
+    {
+        TypeCoercer coercer = getService(TypeCoercer.class);
+
+        SelectModel selectModel = coercer.coerce(" UK , USA , DE=Germany ", SelectModel.class);
+
+        assertNull(selectModel.getOptionGroups());
+        assertEquals(selectModel.getOptions().size(), 3);
+
+        // Waste of effort to re-test each individual option model.
+    }
+
+    @Test
+    public void parse_key_value()
+    {
+        KeyValue kv = TapestryInternalUtils.parseKeyValue("foo=bar");
+
+        assertEquals(kv.getKey(), "foo");
+        assertEquals(kv.getValue(), "bar");
+    }
+
+    @Test
+    public void bad_format_key_value_pair()
+    {
+        String input = "abraxas";
+
+        try
+        {
+            TapestryInternalUtils.parseKeyValue(input);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), InternalMessages.badKeyValue(input));
+        }
+    }
+
+    @Test
+    public void whitespace_trimmed_for_key_value()
+    {
+        KeyValue kv = TapestryInternalUtils.parseKeyValue("  mykey = myvalue ");
+
+        assertEquals(kv.getKey(), "mykey");
+        assertEquals(kv.getValue(), "myvalue");
+    }
+
+    @Test
+    public void extract_id_from_property_expression()
+    {
+        assertEquals(TapestryInternalUtils.extractIdFromPropertyExpression("simpleName"), "simpleName");
+        assertEquals(TapestryInternalUtils.extractIdFromPropertyExpression("complex.name().withStuff"),
+                     "complexnamewithStuff");
+        assertEquals(TapestryInternalUtils.extractIdFromPropertyExpression("number99.withABullet"),
+                     "number99withABullet");
+    }
+
+    @Test
+    public void default_label_key_found()
+    {
+        Messages messages = mockMessages();
+        train_contains(messages, "myid-label", true);
+        train_get(messages, "myid-label", "My Id");
+
+        replay();
+
+        assertEquals(TapestryInternalUtils.defaultLabel("myid", messages, "myid-name-not-used"), "My Id");
+
+        verify();
+    }
+
+    @Test
+    public void default_label_from_name()
+    {
+        Messages messages = mockMessages();
+
+        stub_contains(messages, false);
+
+        replay();
+
+        assertEquals(TapestryInternalUtils.defaultLabel("foobarbazbiff", messages, "foo.bar().baz.biff()"), "Biff");
+
+        verify();
+    }
+
+    @Test
+    public void property_order_basic()
+    {
+        ClassPropertyAdapter adapter = access.getAdapter(DataBean.class);
+
+        List<String> names = adapter.getPropertyNames();
+
+        names.remove("class");
+
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, classFactory, names);
+
+        assertEquals(sorted, Arrays.asList("firstName", "lastName", "age"));
+    }
+
+    @Test
+    public void property_order_on_subclass()
+    {
+        ClassPropertyAdapter adapter = access.getAdapter(DataBeanSubclass.class);
+
+        List<String> names = adapter.getPropertyNames();
+
+        names.remove("class");
+
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, classFactory, names);
+
+        // Subclass properties listed after superclass properties, as desired.
+
+        assertEquals(sorted, Arrays.asList("firstName", "lastName", "age", "street", "city", "state", "zip"));
+    }
+
+    @Test
+    public void properties_with_order_annotation_filtered()
+    {
+        ClassPropertyAdapter adapter = access.getAdapter(PropertyOrderBean.class);
+
+        List<String> names = adapter.getPropertyNames();
+
+        names.remove("class");
+
+        List<String> sorted = TapestryInternalUtils.orderProperties(null, adapter, classFactory, names);
+
+        // Property third has an explicit @OrderBefore
+
+        assertEquals(sorted, Arrays.asList("third", "first", "second"));
+    }
+
+    @Test
+    public void null_equals_null()
+    {
+        assertTrue(TapestryInternalUtils.isEqual(null, null));
+    }
+
+    @Test
+    public void non_null_never_equals_null()
+    {
+        assertFalse(TapestryInternalUtils.isEqual(this, null));
+    }
+
+    @Test
+    public void same_is_equal()
+    {
+        assertTrue(TapestryInternalUtils.isEqual(this, this));
+    }
+
+    @Test
+    public void is_equal_with_objects()
+    {
+        String left = "left";
+        String right = "right";
+
+        assertFalse(TapestryInternalUtils.isEqual(left, right));
+        assertTrue(TapestryInternalUtils.isEqual(left, new String(left)));
+    }
+
+    @Test
+    public void type_coersion_string_to_pattern()
+    {
+        TypeCoercer coercer = getObject(TypeCoercer.class, null);
+
+        String input = "\\s+";
+
+        Pattern pattern = coercer.coerce(input, Pattern.class);
+
+        assertEquals(pattern.toString(), input);
+    }
+
+    @Test
+    public void type_coersion_from_component_resources_aware_to_component_resources()
+    {
+        ComponentResourcesAware input = newMock(ComponentResourcesAware.class);
+        ComponentResources resources = mockComponentResources();
+
+        expect(input.getComponentResources()).andReturn(resources);
+
+        TypeCoercer coercer = getObject(TypeCoercer.class, null);
+
+        replay();
+
+        ComponentResources actual = coercer.coerce(input, ComponentResources.class);
+
+        assertSame(actual, resources);
+
+        verify();
+    }
+
+    @Test
+    public void escape_percent_and_slash()
+    {
+        assertEquals(TapestryInternalUtils.escapePercentAndSlash("foo%bar/baz"), "foo%25bar%2Fbaz");
+    }
+
+    @Test
+    public void unescape_percent_and_slash()
+    {
+        assertEquals(TapestryInternalUtils.unescapePercentAndSlash("foo%25bar%2Fbaz"), "foo%bar/baz");
+    }
+
+    @Test
+    public void encode_alphanum_context()
+    {
+        String input = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+        String expected = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+        assertEquals(TapestryInternalUtils.encodeContext(input), expected);
+    }
+
+    @Test
+    public void encode_unsafe_context()
+    {
+        String input = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
+        String expected = "%20%21%22%23%24%2525%26%27%28%29*%2B%2C-.%252F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D%7E";
+        assertEquals(TapestryInternalUtils.encodeContext(input), expected);
+    }
+
+    @Test
+    public void encode_utf8_japanese_context()
+    {
+        String input = "\u65E5\u672C\u8A9E";
+        String expected = "%E6%97%A5%E6%9C%AC%E8%AA%9E";
+        assertEquals(TapestryInternalUtils.encodeContext(input), expected);
+    }
+
+    @Test
+    public void to_class_attribute_value_empty()
+    {
+        List<String> classes = Collections.emptyList();
+
+        assertNull(TapestryInternalUtils.toClassAttributeValue(classes));
+    }
+
+    @Test
+    public void to_class_attribute_value_normal()
+    {
+        List<String> classes = CollectionFactory.newList("fred", "barney", "wilma");
+
+        assertEquals(TapestryInternalUtils.toClassAttributeValue(classes), "fred barney wilma");
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java
new file mode 100644
index 0000000..c5c1da9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/BeanModelUtilsTest.java
@@ -0,0 +1,138 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class BeanModelUtilsTest extends InternalBaseTestCase
+{
+    @Test(dataProvider = "split_inputs")
+    public void split(String propertyNames, String[] expected)
+    {
+        assertEquals(BeanModelUtils.split(propertyNames), expected);
+    }
+
+    private Object[] build(String propertyNames, String... expected)
+    {
+        return new Object[]
+                { propertyNames, expected };
+    }
+
+    @DataProvider(name = "split_inputs")
+    public Object[][] split_inputs()
+    {
+        return new Object[][]
+                { build("fred", "fred"), build("fred,barney", "fred", "barney"),
+                        build(" fred, barney, wilma, betty ", "fred", "barney", "wilma", "betty"),
+                        new Object[]
+                                { "   ", new String[0] } };
+    }
+
+    @Test
+    public void exclude()
+    {
+        BeanModel model = mockBeanModel();
+
+        expect(model.exclude("fred", "barney")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.exclude(model, "fred,barney");
+
+        verify();
+    }
+
+    @Test
+    public void reorder()
+    {
+        BeanModel model = mockBeanModel();
+
+        expect(model.reorder("fred", "barney")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.reorder(model, "fred,barney");
+
+        verify();
+    }
+
+    @Test
+    public void add()
+    {
+        BeanModel model = mockBeanModel();
+        PropertyModel fred = mockPropertyModel();
+        PropertyModel barney = mockPropertyModel();
+
+        expect(model.add("fred", null)).andReturn(fred);
+        expect(model.add("barney", null)).andReturn(barney);
+
+        replay();
+
+        BeanModelUtils.add(model, "fred,barney");
+
+        verify();
+    }
+
+    @Test
+    public void modify_no_work()
+    {
+        BeanModel model = mockBeanModel();
+
+        replay();
+
+        BeanModelUtils.modify(model, null, null, null, null);
+
+        verify();
+    }
+
+    @Test
+    public void modify_full()
+    {
+        BeanModel model = mockBeanModel();
+        PropertyModel fred = mockPropertyModel();
+        PropertyModel barney = mockPropertyModel();
+
+        expect(model.add("fred", null)).andReturn(fred);
+        expect(model.add("barney", null)).andReturn(barney);
+
+        expect(model.exclude("pebbles", "bambam")).andReturn(model);
+
+        expect(model.reorder("wilma", "betty")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.modify(model, "fred,barney", null, "pebbles,bambam", "wilma,betty");
+
+        verify();
+    }
+
+    @Test
+    public void modify_include()
+    {
+        BeanModel model = mockBeanModel();
+
+        expect(model.include("fred", "wilma")).andReturn(model);
+
+        replay();
+
+        BeanModelUtils.modify(model, null, "fred,wilma", null, null);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java
new file mode 100644
index 0000000..8e44b82
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/beaneditor/ValidateAnnotationConstraintGeneratorTest.java
@@ -0,0 +1,85 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.beaneditor;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+public class ValidateAnnotationConstraintGeneratorTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_annotation()
+    {
+        PropertyConduit conduit = mockPropertyConduit();
+
+        train_getAnnotation(conduit, Validate.class, null);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertNull(gen.buildConstraints(Object.class, conduit));
+
+        verify();
+    }
+
+    @Test
+    public void single_constraint()
+    {
+        PropertyConduit conduit = mockPropertyConduit();
+        Validate validate = newValidate("required");
+
+        train_getAnnotation(conduit, Validate.class, validate);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertEquals(gen.buildConstraints(Object.class, conduit), Arrays.asList("required"));
+
+        verify();
+    }
+
+    @Test
+    public void multiple_constraints()
+    {
+        PropertyConduit conduit = mockPropertyConduit();
+        Validate validate = newValidate("required,minlength=3");
+
+        train_getAnnotation(conduit, Validate.class, validate);
+
+        replay();
+
+        ValidationConstraintGenerator gen = new ValidateAnnotationConstraintGenerator();
+
+        assertEquals(gen.buildConstraints(null, conduit), Arrays.asList("required", "minlength=3"));
+
+        verify();
+    }
+
+    private Validate newValidate(String value)
+    {
+        Validate annotation = newMock(Validate.class);
+
+        expect(annotation.value()).andReturn(value).atLeastOnce();
+
+        return annotation;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/BindingFactoryTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/BindingFactoryTest.java
new file mode 100644
index 0000000..ff0346a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/BindingFactoryTest.java
@@ -0,0 +1,90 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.TranslatorSource;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for several of the simpler binding factories.
+ */
+public class BindingFactoryTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void literal_binding()
+    {
+        ComponentResources res = mockInternalComponentResources();
+        Location l = mockLocation();
+
+        replay();
+
+        BindingFactory factory = new LiteralBindingFactory();
+
+        Binding b = factory.newBinding("test binding", res, null, "Tapestry5", l);
+
+        assertSame(InternalUtils.locationOf(b), l);
+
+        assertEquals(b.get(), "Tapestry5");
+        assertTrue(b.isInvariant());
+        assertSame(b.getBindingType(), String.class);
+
+        try
+        {
+            b.set(null);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void translate_binding()
+    {
+        Translator translator = mockTranslator();
+        TranslatorSource source = newMock(TranslatorSource.class);
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        String description = "foo bar";
+        String expression = "mock";
+
+        expect(source.get(expression)).andReturn(translator);
+
+        replay();
+
+        BindingFactory factory = new TranslateBindingFactory(source);
+
+        Binding binding = factory.newBinding(description, resources, resources, expression, l);
+
+        assertSame(binding.get(), translator);
+
+        assertSame(InternalUtils.locationOf(binding), l);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
new file mode 100644
index 0000000..8e6bdcd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentEvent;
+import org.apache.tapestry.runtime.Event;
+
+/**
+ * For use in places where we don't want to have to transform a class just for testing purposes.
+ */
+public class DefaultComponent implements Component
+{
+
+    public void afterRender(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void afterRenderBody(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void afterRenderTemplate(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void beforeRenderBody(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void beforeRenderTemplate(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void beginRender(MarkupWriter writer, Event event)
+    {
+    }
+
+    public void cleanupRender(MarkupWriter writer, Event event)
+    {
+    }
+
+    public boolean dispatchComponentEvent(ComponentEvent event)
+    {
+        return false;
+    }
+
+    public void postRenderCleanup()
+    {
+    }
+
+    public void setupRender(MarkupWriter writer, Event event)
+    {
+    }
+
+    public ComponentResources getComponentResources()
+    {
+        return null;
+    }
+
+    public void containingPageDidAttach()
+    {
+    }
+
+    public void containingPageDidDetach()
+    {
+    }
+
+    public void containingPageDidLoad()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java
new file mode 100644
index 0000000..12e017a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java
@@ -0,0 +1,620 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotation.BeforeRenderBody;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.util.IntegerRange;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BindingFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class PropBindingFactoryTest extends InternalBaseTestCase
+{
+    private BindingFactory factory;
+
+    @BeforeClass
+    public void setup_factory()
+    {
+        factory = getService("PropBindingFactory", BindingFactory.class);
+    }
+
+    @AfterClass
+    public void cleanup_factory()
+    {
+        factory = null;
+    }
+
+    private ComponentResources newComponentResources(Component component)
+    {
+        ComponentResources resources = mockComponentResources();
+        train_getComponent(resources, component);
+
+        train_getCompleteId(resources, "foo.Bar:baz");
+
+        return resources;
+    }
+
+    @Test
+    public void object_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "objectValue", l);
+
+        assertSame(binding.getBindingType(), String.class);
+
+        bean.setObjectValue("first");
+
+        assertEquals(binding.get(), "first");
+
+        binding.set("second");
+
+        assertEquals(bean.getObjectValue(), "second");
+        assertEquals(InternalUtils.locationOf(binding), l);
+
+        assertEquals(binding.toString(), "PropBinding[test binding foo.Bar:baz(objectValue)]");
+
+        verify();
+    }
+
+    @Test
+    public void annotation_from_read_only_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "readOnly", l);
+
+        assertEquals(binding.getAnnotation(OrderBefore.class).value(), "writeOnly");
+
+        verify();
+    }
+
+    @Test
+    public void annotation_from_write_only_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "writeOnly", l);
+
+        assertEquals(binding.getAnnotation(OrderAfter.class).value(), "foobar");
+
+        verify();
+    }
+
+    @Test
+    public void annotation_does_not_exist()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "intValue", l);
+
+        assertNull(binding.getAnnotation(OrderBefore.class));
+
+        verify();
+    }
+
+    @Test
+    public void annotation_on_named_method()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding(
+                "test binding",
+                resources,
+                null,
+                "stringHolderMethod()",
+                l);
+
+        assertNotNull(binding.getAnnotation(BeforeRenderBody.class));
+
+        verify();
+    }
+
+    @Test
+    public void annnotation_on_read_method_takes_precedence_over_write_method()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "objectValue", l);
+
+        assertEquals(binding.getAnnotation(OrderAfter.class).value(), "readOnly");
+
+        verify();
+    }
+
+    @Test
+    public void property_path()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding(
+                "test binding",
+                resources,
+                null,
+                "stringHolder.value",
+                l);
+
+        assertSame(binding.getBindingType(), String.class);
+
+        bean.getStringHolder().setValue("first");
+
+        assertEquals(binding.get(), "first");
+
+        binding.set("second");
+
+        assertEquals(bean.getStringHolder().getValue(), "second");
+
+        assertEquals(
+                binding.toString(),
+                "PropBinding[test binding foo.Bar:baz(stringHolder.value)]");
+
+        verify();
+    }
+
+    /**
+     * The "preamble" are the non-terminal property or method names.
+     */
+    @Test
+    public void property_path_with_explicit_method_in_preamble()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding(
+                "test binding",
+                resources,
+                null,
+                "stringHolderMethod().value",
+                l);
+
+        assertSame(binding.getBindingType(), String.class);
+
+        bean.getStringHolder().setValue("first");
+
+        assertEquals(binding.get(), "first");
+
+        assertEquals(
+                binding.toString(),
+                "PropBinding[test binding foo.Bar:baz(stringHolderMethod().value)]");
+
+        verify();
+    }
+
+    @Test
+    public void method_call_as_terminal()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding(
+                "test binding",
+                resources,
+                null,
+                "stringHolderMethod().stringValue()",
+                l);
+
+        assertSame(binding.getBindingType(), String.class);
+
+        bean.getStringHolder().setValue("first");
+
+        assertEquals(binding.get(), "first");
+
+        try
+        {
+            binding.set("read-only");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Expression stringHolderMethod().stringValue() for class org.apache.tapestry.internal.bindings.TargetBean is read-only.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void method_not_found_in_preamble()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, "isThatRealBlood().value", l);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No public method \'isThatRealBlood()\' in class org.apache.tapestry.internal.bindings.TargetBean (within property expression \'isThatRealBlood().value\').");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void method_not_found_in_terminal()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        try
+        {
+            factory.newBinding(
+                    "test binding",
+                    resources,
+                    null,
+                    "stringHolder.isThatRealBlood()",
+                    l);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No public method \'isThatRealBlood()\' in class org.apache.tapestry.internal.bindings.StringHolder (within property expression \'stringHolder.isThatRealBlood()\').");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void void_method_in_preamble()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, "voidMethod().value", l);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Method \'voidMethod()\' returns void (in class org.apache.tapestry.internal.bindings.TargetBean, within property expression \'voidMethod().value\').");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void void_method_as_terminal()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, "stringHolder.voidMethod()", l);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Method \'voidMethod()\' returns void (in class org.apache.tapestry.internal.bindings.StringHolder, within property expression \'stringHolder.voidMethod()\').");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void property_path_through_missing_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        String propertyPath = "stringHolder.missingProperty.terminalProperty";
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, propertyPath, l);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Class org.apache.tapestry.internal.bindings.StringHolder does not contain a property named \'missingProperty\' "
+                            + "(within property expression \'stringHolder.missingProperty.terminalProperty\').  Available properties: value.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void property_path_through_write_only_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        String propertyPath = "writeOnly.terminalProperty";
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, propertyPath, l);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Property \'writeOnly\' of class org.apache.tapestry.internal.bindings.TargetBean (within property expression \'writeOnly.terminalProperty\') is not readable (it has no read accessor method).");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void primitive_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "intValue", l);
+
+        assertSame(binding.getBindingType(), int.class);
+
+        bean.setIntValue(1);
+
+        assertEquals(binding.get(), 1);
+
+        binding.set(2);
+
+        assertEquals(bean.getIntValue(), 2);
+
+        verify();
+    }
+
+    @Test
+    public void read_only_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "readOnly", l);
+
+        assertEquals(binding.get(), "ReadOnly");
+
+        try
+        {
+            binding.set("fail");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Expression readOnly for class org.apache.tapestry.internal.bindings.TargetBean is read-only.");
+            assertEquals(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void write_only_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = newComponentResources(bean);
+        Location l = mockLocation();
+
+        replay();
+
+        Binding binding = factory.newBinding("test binding", resources, null, "writeOnly", l);
+
+        binding.set("updated");
+
+        assertEquals(bean.writeOnly, "updated");
+
+        try
+        {
+            assertEquals(binding.get(), "ReadOnly");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Expression writeOnly for class org.apache.tapestry.internal.bindings.TargetBean is write-only.");
+            assertEquals(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void unknown_property()
+    {
+        TargetBean bean = new TargetBean();
+        ComponentResources resources = mockComponentResources();
+        Location l = mockLocation();
+
+        train_getComponent(resources, bean);
+
+        replay();
+
+        try
+        {
+            factory.newBinding("test binding", resources, null, "missingProperty", l);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Class org.apache.tapestry.internal.bindings.TargetBean does not contain a property named \'missingProperty\' "
+                            + "(within property expression \'missingProperty\').  "
+                            + "Available properties: class, componentResources, intValue, objectValue, readOnly, stringHolder, writeOnly.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void special_prop_binding_value_null()
+    {
+        Location l = mockLocation();
+        String description = "my description";
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+
+        train_getComponent(resources, component);
+
+        replay();
+
+        Binding binding = factory.newBinding(description, resources, null, "this", l);
+
+        assertSame(binding.get(), component);
+
+        verify();
+    }
+
+    @Test(dataProvider = "values")
+    public void special_prop_binding_values(String expression, Object expected)
+    {
+        Location l = mockLocation();
+        String description = "my description";
+        ComponentResources resources = mockComponentResources();
+
+        replay();
+
+        Binding binding = factory.newBinding(description, resources, null, expression, l);
+
+        assertEquals(binding.get(), expected);
+
+        verify();
+    }
+
+    @DataProvider(name = "values")
+    public Object[][] values()
+    {
+        return new Object[][]
+                {
+                        { "true", true, },
+                        { "True", true, },
+                        { " true ", true, },
+                        { "false", false },
+                        { "null", null },
+                        { "3", 3l },
+                        { " 37 ", 37l },
+                        { " -227", -227l },
+                        { " 5.", 5d },
+                        { " -100.", -100d },
+                        { " -0.0 ", -0d },
+                        { "1..10", new IntegerRange(1, 10) },
+                        { " -20 .. -30 ", new IntegerRange(-20, -30) },
+                        { "0.", 0d },
+                        { " 227.75", 227.75d },
+                        { " -10123.67", -10123.67d },
+                        { "'Hello World'", "Hello World" },
+                        { " 'Whitespace Ignored' ", "Whitespace Ignored" },
+                        { " ' Inside ' ", " Inside " },
+                        { " 'Nested ' Quotes ' Inside'", "Nested ' Quotes ' Inside" },
+                        { "'''", "'" } };
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolder.java
new file mode 100644
index 0000000..19e1d93
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolder.java
@@ -0,0 +1,26 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;

+

+public interface StringHolder

+{

+    void setValue(String value);

+

+    String getValue();

+

+    String stringValue();

+

+    void voidMethod();

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolderImpl.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolderImpl.java
new file mode 100644
index 0000000..dc11445
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/StringHolderImpl.java
@@ -0,0 +1,39 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+public class StringHolderImpl implements StringHolder
+{
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public String stringValue()
+    {
+        return value;
+    }
+
+    public void voidMethod()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java
new file mode 100644
index 0000000..42f468e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/TargetBean.java
@@ -0,0 +1,80 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.annotation.BeforeRenderBody;
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
+
+public class TargetBean extends DefaultComponent
+{
+    private String objectValue;
+
+    private int intValue;
+
+    String writeOnly;
+
+    private StringHolder stringHolder = new StringHolderImpl();
+
+    public StringHolder getStringHolder()
+    {
+        return stringHolder;
+    }
+
+    @BeforeRenderBody
+    public StringHolder stringHolderMethod()
+    {
+        return stringHolder;
+    }
+
+    public void voidMethod()
+    {
+
+    }
+
+    public int getIntValue()
+    {
+        return intValue;
+    }
+
+    public void setIntValue(int intValue)
+    {
+        this.intValue = intValue;
+    }
+
+    @OrderAfter("readOnly")
+    public String getObjectValue()
+    {
+        return objectValue;
+    }
+
+    @OrderAfter("writeOnly")
+    public void setObjectValue(String objectValue)
+    {
+        this.objectValue = objectValue;
+    }
+
+    @OrderAfter("foobar")
+    public void setWriteOnly(String value)
+    {
+        writeOnly = value;
+    }
+
+    @OrderBefore("writeOnly")
+    public String getReadOnly()
+    {
+        return "ReadOnly";
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/ValidateBindingFactoryTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/ValidateBindingFactoryTest.java
new file mode 100644
index 0000000..2f8b4eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/bindings/ValidateBindingFactoryTest.java
@@ -0,0 +1,95 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.bindings;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.FieldValidatorSource;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class ValidateBindingFactoryTest extends TapestryTestCase
+{
+    private interface FieldComponent extends Field, Component
+    {
+    }
+
+    ;
+
+    @Test
+    public void not_a_field()
+    {
+        FieldValidatorSource source = mockFieldValidatorSource();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Component instance = mockComponent();
+        Location l = mockLocation();
+
+        train_getComponent(component, instance);
+        train_getCompleteId(component, "foo.Bar:baz");
+
+        replay();
+
+        BindingFactory factory = new ValidateBindingFactory(source);
+
+        try
+        {
+            factory.newBinding("descrip", container, component, "zip,zoom", l);
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Component 'foo.Bar:baz' is not a field (it does not implement the Field interface) and may not be used with the validate: binding prefix.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void success()
+    {
+
+        FieldValidatorSource source = mockFieldValidatorSource();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        FieldComponent instance = newMock(FieldComponent.class);
+        Location l = mockLocation();
+        FieldValidator validator = mockFieldValidator();
+
+        String expression = "required,minLength=5";
+
+        train_getComponent(component, instance);
+
+        expect(source.createValidators(instance, expression)).andReturn(validator);
+
+        replay();
+
+        BindingFactory factory = new ValidateBindingFactory(source);
+
+        Binding binding = factory.newBinding("descrip", container, component, expression, l);
+
+        assertSame(binding.get(), validator);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/CollectionGridDataSourceTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/CollectionGridDataSourceTest.java
new file mode 100644
index 0000000..93abaef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/CollectionGridDataSourceTest.java
@@ -0,0 +1,126 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.grid;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.grid.ColumnSort;
+import org.apache.tapestry.grid.SortConstraint;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.BeanModelSource;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class CollectionGridDataSourceTest extends InternalBaseTestCase
+{
+    // Just arbitrary numbers ...
+
+    private static final int FRED = 99;
+
+    private static final int BARNEY = 23;
+
+    private static final int WILMA = 107;
+
+    private static final int BETTY = 298;
+
+    // Arrays.asList returns an unmodifiable list
+
+    private final List raw = Arrays.asList(new Datum(FRED, "Fred"), new Datum(BARNEY, "Barney"),
+                                           new Datum(WILMA, "Wilma"), new Datum(BETTY, null));
+
+    private final CollectionGridDataSource source = new CollectionGridDataSource(raw);
+
+    private BeanModel model;
+
+    @BeforeClass
+    public void setup()
+    {
+        BeanModelSource source = getService(BeanModelSource.class);
+
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        model = source.create(Datum.class, false, resources);
+
+        verify();
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        model = null;
+    }
+
+    @Test
+    public void sort_on_number_ascending()
+    {
+        sort("id", true, BARNEY, FRED, WILMA, BETTY);
+    }
+
+    @Test
+    public void sort_on_number_descending()
+    {
+        sort("id", false, BETTY, WILMA, FRED, BARNEY);
+    }
+
+    @Test
+    public void sort_on_string_value_ascending()
+    {
+        // Nulls sort first
+
+        // Without a secondary sort column, it's kind of arbitrary whether WILMA or BETTY is sorted
+        // first.
+
+        sort("value", true, BETTY, BARNEY, FRED, WILMA);
+    }
+
+    @Test
+    public void sort_on_string_value_descending()
+    {
+        sort("value", false, WILMA, FRED, BARNEY, BETTY);
+    }
+
+    private void sort(String propertyName, boolean ascending, int... ids)
+    {
+        PropertyModel propertyModel = model.get(propertyName);
+
+        int availableRows = source.getAvailableRows();
+
+        SortConstraint constraint = new SortConstraint(propertyModel,
+                                                       ascending ? ColumnSort.ASCENDING : ColumnSort.DESCENDING);
+        List<SortConstraint> constraints = Collections.singletonList(constraint);
+
+        source.prepare(0, availableRows - 1, constraints);
+
+        for (int i = 0; i < ids.length; i++)
+        {
+            Datum row = (Datum) source.getRowValue(i);
+
+            assertEquals(row.getId(), ids[i], "Id for Datum #" + i);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/Datum.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/Datum.java
new file mode 100644
index 0000000..f6fb5af
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/grid/Datum.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.grid;
+
+public class Datum
+{
+    private final int id;
+
+    private final String value;
+
+    public Datum(final int id, final String value)
+    {
+        this.id = id;
+        this.value = value;
+    }
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java
new file mode 100644
index 0000000..166fdf4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java
@@ -0,0 +1,725 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.model;
+
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.model.MutableEmbeddedComponentModel;
+import org.apache.tapestry.model.ParameterModel;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+/**
+ * Tests {@link org.apache.tapestry.internal.model.MutableComponentModelImpl} and {@link
+ * org.apache.tapestry.internal.model.MutableEmbeddedComponentModelImpl}.
+ */
+public class MutableComponentModelImplTest extends InternalBaseTestCase
+{
+    private static final String COMPONENT_CLASS_NAME = "org.example.components.Fred";
+
+    private static final String CLASS_NAME = "org.example.components.Foo";
+
+    @Test
+    public void root_class_vs_sub_class()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.isRootClass());
+
+        MutableComponentModel subModel = new MutableComponentModelImpl(CLASS_NAME, logger, r, model);
+
+        assertFalse(subModel.isRootClass());
+
+        verify();
+    }
+
+    @Test
+    public void add_new_parameter()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.getParameterNames().isEmpty());
+
+        String parameterName = "value";
+
+        model.addParameter(parameterName, true, BindingConstants.PROP);
+
+        ParameterModel pm = model.getParameterModel(parameterName);
+
+        assertEquals(pm.getName(), parameterName);
+        assertEquals(true, pm.isRequired());
+        assertEquals(pm.getDefaultBindingPrefix(), BindingConstants.PROP);
+
+        assertEquals(model.getDeclaredParameterNames(), Arrays.asList(parameterName));
+
+        // Verify that the binding prefix is actually stored:
+
+        model.addParameter("fred", true, "flint");
+
+        // Checks that parameter names are case insensitive
+
+        assertEquals(model.getParameterModel("Fred").getDefaultBindingPrefix(), "flint");
+
+        verify();
+    }
+
+    @Test
+    public void parameter_names_are_sorted()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.addParameter("fred", true, BindingConstants.PROP);
+        model.addParameter("wilma", true, BindingConstants.PROP);
+        model.addParameter("barney", true, BindingConstants.PROP);
+
+        assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void declared_parameter_names_does_not_include_superclass_parameters()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+        ComponentModel parent = mockComponentModel();
+
+        train_getPersistentFieldNames(parent);
+        train_getParameterNames(parent, "betty");
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        model.addParameter("fred", true, BindingConstants.PROP);
+        model.addParameter("wilma", true, BindingConstants.PROP);
+        model.addParameter("barney", true, BindingConstants.PROP);
+
+        assertEquals(model.getDeclaredParameterNames(), Arrays.asList("barney", "fred", "wilma"));
+        assertEquals(model.getParameterNames(), Arrays.asList("barney", "betty", "fred", "wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void add_duplicate_parameter()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.addParameter("fred", true, BindingConstants.PROP);
+
+        try
+        {
+            // This also helps check that the comparison is caseless!
+
+            model.addParameter("Fred", true, BindingConstants.PROP);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Parameter 'Fred' of component org.example.components.Foo is already defined.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_parameter_by_name_with_no_parameters_defined()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertNull(model.getParameterModel("foo"));
+
+        verify();
+    }
+
+    @Test
+    public void get_unknown_parameter()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        model.addParameter("fred", true, BindingConstants.PROP);
+
+        assertNull(model.getParameterModel("barney"));
+
+        verify();
+    }
+
+    @Test
+    public void add_embedded()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+        Location l = mockLocation();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.getEmbeddedComponentIds().isEmpty());
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false, l);
+
+        assertEquals(fred.getId(), "fred");
+        assertEquals(fred.getComponentType(), "Fred");
+        assertFalse(fred.getInheritInformalParameters());
+        assertSame(fred.getLocation(), l);
+
+        MutableEmbeddedComponentModel barney = model.addEmbeddedComponent("barney", "Barney", COMPONENT_CLASS_NAME,
+                                                                          false, null);
+
+        assertEquals(model.getEmbeddedComponentIds(), Arrays.asList("barney", "fred"));
+
+        assertSame(model.getEmbeddedComponentModel("fred"), fred);
+        assertSame(model.getEmbeddedComponentModel("barney"), barney);
+
+        // Access by id is case insensitive
+
+        assertSame(model.getEmbeddedComponentModel("FRED"), fred);
+        assertSame(model.getEmbeddedComponentModel("BARNEY"), barney);
+
+        assertEquals(fred.toString(),
+                     "EmbeddedComponentModel[id=fred type=Fred class=org.example.components.Fred inheritInformals=false]");
+
+        verify();
+    }
+
+    @Test
+    public void add_embedded_component_with_duplicate_id()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.addEmbeddedComponent("fred", "Fred1", COMPONENT_CLASS_NAME, false, null);
+
+        try
+        {
+            model.addEmbeddedComponent("fred", "Fred2", COMPONENT_CLASS_NAME, false, null);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Embedded component 'fred' has already been defined for component class org.example.components.Foo.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void add_embedded_with_inherit_informal_parameters()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+        Location l = mockLocation();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.getEmbeddedComponentIds().isEmpty());
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, true, l);
+
+        assertTrue(fred.getInheritInformalParameters());
+
+        assertEquals(fred.toString(),
+                     "EmbeddedComponentModel[id=fred type=Fred class=org.example.components.Fred inheritInformals=true]");
+
+        verify();
+    }
+
+
+    @Test
+    public void add_embedded_is_case_insensitive()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.addEmbeddedComponent("fred", "Fred1", COMPONENT_CLASS_NAME, false, null);
+
+        try
+        {
+            model.addEmbeddedComponent("FRED", "Fred2", COMPONENT_CLASS_NAME, false, null);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Embedded component 'FRED' has already been defined for component class org.example.components.Foo.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void add_parameters_to_embedded()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
+                                                                        null);
+
+        assertTrue(fred.getParameterNames().isEmpty());
+
+        fred.addParameter("city", "bedrock");
+        fred.addParameter("job", "crane operator");
+
+        assertEquals(fred.getParameterNames(), Arrays.asList("city", "job"));
+
+        assertEquals(fred.getParameterValue("city"), "bedrock");
+
+        verify();
+    }
+
+    @Test
+    public void add_duplicate_parameters_to_embedded()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
+                                                                        null);
+
+        fred.addParameter("city", "bedrock");
+
+        try
+        {
+            fred.addParameter("city", "slateville");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "A value for parameter 'city' of embedded component fred (of component class org.example.components.Foo) has already been provided.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void mixin_names_is_initially_empty_list()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
+                                                                        null);
+
+        assertTrue(fred.getMixinClassNames().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void mixin_class_names_remembered_in_order_added()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
+                                                                        null);
+
+        fred.addMixin("zip.zop.Zoom");
+        fred.addMixin("foo.bar.Baz");
+
+        assertEquals(fred.getMixinClassNames(), Arrays.asList("zip.zop.Zoom", "foo.bar.Baz"));
+
+        verify();
+    }
+
+    @Test
+    public void mixin_name_conflict()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        MutableEmbeddedComponentModel fred = model.addEmbeddedComponent("fred", "Fred", COMPONENT_CLASS_NAME, false,
+                                                                        null);
+
+        fred.addMixin("zip.zop.Zoom");
+
+        try
+        {
+            fred.addMixin("zip.zop.Zoom");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "Mixin zip.zop.Zoom (for component fred) has already been defined.");
+        }
+
+        // Make sure it wasn't actually added.
+
+        assertEquals(fred.getMixinClassNames(), Arrays.asList("zip.zop.Zoom"));
+
+        verify();
+    }
+
+    @Test
+    public void get_persistent_field_names_when_none_defined()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.getPersistentFieldNames().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void get_persistent_field_names_are_sorted()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertEquals(model.setFieldPersistenceStrategy("fred", "session"), "fred");
+        assertEquals(model.setFieldPersistenceStrategy("barney", "client"), "barney");
+
+        assertEquals(model.getPersistentFieldNames(), Arrays.asList("barney", "fred"));
+
+        verify();
+    }
+
+    @Test
+    public void get_persistent_field_names_reflects_parent_model()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertEquals(parent.setFieldPersistenceStrategy("wilma", "session"), "wilma");
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        assertEquals(model.setFieldPersistenceStrategy("fred", "session"), "fred");
+        assertEquals(model.setFieldPersistenceStrategy("barney", "client"), "barney");
+
+        assertEquals(model.getPersistentFieldNames(), Arrays.asList("barney", "fred", "wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void persistent_field_names_allocated_in_subclasses_are_unique()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        assertEquals(parent.setFieldPersistenceStrategy("wilma", "session"), "wilma");
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        assertEquals(model.setFieldPersistenceStrategy("wilma", "session"), "wilma_0");
+
+        assertEquals(model.getPersistentFieldNames(), Arrays.asList("wilma", "wilma_0"));
+
+        verify();
+    }
+
+    @Test
+    public void get_persistent_field_defined_in_model()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.setFieldPersistenceStrategy("fred", "session");
+        model.setFieldPersistenceStrategy("barney", "client");
+
+        assertEquals(model.getFieldPersistenceStrategy("fred"), "session");
+        assertEquals(model.getFieldPersistenceStrategy("barney"), "client");
+
+        verify();
+    }
+
+    @Test
+    public void no_persistence_defined_for_field()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        try
+        {
+            model.getFieldPersistenceStrategy("someField");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "No field persistence strategy has been defined for field \'someField\'.");
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void get_persistent_field_defined_in_parent()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        parent.setFieldPersistenceStrategy("wilma", "parent");
+
+        model.setFieldPersistenceStrategy("fred", "session");
+
+        assertEquals(model.getFieldPersistenceStrategy("wilma"), "parent");
+
+        verify();
+    }
+
+    @Test
+    public void default_for_supports_informal_parameters_is_false()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertFalse(model.getSupportsInformalParameters());
+
+        model.enableSupportsInformalParameters();
+
+        assertTrue(model.getSupportsInformalParameters());
+
+        verify();
+    }
+
+    @Test
+    public void get_mixin_class_names_with_no_mixins()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+        ComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        assertTrue(model.getMixinClassNames().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void get_mixin_class_names_mixes_with_parent_model()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        parent.addMixinClassName("Wilma");
+
+        MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        child.addMixinClassName("Fred");
+        child.addMixinClassName("Barney");
+
+        assertEquals(child.getMixinClassNames(), Arrays.asList("Barney", "Fred", "Wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void get_parent_from_subclass()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        assertSame(child.getParentModel(), parent);
+        assertNull(parent.getParentModel());
+
+        verify();
+    }
+
+    @Test
+    public void set_and_get_meta()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+        model.setMeta("fred", "flintstone");
+        model.setMeta("barney", "rubble");
+
+        assertEquals(model.getMeta("fred"), "flintstone");
+        assertEquals(model.getMeta("barney"), "rubble");
+
+        // Ensure case insensitive:
+
+        assertEquals(model.getMeta("FRED"), "flintstone");
+        assertEquals(model.getMeta("BARNEY"), "rubble");
+
+        verify();
+    }
+
+    @Test
+    public void get_meta_from_parent()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        parent.setMeta("fred", "flintstone");
+
+        assertEquals(child.getMeta("fred"), "flintstone");
+
+        verify();
+    }
+
+    @Test
+    public void parent_does_not_have_meta()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        parent.setMeta("fred", "flintstone");
+
+        assertNull(child.getMeta("wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void child_meta_overrides_parent_meta()
+    {
+        Resource r = mockResource();
+        Logger logger = mockLogger();
+
+        replay();
+
+        MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+        MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+        parent.setMeta("fred", "flintstone");
+        child.setMeta("fred", "mcmurray");
+
+        assertEquals(parent.getMeta("fred"), "flintstone");
+        assertEquals(child.getMeta("fred"), "mcmurray");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java
new file mode 100644
index 0000000..8082e20
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxComponentInstanceEventResultProcessorTest.java
@@ -0,0 +1,90 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+public class AjaxComponentInstanceEventResultProcessorTest extends InternalBaseTestCase
+{
+    @Test
+    public void render_component_within_page() throws IOException
+    {
+        String nestedId = "foo.bar.baz";
+        String pageName = "Biff";
+
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+        ComponentPageElement element = mockComponentPageElement();
+        PageRenderQueue queue = mockPageRenderQueue();
+
+        train_getComponentResources(component, resources);
+        train_getPageName(resources, pageName);
+        train_get(cache, pageName, page);
+        train_getNestedId(resources, nestedId);
+        train_getComponentElementByNestedId(page, nestedId, element);
+
+        queue.initializeForPartialPageRender(element);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new AjaxComponentInstanceEventResultProcessor(
+                cache, queue);
+
+        processor.processResultValue(component);
+
+        verify();
+    }
+
+    @Test
+    public void render_complete_page_as_partial() throws IOException
+    {
+        String pageName = "Biff";
+
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+        ComponentPageElement element = mockComponentPageElement();
+        PageRenderQueue queue = mockPageRenderQueue();
+
+        train_getComponentResources(component, resources);
+        train_getPageName(resources, pageName);
+        train_get(cache, pageName, page);
+        train_getNestedId(resources, null);
+        train_getRootElement(page, element);
+
+        queue.initializeForPartialPageRender(element);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new AjaxComponentInstanceEventResultProcessor(
+                cache,
+                queue);
+
+        processor.processResultValue(component);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasImplTest.java
new file mode 100644
index 0000000..10621c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasImplTest.java
@@ -0,0 +1,140 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.services.Alias;
+import org.apache.tapestry.services.AliasManager;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class AliasImplTest extends InternalBaseTestCase
+{
+    private Map<Class, Object> emptyMap = Collections.emptyMap();
+
+    protected final AliasManager newAliasManager()
+    {
+        return newMock(AliasManager.class);
+    }
+
+    @Test
+    public void resolve_object_within_mode()
+    {
+        String mode = "papyrus";
+
+        AliasManager manager = newAliasManager();
+        AliasManager overridesManager = newAliasManager();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+
+        ObjectLocator locator = mockObjectLocator();
+        Runnable r = mockRunnable();
+
+        Map<Class, Object> configuration = newMap();
+        configuration.put(Runnable.class, r);
+
+        train_getAliasesForMode(manager, mode, configuration);
+        train_getAliasesForMode(overridesManager, mode, emptyMap);
+
+        replay();
+
+        Alias alias = new AliasImpl(manager, mode, overridesManager);
+
+        // Do not assume that infra and provider are the same;
+        // that's an implementation choice.
+
+        ObjectProvider provider = alias.getObjectProvider();
+
+        // Run through a couple of times to ensure that values are cached.
+        for (int i = 0; i < 2; i++)
+        {
+            Runnable actual = provider.provide(Runnable.class, annotationProvider, locator);
+
+            assertSame(actual, r);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void overrides_manager_has_precendence()
+    {
+        String mode = "papyrus";
+
+        AliasManager manager = newAliasManager();
+        AliasManager overridesManager = newAliasManager();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+
+        ObjectLocator locator = mockObjectLocator();
+        Runnable r = mockRunnable();
+        Runnable override = mockRunnable();
+
+        Map<Class, Object> configuration = newMap();
+        configuration.put(Runnable.class, r);
+
+        train_getAliasesForMode(manager, mode, configuration);
+
+        Map<Class, Object> overrideConfiguration = newMap();
+        configuration.put(Runnable.class, override);
+
+        train_getAliasesForMode(overridesManager, mode, overrideConfiguration);
+
+        replay();
+
+        Alias alias = new AliasImpl(manager, mode, overridesManager);
+
+        ObjectProvider provider = alias.getObjectProvider();
+
+        Runnable actual = provider.provide(Runnable.class, annotationProvider, locator);
+
+        assertSame(actual, override);
+
+        verify();
+    }
+
+    @Test
+    public void type_not_found_in_configuration()
+    {
+        String mode = "papyrus";
+
+        AliasManager manager = newAliasManager();
+        AliasManager overridesManager = newAliasManager();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+
+        ObjectLocator locator = mockObjectLocator();
+
+        train_getAliasesForMode(manager, mode, emptyMap);
+        train_getAliasesForMode(overridesManager, mode, emptyMap);
+
+        replay();
+
+        Alias alias = new AliasImpl(manager, mode, overridesManager);
+
+        // Do not assume that infra and provider are the same;
+        // that's an implementation choice.
+
+        ObjectProvider provider = alias.getObjectProvider();
+
+        assertNull(provider.provide(Runnable.class, annotationProvider, locator));
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasManagerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasManagerImplTest.java
new file mode 100644
index 0000000..d9cdf5e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AliasManagerImplTest.java
@@ -0,0 +1,130 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.AliasContribution;
+import org.apache.tapestry.services.AliasManager;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+public class AliasManagerImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_conflict()
+    {
+        Logger logger = mockLogger();
+        Runnable r = mockRunnable();
+
+        replay();
+
+        AliasContribution[] contributions =
+                {AliasContribution.create(String.class, "FRED"),
+                 AliasContribution.create(Runnable.class, r)};
+        Collection<AliasContribution> configuration = Arrays.asList(contributions);
+
+        AliasManager manager = new AliasManagerImpl(logger, configuration);
+
+        Map<Class, Object> map = manager.getAliasesForMode("foo");
+
+        assertEquals(map.size(), 2);
+        assertEquals(map.get(String.class), "FRED");
+        assertSame(map.get(Runnable.class), r);
+
+        verify();
+    }
+
+    @Test
+    public void first_entry_wins_on_conflict()
+    {
+        Logger logger = mockLogger();
+        Runnable r = mockRunnable();
+
+        logger
+                .error("Contribution FRED-CONFLICT (for type java.lang.String) conflicts with existing contribution FRED and has been ignored.");
+
+        replay();
+
+        AliasContribution[] contributions =
+                {AliasContribution.create(String.class, "FRED"),
+                 AliasContribution.create(String.class, "FRED-CONFLICT"),
+                 AliasContribution.create(Runnable.class, r)};
+        Collection<AliasContribution> configuration = Arrays.asList(contributions);
+
+        AliasManager manager = new AliasManagerImpl(logger, configuration);
+
+        Map<Class, Object> map = manager.getAliasesForMode("foo");
+
+        assertEquals(map.size(), 2);
+        assertEquals(map.get(String.class), "FRED");
+        assertSame(map.get(Runnable.class), r);
+
+        verify();
+    }
+
+    @Test
+    public void contributions_to_other_modes_are_ignored()
+    {
+        Logger logger = mockLogger();
+        Runnable r = mockRunnable();
+
+        replay();
+
+        AliasContribution[] contributions =
+                {AliasContribution.create(String.class, "FRED"),
+                 AliasContribution.create(String.class, "bar", "FRED-NON-CONFLICT"),
+                 AliasContribution.create(Runnable.class, r)};
+        Collection<AliasContribution> configuration = Arrays.asList(contributions);
+
+        AliasManager manager = new AliasManagerImpl(logger, configuration);
+
+        Map<Class, Object> map = manager.getAliasesForMode("foo");
+
+        assertEquals(map.size(), 2);
+        assertEquals(map.get(String.class), "FRED");
+        assertSame(map.get(Runnable.class), r);
+
+        verify();
+    }
+
+    @Test
+    public void mode_specific_contribution_overrides_general_contribution()
+    {
+        Logger logger = mockLogger();
+        Runnable r = mockRunnable();
+
+        replay();
+
+        AliasContribution[] contributions =
+                {AliasContribution.create(String.class, "FRED"),
+                 AliasContribution.create(String.class, "bar", "FRED-NON-CONFLICT"),
+                 AliasContribution.create(Runnable.class, r)};
+        Collection<AliasContribution> configuration = Arrays.asList(contributions);
+
+        AliasManager manager = new AliasManagerImpl(logger, configuration);
+
+        Map<Class, Object> map = manager.getAliasesForMode("BAR");
+
+        assertEquals(map.size(), 2);
+        assertEquals(map.get(String.class), "FRED-NON-CONFLICT");
+        assertSame(map.get(Runnable.class), r);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotatedPage.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotatedPage.java
new file mode 100644
index 0000000..b4bf62a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotatedPage.java
@@ -0,0 +1,37 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotation.SetupRender;
+
+public class AnnotatedPage
+{
+
+    @SetupRender
+    void beforeRender()
+    {
+    }
+
+    @SetupRender
+    boolean earlyRender(MarkupWriter writer)
+    {
+        return true;
+    }
+
+    void methodWithoutAnnotation()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzerTest.java
new file mode 100644
index 0000000..05f930e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AnnotationDataTypeAnalyzerTest.java
@@ -0,0 +1,67 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.beaneditor.DataType;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.services.DataTypeAnalyzer;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class AnnotationDataTypeAnalyzerTest extends TapestryTestCase
+{
+    private DataType mockDataType(String annotationValue)
+    {
+        DataType annotation = newMock(DataType.class);
+
+        expect(annotation.value()).andReturn(annotationValue).atLeastOnce();
+
+        return annotation;
+    }
+
+    @Test
+    public void annotation_absent()
+    {
+        PropertyAdapter adapter = mockPropertyAdapter();
+
+        train_getAnnotation(adapter, DataType.class, null);
+
+        replay();
+
+        DataTypeAnalyzer analyzer = new AnnotationDataTypeAnalyzer();
+
+        assertNull(analyzer.identifyDataType(adapter));
+
+        verify();
+    }
+
+    @Test
+    public void value_from_annotation()
+    {
+        String value = "password";
+        PropertyAdapter adapter = mockPropertyAdapter();
+
+        train_getAnnotation(adapter, DataType.class, mockDataType(value));
+
+        replay();
+
+        DataTypeAnalyzer analyzer = new AnnotationDataTypeAnalyzer();
+
+        assertEquals(analyzer.identifyDataType(adapter), value);
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStateManagerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStateManagerImplTest.java
new file mode 100644
index 0000000..28264d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStateManagerImplTest.java
@@ -0,0 +1,241 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.pages.ReadOnlyBean;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.services.*;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.easymock.IAnswer;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class ApplicationStateManagerImplTest extends InternalBaseTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void get_from_configured_aso()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        ApplicationStateCreator<ReadOnlyBean> creator = mockApplicationStateCreator();
+        ReadOnlyBean aso = new ReadOnlyBean();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName,
+                                                                                                  creator));
+
+        train_get(source, strategyName, strategy);
+
+        train_get(strategy, asoClass, creator, aso);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        assertSame(manager.get(asoClass), aso);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void check_exists_when_null()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        ApplicationStateCreator<ReadOnlyBean> creator = mockApplicationStateCreator();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName,
+                                                                                                  creator));
+
+        train_get(source, strategyName, strategy);
+        train_exists(strategy, asoClass, false);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        assertFalse(manager.exists(asoClass));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void check_exists_when_true()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        ApplicationStateCreator<ReadOnlyBean> creator = mockApplicationStateCreator();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName,
+                                                                                                  creator));
+
+        train_get(source, strategyName, strategy);
+        train_exists(strategy, asoClass, true);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        assertTrue(manager.exists(asoClass));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void set_configured_aso()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        Object aso = new ReadOnlyBean();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName));
+
+        train_get(source, strategyName, strategy);
+
+        strategy.set(asoClass, aso);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        manager.set(asoClass, aso);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void get_from_unconfigured_aso()
+    {
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        final Holder holder = new Holder();
+        ObjectLocator locator = mockObjectLocator();
+
+        train_get(source, ApplicationStateManagerImpl.DEFAULT_STRATEGY, strategy);
+
+
+        IAnswer answer = new IAnswer()
+        {
+            public Object answer() throws Throwable
+            {
+                ApplicationStateCreator creator = (ApplicationStateCreator) EasyMock
+                        .getCurrentArguments()[1];
+
+                Object aso = creator.create();
+
+                holder.put(aso);
+
+                return aso;
+            }
+        };
+
+        expect(strategy.get(eq(asoClass), isA(ApplicationStateCreator.class))).andAnswer(answer);
+
+        train_autobuild(locator, asoClass, new ReadOnlyBean());
+
+        replay();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.emptyMap();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, locator);
+
+        Object actual = manager.get(asoClass);
+
+        assertSame(actual, holder.get());
+
+        verify();
+    }
+
+    @Test
+    public void get_if_exists_and_it_doesnt()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        ApplicationStateCreator<ReadOnlyBean> creator = mockApplicationStateCreator();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName,
+                                                                                                  creator));
+
+        train_get(source, strategyName, strategy);
+        train_exists(strategy, asoClass, false);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        assertNull(manager.getIfExists(asoClass));
+
+        verify();
+    }
+
+    @Test
+    public void get_if_exists_when_it_does_exist()
+    {
+        String strategyName = "ethereal";
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+        ApplicationStatePersistenceStrategySource source = mockApplicationStatePersistenceStrategySource();
+        Class asoClass = ReadOnlyBean.class;
+        ApplicationStateCreator<ReadOnlyBean> creator = mockApplicationStateCreator();
+        ReadOnlyBean aso = new ReadOnlyBean();
+
+        Map<Class, ApplicationStateContribution> configuration = Collections.singletonMap(asoClass,
+                                                                                          new ApplicationStateContribution(
+                                                                                                  strategyName,
+                                                                                                  creator));
+
+        train_get(source, strategyName, strategy);
+        train_exists(strategy, asoClass, true);
+        train_get(strategy, asoClass, creator, aso);
+
+        replay();
+
+        ApplicationStateManager manager = new ApplicationStateManagerImpl(configuration, source, null);
+
+        assertSame(manager.getIfExists(asoClass), aso);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImplTest.java
new file mode 100644
index 0000000..cdcf304
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ApplicationStatePersistenceStrategySourceImplTest.java
@@ -0,0 +1,77 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategy;
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategySource;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class ApplicationStatePersistenceStrategySourceImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void strategy_found()
+    {
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+
+        Map<String, ApplicationStatePersistenceStrategy> configuration = Collections.singletonMap(
+                "session",
+                strategy);
+
+        replay();
+
+        ApplicationStatePersistenceStrategySource source = new ApplicationStatePersistenceStrategySourceImpl(
+                configuration);
+
+        assertSame(strategy, source.get("session"));
+
+        verify();
+    }
+
+    @Test
+    public void not_found()
+    {
+        ApplicationStatePersistenceStrategy strategy = mockApplicationStatePersistenceStrategy();
+
+        Map<String, ApplicationStatePersistenceStrategy> configuration = newMap();
+
+        configuration.put("session", strategy);
+        configuration.put("application", strategy);
+
+        replay();
+
+        ApplicationStatePersistenceStrategySource source = new ApplicationStatePersistenceStrategySourceImpl(
+                configuration);
+
+        try
+        {
+            source.get("aether");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No application state persistence strategy is available with name 'aether'. Available strategies: application, session.");
+        }
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetDispatcherTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetDispatcherTest.java
new file mode 100644
index 0000000..5501e10
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetDispatcherTest.java
@@ -0,0 +1,297 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+import org.apache.tapestry.services.Dispatcher;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import static org.easymock.EasyMock.contains;
+import static org.easymock.EasyMock.eq;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpServletResponse;
+
+public class AssetDispatcherTest extends InternalBaseTestCase
+{
+    private static final String SMILEY_CLIENT_URL = "/assets/app1/pages/smiley.png";
+
+    private static final String SMILEY_PATH = "org/apache/tapestry/integration/app1/pages/smiley.png";
+
+    private static final Resource SMILEY = new ClasspathResource(SMILEY_PATH);
+
+    @Test
+    public void not_an_asset_request() throws Exception
+    {
+        Request request = mockRequest();
+
+        train_getPath(request, "/foo/bar/Baz.gif");
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(null, null, null);
+
+        assertFalse(d.dispatch(request, null));
+
+        verify();
+    }
+
+    @Test
+    public void unprotected_asset() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+
+        train_getPath(request, SMILEY_CLIENT_URL);
+
+        train_toResourcePath(aliasManager, SMILEY_CLIENT_URL, SMILEY_PATH);
+
+        train_requiresDigest(cache, SMILEY, false);
+
+        train_getDateHeader(request, AssetDispatcher.IF_MODIFIED_SINCE_HEADER, -1);
+
+        streamer.streamResource(SMILEY);
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void protected_asset_without_an_extension() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+
+        String clientURL = "/assets/app1/pages/smiley_png";
+        String resourcePath = "org/apache/tapestry/integration/app1/pages/smiley_png";
+
+        train_getPath(request, clientURL);
+
+        train_toResourcePath(aliasManager, clientURL, resourcePath);
+
+        train_requiresDigest(cache, new ClasspathResource(resourcePath), true);
+
+        response.sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains(resourcePath));
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void protected_asset_with_incorrect_digest_in_url() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+
+        String clientURL = "/assets/app1/pages/smiley.WRONG.png";
+        String resourcePath = "org/apache/tapestry/integration/app1/pages/smiley.WRONG.png";
+
+        train_getPath(request, clientURL);
+
+        train_toResourcePath(aliasManager, clientURL, resourcePath);
+
+        train_requiresDigest(cache, new ClasspathResource(resourcePath), true);
+
+        train_getDigest(cache, SMILEY, "RIGHT");
+
+        response.sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains(SMILEY_PATH));
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void protected_asset_wth_correct_digest_in_url() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+
+        String clientURL = RequestConstants.ASSET_PATH_PREFIX + "app1/pages/smiley.RIGHT.png";
+        String resourcePath = "org/apache/tapestry/integration/app1/pages/smiley.RIGHT.png";
+
+        train_getPath(request, clientURL);
+
+        train_toResourcePath(aliasManager, clientURL, resourcePath);
+
+        train_requiresDigest(cache, new ClasspathResource(resourcePath), true);
+
+        train_getDigest(cache, SMILEY, "RIGHT");
+
+        train_getDateHeader(request, AssetDispatcher.IF_MODIFIED_SINCE_HEADER, -1);
+
+        streamer.streamResource(SMILEY);
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    protected final void train_getDigest(ResourceCache cache, Resource resource, String digest)
+    {
+        expect(cache.getDigest(resource)).andReturn(digest).atLeastOnce();
+    }
+
+    @Test
+    public void protected_asset_without_digest() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+
+        train_getPath(request, SMILEY_CLIENT_URL);
+
+        train_toResourcePath(aliasManager, SMILEY_CLIENT_URL, SMILEY_PATH);
+
+        train_requiresDigest(cache, SMILEY, true);
+
+        response.sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains(SMILEY_PATH));
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void client_cache_upto_date() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+        long now = System.currentTimeMillis();
+
+        train_getPath(request, SMILEY_CLIENT_URL);
+
+        train_toResourcePath(aliasManager, SMILEY_CLIENT_URL, SMILEY_PATH);
+
+        train_requiresDigest(cache, SMILEY, false);
+
+        train_getDateHeader(request, AssetDispatcher.IF_MODIFIED_SINCE_HEADER, now);
+
+        train_getTimeModified(cache, SMILEY, now - 1000);
+
+        response.sendError(HttpServletResponse.SC_NOT_MODIFIED, "");
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void if_modified_since_header_not_readable() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+        long now = System.currentTimeMillis();
+
+        train_getPath(request, SMILEY_CLIENT_URL);
+
+        train_toResourcePath(aliasManager, SMILEY_CLIENT_URL, SMILEY_PATH);
+
+        train_requiresDigest(cache, SMILEY, false);
+
+        expect(request.getDateHeader(AssetDispatcher.IF_MODIFIED_SINCE_HEADER)).andThrow(
+                new IllegalArgumentException("For testing."));
+
+        streamer.streamResource(SMILEY);
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void client_cache_out_of_date() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+        ResourceCache cache = mockResourceCache();
+        ResourceStreamer streamer = mockResourceStreamer();
+        long now = System.currentTimeMillis();
+
+        train_getPath(request, SMILEY_CLIENT_URL);
+
+        train_toResourcePath(aliasManager, SMILEY_CLIENT_URL, SMILEY_PATH);
+
+        train_requiresDigest(cache, SMILEY, false);
+
+        train_getDateHeader(request, AssetDispatcher.IF_MODIFIED_SINCE_HEADER, now - 1000);
+
+        train_getTimeModified(cache, SMILEY, now + 1000);
+
+        streamer.streamResource(SMILEY);
+
+        replay();
+
+        Dispatcher d = new AssetDispatcher(streamer, aliasManager, cache);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
new file mode 100644
index 0000000..21ada84
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetInjectionProviderTest.java
@@ -0,0 +1,98 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.AssetSource;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+import org.testng.annotations.Test;
+
+public class AssetInjectionProviderTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_path_annotation()
+    {
+        SymbolSource symbolSource = mockSymbolSource();
+        AssetSource assetSource = mockAssetSource();
+        ObjectLocator locator = mockObjectLocator();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        String fieldName = "myField";
+
+        train_getFieldAnnotation(ct, fieldName, Path.class, null);
+
+        replay();
+
+        InjectionProvider provider = new AssetInjectionProvider(symbolSource, assetSource);
+
+        assertFalse(provider.provideInjection(fieldName, String.class, locator, ct, model));
+
+        verify();
+    }
+
+    @Test
+    public void path_annotation_present()
+    {
+        SymbolSource symbolSource = mockSymbolSource();
+        AssetSource assetSource = mockAssetSource();
+        ObjectLocator locator = mockObjectLocator();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        Path annotation = mockPath();
+        Resource baseResource = mockResource();
+
+        String fieldName = "myField";
+        Class fieldType = Object.class;
+        String value = "${foo}";
+        String expanded = "foo.gif";
+
+        train_getFieldAnnotation(ct, fieldName, Path.class, annotation);
+
+        train_value(annotation, value);
+        train_expandSymbols(symbolSource, value, expanded);
+
+        train_addInjectedField(ct, AssetSource.class, "assetSource", assetSource, "as");
+
+        train_getBaseResource(model, baseResource);
+
+        train_addInjectedField(ct, Resource.class, "baseResource", baseResource, "br");
+
+        train_getResourcesFieldName(ct, "rez");
+
+        // This only tests that the code is generated as expected (which is a bit brittle), it
+        // doesn't prove that the generated code actually works, but we have lots of integration
+        // tests for that.
+
+        ct
+                .extendConstructor("myField = (java.lang.Object) as.getAsset(br, \"foo.gif\", rez.getLocale());");
+
+        ct.makeReadOnly(fieldName);
+
+        replay();
+
+        InjectionProvider provider = new AssetInjectionProvider(symbolSource, assetSource);
+
+        assertTrue(provider.provideInjection(fieldName, fieldType, locator, ct, model));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetObjectProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetObjectProviderTest.java
new file mode 100644
index 0000000..4cccefa
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetObjectProviderTest.java
@@ -0,0 +1,80 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotation.Path;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.AssetSource;
+import org.testng.annotations.Test;
+
+public class AssetObjectProviderTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void no_path_annotation()
+    {
+        AssetSource source = mockAssetSource();
+        ObjectLocator locator = mockObjectLocator();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        TypeCoercer typeCoercer = mockTypeCoercer();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        train_getAnnotation(annotationProvider, Path.class, null);
+
+        replay();
+
+        ObjectProvider provider = new AssetObjectProvider(source, typeCoercer, symbolSource);
+
+        assertNull(provider.provide(Asset.class, annotationProvider, locator));
+
+        verify();
+    }
+
+    @Test
+    public void normal_conversion()
+    {
+        AssetSource source = mockAssetSource();
+        ObjectLocator locator = mockObjectLocator();
+        Asset asset = mockAsset();
+        String path = "${foo}";
+        String expanded = "foo/bar/baz.gif";
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        TypeCoercer typeCoercer = mockTypeCoercer();
+        Path pathAnnotation = mockPath();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        train_getAnnotation(annotationProvider, Path.class, pathAnnotation);
+        train_value(pathAnnotation, path);
+        train_expandSymbols(symbolSource, path, expanded);
+        train_getAsset(source, null, expanded, null, asset);
+        train_coerce(typeCoercer, asset, Asset.class, asset);
+
+        replay();
+
+        ObjectProvider provider = new AssetObjectProvider(source, typeCoercer, symbolSource);
+
+        Asset result = provider.provide(Asset.class, annotationProvider, locator);
+
+        assertSame(result, asset);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetSourceImplTest.java
new file mode 100644
index 0000000..d5e5073
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AssetSourceImplTest.java
@@ -0,0 +1,215 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.AssetSource;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+
+public class AssetSourceImplTest extends InternalBaseTestCase
+{
+    private final Resource baseResource = new ClasspathResource(
+            "org/apache/tapestry/internal/services/SimpleComponent.class");
+
+    private final Resource rootResource = new ClasspathResource("/");
+
+    @Test
+    public void relative_asset()
+    {
+        AssetFactory factory = mockAssetFactory();
+        ThreadLocale threadLocale = mockThreadLocale();
+        Asset asset = mockAsset();
+
+        Resource expectedResource = baseResource.forFile("SimpleComponent_en_GB.properties");
+
+        train_getRootResource(factory, rootResource);
+
+        train_createAsset(factory, expectedResource, asset);
+
+        Map<String, AssetFactory> configuration = Collections.singletonMap("classpath", factory);
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        // First try creates it:
+
+        assertSame(source.getAsset(baseResource, "SimpleComponent.properties", Locale.UK), asset);
+
+        // Second try shows that it is cached
+
+        assertSame(source.getAsset(baseResource, "SimpleComponent.properties", Locale.UK), asset);
+
+        verify();
+    }
+
+    @Test
+    public void get_classpath_asset()
+    {
+        AssetFactory factory = mockAssetFactory();
+        ThreadLocale threadLocale = mockThreadLocale();
+        Asset asset = mockAsset();
+
+        Resource expectedResource = baseResource.forFile("SimpleComponent_en_GB.properties");
+
+        train_getRootResource(factory, rootResource);
+
+        train_createAsset(factory, expectedResource, asset);
+
+        Map<String, AssetFactory> configuration = Collections.singletonMap("classpath", factory);
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        // First try creates it:
+
+        assertSame(source.getClasspathAsset(
+                "org/apache/tapestry/internal/services/SimpleComponent.properties",
+                Locale.UK), asset);
+
+        verify();
+    }
+
+    @Test
+    public void get_classpath_asset_for_unspecified_locale()
+    {
+        AssetFactory factory = mockAssetFactory();
+        ThreadLocale threadLocale = mockThreadLocale();
+        Asset asset = mockAsset();
+        Locale locale = Locale.UK;
+
+        Resource expectedResource = baseResource.forFile("SimpleComponent_en_GB.properties");
+
+        train_getRootResource(factory, rootResource);
+
+        train_createAsset(factory, expectedResource, asset);
+
+        Map<String, AssetFactory> configuration = Collections.singletonMap("classpath", factory);
+
+        train_getLocale(threadLocale, locale);
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        assertSame(
+                source
+                        .getClasspathAsset("org/apache/tapestry/internal/services/SimpleComponent.properties"),
+                asset);
+
+        verify();
+    }
+
+    @Test
+    public void absolute_asset_with_known_prefix()
+    {
+        AssetFactory factory = mockAssetFactory();
+        ThreadLocale threadLocale = mockThreadLocale();
+        Asset asset = mockAsset();
+
+        Resource expectedResource = rootResource
+                .forFile("org/apache/tapestry/internal/services/SimpleComponent_en_GB.properties");
+
+        train_getRootResource(factory, rootResource);
+
+        train_createAsset(factory, expectedResource, asset);
+
+        Map<String, AssetFactory> configuration = Collections.singletonMap("classpath", factory);
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        assertSame(source.getAsset(
+                baseResource,
+                "classpath:org/apache/tapestry/internal/services/SimpleComponent.properties",
+                Locale.UK), asset);
+
+        // Check that a leading slash is not a problem:
+
+        assertSame(source.getAsset(
+                baseResource,
+                "classpath:/org/apache/tapestry/internal/services/SimpleComponent.properties",
+                Locale.UK), asset);
+
+        verify();
+    }
+
+    @Test
+    public void unknown_asset_prefix()
+    {
+        ThreadLocale threadLocale = mockThreadLocale();
+
+        Map<String, AssetFactory> configuration = Collections.emptyMap();
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        try
+        {
+            source.getAsset(
+                    baseResource,
+                    "classpath:org/apache/tapestry/internal/services/SimpleComponent.properties",
+                    Locale.UK);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Unknown prefix for asset path 'classpath:org/apache/tapestry/internal/services/SimpleComponent.properties'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void missing_resource()
+    {
+        ThreadLocale threadLocale = mockThreadLocale();
+
+        Map<String, AssetFactory> configuration = Collections.emptyMap();
+
+        replay();
+
+        AssetSource source = new AssetSourceImpl(threadLocale, configuration);
+
+        try
+        {
+            source.getAsset(baseResource, "DoesNotExist.properties", Locale.UK);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Unable to locate asset 'classpath:org/apache/tapestry/internal/services/DoesNotExist.properties' (the file does not exist).");
+        }
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BarInterface.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BarInterface.java
new file mode 100644
index 0000000..6105d35
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BarInterface.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+public interface BarInterface

+{

+    void bar();

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanBlockSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanBlockSourceImplTest.java
new file mode 100644
index 0000000..755632f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanBlockSourceImplTest.java
@@ -0,0 +1,198 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.services.BeanBlockContribution;
+import org.apache.tapestry.services.BeanBlockOverrideSource;
+import org.apache.tapestry.services.BeanBlockSource;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class BeanBlockSourceImplTest extends InternalBaseTestCase
+{
+    private static final Collection<BeanBlockContribution> EMPTY_CONFIGURATION = Collections.emptyList();
+
+    @Test
+    public void found_display_block()
+    {
+        Block block = mockBlock();
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        BeanBlockContribution contribution = new BeanBlockContribution("mydata", "MyPage",
+                                                                       "mydisplay", false);
+        Collection<BeanBlockContribution> configuration = newList(contribution);
+
+        train_get(cache, "MyPage", page);
+        train_getBlock(page, "mydisplay", block);
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, createBeanBlockOverrideSource(cache), configuration);
+
+        // Check case insensitivity while we are at it.
+        assertTrue(source.hasDisplayBlock("MyData"));
+        Block actual = source.getDisplayBlock("MyData");
+
+        assertSame(actual, block);
+
+        verify();
+    }
+
+    @Test
+    public void found_display_block_in_override()
+    {
+        Block block = mockBlock();
+        RequestPageCache cache = mockRequestPageCache();
+        BeanBlockOverrideSource overrideSource = mockBeanBlockOverrideSource();
+        String datatype = "MyData";
+
+        expect(overrideSource.hasDisplayBlock(datatype)).andReturn(true);
+        expect(overrideSource.getDisplayBlock(datatype)).andReturn(block);
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, overrideSource, EMPTY_CONFIGURATION);
+
+        // Check case insensitivity while we are at it.
+        assertTrue(source.hasDisplayBlock(datatype));
+        Block actual = source.getDisplayBlock(datatype);
+
+        assertSame(actual, block);
+
+        verify();
+    }
+
+    protected final BeanBlockOverrideSource mockBeanBlockOverrideSource()
+    {
+        return newMock(BeanBlockOverrideSource.class);
+    }
+
+    private BeanBlockOverrideSource createBeanBlockOverrideSource(RequestPageCache cache)
+    {
+        return new BeanBlockOverrideSourceImpl(cache, EMPTY_CONFIGURATION);
+    }
+
+    @Test
+    public void display_block_not_found()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Collection<BeanBlockContribution> configuration = newList();
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, createBeanBlockOverrideSource(cache), configuration);
+
+        try
+        {
+            assertFalse(source.hasDisplayBlock("MyData"));
+            source.getDisplayBlock("MyData");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "There is no defined way to display data of type \'MyData\'. Make a contribution to the BeanBlockSource service for this type.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void edit_block_not_found()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Collection<BeanBlockContribution> configuration = newList();
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, createBeanBlockOverrideSource(cache), configuration);
+
+        try
+        {
+            source.getEditBlock("MyData");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "There is no defined way to edit data of type \'MyData\'.  Make a contribution to the BeanBlockSource service for this type.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void found_edit_block()
+    {
+        Block block = mockBlock();
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        BeanBlockContribution contribution = new BeanBlockContribution("mydata", "MyPage",
+                                                                       "mydisplay", true);
+        Collection<BeanBlockContribution> configuration = newList(contribution);
+
+        train_get(cache, "MyPage", page);
+        train_getBlock(page, "mydisplay", block);
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, createBeanBlockOverrideSource(cache), configuration);
+
+        // Check case insensitivity while we are at it.
+        Block actual = source.getEditBlock("MyData");
+
+        assertSame(actual, block);
+
+        verify();
+    }
+
+    @Test
+    public void found_edit_block_in_override()
+    {
+        Block block = mockBlock();
+        RequestPageCache cache = mockRequestPageCache();
+        BeanBlockOverrideSource overrideSource = mockBeanBlockOverrideSource();
+        String datatype = "MyData";
+
+        expect(overrideSource.getEditBlock(datatype)).andReturn(block);
+
+        replay();
+
+        BeanBlockSource source = new BeanBlockSourceImpl(cache, overrideSource, EMPTY_CONFIGURATION);
+
+        Block actual = source.getEditBlock(datatype);
+
+        assertSame(actual, block);
+
+        verify();
+    }
+
+    protected final void train_getBlock(Page page, String blockId, Block block)
+    {
+        ComponentPageElement element = mockComponentPageElement();
+        train_getRootElement(page, element);
+
+        expect(element.getBlock(blockId)).andReturn(block);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java
new file mode 100644
index 0000000..c5e4aac
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BeanModelSourceImplTest.java
@@ -0,0 +1,683 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.beaneditor.PropertyModel;
+import org.apache.tapestry.beaneditor.RelativePosition;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.pages.ReadOnlyBean;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.BeanModelSource;
+import org.easymock.EasyMock;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Tests for the bean editor model source itself, as well as the model classes.
+ */
+public class BeanModelSourceImplTest extends InternalBaseTestCase
+{
+    private BeanModelSource source;
+
+    @BeforeClass
+    public void setup()
+    {
+        source = getObject(BeanModelSource.class, null);
+    }
+
+    /**
+     * Tests defaults for property names, labels and conduits.
+     */
+    @Test
+    public void default_model_for_bean()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertSame(model.getBeanType(), SimpleBean.class);
+
+        // Based on order of the getter methods (no longer alphabetical)
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        assertEquals(model.toString(),
+                     "BeanModel[org.apache.tapestry.internal.services.SimpleBean properties:firstName, lastName, age]");
+
+        PropertyModel age = model.get("age");
+
+        assertEquals(age.getLabel(), "Age");
+        assertSame(age.getPropertyType(), int.class);
+        assertEquals(age.getDataType(), "number");
+
+        PropertyModel firstName = model.get("firstName");
+
+        assertEquals(firstName.getLabel(), "First Name");
+        assertEquals(firstName.getPropertyType(), String.class);
+        assertEquals(firstName.getDataType(), "text");
+
+        assertEquals(model.get("lastName").getLabel(), "Last Name");
+
+        PropertyConduit conduit = model.get("lastName").getConduit();
+
+        SimpleBean instance = new SimpleBean();
+
+        instance.setLastName("Lewis Ship");
+
+        assertEquals(conduit.get(instance), "Lewis Ship");
+
+        conduit.set(instance, "TapestryDude");
+
+        assertEquals(instance.getLastName(), "TapestryDude");
+
+        // Now, one with some type coercion.
+
+        age.getConduit().set(instance, "40");
+
+        assertEquals(instance.getAge(), 40);
+
+        verify();
+    }
+
+    @Test
+    public void include_properties()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertSame(model.getBeanType(), SimpleBean.class);
+
+        model.include("lastname", "firstname");
+
+        // Based on order of the getter methods (no longer alphabetical)
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("lastName", "firstName"));
+
+        verify();
+    }
+
+    @Test
+    public void add_before()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+        PropertyConduit conduit = mockPropertyConduit();
+
+        Class propertyType = String.class;
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        expect(conduit.getPropertyType()).andReturn(propertyType).atLeastOnce();
+        expect(conduit.getAnnotation(EasyMock.isA(Class.class))).andStubReturn(null);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        // Note the use of case insensitivity here.
+
+        PropertyModel property = model.add(RelativePosition.BEFORE, "lastname", "middleInitial", conduit);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "middleInitial", "lastName", "age"));
+
+        assertEquals(property.getPropertyName(), "middleInitial");
+        assertSame(property.getConduit(), conduit);
+        assertSame(property.getPropertyType(), propertyType);
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-2202
+     */
+    @Test
+    public void new_instance()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel<SimpleBean> model = source.create(SimpleBean.class, true, resources);
+
+        SimpleBean s1 = model.newInstance();
+
+        assertNotNull(s1);
+
+        SimpleBean s2 = model.newInstance();
+
+        assertNotNull(s2);
+        assertNotSame(s1, s2);
+
+        verify();
+    }
+
+    @Test
+    public void add_before_using_default_conduit()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        model.exclude("firstname");
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("lastName", "age"));
+
+        // Note the use of case insensitivity here.
+
+        PropertyModel property = model.add(RelativePosition.BEFORE, "lastname", "firstName");
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        assertEquals(property.getPropertyName(), "firstName");
+        assertSame(property.getPropertyType(), String.class);
+
+        verify();
+    }
+
+    @Test
+    public void add_after()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+        PropertyConduit conduit = mockPropertyConduit();
+
+        Class propertyType = String.class;
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        expect(conduit.getPropertyType()).andReturn(propertyType).atLeastOnce();
+
+        expect(conduit.getAnnotation(EasyMock.isA(Class.class))).andStubReturn(null);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        PropertyModel property = model.add(RelativePosition.AFTER, "firstname", "middleInitial", conduit);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "middleInitial", "lastName", "age"));
+
+        assertEquals(property.getPropertyName(), "middleInitial");
+        assertSame(property.getConduit(), conduit);
+        assertSame(property.getPropertyType(), propertyType);
+
+        verify();
+    }
+
+    @Test
+    public void filtering_out_read_only_properties()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(ReadOnlyBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("value"));
+
+        model = source.create(ReadOnlyBean.class, false, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("value", "readOnly"));
+
+        verify();
+    }
+
+    @Test
+    public void non_text_property()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(EnumBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("token"));
+
+        assertEquals(model.get("token").getDataType(), "enum");
+
+        verify();
+    }
+
+    @Test
+    public void add_duplicate_property_name_is_failure()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        try
+        {
+            model.add("age");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Bean editor model for org.apache.tapestry.internal.services.SimpleBean already contains a property model for property \'age\'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void unknown_property_name()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        try
+        {
+            model.get("frobozz");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Bean editor model for org.apache.tapestry.internal.services.SimpleBean does not contain a property named \'frobozz\'.  " + "Available properties: age, firstName, lastName.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void unknown_property_id()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        model.add("shrub.foo()", null);
+
+        try
+        {
+            model.getById("frobozz");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Bean editor model for org.apache.tapestry.internal.services.SimpleBean does not contain a property with id \'frobozz\'.  "
+                                 + "Available property ids: age, firstName, lastName, shrubfoo.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_added_property_by_name()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        PropertyModel pm = model.add("shrub.foo()", null);
+
+        assertSame(model.get("Shrub.Foo()"), pm);
+
+        verify();
+    }
+
+    @Test
+    public void get_added_property_by_id()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        PropertyModel pm = model.add("shrub.foo()", null);
+
+        assertSame(model.getById("ShrubFoo"), pm);
+
+        verify();
+
+    }
+
+    @Test
+    public void order_via_annotation()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(StoogeBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("larry", "moe", "shemp", "curly"));
+
+        verify();
+    }
+
+    @Test
+    public void edit_property_label()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources).get("age").label("Decrepitude").model();
+
+        assertEquals(model.get("age").getLabel(), "Decrepitude");
+
+        verify();
+    }
+
+    @Test
+    public void label_from_component_messages()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        train_contains(messages, "age-label", true);
+        train_get(messages, "age-label", "Decrepitude");
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertEquals(model.get("age").getLabel(), "Decrepitude");
+
+        verify();
+    }
+
+    @Test
+    public void array_type_bean()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(StringArrayBean.class, true, resources);
+
+        // There's not editor for string arrays yet, so it won't show up normally.
+
+        PropertyModel propertyModel = model.add("array");
+
+        assertSame(propertyModel.getPropertyType(), String[].class);
+
+        String[] value = { "foo", "bar" };
+
+        StringArrayBean bean = new StringArrayBean();
+
+        PropertyConduit conduit = propertyModel.getConduit();
+
+        conduit.set(bean, value);
+
+        assertSame(bean.getArray(), value);
+
+        assertSame(conduit.get(bean), value);
+
+        verify();
+    }
+
+    @Test
+    public void composite_bean()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        train_contains(messages, "simpleage-label", true);
+        train_get(messages, "simpleage-label", "Years of Age");
+
+        replay();
+
+        BeanModel model = source.create(CompositeBean.class, true, resources);
+
+        // No editor for CompositeBean, so this will be empty.
+
+        assertEquals(model.getPropertyNames(), Collections.emptyList());
+
+        // There's not editor for string arrays yet, so it won't show up normally.
+
+        PropertyModel firstName = model.add("simple.firstName");
+
+        assertEquals(firstName.getLabel(), "First Name");
+
+        PropertyModel age = model.add("simple.age");
+        assertEquals(age.getLabel(), "Years of Age");
+
+        CompositeBean bean = new CompositeBean();
+
+        firstName.getConduit().set(bean, "Fred");
+        age.getConduit().set(bean, "97");
+
+        assertEquals(bean.getSimple().getFirstName(), "Fred");
+        assertEquals(bean.getSimple().getAge(), 97);
+
+        bean.getSimple().setAge(24);
+
+        assertEquals(age.getConduit().get(bean), new Integer(24));
+
+        verify();
+    }
+
+    @Test
+    public void default_properties_exclude_write_only()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(WriteOnlyBean.class, false, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("readOnly", "readWrite"));
+
+        verify();
+    }
+
+    @Test
+    public void add_synthetic_property()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        PropertyModel property = model.add("placeholder", null);
+
+        assertFalse(property.isSortable());
+        assertSame(property.getPropertyType(), Object.class);
+        assertEquals(property.getLabel(), "Placeholder");
+
+        verify();
+    }
+
+    @Test
+    public void exclude_property()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertSame(model.exclude("age"), model);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName"));
+
+        verify();
+    }
+
+    @Test
+    public void exclude_unknown_property_is_noop()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertSame(model.exclude("frobozz"), model);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        verify();
+    }
+
+    @Test
+    public void nonvisual_properties_are_excluded()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(NonVisualBean.class, true, resources);
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("name"));
+
+        verify();
+    }
+
+    @Test
+    public void reorder()
+    {
+        ComponentResources resources = mockComponentResources();
+        Messages messages = mockMessages();
+
+        train_getMessages(resources, messages);
+        stub_contains(messages, false);
+
+        replay();
+
+        BeanModel model = source.create(SimpleBean.class, true, resources);
+
+        assertSame(model.getBeanType(), SimpleBean.class);
+
+        // Based on order of the getter methods (no longer alphabetical)
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("firstName", "lastName", "age"));
+
+        // Testing a couple of things here:
+        // 1) case insensitive
+        // 2) unreferenced property names added to the end.
+
+        model.reorder("lastname", "AGE");
+
+        assertEquals(model.getPropertyNames(), Arrays.asList("lastName", "age", "firstName"));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java
new file mode 100644
index 0000000..1a0c174
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java
@@ -0,0 +1,212 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.services.BindingFactory;
+import org.apache.tapestry.services.BindingSource;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class BindingSourceImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void expression_has_no_prefix()
+    {
+        BindingFactory factory = mockBindingFactory();
+        Binding binding = mockBinding();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Location l = mockLocation();
+
+        String defaultPrefix = "def";
+        String description = "descrip";
+        String expression = "full expression";
+
+        train_newBinding(factory, description, container, component, expression, l, binding);
+
+        replay();
+
+        Map<String, BindingFactory> map = newMap();
+
+        map.put(defaultPrefix, factory);
+
+        BindingSource source = new BindingSourceImpl(map);
+
+        Binding actual = source.newBinding(
+                description,
+                container,
+                component,
+                defaultPrefix,
+                expression,
+                l);
+
+        assertSame(actual, binding);
+
+        verify();
+    }
+
+    @Test
+    public void expression_prefix_not_in_configuration()
+    {
+        BindingFactory factory = mockBindingFactory();
+        Binding binding = mockBinding();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Location l = mockLocation();
+
+        String defaultPrefix = "def";
+        String description = "descrip";
+        String expression = "javascript:not-a-known-prefix";
+
+        train_newBinding(factory, description, container, component, expression, l, binding);
+
+        replay();
+
+        Map<String, BindingFactory> map = newMap();
+
+        map.put(defaultPrefix, factory);
+
+        BindingSource source = new BindingSourceImpl(map);
+
+        Binding actual = source.newBinding(
+                description,
+                container,
+                component,
+                defaultPrefix,
+                expression,
+                l);
+
+        assertSame(actual, binding);
+
+        verify();
+    }
+
+    @Test
+    public void known_prefix()
+    {
+        BindingFactory factory = mockBindingFactory();
+        Binding binding = mockBinding();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Location l = mockLocation();
+
+        String defaultPrefix = "literal";
+        String description = "descrip";
+
+        // The "prop:" prefix is stripped off ...
+        train_newBinding(factory, description, container, component, "myproperty", l, binding);
+
+        replay();
+
+        Map<String, BindingFactory> map = newMap();
+
+        map.put("prop", factory);
+
+        BindingSource source = new BindingSourceImpl(map);
+
+        Binding actual = source.newBinding(
+                description,
+                container,
+                component,
+                defaultPrefix,
+                "prop:myproperty",
+                l);
+
+        assertSame(actual, binding);
+
+        verify();
+    }
+
+    @Test
+    public void factory_throws_exception()
+    {
+        BindingFactory factory = mockBindingFactory();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Location l = mockLocation();
+        Throwable t = new RuntimeException("Simulated failure.");
+
+        String defaultPrefix = "def";
+        String description = "descrip";
+        String expression = "full expression";
+
+        factory.newBinding(description, container, component, expression, l);
+        setThrowable(t);
+
+        replay();
+
+        Map<String, BindingFactory> map = newMap();
+
+        map.put(defaultPrefix, factory);
+
+        BindingSource source = new BindingSourceImpl(map);
+
+        try
+        {
+            source.newBinding(description, container, component, defaultPrefix, expression, l);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertTrue(ex.getMessage().contains(
+                    "Could not convert 'full expression' into a component parameter binding"));
+            assertTrue(ex.getMessage().contains(t.getMessage()));
+            assertSame(ex.getLocation(), l);
+            assertSame(ex.getCause(), t);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void empty_parameter_binding()
+    {
+        BindingFactory factory = mockBindingFactory();
+        ComponentResources container = mockComponentResources();
+        ComponentResources component = mockComponentResources();
+        Location l = mockLocation();
+
+        String defaultPrefix = "def";
+        String description = "wilma";
+        String expression = "";
+
+        replay();
+
+        Map<String, BindingFactory> map = newMap();
+
+        map.put(defaultPrefix, factory);
+
+        BindingSource source = new BindingSourceImpl(map);
+
+        try
+        {
+            source.newBinding(description, container, component, defaultPrefix, expression, l);
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(), "Parameter 'wilma' must have a non-empty binding.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java
new file mode 100644
index 0000000..fa94369
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/BlockInjectionProviderTest.java
@@ -0,0 +1,121 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Block;
+import org.apache.tapestry.annotation.Id;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
+import org.apache.tapestry.services.TransformConstants;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class BlockInjectionProviderTest extends TapestryTestCase
+{
+    @Test
+    public void not_type_block()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        ObjectLocator locator = mockObjectLocator();
+
+        replay();
+
+        InjectionProvider provider = new BlockInjectionProvider();
+
+        assertFalse(provider.provideInjection("myfield", Object.class, locator, ct, model));
+
+        verify();
+    }
+
+    protected final Id newId()
+    {
+        return newMock(Id.class);
+    }
+
+    /**
+     * This doesn't prove anything; later there will be integration tests that prove that the generated code is valid
+     * and works.
+     */
+    @Test
+    public void explicit_block_id_provided_as_annotation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        ObjectLocator locator = mockObjectLocator();
+        Id barneyId = newId();
+
+        String barneyFieldName = "_barneyBlock";
+
+        train_getResourcesFieldName(ct, "rez");
+
+        train_getFieldAnnotation(ct, barneyFieldName, Id.class, barneyId);
+
+        train_value(barneyId, "barney");
+
+        ct.makeReadOnly(barneyFieldName);
+
+        train_extendMethod(
+                ct,
+                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                "_barneyBlock = rez.getBlock(\"barney\");");
+
+        replay();
+
+        assertTrue(new BlockInjectionProvider().provideInjection(
+                barneyFieldName,
+                Block.class,
+                locator,
+                ct,
+                model));
+
+        verify();
+    }
+
+    @Test
+    public void default_id_for_block_from_field_name()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        ObjectLocator locator = mockObjectLocator();
+
+        String barneyFieldName = "_barney";
+
+        train_getResourcesFieldName(ct, "rez");
+
+        train_getFieldAnnotation(ct, barneyFieldName, Id.class, null);
+
+        ct.makeReadOnly(barneyFieldName);
+
+        train_extendMethod(
+                ct,
+                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                "_barney = rez.getBlock(\"barney\");");
+
+        replay();
+
+        assertTrue(new BlockInjectionProvider().provideInjection(
+                barneyFieldName,
+                Block.class,
+                locator,
+                ct,
+                model));
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CheckFieldType.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CheckFieldType.java
new file mode 100644
index 0000000..57a4aef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CheckFieldType.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.util.Map;
+
+public class CheckFieldType
+{
+    private boolean _privateField;
+
+    private final Map _map = null;
+
+    public boolean isPrivateField()
+    {
+        return _privateField;
+    }
+
+    public void setPrivateField(boolean privateField)
+    {
+        _privateField = privateField;
+    }
+
+    public Map getMap()
+    {
+        return _map;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImplTest.java
new file mode 100644
index 0000000..970df30
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetAliasManagerImplTest.java
@@ -0,0 +1,94 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class ClasspathAssetAliasManagerImplTest extends InternalBaseTestCase
+{
+
+    public Map<String, String> configuration()
+    {
+        Map<String, String> configuration = newMap();
+
+        configuration.put("tapestry/", "org/apache/tapestry/");
+        configuration.put("tapestry-internal/", "org/apache/tapestry/internal/");
+        configuration.put("mylib/", "com/example/mylib/");
+
+        return configuration;
+    }
+
+    private static final String OPTIMIZED = "/opt/path";
+
+    @Test(dataProvider = "to_client_url_data")
+    public void to_client_url(String resourcePath, String expectedClientURL)
+    {
+        Request request = mockRequest();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+
+        train_getContextPath(request, "/ctx");
+
+        train_optimizePath(optimizer, "/ctx" + RequestConstants.ASSET_PATH_PREFIX + expectedClientURL, OPTIMIZED);
+
+
+        replay();
+
+        ClasspathAssetAliasManager manager = new ClasspathAssetAliasManagerImpl(request, optimizer, configuration());
+
+        assertEquals(manager.toClientURL(resourcePath), OPTIMIZED);
+
+        verify();
+    }
+
+    @DataProvider(name = "to_client_url_data")
+    public Object[][] to_client_url_data()
+    {
+        return new Object[][] { { "foo/bar/Baz.txt", "foo/bar/Baz.txt" },
+                { "com/example/mylib/Foo.bar", "mylib/Foo.bar" },
+                { "com/example/mylib/nested/Foo.bar", "mylib/nested/Foo.bar" },
+                { "org/apache/tapestry/internal/Foo.bar", "tapestry-internal/Foo.bar" },
+                { "org/apache/tapestry/Foo.bar", "tapestry/Foo.bar" }, };
+    }
+
+    @Test(dataProvider = "to_resource_path_data")
+    public void to_resource_path(String clientURL, String expectedResourcePath)
+    {
+        ClasspathAssetAliasManager manager = new ClasspathAssetAliasManagerImpl(null, null, configuration());
+
+        assertEquals(manager.toResourcePath(clientURL), expectedResourcePath);
+    }
+
+    @DataProvider(name = "to_resource_path_data")
+    public Object[][] to_resource_path_data()
+    {
+        Object[][] data = to_client_url_data();
+
+        for (Object[] pair : data)
+        {
+            Object buffer = pair[0];
+            pair[0] = RequestConstants.ASSET_PATH_PREFIX + pair[1];
+            pair[1] = buffer;
+        }
+
+        return data;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetFactoryTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetFactoryTest.java
new file mode 100644
index 0000000..bd9403b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClasspathAssetFactoryTest.java
@@ -0,0 +1,132 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.ClasspathAssetAliasManager;
+import org.testng.annotations.Test;
+
+public class ClasspathAssetFactoryTest extends InternalBaseTestCase
+{
+    @Test
+    public void asset_client_URL_is_cached()
+    {
+        ResourceCache cache = mockResourceCache();
+
+        Resource r = new ClasspathResource("foo/Bar.txt");
+
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+
+        train_requiresDigest(cache, r, false);
+
+        String expectedClientURL = "/context/asset/foo/Bar.txt";
+
+        train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
+
+        getMocksControl().times(2); // Cache of the raw path, not the final path which may be optimized
+
+        replay();
+
+        ClasspathAssetFactory factory = new ClasspathAssetFactory(cache, aliasManager);
+
+        Asset asset = factory.createAsset(r);
+
+        assertEquals(asset.toClientURL(), expectedClientURL);
+
+        // Now, to check the cache:
+
+        assertEquals(asset.toClientURL(), expectedClientURL);
+
+        verify();
+
+        // Now, to test cache clearing:
+        train_requiresDigest(cache, r, false);
+
+        train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
+
+        replay();
+
+        factory.objectWasInvalidated();
+
+        assertEquals(asset.toClientURL(), expectedClientURL);
+
+        verify();
+    }
+
+    @Test
+    public void simple_asset_client_URL()
+    {
+        ResourceCache cache = mockResourceCache();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+
+        Resource r = new ClasspathResource("foo/Bar.txt");
+
+        train_requiresDigest(cache, r, false);
+
+        String expectedClientURL = "/context/asset/foo/Bar.txt";
+
+        train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
+
+        getMocksControl().times(2); // 2nd time is the toString() call
+
+        replay();
+
+        AssetFactory factory = new ClasspathAssetFactory(cache, aliasManager);
+
+        Asset asset = factory.createAsset(r);
+
+        assertSame(asset.getResource(), r);
+        assertEquals(asset.toClientURL(), expectedClientURL);
+        assertEquals(asset.toString(), expectedClientURL);
+
+        verify();
+    }
+
+    @Test
+    public void protected_asset_client_URL()
+    {
+        ResourceCache cache = mockResourceCache();
+        ClasspathAssetAliasManager aliasManager = mockClasspathAssetAliasManager();
+
+        Resource r = new ClasspathResource("foo/Bar.txt");
+
+        train_requiresDigest(cache, r, true);
+
+        expect(cache.getDigest(r)).andReturn("ABC123");
+
+        String expectedClientURL = "/context/asset/foo/Bar.ABC123.txt";
+
+        train_toClientURL(aliasManager, "foo/Bar.ABC123.txt", expectedClientURL);
+
+        getMocksControl().times(2); // 2nd time is the toString() call
+
+        replay();
+
+        AssetFactory factory = new ClasspathAssetFactory(cache, aliasManager);
+
+        Asset asset = factory.createAsset(r);
+
+        assertSame(asset.getResource(), r);
+        assertEquals(asset.toClientURL(), expectedClientURL);
+        assertEquals(asset.toString(), expectedClientURL);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImplTest.java
new file mode 100644
index 0000000..e50bb2a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImplTest.java
@@ -0,0 +1,118 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+import org.testng.annotations.Test;
+
+public class ClientBehaviorSupportImplTest extends TapestryTestCase
+{
+    @Test
+    public void no_changes()
+    {
+        RenderSupport support = mockRenderSupport();
+
+        replay();
+
+        ClientBehaviorSupportImpl setup = new ClientBehaviorSupportImpl(support);
+
+        setup.commit();
+
+        verify();
+    }
+
+    @Test
+    public void add_links()
+    {
+        RenderSupport support = mockRenderSupport();
+
+        support.addInit("linkZone", new JSONArray("['client1', 'zone1']"));
+        support.addInit("linkZone", new JSONArray("['client2', 'zone2']"));
+
+        replay();
+
+        ClientBehaviorSupportImpl setup = new ClientBehaviorSupportImpl(support);
+
+        setup.linkZone("client1", "zone1");
+        setup.linkZone("client2", "zone2");
+
+        setup.commit();
+
+        verify();
+    }
+
+    @Test
+    public void add_zones()
+    {
+        RenderSupport support = mockRenderSupport();
+
+        support.addInit("zone", "client1");
+        support.addInit("zone", "client2");
+
+        replay();
+
+        ClientBehaviorSupportImpl setup = new ClientBehaviorSupportImpl(support);
+
+        setup.addZone("client1", null, null);
+        setup.addZone("client2", null, null);
+
+        setup.commit();
+
+        verify();
+    }
+
+    @Test
+    public void zones_with_functions()
+    {
+        RenderSupport support = mockRenderSupport();
+
+        support.addInit("zone", new JSONObject("{'element':'client1', 'show':'showme' }"));
+        support.addInit("zone", new JSONObject("{'element':'client2', 'update':'updateme' }"));
+
+        replay();
+
+        ClientBehaviorSupportImpl setup = new ClientBehaviorSupportImpl(support);
+
+        setup.addZone("client1", "showme", null);
+        setup.addZone("client2", null, "updateme");
+
+        setup.commit();
+
+        verify();
+    }
+
+    @Test
+    public void zone_function_names_are_converted_to_lower_case()
+    {
+        RenderSupport support = mockRenderSupport();
+
+        support.addInit("zone", new JSONObject("{'element':'client1', 'show':'showme' }"));
+        support.addInit("zone", new JSONObject("{'element':'client2', 'update':'updateme' }"));
+
+        replay();
+
+        ClientBehaviorSupportImpl setup = new ClientBehaviorSupportImpl(support);
+
+        setup.addZone("client1", "ShowMe", null);
+        setup.addZone("client2", null, "UpdateMe");
+
+        setup.commit();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java
new file mode 100644
index 0000000..4a46bb0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientPersistentFieldStorageImplTest.java
@@ -0,0 +1,273 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.util.Holder;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.easymock.IAnswer;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+public class ClientPersistentFieldStorageImplTest extends TapestryTestCase
+{
+    @Test
+    public void no_client_data_in_request()
+    {
+        Request request = mockRequest(null);
+        Link link = mockLink();
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        // Should do nothing.
+
+        storage.updateLink(link);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void store_and_restore_a_change()
+    {
+        Request request = mockRequest(null);
+        Link link = mockLink();
+        final Holder<String> holder = Holder.create();
+
+        String pageName = "Foo";
+        String componentId = "bar.baz";
+        String fieldName = "biff";
+        Object value = 99;
+
+        // Use an IAnswer to capture the value.
+
+        link.addParameter(eq(ClientPersistentFieldStorageImpl.PARAMETER_NAME), isA(String.class));
+        getMocksControl().andAnswer(new IAnswer<Void>()
+        {
+            public Void answer() throws Throwable
+            {
+                String base64 = (String) EasyMock.getCurrentArguments()[1];
+
+                holder.put(base64);
+
+                return null;
+            }
+        });
+
+        replay();
+
+        ClientPersistentFieldStorage storage1 = new ClientPersistentFieldStorageImpl(request);
+
+        storage1.postChange(pageName, componentId, fieldName, value);
+
+        List<PersistentFieldChange> changes1 = newList(storage1.gatherFieldChanges(pageName));
+
+        storage1.updateLink(link);
+
+        verify();
+
+        System.out.println(holder.get());
+
+        assertEquals(changes1.size(), 1);
+        PersistentFieldChange change1 = changes1.get(0);
+
+        assertEquals(change1.getComponentId(), componentId);
+        assertEquals(change1.getFieldName(), fieldName);
+        assertEquals(change1.getValue(), value);
+
+        // Now more training ...
+
+        train_getParameter(request, ClientPersistentFieldStorageImpl.PARAMETER_NAME, holder.get());
+
+        replay();
+
+        ClientPersistentFieldStorage storage2 = new ClientPersistentFieldStorageImpl(request);
+
+        List<PersistentFieldChange> changes2 = newList(storage2.gatherFieldChanges(pageName));
+
+        verify();
+
+        assertEquals(changes2.size(), 1);
+        PersistentFieldChange change2 = changes2.get(0);
+
+        assertEquals(change2.getComponentId(), componentId);
+        assertEquals(change2.getFieldName(), fieldName);
+        assertEquals(change2.getValue(), value);
+
+        assertNotSame(change1, change2);
+    }
+
+    @Test
+    public void multiple_changes()
+    {
+        Request request = mockRequest(null);
+        Link link = mockLink();
+
+        String pageName = "Foo";
+        String componentId = "bar.baz";
+
+        link.addParameter(eq(ClientPersistentFieldStorageImpl.PARAMETER_NAME), isA(String.class));
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        for (int k = 0; k < 3; k++)
+        {
+            for (int i = 0; i < 20; i++)
+            {
+                // Force some cache collisions ...
+
+                storage.postChange(pageName, componentId, "field" + i, i * k);
+            }
+        }
+
+        storage.postChange(pageName, null, "field", "foo");
+        storage.postChange(pageName, null, "field", "bar");
+
+        storage.updateLink(link);
+
+        verify();
+    }
+
+    @Test
+    public void null_value_is_a_remove()
+    {
+        Request request = mockRequest(null);
+        Link link = mockLink();
+
+        String pageName = "Foo";
+        String componentId = "bar.baz";
+        String fieldName = "woops";
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        storage.postChange(pageName, componentId, fieldName, 99);
+        storage.postChange(pageName, componentId, fieldName, null);
+
+        storage.updateLink(link);
+
+        assertTrue(storage.gatherFieldChanges(pageName).isEmpty());
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1475
+     */
+    @Test
+    public void discard_changes()
+    {
+        Request request = mockRequest(null);
+        Link link = mockLink();
+
+        String pageName = "Foo";
+        String componentId = "bar.baz";
+        String fieldName = "woops";
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        storage.postChange(pageName, componentId, fieldName, 99);
+
+        storage.discardChanges(pageName);
+
+        storage.updateLink(link);
+
+        assertTrue(storage.gatherFieldChanges(pageName).isEmpty());
+
+        verify();
+    }
+
+
+    @Test
+    public void value_not_serializable()
+    {
+        Request request = mockRequest(null);
+
+        Object badBody = new Object()
+        {
+            @Override
+            public String toString()
+            {
+                return "<BadBoy>";
+            }
+        };
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        try
+        {
+            storage.postChange("Foo", "bar.baz", "woops", badBody);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "State persisted on the client must be serializable, but <BadBoy> does not implement the Serializable interface.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void corrupt_client_data()
+    {
+        // A cut-n-paste from some previous output, with the full value significantly truncated.
+        Request request = mockRequest("H4sIAAAAAAAAAEWQsUoDQRCGJxdDTEwRU2hlZ71pBQ");
+
+        replay();
+
+        ClientPersistentFieldStorage storage = new ClientPersistentFieldStorageImpl(request);
+
+        try
+        {
+            storage.postChange("Foo", "bar.baz", "woops", 99);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), ServicesMessages.corruptClientState());
+            assertNotNull(ex.getCause());
+        }
+
+        verify();
+    }
+
+    protected final Request mockRequest(String clientData)
+    {
+        Request request = mockRequest();
+
+        train_getParameter(request, ClientPersistentFieldStorageImpl.PARAMETER_NAME, clientData);
+
+        return request;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
new file mode 100644
index 0000000..e076975
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentClassResolverImplTest.java
@@ -0,0 +1,884 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.LibraryMapping;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.isA;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class ComponentClassResolverImplTest extends InternalBaseTestCase
+{
+    private static final String APP_ROOT_PACKAGE = "org.example.app";
+
+    private static final String CORE_PREFIX = "core";
+
+    private static final String CORE_ROOT_PACKAGE = "org.apache.tapestry.corelib";
+
+    private static final String LIB_PREFIX = "lib";
+
+    private static final String LIB_ROOT_PACKAGE = "org.example.lib";
+
+    private ComponentClassResolverImpl create(Logger logger, ComponentInstantiatorSource source,
+                                              ClassNameLocator locator, LibraryMapping... mappings)
+    {
+        List<LibraryMapping> list = Arrays.asList(mappings);
+
+        return new ComponentClassResolverImpl(logger, source, locator, APP_ROOT_PACKAGE, list);
+    }
+
+    private Logger compliantLogger()
+    {
+        Logger logger = mockLogger();
+
+        logger.info(EasyMock.isA(String.class));
+
+        getMocksControl().atLeastOnce();
+
+        return logger;
+    }
+
+    @Test
+    public void simple_page_name()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.SimplePage";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("SimplePage"), className);
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1541
+     */
+    @Test
+    public void page_name_matches_containing_folder_name()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.admin.product.ProductAdmin";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("admin/product/ProductAdmin"), className);
+
+        verify();
+    }
+
+
+    @Test
+    public void canonicalize_existing_page_name()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.SimplePage";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.canonicalizePageName("simplepage"), "SimplePage");
+
+        verify();
+
+    }
+
+    @Test
+    public void page_name_in_subfolder()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.subfolder.NestedPage";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("subfolder/NestedPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void lots_of_prefixes_and_suffixes_stripped()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.admin.edit.AdminUserEdit";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("admin/edit/User"), className);
+        assertEquals(resolver.resolvePageNameToClassName("admin/edit/AdminUserEdit"), className);
+
+        verify();
+    }
+
+    @Test
+    public void page_in_subfolder()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.subfolder.NestedPage";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("subfolder/NestedPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void subfolder_name_as_classname_prefix_is_stripped()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.foo.FooBar";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("foo/Bar"), className);
+
+        verify();
+    }
+
+    @Test
+    public void core_prefix_stripped_from_exception_message()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, CORE_ROOT_PACKAGE + ".pages", CORE_ROOT_PACKAGE + ".pages.Fred",
+                                        CORE_ROOT_PACKAGE + ".pages.Barney");
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", APP_ROOT_PACKAGE + ".pages.Wilma",
+                                        APP_ROOT_PACKAGE + ".pages.Betty");
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        try
+        {
+            resolver.resolvePageNameToClassName("Unknown");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Unable to resolve \'Unknown\' to a page class name.  Available page names: Barney, Betty, Fred, Wilma.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void is_page_name()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.SimplePage";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertTrue(resolver.isPageName("SimplePage"));
+        assertTrue(resolver.isPageName("simplepage"));
+        assertFalse(resolver.isPageName("UnknownPage"));
+
+        verify();
+    }
+
+    @Test
+    public void index_page_name_at_root()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        String className = APP_ROOT_PACKAGE + ".pages.Index";
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertTrue(resolver.isPageName("Index"));
+        assertTrue(resolver.isPageName(""));
+
+        verify();
+    }
+
+    @Test
+    public void is_page_name_for_core_page()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+
+        String className = CORE_ROOT_PACKAGE + ".pages.MyCorePage";
+
+        train_locateComponentClassNames(locator, CORE_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        // Can look like an application page, but still resolves to the core library class name.
+
+        assertTrue(resolver.isPageName("MyCorePage"));
+
+        // Or we can give it its true name
+
+        assertTrue(resolver.isPageName("core/mycorepage"));
+
+        assertFalse(resolver.isPageName("UnknownPage"));
+
+        verify();
+    }
+
+    protected final ClassNameLocator newClassNameLocator()
+    {
+        ClassNameLocator locator = newMock(ClassNameLocator.class);
+
+        stub_locateComponentClassNames(locator);
+
+        return locator;
+    }
+
+    private void stub_locateComponentClassNames(ClassNameLocator locator)
+    {
+        Collection<String> noMatches = Collections.emptyList();
+
+        expect(locator.locateClassNames(isA(String.class))).andStubReturn(noMatches);
+    }
+
+    protected final void train_locateComponentClassNames(ClassNameLocator locator, String packageName,
+                                                         String... classNames)
+    {
+        expect(locator.locateClassNames(packageName)).andReturn(Arrays.asList(classNames));
+    }
+
+    @Test
+    public void class_name_to_simple_page_name()
+    {
+        String className = APP_ROOT_PACKAGE + ".pages.SimplePage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageClassNameToPageName(className), "SimplePage");
+
+        verify();
+    }
+
+    /**
+     * All of the caches are handled identically, so we just test the pages for caching.
+     */
+    @Test
+    public void resolved_page_names_are_cached()
+    {
+        String pageClassName = APP_ROOT_PACKAGE + ".pages.SimplePage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", pageClassName);
+
+        replay();
+
+        ComponentClassResolverImpl resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolvePageNameToClassName("SimplePage"), pageClassName);
+
+        verify();
+
+        // No more training, because it's already cached.
+
+        replay();
+
+        assertEquals(resolver.resolvePageNameToClassName("SimplePage"), pageClassName);
+
+        verify();
+
+        // After clearing the cache, redoes the work.
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", pageClassName);
+        stub_locateComponentClassNames(locator);
+
+        replay();
+
+        resolver.objectWasInvalidated();
+
+        assertEquals(resolver.resolvePageNameToClassName("SimplePage"), pageClassName);
+
+        verify();
+    }
+
+    @Test
+    public void page_found_in_core_lib()
+    {
+        String className = CORE_ROOT_PACKAGE + ".pages.MyCorePage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, CORE_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("MyCorePage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void page_class_name_resolved_to_core_page()
+    {
+        String className = CORE_ROOT_PACKAGE + ".pages.MyCorePage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, CORE_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageClassNameToPageName(className), "core/MyCorePage");
+
+        verify();
+    }
+
+    @Test
+    public void page_found_in_library()
+    {
+        String className = LIB_ROOT_PACKAGE + ".pages.MyLibPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, LIB_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(LIB_PREFIX, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/MyLibPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void slashes_trimmed_from_library_prefix()
+    {
+        String className = LIB_ROOT_PACKAGE + ".pages.MyLibPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, LIB_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping("/" + LIB_PREFIX + "/", LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/MyLibPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void lookup_by_logical_name_is_case_insensitive()
+    {
+        String className = LIB_ROOT_PACKAGE + ".pages.MyLibPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, LIB_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(LIB_PREFIX, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/MyLibPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void name_stripping_includes_library_folder()
+    {
+        String className = LIB_ROOT_PACKAGE + ".pages.LibPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, LIB_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(LIB_PREFIX, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/Page"), className);
+
+        verify();
+    }
+
+    @Test
+    public void name_stripping_for_complex_library_folder_name()
+    {
+        String libPrefix = "lib/deep";
+
+        String className = LIB_ROOT_PACKAGE + ".pages.LibDeepPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, LIB_ROOT_PACKAGE + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(libPrefix, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/deep/Page"), className);
+        assertEquals(resolver.resolvePageNameToClassName("lib/deep/LibDeepPage"), className);
+
+        verify();
+    }
+
+
+    @Test
+    public void class_name_does_not_resolve_to_page_name()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = mockLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        String className = LIB_ROOT_PACKAGE + ".pages.LibPage";
+
+        try
+        {
+            resolver.resolvePageClassNameToPageName(className);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "Unable to resolve class name " + className + " to a logical page name.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void page_name_to_canonicalize_does_not_exist()
+    {
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".pages", APP_ROOT_PACKAGE + ".pages.Start");
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        try
+        {
+            resolver.canonicalizePageName("MissingPage");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Unable to resolve \'MissingPage\' to a known page name. Available page names: Start.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void class_name_not_in_a_pages_package()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = mockLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        String className = CORE_ROOT_PACKAGE + ".foo.CorePage";
+
+        try
+        {
+            resolver.resolvePageClassNameToPageName(className);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "Unable to resolve class name " + className + " to a logical page name.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void multiple_mappings_for_same_prefix()
+    {
+        String secondaryLibPackage = "org.examples.addon.lib";
+        String className = secondaryLibPackage + ".pages.MyLibPage";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, secondaryLibPackage);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, secondaryLibPackage + ".pages", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(LIB_PREFIX, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(LIB_PREFIX, secondaryLibPackage),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        assertEquals(resolver.resolvePageNameToClassName("lib/MyLibPage"), className);
+
+        verify();
+    }
+
+    @Test
+    public void complex_prefix_search_fails()
+    {
+        String deepPackage = "org.deep";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = mockLogger();
+
+        train_for_packages(source, deepPackage);
+        train_for_packages(source, LIB_ROOT_PACKAGE);
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        // Is this test even needed any more with the new algorithm?
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator, new LibraryMapping("lib/deep", deepPackage),
+                                                 new LibraryMapping(LIB_PREFIX, LIB_ROOT_PACKAGE),
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        try
+        {
+            resolver.resolvePageNameToClassName("lib/deep/DeepPage");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertMessageContains(ex, "Unable to resolve 'lib/deep/DeepPage' to a page class name.");
+        }
+
+        verify();
+    }
+
+    private void train_for_packages(ComponentInstantiatorSource source, String packageName)
+    {
+        source.addPackage(packageName + ".pages");
+        source.addPackage(packageName + ".components");
+        source.addPackage(packageName + ".mixins");
+        source.addPackage(packageName + ".base");
+    }
+
+    /**
+     * The logic for searching is pretty much identical for both components and pages, so even a cursory test of
+     * component types should nail it.
+     */
+    @Test
+    public void simple_component_type()
+    {
+        String className = APP_ROOT_PACKAGE + ".components.SimpleComponent";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".components", className);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolveComponentTypeToClassName("SimpleComponent"), className);
+
+        verify();
+    }
+
+    /**
+     * Likewise for mixins; it's all just setup for a particular method.
+     */
+
+    @Test
+    public void simple_mixin_type()
+    {
+        String expectedClassName = APP_ROOT_PACKAGE + ".mixins.SimpleMixin";
+
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = compliantLogger();
+
+        train_for_app_packages(source);
+
+        train_locateComponentClassNames(locator, APP_ROOT_PACKAGE + ".mixins", expectedClassName);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator);
+
+        assertEquals(resolver.resolveMixinTypeToClassName("SimpleMixin"), expectedClassName);
+
+        verify();
+    }
+
+    @Test
+    public void mixin_type_not_found()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = mockLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        try
+        {
+            resolver.resolveMixinTypeToClassName("SimpleMixin");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertMessageContains(ex, "Unable to resolve 'SimpleMixin' to a mixin class name.");
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void component_type_not_found()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ClassNameLocator locator = newClassNameLocator();
+        Logger logger = mockLogger();
+
+        train_for_packages(source, CORE_ROOT_PACKAGE);
+        train_for_app_packages(source);
+
+        replay();
+
+        ComponentClassResolver resolver = create(logger, source, locator,
+                                                 new LibraryMapping(CORE_PREFIX, CORE_ROOT_PACKAGE));
+
+        try
+        {
+            resolver.resolveComponentTypeToClassName("SimpleComponent");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertTrue(ex.getMessage().contains("Unable to resolve 'SimpleComponent' to a component class name."));
+        }
+
+        verify();
+    }
+
+    private void train_for_app_packages(ComponentInstantiatorSource source)
+    {
+        train_for_packages(source, APP_ROOT_PACKAGE);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImplTest.java
new file mode 100644
index 0000000..74a51ea
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentDefaultProviderImplTest.java
@@ -0,0 +1,192 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.ComponentDefaultProvider;
+import org.apache.tapestry.services.TranslatorSource;
+import org.testng.annotations.Test;
+
+public class ComponentDefaultProviderImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void default_label_key_exists()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentResources container = mockComponentResources();
+        Messages messages = mockMessages();
+
+        String componentId = "myfield";
+        String key = componentId + "-label";
+        String message = "My Lovely Field";
+
+        train_getId(resources, componentId);
+        train_getContainerResources(resources, container);
+        train_getMessages(container, messages);
+        train_contains(messages, key, true);
+        train_get(messages, key, message);
+
+        replay();
+
+        ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null);
+
+        assertSame(provider.defaultLabel(resources), message);
+
+        verify();
+    }
+
+    @Test
+    public void default_label_key_missing()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentResources container = mockComponentResources();
+        Messages messages = mockMessages();
+
+        String componentId = "myField";
+        String key = componentId + "-label";
+
+        train_getId(resources, componentId);
+        train_getContainerResources(resources, container);
+        train_getMessages(container, messages);
+        train_contains(messages, key, false);
+
+        replay();
+
+        ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null);
+
+        assertEquals(provider.defaultLabel(resources), "My Field");
+
+        verify();
+    }
+
+    @Test
+    public void no_matching_property_for_default()
+    {
+        String parameterName = "myparam";
+
+        String id = "mycomponentid";
+
+        ComponentResources resources = mockComponentResources();
+        Component container = mockComponent();
+        PropertyAccess access = mockPropertyAccess();
+        ClassPropertyAdapter classPropertyAdapter = mockClassPropertyAdapter();
+        BindingSource bindingSource = mockBindingSource();
+
+        train_getId(resources, id);
+        train_getContainer(resources, container);
+
+        train_getAdapter(access, container, classPropertyAdapter);
+        train_getPropertyAdapter(classPropertyAdapter, id, null);
+
+        replay();
+
+        ComponentDefaultProvider source = new ComponentDefaultProviderImpl(access, bindingSource, null,
+                                                                           null);
+
+        assertNull(source.defaultBinding(parameterName, resources));
+
+        verify();
+    }
+
+    @Test
+    public void default_property_exists()
+    {
+        String parameterName = "myparam";
+
+        String id = "mycomponentid";
+
+        ComponentResources resources = mockComponentResources();
+        Component container = mockComponent();
+        PropertyAccess access = mockPropertyAccess();
+        ClassPropertyAdapter classPropertyAdapter = mockClassPropertyAdapter();
+        PropertyAdapter propertyAdapter = mockPropertyAdapter();
+        BindingSource bindingSource = mockBindingSource();
+        Binding binding = mockBinding();
+        ComponentResources containerResources = mockComponentResources();
+
+        train_getId(resources, id);
+        train_getContainer(resources, container);
+
+        train_getAdapter(access, container, classPropertyAdapter);
+        train_getPropertyAdapter(classPropertyAdapter, id, propertyAdapter);
+
+        train_getContainerResources(resources, containerResources);
+
+        train_newBinding(
+                bindingSource,
+                "default myparam",
+                containerResources,
+                BindingConstants.PROP,
+                id,
+                binding);
+
+        replay();
+
+        ComponentDefaultProvider source = new ComponentDefaultProviderImpl(access, bindingSource, null,
+                                                                           null);
+
+        assertSame(source.defaultBinding(parameterName, resources), binding);
+
+        verify();
+    }
+
+    @Test
+    public void default_translator_property_type_is_null()
+    {
+        TranslatorSource source = mockTranslatorSource();
+        ComponentResources resources = mockComponentResources();
+
+        train_getBoundType(resources, "object", null);
+
+        replay();
+
+        ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source);
+
+        assertNull(provider.defaultTranslator("object", resources));
+
+        verify();
+    }
+
+    @Test
+    public void default_translator()
+    {
+        TranslatorSource source = mockTranslatorSource();
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+
+        train_getBoundType(resources, "object", Integer.class);
+
+        expect(source.findByType(Integer.class)).andReturn(translator);
+
+        replay();
+
+        ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source);
+
+        assertSame(provider.defaultTranslator("object", resources), translator);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
new file mode 100644
index 0000000..1572a6c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventDispatcherTest.java
@@ -0,0 +1,272 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.internal.EmptyEventContext;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.URLEventContext;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.*;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+public class ComponentEventDispatcherTest extends InternalBaseTestCase
+{
+    private ContextValueEncoder contextValueEncoder;
+
+    @BeforeClass
+    public void setup()
+    {
+        contextValueEncoder = getService(ContextValueEncoder.class);
+    }
+
+    @Test
+    public void no_dot_or_colon_in_path() throws Exception
+    {
+        ComponentEventRequestHandler handler = newComponentEventRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
+
+        train_getPath(request, "/foo/bar/baz");
+
+        replay();
+
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, null, null, requestEncodingInitializer);
+
+        assertFalse(dispatcher.dispatch(request, response));
+
+        verify();
+    }
+
+    protected final RequestEncodingInitializer mockRequestEncodingInitializer()
+    {
+        return newMock(RequestEncodingInitializer.class);
+    }
+
+    protected final ComponentEventRequestHandler newComponentEventRequestHandler()
+    {
+        return newMock(ComponentEventRequestHandler.class);
+    }
+
+    @Test
+    public void event_on_page() throws Exception
+    {
+        test("/foo/MyPage:anevent", "foo/MyPage", "", "anevent");
+    }
+
+    /**
+     * @see https://issues.apache.org/jira/browse/TAPESTRY-1949
+     */
+    @Test
+    public void event_on_page_with_name_and_dotted_parameters() throws Exception
+    {
+        test("/foo/MyPage:myevent/1.2.3/4.5.6", "foo/MyPage", "", "myevent", "1.2.3", "4.5.6");
+    }
+
+    /**
+     * @see https://issues.apache.org/jira/browse/TAPESTRY-1949
+     */
+    @Test
+    public void event_on_page_dotted_parameters() throws Exception
+    {
+        test("/foo/MyPage:action/1.2.3/4.5.6", "foo/MyPage", "", EventConstants.ACTION, "1.2.3", "4.5.6");
+    }
+
+    @Test
+    public void event_on_component_within_page() throws Exception
+    {
+        test("/foo/MyPage.fred:anevent", "foo/MyPage", "fred", "anevent");
+    }
+
+    @Test
+    public void default_event_with_nested_id() throws Exception
+    {
+        test("/foo/MyPage.fred", "foo/MyPage", "fred", EventConstants.ACTION);
+    }
+
+    @Test
+    public void default_event_with_nested_id_and_context() throws Exception
+    {
+        test("/foo/MyPage.fred/fee/fie/foe/fum", "foo/MyPage", "fred", EventConstants.ACTION, "fee", "fie",
+             "foe", "fum");
+    }
+
+    @Test
+    public void default_event_with_context_that_includes_a_colon() throws Exception
+    {
+        test("/foo/MyPage.underdog/a:b:c/d", "foo/MyPage", "underdog", EventConstants.ACTION, "a:b:c", "d");
+    }
+
+    @Test
+    public void event_on_nested_component_within_page() throws Exception
+    {
+        test("/foo/MyPage.barney.fred:anevent", "foo/MyPage", "barney.fred", "anevent");
+    }
+
+    @Test
+    public void page_event_with_context() throws Exception
+    {
+        test("/foo/MyPage:trigger/foo", "foo/MyPage", "", "trigger", "foo");
+    }
+
+    @Test
+    public void nested_component_event_with_context() throws Exception
+    {
+        test("/foo/MyPage.nested:trigger/foo/bar/baz", "foo/MyPage", "nested", "trigger", "foo", "bar", "baz");
+    }
+
+    @Test
+    public void page_activation_context_in_request() throws Exception
+    {
+        ComponentEventRequestHandler handler = newComponentEventRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
+
+
+        ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("mypage", "mypage", "",
+                                                                                                 "eventname",
+                                                                                                 new URLEventContext(
+                                                                                                         contextValueEncoder,
+                                                                                                         new String[] {
+                                                                                                                 "alpha",
+                                                                                                                 "beta" }),
+                                                                                                 new EmptyEventContext());
+
+        train_getPath(request, "/mypage:eventname");
+
+        train_isPageName(resolver, "mypage", true);
+
+        train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, "alpha/beta");
+
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, null);
+
+        requestEncodingInitializer.initializeRequestEncoding("mypage");
+
+        handler.handle(expectedParameters);
+
+        replay();
+
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
+                                                             requestEncodingInitializer);
+
+        assertTrue(dispatcher.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void different_active_and_containing_pages() throws Exception
+    {
+        ComponentEventRequestHandler handler = newComponentEventRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
+
+        ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters("activepage", "mypage",
+                                                                                                 "", "eventname",
+                                                                                                 new EmptyEventContext(),
+                                                                                                 new EmptyEventContext());
+
+        train_getPath(request, "/activepage:eventname");
+
+        train_isPageName(resolver, "activepage", true);
+
+        requestEncodingInitializer.initializeRequestEncoding("activepage");
+
+        train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
+
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, "mypage");
+
+        handler.handle(expectedParameters);
+
+        replay();
+
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
+                                                             requestEncodingInitializer);
+
+        assertTrue(dispatcher.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void request_path_reference_non_existent_page() throws Exception
+    {
+        ComponentEventRequestHandler handler = newComponentEventRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
+
+        train_getPath(request, "/mypage.foo");
+
+        train_isPageName(resolver, "mypage", false);
+
+        replay();
+
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, null, requestEncodingInitializer);
+
+        assertFalse(dispatcher.dispatch(request, response));
+
+        verify();
+    }
+
+    private void test(String requestPath, String containerPageName, String nestedComponentId, String eventType,
+                      String... eventContext) throws IOException
+    {
+        ComponentEventRequestHandler handler = newComponentEventRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestEncodingInitializer requestEncodingInitializer = mockRequestEncodingInitializer();
+
+        ComponentEventRequestParameters expectedParameters = new ComponentEventRequestParameters(containerPageName,
+                                                                                                 containerPageName,
+                                                                                                 nestedComponentId,
+                                                                                                 eventType,
+                                                                                                 new EmptyEventContext(),
+                                                                                                 new URLEventContext(
+                                                                                                         contextValueEncoder,
+                                                                                                         eventContext));
+
+        train_getPath(request, requestPath);
+
+        train_isPageName(resolver, containerPageName, true);
+
+        train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null);
+
+        train_getParameter(request, InternalConstants.CONTAINER_PAGE_NAME, null);
+
+        requestEncodingInitializer.initializeRequestEncoding(containerPageName);
+
+        handler.handle(expectedParameters);
+
+        replay();
+
+        Dispatcher dispatcher = new ComponentEventDispatcher(handler, resolver, contextValueEncoder,
+                                                             requestEncodingInitializer);
+
+        assertTrue(dispatcher.dispatch(request, response));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
new file mode 100644
index 0000000..3e45245
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
@@ -0,0 +1,293 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.structure.PageResources;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.ComponentEvent;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ComponentEventImplTest extends InternalBaseTestCase
+{
+    private TypeCoercer coercer;
+
+    @BeforeClass
+    public void setup_coercer()
+    {
+        coercer = getObject(TypeCoercer.class, null);
+    }
+
+    @AfterClass
+    public void cleanup_coercer()
+    {
+        coercer = null;
+    }
+
+    @Test
+    public void matches_on_event_type()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+
+        assertTrue(event.matches("eventType", "someId", 0));
+        assertFalse(event.matches("foo", "someId", 0));
+
+        verify();
+    }
+
+    @Test
+    public void event_type_match_is_case_insensitive()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+
+        assertTrue(event.matches("EVENTTYPE", "someid", 0));
+
+        verify();
+    }
+
+    @Test
+    public void matches_on_component_id()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+
+        assertTrue(event.matches("eventType", "someId", 0));
+
+        assertFalse(event.matches("eventtype", "bar", 0));
+
+        verify();
+    }
+
+    @Test
+    public void component_id_matches_are_case_insensitive()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+
+        assertTrue(event.matches("eventtype", "SOMEID", 0));
+
+        verify();
+    }
+
+    @Test
+    public void coerce_context()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        PageResources resources = mockPageResources();
+        EventContext context = mockEventContext();
+        Integer value = new Integer(27);
+
+        train_toClass(resources, "java.lang.Integer", Integer.class);
+
+        train_getCount(context, 2);
+        train_get(context, Integer.class, 0, value);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
+
+        assertSame(event.coerceContext(0, "java.lang.Integer"), value);
+
+        verify();
+    }
+
+    @Test
+    public void coerce_when_not_enough_context()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
+
+        event.setMethodDescription("foo.Bar.baz()");
+
+        try
+        {
+            event.coerceContext(1, "java.lang.Integer");
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Method foo.Bar.baz() has more parameters than there are context values for this component event.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void unable_to_coerce()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+        PageResources resources = mockPageResources();
+
+        train_toClass(resources, Integer.class.getName(), Integer.class);
+
+        train_getCount(context, 1);
+
+        expect(context.get(Integer.class, 0)).andThrow(new NumberFormatException("Not so easy, is it?"));
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
+
+        event.setMethodDescription("foo.Bar.baz()");
+
+        try
+        {
+            event.coerceContext(0, "java.lang.Integer");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            // Different JVMs will report the conversion error slightly differently,
+            // so we don't try to check that part of the error message.
+
+            assertTrue(ex.getMessage().startsWith("Exception in method foo.Bar.baz(), parameter #1:"));
+        }
+
+        verify();
+    }
+
+    @Test
+    public void store_result_and_abort()
+    {
+        Object result = new Object();
+        String methodDescription = "foo.Bar.baz()";
+
+        ComponentEventCallback handler = mockComponentEventHandler();
+
+        train_handleResult(handler, result, true);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+
+        event.setMethodDescription(methodDescription);
+
+        assertFalse(event.isAborted());
+
+        assertTrue(event.storeResult(result));
+
+        assertTrue(event.isAborted());
+
+        verify();
+    }
+
+    @Test
+    public void store_result_and_continue()
+    {
+        Object result = new Object();
+        String methodDescription = "foo.Bar.baz()";
+        ComponentEventCallback handler = mockComponentEventHandler();
+
+        train_handleResult(handler, result, false);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+
+        event.setMethodDescription(methodDescription);
+
+        assertFalse(event.storeResult(result));
+
+        assertFalse(event.isAborted());
+
+        verify();
+    }
+
+    @Test
+    public void store_null_result_does_not_abort_or_invoke_handler()
+    {
+        ComponentEventCallback handler = mockComponentEventHandler();
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+
+        event.setMethodDescription("foo.Bar.baz()");
+
+        assertFalse(event.storeResult(null));
+
+        assertFalse(event.isAborted());
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void store_result_when_aborted_is_failure()
+    {
+        Object result = new Object();
+        ComponentEventCallback handler = mockComponentEventHandler();
+
+        expect(handler.handleResult(result)).andReturn(true);
+
+        replay();
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+
+        event.setMethodDescription("foo.Bar.baz()");
+        event.storeResult(result);
+
+        try
+        {
+            event.setMethodDescription("foo.Bar.biff()");
+            event.storeResult(null);
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(), ServicesMessages
+                    .componentEventIsAborted("foo.Bar.biff()"));
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java
new file mode 100644
index 0000000..b068bed
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java
@@ -0,0 +1,96 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class ComponentInstanceResultProcessorTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "Zoop";
+
+    private static final String METHOD_DESCRIPTION = "foo.bar.Baz.biff()";
+
+    @Test
+    public void result_is_root_component() throws Exception
+    {
+        Component result = mockComponent();
+        Component source = mockComponent();
+        ComponentResources resources = mockComponentResources();
+        Logger logger = mockLogger();
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ActionRenderResponseGenerator generator = mockActionRenderResponseGenerator();
+
+        train_getComponentResources(result, resources);
+        train_getContainer(resources, null);
+
+        train_getPageName(resources, PAGE_NAME);
+        train_get(cache, PAGE_NAME, page);
+
+        generator.generateResponse(page);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor(logger, cache,
+                                                                                                  generator);
+
+        processor.processResultValue(result);
+
+        verify();
+    }
+
+    @Test
+    public void warning_for_component_is_not_root_component() throws Exception
+    {
+        Component value = mockComponent();
+        Component containerResources = mockComponent();
+        ComponentResources valueResources = mockComponentResources();
+        Logger logger = mockLogger();
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ActionRenderResponseGenerator generator = mockActionRenderResponseGenerator();
+
+
+        train_getComponentResources(value, valueResources);
+
+        train_getContainer(valueResources, containerResources);
+
+        train_getCompleteId(valueResources, PAGE_NAME + ":child");
+
+        logger
+                .warn("Component Zoop:child was returned from an event handler method, but is not a page component. The page containing the component will render the client response.");
+
+        train_getPageName(valueResources, PAGE_NAME);
+        train_get(cache, PAGE_NAME, page);
+
+        generator.generateResponse(page);
+
+        replay();
+
+        ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor(logger, cache,
+                                                                                                  generator);
+
+        processor.processResultValue(value);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java
new file mode 100644
index 0000000..50b4abc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImplTest.java
@@ -0,0 +1,294 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.*;
+import org.apache.tapestry.internal.*;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.pages.BasicComponent;
+import org.apache.tapestry.internal.transform.pages.BasicSubComponent;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.RegistryBuilder;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.TapestryModule;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.UUID;
+
+/**
+ * Tests for {@link org.apache.tapestry.internal.services.ComponentInstantiatorSourceImpl}. Several of these tests are
+ * more of the form of integration tests that instantiate the Tapestry IoC Registry.
+ */
+public class ComponentInstantiatorSourceImplTest extends InternalBaseTestCase
+{
+    private static final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+
+    private static final String SYNTH_COMPONENT_CLASSNAME = "org.apache.tapestry.internal.transform.pages.SynthComponent";
+
+    private File extraClasspath;
+
+    private ComponentInstantiatorSource source;
+
+    private Registry registry;
+
+    private PropertyAccess access;
+
+    private ClassLoader extraLoader;
+
+    private String tempDir;
+
+    @Test
+    public void controlled_packages() throws Exception
+    {
+        ComponentClassTransformer transformer = newMock(ComponentClassTransformer.class);
+        Logger logger = mockLogger();
+
+        replay();
+
+        ComponentInstantiatorSourceImpl e = new ComponentInstantiatorSourceImpl(logger, contextLoader, transformer,
+                                                                                null);
+
+        assertEquals(e.inControlledPackage("foo.bar.Baz"), false);
+
+        // Check that classes in the default package are never controlled
+
+        assertEquals(e.inControlledPackage("Biff"), false);
+
+        // Now add a controlled package
+
+        e.addPackage("foo.bar");
+
+        assertEquals(e.inControlledPackage("foo.bar.Baz"), true);
+
+        // Sub-packages of controlled packages are controlled as well
+
+        assertEquals(e.inControlledPackage("foo.bar.biff.Pop"), true);
+
+        // Parents of controlled packages are not controlled
+
+        assertEquals(e.inControlledPackage("foo.Gloop"), false);
+
+        verify();
+    }
+
+    /**
+     * More of an integration test.
+     */
+    @Test
+    public void load_component_via_service() throws Exception
+    {
+        Component target = createComponent(BasicComponent.class);
+
+        // Should not be an instance, since it is loaded by a different class loader.
+        assertFalse(BasicComponent.class.isInstance(target));
+
+        access.set(target, "value", "some default value");
+        assertEquals(access.get(target, "value"), "some default value");
+
+        access.set(target, "retainedValue", "some retained value");
+        assertEquals(access.get(target, "retainedValue"), "some retained value");
+
+        // Setting a property value before pageDidLoad will cause that value
+        // to be the default when the page detaches.
+
+        target.containingPageDidLoad();
+
+        access.set(target, "value", "some transient value");
+        assertEquals(access.get(target, "value"), "some transient value");
+
+        target.containingPageDidDetach();
+
+        assertEquals(access.get(target, "value"), "some default value");
+        assertEquals(access.get(target, "retainedValue"), "some retained value");
+    }
+
+    @Test
+    public void load_sub_component_via_service() throws Exception
+    {
+        Component target = createComponent(BasicSubComponent.class);
+
+        target.containingPageDidLoad();
+
+        access.set(target, "value", "base class");
+        assertEquals(access.get(target, "value"), "base class");
+
+        access.set(target, "intValue", 33);
+        assertEquals(access.get(target, "intValue"), 33);
+
+        target.containingPageDidDetach();
+
+        assertNull(access.get(target, "value"));
+        assertEquals(access.get(target, "intValue"), 0);
+    }
+
+    /**
+     * This allows tests the exists() method.
+     */
+    @Test
+    public void component_class_reload() throws Exception
+    {
+        // Ensure it doesn't already exist:
+
+        assertFalse(source.exists(SYNTH_COMPONENT_CLASSNAME));
+
+        // Create the class on the fly.
+
+        createSynthComponentClass("Original");
+
+        assertTrue(source.exists(SYNTH_COMPONENT_CLASSNAME));
+
+        Named named = (Named) createComponent(SYNTH_COMPONENT_CLASSNAME);
+
+        assertEquals(named.getName(), "Original");
+
+        String path = tempDir + "/" + SYNTH_COMPONENT_CLASSNAME.replace('.', '/') + ".class";
+        URL url = new File(path).toURL();
+
+        long dtm = readDTM(url);
+
+        while (true)
+        {
+            if (readDTM(url) != dtm) break;
+
+            // Keep re-writing the file until we see the DTM change.
+
+            createSynthComponentClass("Updated");
+        }
+
+        // Detect the change and clear out the internal caches
+
+        UpdateListenerHub hub = registry.getService("UpdateListenerHub", UpdateListenerHub.class);
+
+        hub.fireUpdateEvent();
+
+        // This will be the new version of the class
+
+        named = (Named) createComponent(SYNTH_COMPONENT_CLASSNAME);
+
+        assertEquals(named.getName(), "Updated");
+    }
+
+    private long readDTM(URL url) throws Exception
+    {
+        URLConnection connection = url.openConnection();
+
+        connection.connect();
+
+        return connection.getLastModified();
+    }
+
+    private void createSynthComponentClass(String name) throws CannotCompileException, NotFoundException, IOException
+    {
+        ClassPool pool = new ClassPool();
+        // Inside Maven Surefire, the system classpath is not sufficient to find all
+        // the necessary files.
+        pool.appendClassPath(new LoaderClassPath(extraLoader));
+
+        CtClass ctClass = pool.makeClass(SYNTH_COMPONENT_CLASSNAME);
+
+        ctClass.setSuperclass(pool.get(BasicComponent.class.getName()));
+
+        // Implement method getName()
+
+        CtMethod method = CtNewMethod.make("public String getName() { return \"" + name + "\"; }", ctClass);
+        ctClass.addMethod(method);
+
+        ctClass.addInterface(pool.get(Named.class.getName()));
+
+        ctClass.writeFile(extraClasspath.getAbsolutePath());
+    }
+
+    private Component createComponent(Class componentClass)
+    {
+        String classname = componentClass.getName();
+
+        return createComponent(classname);
+    }
+
+    private Component createComponent(String classname)
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        replay();
+
+        Instantiator inst = source.findInstantiator(classname);
+
+        Component target = inst.newInstance(resources);
+
+        verify();
+
+        return target;
+    }
+
+    @BeforeClass
+    public void setup_tests() throws Exception
+    {
+        String tempdir = System.getProperty("java.io.tmpdir");
+        String uid = UUID.randomUUID().toString();
+
+        tempDir = tempdir + "/tapestry-test-classpath/" + uid;
+        extraClasspath = new File(tempDir);
+
+        System.out.println("Creating dir: " + extraClasspath);
+
+        extraClasspath.mkdirs();
+
+        URL url = extraClasspath.toURL();
+
+        extraLoader = new URLClassLoader(new URL[] { url }, contextLoader);
+        RegistryBuilder builder = new RegistryBuilder(extraLoader);
+
+        builder.add(TapestryModule.class);
+
+        SymbolProvider provider = new SingleKeySymbolProvider(InternalConstants.TAPESTRY_ALIAS_MODE_SYMBOL, "servlet");
+        ContributionDef contribution = new SyntheticSymbolSourceContributionDef("AliasMode", provider,
+                                                                                "before:ApplicationDefaults");
+
+        ModuleDef module = new SyntheticModuleDef(contribution);
+
+        builder.add(module);
+
+        registry = builder.build();
+
+        // registry.getService("Alias", Alias.class).setMode("servlet");
+
+        source = registry.getService(ComponentInstantiatorSource.class);
+        access = registry.getService(PropertyAccess.class);
+
+        source.addPackage("org.apache.tapestry.internal.transform.pages");
+    }
+
+    @AfterClass
+    public void cleanup_tests()
+    {
+        registry.shutdown();
+
+        registry = null;
+        source = null;
+        access = null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInvocationTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInvocationTest.java
new file mode 100644
index 0000000..77c8fb0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInvocationTest.java
@@ -0,0 +1,50 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class ComponentInvocationTest extends Assert
+{
+    @Test
+    public void no_context()
+    {
+        ComponentInvocation invocation = new ComponentInvocationImpl(new OpaqueConstantTarget("abc"), new String[0],
+                                                                     null);
+        assertEquals(invocation.buildURI(false), "abc");
+        assertEquals(invocation.buildURI(true), "abc");
+    }
+
+    @Test
+    public void context()
+    {
+        ComponentInvocation invocation = new ComponentInvocationImpl(new OpaqueConstantTarget("abc"),
+                                                                     new String[]{"x", "123"}, null);
+        assertEquals(invocation.buildURI(false), "abc/x/123");
+        assertEquals(invocation.buildURI(true), "abc/x/123");
+    }
+
+    @Test
+    public void parameters()
+    {
+        ComponentInvocation invocation = new ComponentInvocationImpl(new OpaqueConstantTarget("abc"),
+                                                                     new String[]{"x", "123"}, null);
+        invocation.addParameter("p1", "foo");
+        invocation.addParameter("p2", "bar");
+        assertEquals(invocation.buildURI(false), "abc/x/123?p1=foo&p2=bar");
+        assertEquals(invocation.buildURI(true), "abc/x/123");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImplTest.java
new file mode 100644
index 0000000..9e797e3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentMessagesSourceImplTest.java
@@ -0,0 +1,219 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+/**
+ * Tests {@link ComponentMessagesSourceImpl} as well as {@link MessagesSourceImpl} (which contains code refactored out
+ * of CMSI).
+ */
+@Test(sequential = true)
+public class ComponentMessagesSourceImplTest extends InternalBaseTestCase
+{
+    // With control of the tracker, we can force changes as if underlying files were changed.
+
+    private static final String SIMPLE_COMPONENT_CLASS_NAME = "org.apache.tapestry.internal.services.SimpleComponent";
+
+    private final URLChangeTracker tracker = new URLChangeTracker();
+
+    private final Resource simpleComponentResource = new ClasspathResource(
+            "org/apache/tapestry/internal/services/SimpleComponent.class");
+
+    private final ComponentMessagesSourceImpl source = new ComponentMessagesSourceImpl(
+            simpleComponentResource, "AppCatalog.properties", tracker);
+
+    @Test
+    public void simple_component()
+    {
+        ComponentModel model = mockComponentModel();
+
+        train_getComponentClassName(model, SIMPLE_COMPONENT_CLASS_NAME);
+
+        train_getBaseResource(model, simpleComponentResource);
+
+        train_getParentModel(model, null);
+
+        replay();
+
+        forceCacheClear();
+
+        Messages messages = source.getMessages(model, Locale.ENGLISH);
+
+        assertEquals(messages.get("color"), "color");
+        assertEquals(messages.get("framework"), "Tapestry");
+
+        // Check normal caching
+
+        assertSame(source.getMessages(model, Locale.ENGLISH), messages);
+
+        // Now, force a cache clear and retry.
+
+        forceCacheClear();
+
+        Messages messages2 = source.getMessages(model, Locale.ENGLISH);
+
+        // Check that a new Messages was created
+
+        assertNotSame(messages2, messages);
+
+        assertEquals(messages2.get("color"), "color");
+        assertEquals(messages2.get("framework"), "Tapestry");
+
+        verify();
+    }
+
+    private void forceCacheClear()
+    {
+        tracker.forceChange();
+        source.checkForUpdates();
+    }
+
+    @Test
+    public void per_language_messages_override()
+    {
+        ComponentModel model = mockComponentModel();
+
+        train_getComponentClassName(model, SIMPLE_COMPONENT_CLASS_NAME);
+
+        train_getBaseResource(model, simpleComponentResource);
+
+        train_getParentModel(model, null);
+
+        replay();
+
+        forceCacheClear();
+
+        Messages messages = source.getMessages(model, Locale.UK);
+
+        assertEquals(messages.get("color"), "colour");
+        assertEquals(messages.get("framework"), "Tapestry");
+
+        verify();
+    }
+
+    @Test
+    public void messages_keys_are_case_insensitive()
+    {
+        ComponentModel model = mockComponentModel();
+
+        train_getComponentClassName(model, SIMPLE_COMPONENT_CLASS_NAME);
+
+        train_getBaseResource(model, simpleComponentResource);
+
+        train_getParentModel(model, null);
+
+        replay();
+
+        forceCacheClear();
+
+        Messages messages = source.getMessages(model, Locale.UK);
+
+        assertEquals(messages.get("COlor"), "colour");
+        assertEquals(messages.get("Framework"), "Tapestry");
+
+        verify();
+    }
+
+    @Test
+    public void subclass_inherits_base_class_messages()
+    {
+        ComponentModel model = mockComponentModel();
+        ComponentModel parent = mockComponentModel();
+
+        train_getComponentClassName(
+                model,
+                "org.apache.tapestry.internal.services.SubclassComponent");
+
+        train_getBaseResource(model, new ClasspathResource(
+                "org/apache/tapestry/internal/services/SubclassComponent.class"));
+
+        train_getParentModel(model, parent);
+
+        train_getComponentClassName(parent, SIMPLE_COMPONENT_CLASS_NAME);
+
+        train_getBaseResource(parent, simpleComponentResource);
+
+        train_getParentModel(parent, null);
+
+        replay();
+
+        forceCacheClear();
+
+        Messages messages = source.getMessages(model, Locale.ENGLISH);
+
+        assertEquals(messages.get("color"), "color");
+        assertEquals(messages.get("framework"), "Tapestry");
+        assertEquals(messages.get("source"), "SubclassComponent");
+        assertEquals(messages.get("metal"), "steel");
+        assertEquals(messages.get("app-catalog-source"), "AppCatalog");
+        assertEquals(messages.get("app-catalog-overridden"), "Overridden by Component");
+
+        messages = source.getMessages(model, Locale.UK);
+
+        assertEquals(messages.get("color"), "colour");
+        assertEquals(messages.get("framework"), "Tapestry");
+        assertEquals(messages.get("source"), "SubclassComponent");
+        assertEquals(messages.get("metal"), "aluminium");
+
+        verify();
+    }
+
+    @Test
+    public void no_app_catalog()
+    {
+        ComponentModel model = mockComponentModel();
+        ComponentModel parent = mockComponentModel();
+
+        train_getComponentClassName(
+                model,
+                "org.apache.tapestry.internal.services.SubclassComponent");
+
+        train_getBaseResource(model, new ClasspathResource(
+                "org/apache/tapestry/internal/services/SubclassComponent.class"));
+
+        train_getParentModel(model, parent);
+
+        train_getComponentClassName(parent, SIMPLE_COMPONENT_CLASS_NAME);
+
+        train_getBaseResource(parent, simpleComponentResource);
+
+        train_getParentModel(parent, null);
+
+        replay();
+
+        forceCacheClear();
+
+        ComponentMessagesSource source = new ComponentMessagesSourceImpl(simpleComponentResource,
+                                                                         "NoSuchAppCatalog.properties");
+
+        Messages messages = source.getMessages(model, Locale.ENGLISH);
+
+        assertEquals(messages.get("color"), "color");
+        assertEquals(messages.get("app-catalog-source"), "[[missing key: app-catalog-source]]");
+        assertEquals(messages.get("app-catalog-overridden"), "Overridden by Component");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
new file mode 100644
index 0000000..abdbf43
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
@@ -0,0 +1,97 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+import org.testng.annotations.Test;
+
+public class ComponentSourceImplTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "Bar";
+
+    private static final String NESTED_ELEMENT_ID = "zip.zoom";
+
+    @Test
+    public void root_element_of_page()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        Component component = mockComponent();
+
+        train_get(cache, PAGE_NAME, page);
+
+        train_getRootComponent(page, component);
+
+        replay();
+
+        ComponentSource source = new ComponentSourceImpl(cache);
+
+        assertSame(source.getComponent(PAGE_NAME), component);
+
+        verify();
+    }
+
+    @Test
+    public void nested_element_within_page()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ComponentPageElement element = mockComponentPageElement();
+        Component component = mockComponent();
+
+        train_get(cache, PAGE_NAME, page);
+
+        train_getComponentElementByNestedId(page, NESTED_ELEMENT_ID, element);
+
+        train_getComponent(element, component);
+
+        replay();
+
+        ComponentSource source = new ComponentSourceImpl(cache);
+
+        assertSame(source.getComponent(PAGE_NAME + ":" + NESTED_ELEMENT_ID), component);
+
+        verify();
+    }
+
+    @Test
+    public void get_page_by_logical_name()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        Component component = mockComponent();
+
+        train_get(cache, PAGE_NAME, page);
+        train_getRootComponent(page, component);
+
+        replay();
+
+        ComponentSource source = new ComponentSourceImpl(cache);
+
+        assertSame(source.getPage(PAGE_NAME), component);
+
+        verify();
+    }
+
+    @Test
+    public void get_page_by_class()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java
new file mode 100644
index 0000000..6872a9f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java
@@ -0,0 +1,313 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.model.ComponentModel;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Locale;
+import java.util.UUID;
+
+public class ComponentTemplateSourceImplTest extends InternalBaseTestCase
+{
+    private static final String PACKAGE = "org.apache.tapestry.internal.pageload";
+
+    static public final String PATH = "org/apache/tapestry/internal/pageload";
+
+    private final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+    /**
+     * Creates a new class loader, whose parent is the thread's context class loader, but adds a single classpath root
+     * from the filesystem.
+     *
+     * @see #createClasspathRoot()
+     */
+    protected final URLClassLoader newLoaderWithClasspathRoot(File rootDir)
+            throws MalformedURLException
+    {
+        String urlPath = rootDir.toURL().toString();
+        // URLs for folders must end with a slash to make URLClassLoader happy.
+        URL url = new URL(urlPath + "/");
+
+        return new URLClassLoader(new URL[]
+                { url }, loader);
+    }
+
+    /**
+     * Creates a new temporary directory which can act as a classpath root.
+     *
+     * @see #newLoaderWithClasspathRoot(File)
+     */
+    protected final File createClasspathRoot()
+    {
+        String temp = System.getProperty("java.io.tmpdir");
+        String rootDirPath = temp + "/" + UUID.randomUUID().toString();
+
+        return new File(rootDirPath);
+    }
+
+    @Test
+    public void caching()
+    {
+        Resource baseResource = newResource("Fred.class");
+
+        TemplateParser parser = mockTemplateParser();
+        ComponentTemplate template = mockComponentTemplate();
+        ComponentModel model = mockComponentModel();
+
+        train_getComponentClassName(model, PACKAGE + ".Fred");
+
+        train_getBaseResource(model, baseResource);
+
+        train_parseTemplate(parser, baseResource
+                .withExtension(InternalConstants.TEMPLATE_EXTENSION), template);
+
+        replay();
+
+        ComponentTemplateSource source = new ComponentTemplateSourceImpl(parser, null);
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        // A second pass will test the caching (the
+        // parser is not invoked).
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        verify();
+    }
+
+    /**
+     * Tests resource invalidation.
+     */
+    @Test
+    public void invalidation() throws Exception
+    {
+        File rootDir = createClasspathRoot();
+        URLClassLoader loader = newLoaderWithClasspathRoot(rootDir);
+        ComponentModel model = mockComponentModel();
+
+        File packageDir = new File(rootDir, "baz");
+        packageDir.mkdirs();
+
+        File f = new File(packageDir, "Biff.tml");
+
+        f.createNewFile();
+
+        Resource baseResource = new ClasspathResource(loader, "baz/Biff.class");
+        Resource localized = baseResource.withExtension(InternalConstants.TEMPLATE_EXTENSION);
+
+        TemplateParser parser = mockTemplateParser();
+        ComponentTemplate template = mockComponentTemplate();
+        InvalidationListener listener = mockInvalidationListener();
+
+        train_getComponentClassName(model, "baz.Biff");
+
+        train_getBaseResource(model, baseResource);
+
+        train_parseTemplate(parser, localized, template);
+
+        replay();
+
+        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, null);
+        source.addInvalidationListener(listener);
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        // Check for updates (which won't be found).
+        source.checkForUpdates();
+
+        // A second pass will test the caching (the
+        // parser is not invoked).
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        verify();
+
+        // Now, change the file and process an UpdateEvent.
+
+        touch(f);
+
+        listener.objectWasInvalidated();
+
+        replay();
+
+        // Check for updates (which will be found).
+        source.checkForUpdates();
+
+        verify();
+
+        // Check that the cache really is cleared.
+
+        train_getComponentClassName(model, "baz.Biff");
+
+        train_getBaseResource(model, baseResource);
+
+        train_parseTemplate(parser, localized, template);
+
+        replay();
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        verify();
+    }
+
+    /**
+     * Checks that localization to the same resource works (w/ caching).
+     */
+    @Test
+    public void localization_to_same()
+    {
+        Resource baseResource = newResource("Fred.class");
+
+        TemplateParser parser = mockTemplateParser();
+        ComponentTemplate template = mockComponentTemplate();
+        ComponentModel model = mockComponentModel();
+
+        train_getComponentClassName(model, PACKAGE + ".Fred");
+
+        train_getBaseResource(model, baseResource);
+
+        train_parseTemplate(parser, baseResource
+                .withExtension(InternalConstants.TEMPLATE_EXTENSION), template);
+
+        replay();
+
+        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, null);
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        // A second pass finds the same resource, but using a different
+        // path/locale combination.
+
+        assertSame(source.getTemplate(model, Locale.FRENCH), template);
+
+        // A third pass should further demonstrate the caching.
+
+        assertSame(source.getTemplate(model, Locale.FRENCH), template);
+
+        verify();
+    }
+
+    @Test
+    public void page_template_found_in_context()
+    {
+        Resource baseResource = newResource("NotInClasspath.class");
+
+        // Simpler to do it this way ...
+
+        Resource contextTemplateResource = newResource("Fred.tml");
+
+        TemplateParser parser = mockTemplateParser();
+        ComponentTemplate template = mockComponentTemplate();
+        ComponentModel model = mockComponentModel();
+        PageTemplateLocator locator = mockPageTemplateLocator();
+        Locale locale = Locale.FRENCH;
+
+        train_getComponentClassName(model, PACKAGE + ".NotInClasspath");
+
+        train_getBaseResource(model, baseResource);
+
+        train_findPageTemplateResource(locator, model, locale, contextTemplateResource);
+
+        train_parseTemplate(parser, contextTemplateResource, template);
+
+        replay();
+
+        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, locator);
+
+        assertSame(source.getTemplate(model, locale), template);
+
+        verify();
+    }
+
+    @Test
+    public void no_template_found()
+    {
+        TemplateParser parser = mockTemplateParser();
+        ComponentModel model = mockComponentModel();
+        PageTemplateLocator locator = mockPageTemplateLocator();
+
+        Resource baseResource = newResource("Barney.class");
+
+        train_getComponentClassName(model, PACKAGE + ".Barney");
+
+        train_getBaseResource(model, baseResource);
+
+        train_findPageTemplateResource(locator, model, Locale.ENGLISH, null);
+
+        train_getParentModel(model, null);
+
+        replay();
+
+        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, locator);
+
+        ComponentTemplate template = source.getTemplate(model, Locale.ENGLISH);
+
+        assertTrue(template.isMissing());
+
+        verify();
+    }
+
+    @Test
+    public void child_component_inherits_parent_template()
+    {
+        Resource baseFred = newResource("Fred.class");
+        Resource baseBarney = baseFred.forFile("Barney.class");
+        PageTemplateLocator locator = mockPageTemplateLocator();
+
+        TemplateParser parser = mockTemplateParser();
+        ComponentTemplate template = mockComponentTemplate();
+        ComponentModel model = mockComponentModel();
+        ComponentModel parentModel = mockComponentModel();
+
+        train_getComponentClassName(model, PACKAGE + ".Barney");
+
+        train_getBaseResource(model, baseBarney);
+
+        train_findPageTemplateResource(locator, model, Locale.ENGLISH, null);
+
+        train_getParentModel(model, parentModel);
+
+        train_getBaseResource(parentModel, baseFred);
+
+        train_parseTemplate(
+                parser,
+                baseFred.withExtension(InternalConstants.TEMPLATE_EXTENSION),
+                template);
+
+        replay();
+
+        ComponentTemplateSource source = new ComponentTemplateSourceImpl(parser, locator);
+
+        assertSame(source.getTemplate(model, Locale.ENGLISH), template);
+
+        verify();
+    }
+
+    private Resource newResource(String name)
+    {
+        return new ClasspathResource(loader, PATH + "/" + name);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CompositeBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CompositeBean.java
new file mode 100644
index 0000000..b2d6e49
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CompositeBean.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class CompositeBean
+{
+    private SimpleBean simple = new SimpleBean();
+
+    public SimpleBean getSimple()
+    {
+        return simple;
+    }
+
+    public void setSimple(SimpleBean simple)
+    {
+        this.simple = simple;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextAssetFactoryTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextAssetFactoryTest.java
new file mode 100644
index 0000000..57e0f07
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextAssetFactoryTest.java
@@ -0,0 +1,74 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.services.AssetFactory;
+import org.apache.tapestry.services.Context;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.Test;
+
+public class ContextAssetFactoryTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void root_resource()
+    {
+        Context context = mockContext();
+        Request request = mockRequest();
+
+        replay();
+
+        AssetFactory factory = new ContextAssetFactory(request, context, null);
+
+        assertEquals(factory.getRootResource().toString(), "context:/");
+
+        verify();
+    }
+
+    @Test
+    public void asset_client_URL()
+    {
+        Context context = mockContext();
+        Request request = mockRequest();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+
+        Resource r = new ContextResource(context, "foo/Bar.txt");
+
+        train_getContextPath(request, "/context");
+
+        train_optimizePath(optimizer, "/context/foo/Bar.txt", "/opt/path1");
+        train_optimizePath(optimizer, "/context/foo/Bar.txt", "/opt/path2");
+
+        replay();
+
+        AssetFactory factory = new ContextAssetFactory(request, context, optimizer);
+
+        Asset asset = factory.createAsset(r);
+
+        assertSame(asset.getResource(), r);
+        assertEquals(asset.toClientURL(), "/opt/path1");
+
+        // In real life, toString() is the same as toClientURL(), but we're testing
+        // that the optimize method is getting called, basically.
+
+        assertEquals(asset.toString(), "/opt/path2");
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java
new file mode 100644
index 0000000..5a6be29
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextImplTest.java
@@ -0,0 +1,193 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.Context;
+import org.testng.annotations.Test;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+public class ContextImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void get_resource_exists() throws Exception
+    {
+        String path = "/foo";
+        URL url = getClass().getResource("ContextImplTest.class");
+
+        ServletContext servletContext = newServletContext();
+
+        expect(servletContext.getResource(path)).andReturn(url);
+
+        replay();
+
+        URL result = new ContextImpl(servletContext).getResource(path);
+
+        assertSame(result, url);
+
+        verify();
+    }
+
+    @Test
+    public void get_resource_exception() throws Exception
+    {
+        String path = "/foo";
+        Throwable t = new MalformedURLException("/foo is not a URL.");
+
+        ServletContext servletContext = newServletContext();
+
+        expect(servletContext.getResource(path)).andThrow(t);
+
+        replay();
+
+        try
+        {
+            new ContextImpl(servletContext).getResource(path);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "java.net.MalformedURLException: /foo is not a URL.");
+            assertSame(ex.getCause(), t);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_resource_paths() throws Exception
+    {
+        ServletContext servletContext = newServletContext();
+
+        train_getResourcePaths(servletContext, "/foo", "/foo/alpha.tml", "/foo/beta/", "/foo/gamma.tml");
+        train_getResourcePaths(servletContext, "/foo/beta/", "/foo/beta/b.tml", "/foo/beta/a.tml", "/foo/beta/c/");
+        train_getResourcePaths(servletContext, "/foo/beta/c/", "/foo/beta/c/c.tml");
+
+        replay();
+
+        List<String> actual = new ContextImpl(servletContext).getResourcePaths("/foo");
+
+        assertEquals(actual, Arrays.asList("/foo/alpha.tml", "/foo/beta/a.tml", "/foo/beta/b.tml", "/foo/beta/c/c.tml",
+                                           "/foo/gamma.tml"));
+
+        verify();
+    }
+
+    @Test
+    public void get_attribute()
+    {
+        String name = "foo";
+        Object value = new Object();
+
+        ServletContext servletContext = newServletContext();
+
+        expect(servletContext.getAttribute(name)).andReturn(value);
+
+        replay();
+
+        Context context = new ContextImpl(servletContext);
+
+        assertSame(context.getAttribute(name), value);
+
+        verify();
+    }
+
+    /**
+     * Tomcat 5.5.20 appears to sometimes return null if it can't find a match.
+     */
+    @Test
+    public void ignore_null_from_get_resource_paths() throws Exception
+    {
+        ServletContext servletContext = newServletContext();
+
+        expect(servletContext.getResourcePaths("/foo")).andReturn(null);
+
+        replay();
+
+        List<String> actual = new ContextImpl(servletContext).getResourcePaths("/foo");
+
+        assertTrue(actual.isEmpty());
+
+        verify();
+
+    }
+
+    @Test
+    public void get_real_file_exists() throws IOException
+    {
+        String path = "/foo.gif";
+        File file = File.createTempFile("foo", "gif");
+        String realPath = file.getPath();
+
+        ServletContext servletContext = newServletContext();
+
+        train_getRealPath(servletContext, path, realPath);
+
+        replay();
+
+        Context c = new ContextImpl(servletContext);
+
+        File f = c.getRealFile(path);
+
+        assertEquals(f, file);
+
+
+        verify();
+    }
+
+    @Test
+    public void get_real_file_missing()
+    {
+        String path = "/foo.gif";
+
+        ServletContext servletContext = newServletContext();
+
+        train_getRealPath(servletContext, path, null);
+
+        replay();
+
+        Context c = new ContextImpl(servletContext);
+
+        assertNull(c.getRealFile(path));
+
+        verify();
+    }
+
+    private void train_getRealPath(ServletContext servletContext, String path, String realPath)
+    {
+        expect(servletContext.getRealPath(path)).andReturn(realPath);
+    }
+
+    protected final ServletContext newServletContext()
+    {
+        return newMock(ServletContext.class);
+    }
+
+    protected final void train_getResourcePaths(ServletContext context, String path, String... paths)
+    {
+        Set<String> set = CollectionFactory.newSet(Arrays.asList(paths));
+
+        expect(context.getResourcePaths(path)).andReturn(set);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextResourceTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextResourceTest.java
new file mode 100644
index 0000000..d6ee715
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextResourceTest.java
@@ -0,0 +1,127 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.services.Context;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.net.URL;
+
+public class ContextResourceTest extends InternalBaseTestCase
+{
+    @Test
+    public void get_url_no_real_file() throws Exception
+    {
+        String path = "/foo/Bar.txt";
+        URL url = getClass().getResource("ContextResourceTest.class");
+
+        Context context = mockContext();
+
+        expect(context.getRealFile(path)).andReturn(null);
+
+        expect(context.getResource("/foo/Bar.txt")).andReturn(url);
+
+        replay();
+
+        Resource r = new ContextResource(context, "foo/Bar.txt");
+
+        assertSame(r.toURL(), url);
+
+        verify();
+    }
+
+    @Test
+    public void get_url_file_exists() throws Exception
+    {
+        File f = File.createTempFile("Bar", ".txt");
+
+        String path = "/foo/Bar.txt";
+
+        Context context = mockContext();
+
+        expect(context.getRealFile(path)).andReturn(f);
+
+        replay();
+
+        Resource r = new ContextResource(context, "foo/Bar.txt");
+
+        assertEquals(r.toURL(), f.toURL());
+
+        verify();
+    }
+
+    @Test
+    public void to_string()
+    {
+        Context context = mockContext();
+
+        replay();
+
+        Resource r = new ContextResource(context, "foo/Bar.txt");
+
+        assertEquals(r.toString(), "context:foo/Bar.txt");
+
+        verify();
+    }
+
+    @Test
+    public void hash_code()
+    {
+        Context context1 = mockContext();
+        Context context2 = mockContext();
+
+        replay();
+
+        Resource r1 = new ContextResource(context1, "foo");
+        Resource r2 = new ContextResource(context1, "foo");
+        Resource r3 = new ContextResource(context2, "foo");
+        Resource r4 = new ContextResource(context1, "bar");
+
+        assertTrue(r1.hashCode() == r2.hashCode());
+        assertFalse(r1.hashCode() == r3.hashCode());
+        assertFalse(r1.hashCode() == r4.hashCode());
+
+        verify();
+    }
+
+    @Test
+    public void equals()
+    {
+        Context context1 = mockContext();
+        Context context2 = mockContext();
+        Resource r = mockResource();
+
+        replay();
+
+        Resource r1 = new ContextResource(context1, "foo");
+        Resource r2 = new ContextResource(context1, "foo");
+        Resource r3 = new ContextResource(context2, "foo");
+        Resource r4 = new ContextResource(context1, "bar");
+
+        assertTrue(r1.equals(r2));
+        assertFalse(r1.equals(r3));
+        assertFalse(r1.equals(r4));
+
+        assertFalse(r1.equals(null));
+        assertTrue(r1.equals(r1));
+
+        assertFalse(r1.equals(r));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java
new file mode 100644
index 0000000..8152777
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java
@@ -0,0 +1,70 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.ValueEncoderSource;
+import org.testng.annotations.Test;
+
+public class ContextValueEncoderImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void to_client()
+    {
+        ValueEncoder valueEncoder = mockValueEncoder();
+        ValueEncoderSource source = mockValueEncoderSource();
+
+        Long value = 23L;
+        String encoded = "twentythree";
+
+
+        train_getValueEncoder(source, Long.class, valueEncoder);
+        train_toClient(valueEncoder, value, encoded);
+
+        replay();
+
+        ContextValueEncoder cve = new ContextValueEncoderImpl(source);
+
+        assertSame(cve.toClient(value), encoded);
+
+        verify();
+    }
+
+
+    @Test
+    public void to_value()
+    {
+        ValueEncoder valueEncoder = mockValueEncoder();
+        ValueEncoderSource source = mockValueEncoderSource();
+
+        Long value = 23L;
+        String clientValue = "twentythree";
+
+
+        train_getValueEncoder(source, Long.class, valueEncoder);
+        train_toValue(valueEncoder, clientValue, value);
+
+        replay();
+
+        ContextValueEncoder cve = new ContextValueEncoderImpl(source);
+
+        assertSame(cve.toValue(Long.class, clientValue), value);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CookiesImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CookiesImplTest.java
new file mode 100644
index 0000000..50e3750
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/CookiesImplTest.java
@@ -0,0 +1,170 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.TestableRequestImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.Cookie;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link org.apache.tapestry.services.impl.CookiesImpl}.
+ */
+@Test
+public class CookiesImplTest extends Assert
+{
+    private static class ComparableCookie extends Cookie
+    {
+        public ComparableCookie(String name, String value, int maxAge)
+        {
+            super(name, value);
+            setMaxAge(maxAge);
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            Cookie c = (Cookie) obj;
+
+            return equals(getName(), c.getName()) && equals(getValue(), c.getValue()) && equals(getPath(),
+                                                                                                c.getPath()) && getMaxAge() == c.getMaxAge();
+        }
+
+        private boolean equals(Object value, Object other)
+        {
+            return value == other || (value != null && value.equals(other));
+        }
+    }
+
+    private CookieSource newCookieSource(final String[] nameValues)
+    {
+        return new CookieSource()
+        {
+            public Cookie[] getCookies()
+            {
+
+                Cookie[] cookies = null;
+
+                if (nameValues != null)
+                {
+
+                    List<Cookie> l = new ArrayList<Cookie>();
+
+                    for (int i = 0; i < nameValues.length; i += 2)
+                    {
+                        String name = nameValues[i];
+                        String value = nameValues[i + 1];
+
+                        Cookie c = new Cookie(name, value);
+
+                        l.add(c);
+                    }
+
+                    cookies = l.toArray(new Cookie[l.size()]);
+                }
+                return cookies;
+            }
+        };
+    }
+
+    private void attempt(String name, String expected, String[] nameValues)
+    {
+        // In seconds
+        final int ONE_WEEK = 7 * 24 * 60 * 60;
+        CookiesImpl cs = new CookiesImpl(null, newCookieSource(nameValues), null, ONE_WEEK);
+        String actual = cs.readCookieValue(name);
+        assertEquals(actual, expected);
+    }
+
+    public void test_No_Cookies()
+    {
+        attempt("foo", null, null);
+    }
+
+    public void test_Match()
+    {
+        attempt("fred", "flintstone", new String[]{"barney", "rubble", "fred", "flintstone"});
+    }
+
+    public void test_No_Match()
+    {
+        attempt("foo", null, new String[]{"bar", "baz"});
+    }
+
+    public void test_Write_Cookie_Domain()
+    {
+        List<Cookie> cookies = CollectionFactory.newList();
+        CookiesImpl cs = createCookiesFixture("/context", cookies);
+
+        cs.writeDomainCookieValue("foo", "bar", "fobar.com", 1234);
+        Cookie expectedCookie = new ComparableCookie("foo", "bar", 1234);
+        expectedCookie.setPath("/context/");
+        expectedCookie.setDomain("fobar.com");
+        assertEquals(cookies.size(), 1);
+        assertEquals(cookies.get(0), expectedCookie);
+    }
+
+    private CookiesImpl createCookiesFixture(String contextPath, final List<Cookie> cookies)
+    {
+        return new CookiesImpl(new TestableRequestImpl(contextPath), null, new CookieSink()
+        {
+            public void addCookie(Cookie cookie)
+            {
+                cookies.add(cookie);
+            }
+
+        }, 1000l * 1000l);
+    }
+
+    public void test_Write_Cookie_With_Max_Age()
+    {
+        final List<Cookie> cookies = CollectionFactory.newList();
+        CookiesImpl cs = createCookiesFixture("/ctx", cookies);
+
+        cs.writeCookieValue("foo", "bar", -1);
+        Cookie expectedCookie = new ComparableCookie("foo", "bar", -1);
+        expectedCookie.setPath("/ctx/");
+        assertEquals(cookies.size(), 1);
+        assertEquals(cookies.get(0), expectedCookie);
+    }
+
+    public void test_Write_Cookie()
+    {
+        final List<Cookie> cookies = CollectionFactory.newList();
+        CookiesImpl cs = createCookiesFixture("/ctx", cookies);
+
+        cs.writeCookieValue("foo", "bar");
+        Cookie expectedCookie = new ComparableCookie("foo", "bar", 1000);
+        expectedCookie.setPath("/ctx/");
+        assertEquals(cookies.size(), 1);
+        assertEquals(cookies.get(0), expectedCookie);
+    }
+
+    public void test_Remove_Cookie()
+    {
+        final List<Cookie> cookies = CollectionFactory.newList();
+        CookiesImpl cs = createCookiesFixture("/ctx", cookies);
+
+        cs.removeCookieValue("foo");
+        Cookie expectedCookie = new ComparableCookie("foo", null, 0);
+        expectedCookie.setPath("/ctx/");
+        assertEquals(cookies.size(), 1);
+        assertEquals(cookies.get(0), expectedCookie);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java
new file mode 100644
index 0000000..cd9e8a4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DefaultInjectionProviderTest.java
@@ -0,0 +1,72 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.services.MasterObjectProvider;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.Request;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.testng.annotations.Test;
+
+public class DefaultInjectionProviderTest extends InternalBaseTestCase
+{
+    @Test
+    public void object_found()
+    {
+        MasterObjectProvider master = mockMasterObjectProvider();
+        ObjectLocator locator = mockObjectLocator();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        Request injected = mockRequest();
+
+        expect(master.provide(eq(Request.class), isA(AnnotationProvider.class), eq(locator), eq(false))).andReturn(
+                injected);
+
+        ct.injectField("myfield", injected);
+
+        replay();
+
+        DefaultInjectionProvider provider = new DefaultInjectionProvider(master, locator);
+
+        assertTrue(provider.provideInjection("myfield", Request.class, locator, ct, model));
+
+        verify();
+    }
+
+    @Test
+    public void object_not_found()
+    {
+        MasterObjectProvider master = mockMasterObjectProvider();
+        ObjectLocator locator = mockObjectLocator();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        expect(master.provide(eq(Request.class), isA(AnnotationProvider.class), eq(locator), eq(false))).andReturn(
+                null);
+
+        replay();
+
+        DefaultInjectionProvider provider = new DefaultInjectionProvider(master, locator);
+
+        assertFalse(provider.provideInjection("myfield", Request.class, locator, ct, model));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DocumentLinkerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DocumentLinkerImplTest.java
new file mode 100644
index 0000000..e6126ea
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/DocumentLinkerImplTest.java
@@ -0,0 +1,189 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class DocumentLinkerImplTest extends InternalBaseTestCase
+{
+    private void check(Document document, String file) throws Exception
+    {
+        assertEquals(document.toString(), readFile(file));
+    }
+
+    @Test
+    public void do_nothing_if_no_body()
+    {
+        Document document = new Document();
+
+        document.newRootElement("not-html").text("not an HTML document");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addScript("foo.js");
+        linker.addScript("doSomething();");
+
+        linker.updateDocument(document);
+
+        assertEquals(document.toString(), "<not-html>not an HTML document</not-html>");
+    }
+
+    @Test
+    public void add_script_links() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addScriptLink("foo.js");
+        linker.addScriptLink("bar/baz.js");
+
+        linker.updateDocument(document);
+
+        check(document, "add_script_links.txt");
+    }
+
+    @Test
+    public void add_style_links() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with styles.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addStylesheetLink("foo.css", null);
+        linker.addStylesheetLink("bar/baz.css", "print");
+
+        linker.updateDocument(document);
+
+        check(document, "add_style_links.txt");
+    }
+
+    @Test
+    public void duplicate_scripts_ignored_first_media_wins() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with styles.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addStylesheetLink("foo.css", null);
+        linker.addStylesheetLink("bar/baz.css", "print");
+        linker.addStylesheetLink("foo.css", "implant");
+        linker.addStylesheetLink("bar/baz.css", null);
+        linker.addStylesheetLink("bar/baz.css", "duplicate");
+
+        linker.updateDocument(document);
+
+        check(document, "duplicate_scripts_ignored_first_media_wins.txt");
+    }
+
+    @Test
+    public void existing_head_used_if_present() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("head").comment("existing head").getParent()
+                .element("body").text("body content");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addStylesheetLink("foo.css", null);
+
+        linker.updateDocument(document);
+
+        check(document, "existing_head_used_if_present.txt");
+    }
+
+    @Test
+    public void duplicate_script_links_ignored() throws Exception
+    {
+        Document document = new Document();
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        for (int i = 0; i < 3; i++)
+        {
+            linker.addScriptLink("foo.js");
+            linker.addScriptLink("bar/baz.js");
+            linker.addScriptLink("biff.js");
+        }
+
+        linker.updateDocument(document);
+
+        check(document, "duplicate_script_links_ignored.txt");
+    }
+
+    @Test
+    public void add_script() throws Exception
+    {
+        Document document = new Document();
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addScript("doSomething();");
+        linker.addScript("doSomethingElse();");
+
+        linker.updateDocument(document);
+
+        assertEquals(document.toString(), readFile("add_script.txt").trim());
+    }
+
+    @Test
+    public void add_script_in_development_mode() throws Exception
+    {
+        Document document = new Document();
+
+        document.newRootElement("html").element("body").element("p").text("Ready to be updated with scripts.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(false);
+
+        linker.addScriptLink("foo.js");
+
+        linker.updateDocument(document);
+
+        assertEquals(document.toString(), readFile("add_script_in_development_mode.txt").trim());
+    }
+
+    /**
+     * Perhaps the linker should create the &lt;body&gt; element in this case? In the meantime,
+     */
+    @Test
+    public void no_body_element() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("notbody").element("p").text("Ready to be updated with scripts.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+
+        linker.addScriptLink("foo.js");
+
+        linker.updateDocument(document);
+
+        check(document, "no_body_element.txt");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnumBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnumBean.java
new file mode 100644
index 0000000..526c8df
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnumBean.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.parser.TokenType;
+
+public class EnumBean
+{
+    private TokenType token;
+
+    public TokenType getToken()
+    {
+        return token;
+    }
+
+    public void setToken(TokenType token)
+    {
+        this.token = token;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentImplTest.java
new file mode 100644
index 0000000..3d68f15
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentImplTest.java
@@ -0,0 +1,136 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+public class EnvironmentImplTest extends TapestryTestCase
+{
+    @Test
+    public void peek_when_empty_returns_null()
+    {
+        Environment e = new EnvironmentImpl();
+
+        assertNull(e.peek(Runnable.class));
+        assertNull(e.peek(Map.class));
+    }
+
+    @Test
+    public void push_and_pop()
+    {
+        Environment e = new EnvironmentImpl();
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        assertNull(e.push(Runnable.class, r1));
+
+        assertSame(r1, e.peek(Runnable.class));
+
+        assertSame(r1, e.push(Runnable.class, r2));
+
+        assertSame(r2, e.peek(Runnable.class));
+
+        assertSame(r2, e.pop(Runnable.class));
+        assertSame(r1, e.pop(Runnable.class));
+
+        verify();
+    }
+
+    @Test
+    public void clear()
+    {
+        Environment e = new EnvironmentImpl();
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        e.push(Runnable.class, r1);
+        e.push(Runnable.class, r2);
+
+        e.clear();
+
+        assertNull(e.peek(Runnable.class));
+
+        verify();
+    }
+
+    @Test
+    public void pop_when_empty_is_error()
+    {
+        Environment e = new EnvironmentImpl();
+
+        try
+        {
+            e.pop(Runnable.class);
+            unreachable();
+        }
+        catch (NoSuchElementException ex)
+        {
+        }
+    }
+
+    @Test
+    public void peek_required_when_available()
+    {
+        Environment e = new EnvironmentImpl();
+        Location l = mockLocation();
+
+        replay();
+
+        e.push(Location.class, l);
+
+        assertSame(l, e.peekRequired(Location.class));
+
+        verify();
+    }
+
+    @Test
+    public void peek_required_without_value_is_error()
+    {
+        Environment e = new EnvironmentImpl();
+        Location l = mockLocation();
+        Component c = mockComponent();
+
+        replay();
+
+        e.push(Location.class, l);
+        e.push(Component.class, c);
+
+        try
+        {
+            e.peekRequired(List.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No object of type java.util.List is available from the Environment.  Available types are org.apache.tapestry.ioc.Location, org.apache.tapestry.runtime.Component.");
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImplTest.java
new file mode 100644
index 0000000..e4b5191
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/EnvironmentalShadowBuilderImplTest.java
@@ -0,0 +1,48 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.EnvironmentalShadowBuilder;
+import org.testng.annotations.Test;
+
+public class EnvironmentalShadowBuilderImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void proxy_class()
+    {
+        RenderSupport delegate = newMock(RenderSupport.class);
+        ClassFactory factory = new ClassFactoryImpl();
+        Environment env = mockEnvironment();
+
+        train_peekRequired(env, RenderSupport.class, delegate);
+
+        expect(delegate.allocateClientId("fred")).andReturn("barney");
+
+        replay();
+
+        EnvironmentalShadowBuilder builder = new EnvironmentalShadowBuilderImpl(factory, env);
+
+        RenderSupport proxy = builder.build(RenderSupport.class);
+
+        assertEquals(proxy.allocateClientId("fred"), "barney");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidationSupportImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidationSupportImplTest.java
new file mode 100644
index 0000000..2471871
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidationSupportImplTest.java
@@ -0,0 +1,418 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.corelib.internal.InternalMessages;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.ValidationMessagesSource;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class FieldValidationSupportImplTest extends InternalBaseTestCase
+{
+    private TypeCoercer typeCoercer;
+
+    @BeforeClass
+    public void setup()
+    {
+        typeCoercer = getService(TypeCoercer.class);
+    }
+
+
+    @SuppressWarnings({ "unchecked" })
+    @Test
+    public void parse_client_via_event() throws ValidationException
+    {
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        String clientValue = "abracadabra";
+
+        IAnswer answer = new IAnswer()
+        {
+            @SuppressWarnings({ "unchecked" })
+            public Object answer() throws Throwable
+            {
+                Object[] args = EasyMock.getCurrentArguments();
+                Object[] context = (Object[]) args[1];
+                ComponentEventCallback handler = (ComponentEventCallback) args[2];
+
+                // Pretend that the parser event handler converted it to upper case.
+
+                return handler.handleResult(context[0].toString().toUpperCase());
+            }
+        };
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.PARSE_CLIENT_EVENT),
+                                               EasyMock.isA(Object[].class),
+                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+
+
+        replay();
+
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
+
+        assertEquals(actual, clientValue.toUpperCase());
+
+        verify();
+    }
+
+    @Test
+    public void parse_client_for_null_value_returns_null_and_bypasses_events_and_translator() throws Exception
+    {
+        Messages messages = mockMessages();
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        Locale locale = Locale.GERMAN;
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        String clientValue = "";
+
+        train_replaceFromClient(nullFieldStrategy, "");
+
+        ignoreEvent(resources, FieldValidationSupportImpl.PARSE_CLIENT_EVENT, clientValue);
+
+        train_getLocale(resources, locale);
+
+        train_getValidationMessages(source, locale, messages);
+
+        expect(translator.parseClient(clientValue, messages)).andReturn("");
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
+
+        assertEquals(actual, "");
+
+        verify();
+    }
+
+    private void ignoreEvent(ComponentResources resources, String event, Object... context)
+    {
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(event),
+                                               EasyMock.aryEq(context),
+                                               EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
+    }
+
+    protected final void train_replaceFromClient(NullFieldStrategy nullFieldStrategy, String value)
+    {
+        expect(nullFieldStrategy.replaceFromClient()).andReturn(value).atLeastOnce();
+    }
+
+    @SuppressWarnings({ "ThrowableInstanceNeverThrown" })
+    @Test
+    public void parse_client_event_handler_throws_validation_exception() throws Exception
+    {
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationException ve = new ValidationException("Just didn't feel right.");
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        String clientValue = "abracadabra";
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.PARSE_CLIENT_EVENT),
+                                               EasyMock.isA(Object[].class),
+                                               EasyMock.isA(ComponentEventCallback.class))).andThrow(
+                new RuntimeException(ve));
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        try
+        {
+            support.parseClient(clientValue, resources, translator, nullFieldStrategy);
+
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertSame(ex, ve);
+        }
+
+
+        verify();
+    }
+
+    @SuppressWarnings({ "ThrowableInstanceNeverThrown" })
+    @Test
+    public void parse_client_event_handler_fails_with_other_exception() throws Exception
+    {
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        RuntimeException re = new RuntimeException("Just didn't feel right.");
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        String clientValue = "abracadabra";
+
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.PARSE_CLIENT_EVENT),
+                                               EasyMock.isA(Object[].class),
+                                               EasyMock.isA(ComponentEventCallback.class))).andThrow(re);
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        try
+        {
+            support.parseClient(clientValue, resources, translator, nullFieldStrategy);
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertSame(ex, re);
+        }
+
+
+        verify();
+    }
+
+    @Test
+    public void parse_client_via_translator() throws ValidationException
+    {
+        Messages messages = mockMessages();
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        Locale locale = Locale.GERMAN;
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        String clientValue = "abracadabra";
+
+        ignoreEvent(resources, FieldValidationSupportImpl.PARSE_CLIENT_EVENT, clientValue);
+
+        train_getLocale(resources, locale);
+
+        train_getValidationMessages(source, locale, messages);
+
+        expect(translator.parseClient(clientValue, messages)).andReturn("foobar");
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        Object actual = support.parseClient(clientValue, resources, translator, nullFieldStrategy);
+
+        assertEquals(actual, "foobar");
+
+        verify();
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Test
+    public void to_client_via_translator()
+    {
+        Object value = new Integer(99);
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        expect(translator.getType()).andReturn(Integer.class);
+
+        String clientValue = "abracadabra";
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.TO_CLIENT_EVENT),
+                                               EasyMock.aryEq(new Object[] { value }),
+                                               EasyMock.isA(ComponentEventCallback.class))).andReturn(false);
+
+        expect(translator.toClient(value)).andReturn(clientValue);
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        String actual = support.toClient(value, resources, translator, nullFieldStrategy);
+
+        assertEquals(actual, clientValue);
+
+        verify();
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Test
+    public void to_client_via_event_handler() throws Exception
+    {
+        Object value = new Object();
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+        NullFieldStrategy nullFieldStrategy = mockNullFieldStrategy();
+
+        final String clientValue = "abracadabra";
+
+        IAnswer answer = new IAnswer()
+        {
+            @SuppressWarnings({ "unchecked" })
+            public Object answer() throws Throwable
+            {
+                Object[] args = EasyMock.getCurrentArguments();
+                ComponentEventCallback handler = (ComponentEventCallback) args[2];
+
+                return handler.handleResult(clientValue);
+            }
+        };
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.TO_CLIENT_EVENT),
+                                               EasyMock.aryEq(new Object[] { value }),
+                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, null);
+
+        String actual = support.toClient(value, resources, translator, nullFieldStrategy);
+
+        assertEquals(actual, clientValue);
+
+        verify();
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public void to_client_via_event_handler_returns_non_string() throws Exception
+    {
+        Object value = new Object();
+        ComponentResources resources = mockComponentResources();
+        Translator translator = mockTranslator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+
+        IAnswer answer = new IAnswer()
+        {
+            @SuppressWarnings({ "unchecked" })
+            public Object answer() throws Throwable
+            {
+                Object[] args = EasyMock.getCurrentArguments();
+                ComponentEventCallback handler = (ComponentEventCallback) args[2];
+
+                // Return an innappropriate value.
+
+                return handler.handleResult(this);
+            }
+        };
+
+        EasyMock.expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.TO_CLIENT_EVENT),
+                                               EasyMock.aryEq(new Object[] { value }),
+                                               EasyMock.isA(ComponentEventCallback.class))).andAnswer(answer);
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, null);
+
+        try
+        {
+
+            support.toClient(value, resources, translator, null);
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), InternalMessages.toClientShouldReturnString());
+        }
+
+        verify();
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Test
+    public void event_triggered_after_delegate_invoked() throws Exception
+    {
+        getMocksControl().checkOrder(true);
+
+        ComponentResources resources = mockComponentResources();
+        FieldValidator fv = mockFieldValidator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+
+        Object value = new Object();
+
+        fv.validate(value);
+
+        ComponentEventCallback handler = null;
+
+        expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.VALIDATE_EVENT),
+                                      EasyMock.aryEq(new Object[] { value }), EasyMock.eq(handler))).andReturn(true);
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+        support.validate(value, resources, fv);
+
+        verify();
+    }
+
+    @SuppressWarnings({ "unchecked", "ThrowableInstanceNeverThrown" })
+    @Test
+    public void event_trigger_throws_validation_exception() throws Exception
+    {
+        ComponentResources resources = mockComponentResources();
+        FieldValidator fv = mockFieldValidator();
+        ValidationMessagesSource source = mockValidationMessagesSource();
+
+        Object value = new Object();
+
+        ValidationException ve = new ValidationException("Bah!");
+        RuntimeException re = new RuntimeException(ve);
+
+        ComponentEventCallback handler = null;
+
+        fv.validate(value);
+
+        expect(resources.triggerEvent(EasyMock.eq(FieldValidationSupportImpl.VALIDATE_EVENT),
+                                      EasyMock.aryEq(new Object[] { value }), EasyMock.eq(handler))).andThrow(re);
+
+
+        replay();
+
+        FieldValidationSupport support = new FieldValidationSupportImpl(source, typeCoercer);
+
+
+        try
+        {
+            support.validate(value, resources, fv);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertSame(ex, ve);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImplTest.java
new file mode 100644
index 0000000..ea29550
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorDefaultSourceImplTest.java
@@ -0,0 +1,161 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.services.FieldValidatorDefaultSource;
+import org.apache.tapestry.services.FieldValidatorSource;
+import org.apache.tapestry.services.ValidationConstraintGenerator;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class FieldValidatorDefaultSourceImplTest extends InternalBaseTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void invokes_all_constraint_generators() throws Exception
+    {
+        getMocksControl().checkOrder(true);
+
+        ValidationConstraintGenerator gen = mockValidationConstraintGenerator();
+        FieldValidator fv1 = mockFieldValidator();
+        FieldValidator fv2 = mockFieldValidator();
+        FieldValidatorSource source = mockFieldValidatorSource();
+        Class propertyType = Integer.class;
+        AnnotationProvider provider = mockAnnotationProvider();
+        String overrideId = "overrideId";
+        Messages overrideMessages = mockMessages();
+        Field field = mockField();
+        Locale locale = Locale.ENGLISH;
+        String value = "*VALUE*";
+
+        train_buildConstraints(gen, propertyType, provider, "cons1", "cons2");
+
+        train_createValidator(
+                source,
+                field,
+                "cons1",
+                null,
+                overrideId,
+                overrideMessages,
+                locale,
+                fv1);
+
+        train_createValidator(
+                source,
+                field,
+                "cons2",
+                null,
+                overrideId,
+                overrideMessages,
+                locale,
+                fv2);
+
+        fv1.validate(value);
+        fv2.validate(value);
+
+        replay();
+
+        FieldValidatorDefaultSource fieldValidatorSource = new FieldValidatorDefaultSourceImpl(gen,
+                                                                                               source);
+
+        FieldValidator composite = fieldValidatorSource.createDefaultValidator(
+                field,
+                overrideId,
+                overrideMessages,
+                locale,
+                propertyType,
+                provider);
+
+        composite.validate(value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void validator_with_constraint() throws Exception
+    {
+        ValidationConstraintGenerator gen = mockValidationConstraintGenerator();
+        FieldValidator fv = mockFieldValidator();
+        FieldValidatorSource source = mockFieldValidatorSource();
+        Class propertyType = Integer.class;
+        AnnotationProvider provider = mockAnnotationProvider();
+        String overrideId = "overrideId";
+        Messages overrideMessages = mockMessages();
+        Field field = mockField();
+        Locale locale = Locale.ENGLISH;
+
+        train_buildConstraints(gen, propertyType, provider, "foo=bar");
+
+        train_createValidator(source, field, "foo", "bar", overrideId, overrideMessages, locale, fv);
+
+        replay();
+
+        FieldValidatorDefaultSource fieldValidatorSource = new FieldValidatorDefaultSourceImpl(gen,
+                                                                                               source);
+
+        FieldValidator composite = fieldValidatorSource.createDefaultValidator(
+                field,
+                overrideId,
+                overrideMessages,
+                locale,
+                propertyType,
+                provider);
+
+        assertSame(composite, fv);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void no_validators_at_all() throws Exception
+    {
+        ValidationConstraintGenerator gen = mockValidationConstraintGenerator();
+        FieldValidatorSource source = mockFieldValidatorSource();
+        Class propertyType = Integer.class;
+        AnnotationProvider provider = mockAnnotationProvider();
+        String overrideId = "overrideId";
+        Messages overrideMessages = mockMessages();
+        Field field = mockField();
+        Locale locale = Locale.ENGLISH;
+        String value = "*VALUE*";
+
+        train_buildConstraints(gen, propertyType, provider);
+
+        replay();
+
+        FieldValidatorDefaultSource fieldValidatorSource = new FieldValidatorDefaultSourceImpl(gen,
+                                                                                               source);
+
+        FieldValidator composite = fieldValidatorSource.createDefaultValidator(
+                field,
+                overrideId,
+                overrideMessages,
+                locale,
+                propertyType,
+                provider);
+
+        composite.validate(value);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
new file mode 100644
index 0000000..57220e6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorImplTest.java
@@ -0,0 +1,108 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+/**
+ * Tests a few outlier cases not covered by {@link FieldValidatorSourceImplTest}.
+ */
+public class FieldValidatorImplTest extends InternalBaseTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void null_value_skipped() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Validator validator = mockValidator();
+
+        train_isRequired(validator, false);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, validator, null);
+
+        fv.validate(null);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void blank_value_skipped() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Validator validator = mockValidator();
+
+        train_isRequired(validator, false);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, validator, null);
+
+        fv.validate("");
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void nonmatching_value_type_skipped() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Validator validator = mockValidator();
+        Integer value = 15;
+
+        train_isRequired(validator, true);
+        train_getValueType(validator, String.class);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, validator, null);
+
+        fv.validate(value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void value_type_check_skipped_for_null_values() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Validator validator = mockValidator();
+
+        train_isRequired(validator, true);
+
+        validator.validate(field, null, formatter, null);
+
+        replay();
+
+        FieldValidator fv = new FieldValidatorImpl(field, null, formatter, validator, null);
+
+        fv.validate(null);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
new file mode 100644
index 0000000..d8c338e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FieldValidatorSourceImplTest.java
@@ -0,0 +1,493 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.FieldValidator;
+import org.apache.tapestry.Validator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.FieldValidatorSource;
+import org.apache.tapestry.services.ValidationMessagesSource;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import static java.util.Collections.singletonMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+public class FieldValidatorSourceImplTest extends InternalBaseTestCase
+{
+    public interface FieldComponent extends Field, Component
+    {
+
+    }
+
+    @Test
+    public void unknown_validator_type()
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+        Map<String, Validator> map = newMap();
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getLocale(resources, Locale.ENGLISH);
+        train_getContainerMessages(resources, containerMessages);
+
+        map.put("alpha", validator);
+        map.put("beta", validator);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        try
+        {
+            source.createValidator(field, "foo", null);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "Unknown validator type 'foo'.  Configured validators are alpha, beta.");
+        }
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void validator_with_no_constraint() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        Messages messages = mockMessages();
+        MessageFormatter formatter = mockMessageFormatter();
+        Object inputValue = new Object();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+
+        Map<String, Validator> map = singletonMap("required", validator);
+
+        train_getConstraintType(validator, null);
+
+        train_getComponentResources(field, resources);
+
+        train_getId(resources, "fred");
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-required-message", false);
+
+        train_getLocale(resources, Locale.FRENCH);
+
+        train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+
+        train_getMessageKey(validator, "key");
+        train_getMessageFormatter(messages, "key", formatter);
+
+        train_isRequired(validator, false);
+        train_getValueType(validator, Object.class);
+        validator.validate(field, null, formatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidator(field, "required", null);
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void component_messages_overrides_validator_messages() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        MessageFormatter formatter = mockMessageFormatter();
+        Object inputValue = new Object();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+
+        Map<String, Validator> map = singletonMap("required", validator);
+
+        train_getConstraintType(validator, null);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getLocale(resources, Locale.ENGLISH);
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-required-message", true);
+
+        train_getMessageFormatter(containerMessages, "fred-required-message", formatter);
+
+        train_isRequired(validator, false);
+        train_getValueType(validator, Object.class);
+        validator.validate(field, null, formatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidator(field, "required", null);
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void constraint_value_from_message_catalog() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        Messages messages = mockMessages();
+        MessageFormatter formatter = mockMessageFormatter();
+        Object inputValue = new Object();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+
+        Map<String, Validator> map = singletonMap("minlength", validator);
+
+        train_getConstraintType(validator, Integer.class);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+
+        train_contains(containerMessages, "fred-minlength", true);
+        train_get(containerMessages, "fred-minlength", "5");
+
+        train_coerce(coercer, "5", Integer.class, 5);
+
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-minlength-message", false);
+
+        train_getLocale(resources, Locale.FRENCH);
+
+        train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+
+        train_getMessageKey(validator, "key");
+        train_getMessageFormatter(messages, "key", formatter);
+
+        train_isRequired(validator, false);
+        train_getValueType(validator, Object.class);
+        validator.validate(field, 5, formatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidators(field, "minlength");
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void missing_field_validator_constraint() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+
+        Map<String, Validator> map = singletonMap("minlength", validator);
+
+        train_getConstraintType(validator, Integer.class);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getLocale(resources, Locale.GERMAN);
+        train_getContainerMessages(resources, containerMessages);
+
+        train_contains(containerMessages, "fred-minlength", false);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        try
+        {
+            source.createValidators(field, "minlength");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Validator \'minlength\' requires a validation constraint (of type java.lang.Integer) but none was provided.");
+        }
+
+        verify();
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void single_validator_via_specification() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        Messages messages = mockMessages();
+        MessageFormatter formatter = mockMessageFormatter();
+        Object inputValue = new Object();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+
+        Map<String, Validator> map = singletonMap("required", validator);
+
+        train_getConstraintType(validator, null);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-required-message", false);
+
+        train_getLocale(resources, Locale.FRENCH);
+
+        train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+
+        train_getMessageKey(validator, "key");
+        train_getMessageFormatter(messages, "key", formatter);
+
+        train_isRequired(validator, false);
+        train_getValueType(validator, Object.class);
+        validator.validate(field, null, formatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidators(field, "required");
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void multiple_validators_via_specification() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator required = mockValidator();
+        Validator minLength = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        Messages messages = mockMessages();
+        MessageFormatter requiredFormatter = mockMessageFormatter();
+        MessageFormatter minLengthFormatter = mockMessageFormatter();
+        Object inputValue = "input value";
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+        Integer fifteen = 15;
+
+        Map<String, Validator> map = newMap();
+
+        map.put("required", required);
+        map.put("minLength", minLength);
+
+        train_getConstraintType(required, null);
+        train_getConstraintType(minLength, Integer.class);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-required-message", false);
+
+        train_getLocale(resources, Locale.FRENCH);
+
+        train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+
+        train_getMessageKey(required, "required");
+        train_getMessageFormatter(messages, "required", requiredFormatter);
+
+        train_contains(containerMessages, "fred-minLength-message", false);
+
+        train_getMessageKey(minLength, "min-length");
+        train_getMessageFormatter(messages, "min-length", minLengthFormatter);
+
+        train_coerce(coercer, "15", Integer.class, fifteen);
+
+        train_isRequired(required, true);
+        train_getValueType(required, Object.class);
+        required.validate(field, null, requiredFormatter, inputValue);
+
+        train_isRequired(minLength, false);
+        train_getValueType(minLength, String.class);
+        minLength.validate(field, fifteen, minLengthFormatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidators(field, "required,minLength=15");
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void validator_with_constraint() throws Exception
+    {
+        ValidationMessagesSource messagesSource = mockValidationMessagesSource();
+        Validator validator = mockValidator();
+        TypeCoercer coercer = mockTypeCoercer();
+        FieldComponent field = newFieldComponent();
+        Messages messages = mockMessages();
+        MessageFormatter formatter = mockMessageFormatter();
+        Object inputValue = new Object();
+        ComponentResources resources = mockComponentResources();
+        Messages containerMessages = mockMessages();
+        Integer five = 5;
+
+        Map<String, Validator> map = singletonMap("minLength", validator);
+
+        train_getConstraintType(validator, Integer.class);
+
+        train_coerce(coercer, "5", Integer.class, five);
+
+        train_getComponentResources(field, resources);
+        train_getId(resources, "fred");
+        train_getContainerMessages(resources, containerMessages);
+        train_contains(containerMessages, "fred-minLength-message", false);
+
+        train_getLocale(resources, Locale.FRENCH);
+
+        train_getValidationMessages(messagesSource, Locale.FRENCH, messages);
+
+        train_getMessageKey(validator, "key");
+        train_getMessageFormatter(messages, "key", formatter);
+
+        train_isRequired(validator, false);
+        train_getValueType(validator, Object.class);
+        validator.validate(field, five, formatter, inputValue);
+
+        replay();
+
+        FieldValidatorSource source = new FieldValidatorSourceImpl(messagesSource, coercer, null, map);
+
+        FieldValidator fieldValidator = source.createValidator(field, "minLength", "5");
+
+        fieldValidator.validate(inputValue);
+
+        verify();
+    }
+
+    private FieldComponent newFieldComponent()
+    {
+        return newMock(FieldComponent.class);
+    }
+
+    private void test(String specification, ValidatorSpecification... expected)
+    {
+        List<ValidatorSpecification> specs = FieldValidatorSourceImpl.parse(specification);
+
+        assertEquals(specs, Arrays.asList(expected));
+    }
+
+    @Test
+    public void parse_simple_type_list()
+    {
+        test("required,email", new ValidatorSpecification("required", null), new ValidatorSpecification("email", null));
+    }
+
+    @Test
+    public void parse_single_type()
+    {
+        test("required", new ValidatorSpecification("required", null));
+    }
+
+    @Test
+    public void ignore_whitespace_around_type_name()
+    {
+        test("  required  ,  email  ", new ValidatorSpecification("required", null),
+             new ValidatorSpecification("email", null));
+    }
+
+    @Test
+    public void parse_simple_type_with_value()
+    {
+        test("minLength=5,sameAs=otherComponentId", new ValidatorSpecification("minLength", "5"),
+             new ValidatorSpecification("sameAs", "otherComponentId"));
+    }
+
+    @Test
+    public void whitespace_ignored_around_value()
+    {
+        test("minLength=  5 , sameAs  = otherComponentId ", new ValidatorSpecification("minLength", "5"),
+             new ValidatorSpecification("sameAs", "otherComponentId"));
+    }
+
+    @Test
+    public void dangling_equals_sign_is_empty_string_value()
+    {
+        test("minLength=  ", new ValidatorSpecification("minLength", ""));
+    }
+
+    @Test
+    public void unexpected_character_not_a_comma()
+    {
+        try
+        {
+            test("required.email");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Unexpected character '.' at position 9 of input string: required.email");
+        }
+    }
+
+    @Test
+    public void unexpected_character_after_constraint_value()
+    {
+        try
+        {
+            test("minLength=3 . email");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Unexpected character '.' at position 13 of input string: minLength=3 . email");
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategyTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategyTest.java
new file mode 100644
index 0000000..0779588
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FlashPersistentFieldStrategyTest.java
@@ -0,0 +1,96 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * A more minimal test, since common behavior is already tested by
+ * {@link SessionPersistentFieldStrategyTest}.
+ */
+public class FlashPersistentFieldStrategyTest extends InternalBaseTestCase
+{
+    @Test
+    public void post_change_to_root_component()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+        Object value = new Object();
+
+        train_getSession(request, true, session);
+
+        session.setAttribute("flash:foo.Bar::field", value);
+
+        replay();
+
+        PersistentFieldStrategy strategy = new FlashPersistentFieldStrategy(request);
+
+        strategy.postChange("foo.Bar", null, "field", value);
+
+        verify();
+    }
+
+    @Test
+    public void gather_changes_with_active_session()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+
+        train_getSession(request, false, session);
+        train_getAttributeNames(
+                session,
+                "flash:foo.Bar:",
+                "flash:foo.Bar::root",
+                "flash:foo.Bar:nested:down");
+
+        train_getAttribute(session, "flash:foo.Bar::root", "ROOT");
+        session.setAttribute("flash:foo.Bar::root", null);
+
+        train_getAttribute(session, "flash:foo.Bar:nested:down", "DOWN");
+        session.setAttribute("flash:foo.Bar:nested:down", null);
+
+        replay();
+
+        PersistentFieldStrategy strategy = new FlashPersistentFieldStrategy(request);
+
+        Collection<PersistentFieldChange> changes = strategy.gatherFieldChanges("foo.Bar");
+
+        assertEquals(changes.size(), 2);
+
+        Iterator<PersistentFieldChange> i = changes.iterator();
+
+        PersistentFieldChange change1 = i.next();
+
+        assertEquals(change1.getComponentId(), "");
+        assertEquals(change1.getFieldName(), "root");
+        assertEquals(change1.getValue(), "ROOT");
+
+        PersistentFieldChange change2 = i.next();
+
+        assertEquals(change2.getComponentId(), "nested");
+        assertEquals(change2.getFieldName(), "down");
+        assertEquals(change2.getValue(), "DOWN");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooBarInterface.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooBarInterface.java
new file mode 100644
index 0000000..0fb5014
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooBarInterface.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+public interface FooBarInterface extends FooInterface, BarInterface

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooInterface.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooInterface.java
new file mode 100644
index 0000000..9f1ea66
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/FooInterface.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+/**

+ *

+ */

+public interface FooInterface

+{

+    void foo();

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GenericBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GenericBean.java
new file mode 100644
index 0000000..4070b91
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GenericBean.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class GenericBean<T>
+{
+    private T value;
+
+    public T getValue()
+    {
+        return value;
+    }
+
+    public void setValue(T value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GetterMethodsInterface.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GetterMethodsInterface.java
new file mode 100644
index 0000000..af5d046
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/GetterMethodsInterface.java
@@ -0,0 +1,41 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+/**

+ *

+ */

+public interface GetterMethodsInterface

+{

+    boolean getBoolean();

+

+    byte getByte();

+

+    short getShort();

+

+    int getInt();

+

+    long getLong();

+

+    float getFloat();

+

+    double getDouble();

+

+    String getString();

+

+    int[] getIntArray();

+

+    Object[] getObjectArray();

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/HeartbeatImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/HeartbeatImplTest.java
new file mode 100644
index 0000000..821af08
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/HeartbeatImplTest.java
@@ -0,0 +1,89 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Heartbeat;
+import org.testng.annotations.Test;
+
+public class HeartbeatImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void single_heartbeat()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        Heartbeat hb = new HeartbeatImpl();
+
+        hb.begin();
+
+        hb.defer(r1);
+        hb.defer(r2);
+
+        verify();
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        hb.end();
+
+        verify();
+    }
+
+    @Test
+    public void nested_heartbeats()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+        Runnable r3 = mockRunnable();
+
+        replay();
+
+        Heartbeat hb = new HeartbeatImpl();
+
+        hb.begin();
+
+        hb.defer(r1);
+        hb.defer(r2);
+
+        hb.begin();
+
+        hb.defer(r3);
+
+        verify();
+
+        r3.run();
+
+        replay();
+
+        hb.end();
+
+        verify();
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        hb.end();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/IgnoredPathsFilterTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/IgnoredPathsFilterTest.java
new file mode 100644
index 0000000..49b481b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/IgnoredPathsFilterTest.java
@@ -0,0 +1,99 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.HttpServletRequestFilter;
+import org.apache.tapestry.services.HttpServletRequestHandler;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+public class IgnoredPathsFilterTest extends TapestryTestCase
+{
+    @Test
+    public void no_match() throws IOException
+    {
+        HttpServletRequest request = mockHttpServletRequest();
+        HttpServletResponse response = mockHttpServletResponse();
+        HttpServletRequestHandler handler = mockHttpServletRequestHandler();
+
+        train_getServletPath(request, "/");
+        train_getPathInfo(request, "barney");
+
+        train_service(handler, request, response, true);
+
+        List<String> configuration = CollectionFactory.newList("/fred");
+
+
+        replay();
+
+        HttpServletRequestFilter filter = new IgnoredPathsFilter(configuration);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void no_path_info() throws Exception
+    {
+        HttpServletRequest request = mockHttpServletRequest();
+        HttpServletResponse response = mockHttpServletResponse();
+        HttpServletRequestHandler handler = mockHttpServletRequestHandler();
+
+        train_getServletPath(request, "/");
+        train_getPathInfo(request, null);
+
+        train_service(handler, request, response, true);
+
+        List<String> configuration = CollectionFactory.newList("/fred");
+
+
+        replay();
+
+        HttpServletRequestFilter filter = new IgnoredPathsFilter(configuration);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void path_excluded() throws Exception
+    {
+        HttpServletRequest request = mockHttpServletRequest();
+        HttpServletResponse response = mockHttpServletResponse();
+        HttpServletRequestHandler handler = mockHttpServletRequestHandler();
+
+        train_getServletPath(request, "/");
+        train_getPathInfo(request, "barney/rubble");
+
+        List<String> configuration = CollectionFactory.newList("/barney.*");
+
+        replay();
+
+        HttpServletRequestFilter filter = new IgnoredPathsFilter(configuration);
+
+        assertFalse(filter.service(request, response, handler));
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java
new file mode 100644
index 0000000..0b0754c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java
@@ -0,0 +1,272 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class InheritedBindingTest extends TapestryTestCase
+{
+    private static final String BINDING_DESCRIPTION = "binding description";
+
+    private static final String MESSAGE = "Exception in inner.";
+
+    private static final Throwable exception = new RuntimeException(MESSAGE);
+
+    @Test
+    public void to_string_and_location()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.toString(), BINDING_DESCRIPTION);
+        assertSame(binding.getLocation(), l);
+
+        verify();
+    }
+
+    @Test
+    public void get_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Object expected = new Object();
+
+        train_get(inner, expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.get(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void get_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        expect(inner.get()).andThrow(exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.get();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_binding_type_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Class expected = Runnable.class;
+
+        expect(inner.getBindingType()).andReturn(expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.getBindingType(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void get_binding_type_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        String description = BINDING_DESCRIPTION;
+
+        expect(inner.getBindingType()).andThrow(exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(description, inner, l);
+
+        try
+        {
+            binding.getBindingType();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    private void checkException(TapestryException ex, Location l)
+    {
+        assertEquals(ex.getMessage(), MESSAGE);
+        assertEquals(ex.getLocation(), l);
+        assertSame(ex.getCause(), exception);
+    }
+
+    @Test
+    public void is_invariant_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        boolean expected = true;
+
+        expect(inner.isInvariant()).andReturn(expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertEquals(binding.isInvariant(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void is_invariant_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        expect(inner.isInvariant()).andThrow(exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.isInvariant();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void set_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        String description = BINDING_DESCRIPTION;
+        Object parameter = new Object();
+
+        inner.set(parameter);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(description, inner, l);
+
+        binding.set(parameter);
+
+        verify();
+    }
+
+    @Test
+    public void set_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Object parameter = new Object();
+
+        inner.set(parameter);
+        getMocksControl().andThrow(exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.set(parameter);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_annotation_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Inject inject = newMock(Inject.class);
+
+        train_getAnnotation(inner, Inject.class, inject);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.getAnnotation(Inject.class), inject);
+
+        verify();
+    }
+
+    @Test
+    public void get_annotation_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        expect(inner.getAnnotation(Inject.class)).andThrow(exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.getAnnotation(Inject.class);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
new file mode 100644
index 0000000..9d24228
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
@@ -0,0 +1,1173 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import javassist.*;
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.annotation.OnEvent;
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.annotation.SetupRender;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.model.MutableComponentModelImpl;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.FieldRemoval;
+import org.apache.tapestry.internal.transform.InheritedAnnotation;
+import org.apache.tapestry.internal.transform.TestPackageAwareLoader;
+import org.apache.tapestry.internal.transform.pages.*;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryClassPool;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentResourcesAware;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.MethodFilter;
+import org.apache.tapestry.services.TransformMethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static java.lang.Thread.currentThread;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import static java.util.Arrays.asList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The tests share a number of resources, and so are run sequentially.
+ */
+@Test(sequential = true)
+public class InternalClassTransformationImplTest extends InternalBaseTestCase
+{
+    private static final String STRING_CLASS_NAME = "java.lang.String";
+
+    private PropertyAccess access;
+
+    private final ClassLoader contextClassLoader = currentThread().getContextClassLoader();
+
+    private ClassFactory classFactory;
+
+    private Loader loader;
+
+    private ClassFactoryClassPool classFactoryClassPool;
+
+    @BeforeClass
+    public void setup_access()
+    {
+        access = getService("PropertyAccess", PropertyAccess.class);
+    }
+
+    @AfterClass
+    public void cleanup_access()
+    {
+        access = null;
+    }
+
+    /**
+     * We need a new ClassPool for each individual test, since many of the tests will end up modifying one or more
+     * CtClass instances.
+     */
+    @BeforeMethod
+    public void setup_classpool()
+    {
+        //  _classPool = new ClassPool();
+
+        classFactoryClassPool = new ClassFactoryClassPool(contextClassLoader);
+
+        loader = new TestPackageAwareLoader(contextClassLoader, classFactoryClassPool);
+
+        // Inside Maven Surefire, the system classpath is not sufficient to find all
+        // the necessary files.
+        classFactoryClassPool.appendClassPath(new LoaderClassPath(loader));
+
+        Logger logger = LoggerFactory.getLogger(InternalClassTransformationImplTest.class);
+
+        classFactory = new ClassFactoryImpl(loader, classFactoryClassPool, logger);
+    }
+
+    private CtClass findCtClass(Class targetClass) throws NotFoundException
+    {
+        return classFactoryClassPool.get(targetClass.getName());
+    }
+
+    private Class toClass(CtClass ctClass) throws Exception
+    {
+        return classFactoryClassPool.toClass(ctClass, loader, null);
+    }
+
+    @Test
+    public void new_member_name() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        assertEquals(ct.newMemberName("fred"), "_$fred");
+        assertEquals(ct.newMemberName("fred"), "_$fred_0");
+
+        // Here we're exposing a bit of the internal algorithm, which strips
+        // off '$' and '_' before tacking "_$" in front.
+
+        assertEquals(ct.newMemberName("_fred"), "_$fred_1");
+        assertEquals(ct.newMemberName("_$fred"), "_$fred_2");
+        assertEquals(ct.newMemberName("__$___$____$_fred"), "_$fred_3");
+
+        // Here we're trying to force conflicts with existing declared
+        // fields and methods of the class.
+
+        assertEquals(ct.newMemberName("_parentField"), "_$parentField");
+        assertEquals(ct.newMemberName("conflictField"), "_$conflictField_0");
+        assertEquals(ct.newMemberName("conflictMethod"), "_$conflictMethod_0");
+
+        verify();
+    }
+
+    @Test
+    public void new_member_name_with_prefix() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        assertEquals(ct.newMemberName("prefix", "fred"), "_$prefix_fred");
+        assertEquals(ct.newMemberName("prefix", "fred"), "_$prefix_fred_0");
+
+        // Here we're exposing a bit of the internal algorithm, which strips
+        // off '$' and '_' before tacking "_$" in front.
+
+        assertEquals(ct.newMemberName("prefix", "_fred"), "_$prefix_fred_1");
+        assertEquals(ct.newMemberName("prefix", "_$fred"), "_$prefix_fred_2");
+        assertEquals(ct.newMemberName("prefix", "__$___$____$_fred"), "_$prefix_fred_3");
+
+        verify();
+    }
+
+    private InternalClassTransformation createClassTransformation(Class targetClass, Logger logger)
+            throws NotFoundException
+    {
+        CtClass ctClass = findCtClass(targetClass);
+
+        MutableComponentModel model = new MutableComponentModelImpl("unknown-class", logger, null, null);
+
+        return new InternalClassTransformationImpl(classFactory, ctClass, null, model, null);
+    }
+
+    @Test
+    public void find_annotation_on_unknown_field() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        try
+        {
+            ct.getFieldAnnotation("unknownField", Retain.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class org.apache.tapestry.internal.transform.pages.ParentClass does not contain a field named 'unknownField'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void find_field_annotation() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        Retain retain = ct.getFieldAnnotation("_annotatedField", Retain.class);
+
+        assertNotNull(retain);
+
+        verify();
+    }
+
+    @Test
+    public void field_does_not_contain_requested_annotation() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        // Field with annotation, but not that annotation
+        assertNull(ct.getFieldAnnotation("_annotatedField", Override.class));
+
+        // Field with no annotation
+        assertNull(ct.getFieldAnnotation("_parentField", Override.class));
+
+        verify();
+    }
+
+    @Test
+    public void find_fields_with_annotation() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        List<String> fields = ct.findFieldsWithAnnotation(Retain.class);
+
+        assertEquals(fields.size(), 1);
+        assertEquals(fields.get(0), "_annotatedField");
+
+        verify();
+    }
+
+    @Test
+    public void get_field_modifiers() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(CheckFieldType.class, logger);
+
+        assertEquals(ct.getFieldModifiers("_privateField"), Modifier.PRIVATE);
+        assertEquals(ct.getFieldModifiers("_map"), Modifier.PRIVATE + Modifier.FINAL);
+    }
+
+    @Test
+    public void get_field_exists() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(CheckFieldType.class, logger);
+
+        assertTrue(ct.isField("_privateField"));
+        assertFalse(ct.isField("_doesNotExist"));
+
+        verify();
+    }
+
+    @Test
+    public void find_fields_with_annotation_excludes_claimed_files() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        ct.claimField("_annotatedField", this);
+
+        List<String> fields = ct.findFieldsWithAnnotation(Retain.class);
+
+        assertTrue(fields.isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void no_fields_contain_requested_annotation() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        List<String> fields = ct.findFieldsWithAnnotation(Documented.class);
+
+        assertTrue(fields.isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void claim_fields() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ClaimedFields.class, logger);
+
+        List<String> unclaimed = ct.findUnclaimedFields();
+
+        assertEquals(unclaimed, asList("_field1", "_field4", "_zzfield"));
+
+        ct.claimField("_field4", "Fred");
+
+        unclaimed = ct.findUnclaimedFields();
+
+        assertEquals(unclaimed, asList("_field1", "_zzfield"));
+
+        try
+        {
+            ct.claimField("_field4", "Barney");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Field _field4 of class org.apache.tapestry.internal.transform.pages.ClaimedFields is already claimed by Fred and can not be claimed by Barney.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void added_fields_are_not_listed_as_unclaimed_fields() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ClaimedFields.class, logger);
+
+        ct.addField(Modifier.PRIVATE, "int", "newField");
+
+        List<String> unclaimed = ct.findUnclaimedFields();
+
+        assertEquals(unclaimed, asList("_field1", "_field4", "_zzfield"));
+
+        verify();
+    }
+
+    @Test
+    public void find_class_annotations() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        Meta meta = ct.getAnnotation(Meta.class);
+
+        assertNotNull(meta);
+
+        // Try again (the annotation will be cached). Use an annotation
+        // that will not be present.
+
+        Target t = ct.getAnnotation(Target.class);
+
+        assertNull(t);
+
+        verify();
+    }
+
+    /**
+     * More a test of how Javassist works. Javassist does not honor the Inherited annotation for classes (this kind of
+     * makes sense, since it won't necessarily have the super-class in memory).
+     */
+    @Test
+    public void ensure_subclasses_inherit_parent_class_annotations() throws Exception
+    {
+        // The Java runtime does honor @Inherited
+        assertNotNull(ChildClassInheritsAnnotation.class.getAnnotation(InheritedAnnotation.class));
+
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ChildClassInheritsAnnotation.class, logger);
+
+        InheritedAnnotation ia = ct.getAnnotation(InheritedAnnotation.class);
+
+        // Javassist does not, but ClassTransformation patches around that.
+
+        assertNotNull(ia);
+
+        verify();
+    }
+
+    /**
+     * These tests are really to assert my understanding of Javassist's API. I guess we should keep them around to make
+     * sure that future versions of Javassist work the same as our expectations.
+     */
+    @Test
+    public void ensure_javassist_still_does_not_show_inherited_interfaces() throws Exception
+    {
+        CtClass ctClass = findCtClass(BarImpl.class);
+
+        CtClass[] interfaces = ctClass.getInterfaces();
+
+        // Just the interfaces implemented by this particular class, not
+        // inherited interfaces.
+
+        assertEquals(interfaces.length, 1);
+
+        assertEquals(interfaces[0].getName(), BarInterface.class.getName());
+
+        CtClass parentClass = ctClass.getSuperclass();
+
+        interfaces = parentClass.getInterfaces();
+
+        assertEquals(interfaces.length, 1);
+
+        assertEquals(interfaces[0].getName(), FooInterface.class.getName());
+    }
+
+    @Test
+    public void ensure_javassist_does_not_show_interface_methods_on_abstract_class() throws Exception
+    {
+        CtClass ctClass = findCtClass(AbstractFoo.class);
+
+        CtClass[] interfaces = ctClass.getInterfaces();
+
+        assertEquals(interfaces.length, 1);
+
+        assertEquals(interfaces[0].getName(), FooInterface.class.getName());
+
+        // In some cases, Java reflection on an abstract class implementing an interface
+        // will show the interface methods as abstract methods on the class. This seems
+        // to vary from JVM to JVM. I believe Javassist is more consistent here.
+
+        CtMethod[] methods = ctClass.getDeclaredMethods();
+
+        assertEquals(methods.length, 0);
+    }
+
+    @Test
+    public void ensure_javassist_does_not_show_extended_interface_methods_on_interface() throws Exception
+    {
+        CtClass ctClass = findCtClass(FooBarInterface.class);
+
+        // Just want to check that an interface that extends other interfaces
+        // doesn't show those other interface's methods.
+
+        CtMethod[] methods = ctClass.getDeclaredMethods();
+
+        assertEquals(methods.length, 0);
+    }
+
+    @Test
+    public void add_injected_field() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        CtClass targetObjectCtClass = findCtClass(TargetObject.class);
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        // Default behavior is to add an injected field for the InternalComponentResources object,
+        // so we'll just check that.
+
+        ct.finish();
+
+        Instantiator instantiator = ct.createInstantiator();
+
+        ComponentResourcesAware instance = instantiator.newInstance(resources);
+
+        assertSame(instance.getComponentResources(), resources);
+
+        verify();
+    }
+
+    @Test
+    public void add_injected_field_from_parent_transformation() throws Exception
+    {
+        final String value = "from the parent";
+
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        CtClass targetObjectCtClass = findCtClass(TargetObject.class);
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getLogger(model, logger);
+
+        replay();
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        String parentFieldName = ct.addInjectedField(String.class, "_value", value);
+
+        // Default behavior is to add an injected field for the InternalComponentResources object,
+        // so we'll just check that.
+
+        ct.finish();
+
+        // Now lets work on the subclass
+
+        CtClass subclassCtClass = findCtClass(TargetObjectSubclass.class);
+
+        ct = ct.createChildTransformation(subclassCtClass, model);
+
+        String subclassFieldName = ct.addInjectedField(String.class, "_childValue", value);
+
+        // This is what proves it is cached.
+
+        assertEquals(subclassFieldName, parentFieldName);
+
+        // This proves the the field is protected and can be used in subclasses.
+
+        ct.addMethod(new TransformMethodSignature(Modifier.PUBLIC, "java.lang.String", "getValue", null, null),
+                     "return " + subclassFieldName + ";");
+
+        ct.finish();
+
+        Instantiator instantiator = ct.createInstantiator();
+
+        Object instance = instantiator.newInstance(resources);
+
+        Object actual = access.get(instance, "value");
+
+        assertSame(actual, value);
+
+        verify();
+    }
+
+    @Test
+    public void add_interface_to_class() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        CtClass targetObjectCtClass = findCtClass(TargetObject.class);
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        ct.addImplementedInterface(FooInterface.class);
+        ct.addImplementedInterface(GetterMethodsInterface.class);
+
+        ct.finish();
+
+        Class transformed = toClass(targetObjectCtClass);
+
+        Class[] interfaces = transformed.getInterfaces();
+
+        assertEquals(interfaces, new Class[] { Component.class, FooInterface.class, GetterMethodsInterface.class });
+
+        Object target = ct.createInstantiator().newInstance(resources);
+
+        FooInterface asFoo = (FooInterface) target;
+
+        asFoo.foo();
+
+        GetterMethodsInterface getters = (GetterMethodsInterface) target;
+
+        assertEquals(getters.getBoolean(), false);
+        assertEquals(getters.getByte(), (byte) 0);
+        assertEquals(getters.getShort(), (short) 0);
+        assertEquals(getters.getInt(), 0);
+        assertEquals(getters.getLong(), 0l);
+        assertEquals(getters.getFloat(), 0.0f);
+        assertEquals(getters.getDouble(), 0.0d);
+        assertNull(getters.getString());
+        assertNull(getters.getObjectArray());
+        assertNull(getters.getIntArray());
+
+        verify();
+    }
+
+    @Test
+    public void make_field_read_only() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        ct.makeReadOnly("_value");
+
+        ct.finish();
+
+        Object target = instantiate(ReadOnlyBean.class, ct, resources);
+
+        try
+        {
+            access.set(target, "value", "anything");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // The PropertyAccess layer adds a wrapper exception around the real one.
+
+            assertEquals(ex.getCause().getMessage(),
+                         "Field org.apache.tapestry.internal.transform.pages.ReadOnlyBean._value is read-only.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void removed_fields_should_not_show_up_as_unclaimed() throws Exception
+    {
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(RemoveFieldBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(null, targetObjectCtClass, null, model,
+                                                                             null);
+
+        ct.removeField("_barney");
+
+        assertEquals(ct.findUnclaimedFields(), asList("_fred"));
+
+        verify();
+    }
+
+    @Test
+    public void add_to_constructor() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        ct.extendConstructor("_value = \"from constructor\";");
+
+        ct.finish();
+
+        Object target = instantiate(ReadOnlyBean.class, ct, resources);
+
+        assertEquals(access.get(target, "value"), "from constructor");
+
+        verify();
+    }
+
+    @Test
+    public void inject_field() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(ReadOnlyBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        ct.injectField("_value", "Tapestry");
+
+        ct.finish();
+
+        Object target = instantiate(ReadOnlyBean.class, ct, resources);
+
+        assertEquals(access.get(target, "value"), "Tapestry");
+
+        try
+        {
+            access.set(target, "value", "anything");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // The PropertyAccess layer adds a wrapper exception around the real one.
+
+            assertEquals(ex.getCause().getMessage(),
+                         "Field org.apache.tapestry.internal.transform.pages.ReadOnlyBean._value is read-only.");
+        }
+
+        verify();
+    }
+
+    /**
+     * Tests the basic functionality of overriding read and write; also tests the case for multiple field read/field
+     * write substitions.
+     */
+    @Test
+    public void override_field_read_and_write() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(FieldAccessBean.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        replaceAccessToField(ct, "foo");
+        replaceAccessToField(ct, "bar");
+
+        // Stuff ...
+
+        ct.finish();
+
+        Object target = instantiate(FieldAccessBean.class, ct, resources);
+
+        // target is no longer assignable to FieldAccessBean; its a new class from a new class
+        // loader. So we use reflective access, which doesn't care about such things.
+
+        checkReplacedFieldAccess(target, "foo");
+        checkReplacedFieldAccess(target, "bar");
+
+        verify();
+    }
+
+    private void checkReplacedFieldAccess(Object target, String propertyName)
+    {
+
+        try
+        {
+            access.get(target, propertyName);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // PropertyAccess adds a wrapper exception
+            assertEquals(ex.getCause().getMessage(), "read " + propertyName);
+        }
+
+        try
+        {
+            access.set(target, propertyName, "new value");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // PropertyAccess adds a wrapper exception
+            assertEquals(ex.getCause().getMessage(), "write " + propertyName);
+        }
+    }
+
+    private void replaceAccessToField(InternalClassTransformation ct, String baseName)
+    {
+        String fieldName = "_" + baseName;
+        String readMethodName = "_read_" + baseName;
+
+        TransformMethodSignature readMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, STRING_CLASS_NAME,
+                                                                                    readMethodName, null, null);
+
+        ct.addMethod(readMethodSignature, String.format("throw new RuntimeException(\"read %s\");", baseName));
+
+        ct.replaceReadAccess(fieldName, readMethodName);
+
+        String writeMethodName = "_write_" + baseName;
+
+        TransformMethodSignature writeMethodSignature = new TransformMethodSignature(Modifier.PRIVATE, "void",
+                                                                                     writeMethodName,
+                                                                                     new String[] { STRING_CLASS_NAME },
+                                                                                     null);
+        ct.addMethod(writeMethodSignature, String.format("throw new RuntimeException(\"write %s\");", baseName));
+
+        ct.replaceWriteAccess(fieldName, writeMethodName);
+    }
+
+    @Test
+    public void find_methods_with_annotation() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, logger);
+
+        List<TransformMethodSignature> l = ct.findMethodsWithAnnotation(SetupRender.class);
+
+        // Check order
+
+        assertEquals(l.size(), 2);
+        assertEquals(l.get(0).toString(), "void beforeRender()");
+        assertEquals(l.get(1).toString(), "boolean earlyRender(org.apache.tapestry.MarkupWriter)");
+
+        // Check up on cacheing
+
+        assertEquals(ct.findMethodsWithAnnotation(SetupRender.class), l);
+
+        // Check up on no match.
+
+        assertTrue(ct.findFieldsWithAnnotation(Deprecated.class).isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void find_methods_using_filter() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        final ClassTransformation ct = createClassTransformation(AnnotatedPage.class, logger);
+
+        // Duplicates, somewhat less efficiently, the logic in find_methods_with_annotation().
+
+        MethodFilter filter = new MethodFilter()
+        {
+            public boolean accept(TransformMethodSignature signature)
+            {
+                return ct.getMethodAnnotation(signature, SetupRender.class) != null;
+            }
+        };
+
+        List<TransformMethodSignature> l = ct.findMethods(filter);
+
+        // Check order
+
+        assertEquals(l.size(), 2);
+        assertEquals(l.get(0).toString(), "void beforeRender()");
+        assertEquals(l.get(1).toString(), "boolean earlyRender(org.apache.tapestry.MarkupWriter)");
+
+        // Check up on cacheing
+
+        assertEquals(ct.findMethodsWithAnnotation(SetupRender.class), l);
+
+        // Check up on no match.
+
+        assertTrue(ct.findFieldsWithAnnotation(Deprecated.class).isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void to_class_with_primitive_type() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, logger);
+
+        assertSame(ct.toClass("float"), Float.class);
+
+        verify();
+    }
+
+    @Test
+    public void to_class_with_object_type() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(AnnotatedPage.class, logger);
+
+        assertSame(ct.toClass("java.util.Map"), Map.class);
+
+        verify();
+    }
+
+    @Test
+    public void non_private_fields_are_an_exception() throws Exception
+    {
+        Logger logger = mockLogger();
+
+
+        replay();
+
+        InternalClassTransformation ct = createClassTransformation(VisibilityBean.class, logger);
+
+        try
+        {
+
+            ct.finish();
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Class " + VisibilityBean.class.getName() + " contains field(s)",
+                                  "_$myPackagePrivate", "_$myProtected", "_$myPublic");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void find_annotation_in_method() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(EventHandlerTarget.class, logger);
+
+        OnEvent annotation = ct.getMethodAnnotation(new TransformMethodSignature("handler"), OnEvent.class);
+
+        // Check that the attributes of the annotation match the expectation.
+
+        assertEquals(annotation.value(), "fred");
+        assertEquals(annotation.component(), "alpha");
+
+        verify();
+    }
+
+    @Test
+    public void find_annotation_in_unknown_method() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        try
+        {
+            ct.getMethodAnnotation(new TransformMethodSignature("foo"), OnEvent.class);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class org.apache.tapestry.internal.transform.pages.ParentClass does not declare method 'public void foo()'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void prefix_method() throws Exception
+    {
+        Logger logger = mockLogger();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getParentField", null,
+                                                                    null);
+
+        replay();
+
+        InternalClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+        ct.prefixMethod(sig, "return 42;");
+
+        String desc = ct.toString();
+        assertTrue(desc.contains("prefix"));
+        assertTrue(desc.contains("getParentField"));
+
+        // fail if frozen
+        ct.finish();
+        try
+        {
+            ct.prefixMethod(sig, "return 0;");
+            unreachable();
+        }
+        catch (IllegalStateException e)
+        {
+        }
+
+
+        verify();
+    }
+
+    @Test
+    public void fields_in_prefixed_methods_are_transformed() throws Exception
+    {
+        Logger logger = mockLogger();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getTargetValue", null,
+                                                                    null);
+        Runnable runnable = mockRunnable();
+
+        runnable.run();
+
+        replay();
+
+        InternalClassTransformation ct = createClassTransformation(MethodPrefixTarget.class, logger);
+
+        String name = ct.addInjectedField(Runnable.class, "runnable", runnable);
+
+        // Transform the field.
+
+        TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int", "read_target_value",
+                                                                       null, null);
+
+        ct.addMethod(reader, "return 66;");
+
+        ct.replaceReadAccess("_targetField", "read_target_value");
+
+        ct.prefixMethod(sig, name + ".run();");
+
+        ct.finish();
+
+        Object target = instantiate(MethodPrefixTarget.class, ct, null);
+
+        // 66 reflects the change to the field.
+
+        assertEquals(access.get(target, "targetValue"), 66);
+
+        verify();
+    }
+
+    private Component instantiate(Class<?> expectedClass, InternalClassTransformation ct,
+                                  InternalComponentResources resources) throws Exception
+    {
+        Instantiator ins = ct.createInstantiator();
+
+        return ins.newInstance(resources);
+    }
+
+    @Test
+    public void extend_existing_method_fields_are_transformed() throws Exception
+    {
+        Logger logger = mockLogger();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getTargetValue", null,
+                                                                    null);
+        Runnable runnable = mockRunnable();
+
+        runnable.run();
+
+        replay();
+
+        InternalClassTransformation ct = createClassTransformation(MethodPrefixTarget.class, logger);
+
+        String name = ct.addInjectedField(Runnable.class, "runnable", runnable);
+
+        // Transform the field.
+
+        TransformMethodSignature reader = new TransformMethodSignature(Modifier.PRIVATE, "int", "read_target_value",
+                                                                       null, null);
+
+        ct.addMethod(reader, "return 66;");
+
+        ct.replaceReadAccess("_targetField", "read_target_value");
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+        builder.addln("%s.run();", name);
+        builder.addln("return $_ + 1;");
+        builder.end();
+
+        ct.extendExistingMethod(sig, builder.toString());
+
+        ct.finish();
+
+        Object target = instantiate(MethodPrefixTarget.class, ct, null);
+
+        // 66 reflects the change to the field, +1 reflects the extension of the method.
+
+        assertEquals(access.get(target, "targetValue"), 67);
+
+        verify();
+    }
+
+    @Test
+    public void invalid_code() throws Exception
+    {
+        Logger logger = mockLogger();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "getParentField", null,
+                                                                    null);
+
+        replay();
+
+        InternalClassTransformation ct = createClassTransformation(ParentClass.class, logger);
+
+        try
+        {
+            ct.prefixMethod(sig, "return supercalafragalistic;");
+            unreachable();
+        }
+        catch (MethodCompileException ex)
+        {
+
+        }
+
+        verify();
+    }
+
+
+    @Test
+    public void remove_field() throws Exception
+    {
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        replay();
+
+        CtClass targetObjectCtClass = findCtClass(FieldRemoval.class);
+
+        InternalClassTransformation ct = new InternalClassTransformationImpl(classFactory, targetObjectCtClass, null,
+                                                                             model, null);
+
+        ct.removeField("_fieldToRemove");
+
+        ct.finish();
+
+        Class transformed = toClass(targetObjectCtClass);
+
+        for (Field f : transformed.getDeclaredFields())
+        {
+            if (f.getName().equals("_fieldToRemove"))
+                throw new AssertionError("_fieldToRemove still in transformed class.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_method_identifier() throws Exception
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(MethodIdentifier.class, logger);
+
+        List<TransformMethodSignature> sigs = ct.findMethodsWithAnnotation(OnEvent.class);
+
+        assertEquals(sigs.size(), 1);
+
+        TransformMethodSignature sig = sigs.get(0);
+
+        assertEquals(ct.getMethodIdentifier(sig),
+                     "org.apache.tapestry.internal.transform.pages.MethodIdentifier.makeWaves(java.lang.String, int[]) (at MethodIdentifier.java:24)");
+
+        verify();
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
new file mode 100644
index 0000000..212dde9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
@@ -0,0 +1,665 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.util.Holder;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.*;
+import org.easymock.IAnswer;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class LinkFactoryImplTest extends InternalBaseTestCase
+{
+    private static final String ENCODED = "*encoded*";
+
+    private static final String PAGE_LOGICAL_NAME = "sub/MyPage";
+
+    private ContextValueEncoder contextValueEncoder;
+
+    @BeforeClass
+    public void setup()
+    {
+        contextValueEncoder = getObject(ContextValueEncoder.class, null);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        contextValueEncoder = null;
+    }
+
+    @Test
+    public void action_link_root_context_no_ids()
+    {
+        testActionLink("", PAGE_LOGICAL_NAME, "foo.bar", "someaction", "/sub/mypage.foo.bar:someaction");
+
+    }
+
+    @Test
+    public void action_link_root_context_with_ids()
+    {
+        testActionLink("", PAGE_LOGICAL_NAME, "foo.bar", "publish", "/sub/mypage.foo.bar:publish/fred/5", "fred", 5);
+    }
+
+    @Test
+    public void action_link_with_default_action()
+    {
+        testActionLink("", PAGE_LOGICAL_NAME, "foo.bar", EventConstants.ACTION, "/sub/mypage.foo.bar/fred/5",
+                       "fred", 5);
+    }
+
+    @Test
+    public void page_level_event_always_includes_action()
+    {
+        testActionLink("", PAGE_LOGICAL_NAME, "", EventConstants.ACTION, "/sub/mypage:action/barney/99",
+                       "barney", 99);
+    }
+
+    @Test
+    public void action_link_named_context_no_ids()
+    {
+        testActionLink("/fred", PAGE_LOGICAL_NAME, "foo.bar", "someaction", "/fred/sub/mypage.foo.bar:someaction");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void page_link()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        train_getLogicalName(page, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_triggerPassivateEventForPageLink(rootElement, listener, holder);
+
+        train_getBaseURL(securityManager, page, null);
+
+
+        train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME.toLowerCase() + "/foo/bar", ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(page, false);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @Test
+    public void secure_page_link()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        train_getLogicalName(page, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_triggerPassivateEventForPageLink(rootElement, listener, holder);
+
+
+        train_getBaseURL(securityManager, page, "https://example.org");
+
+
+        train_encodeRedirectURL(response,
+                                "https://example.org/barney/" + PAGE_LOGICAL_NAME.toLowerCase() + "/foo/bar",
+                                ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null,
+                                                  contextValueEncoder,
+                                                  securityManager);
+
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(page, false);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void page_link_using_supplied_activation_context()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        train_getLogicalName(page, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        Holder<Link> holder = new Holder<Link>();
+
+        IAnswer<Void> createdPageLinkAnswer = newAnswerForCreatedLink(holder);
+
+        listener.createdPageLink(isA(Link.class));
+        getMocksControl().andAnswer(createdPageLinkAnswer);
+
+        train_getBaseURL(securityManager, page, null);
+
+
+        train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME.toLowerCase() + "/biff/bazz", ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(page, false, "biff", "bazz");
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void page_link_using_empty_activation_context_and_override()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        train_getLogicalName(page, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        Holder<Link> holder = new Holder<Link>();
+
+        IAnswer<Void> createdPageLinkAnswer = newAnswerForCreatedLink(holder);
+
+        listener.createdPageLink(isA(Link.class));
+        getMocksControl().andAnswer(createdPageLinkAnswer);
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME.toLowerCase(), ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(page, true);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @Test
+    public void page_link_by_name()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        train_get(cache, PAGE_LOGICAL_NAME, page);
+
+        train_getLogicalName(page, PAGE_LOGICAL_NAME);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        // Answer for triggerEvent() which returns a boolean.
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_triggerPassivateEventForPageLink(rootElement, listener, holder);
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_encodeRedirectURL(response, "/barney/" + PAGE_LOGICAL_NAME.toLowerCase() + "/foo/bar", ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(PAGE_LOGICAL_NAME, false);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @Test
+    public void page_link_for_root_index()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        String logicalName = "Index";
+
+        train_get(cache, logicalName, page);
+
+        train_getLogicalName(page, logicalName);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        // Answer for triggerEvent() which returns a boolean.
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_triggerPassivateEventForPageLink(rootElement, listener, holder);
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_encodeRedirectURL(response, "/barney/foo/bar", ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(logicalName, false);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @Test
+    public void page_link_for_index_in_folder()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        String logicalName = "mylib/stuff/Index";
+
+        train_get(cache, logicalName, page);
+
+        train_getLogicalName(page, logicalName);
+        train_getContextPath(request, "/barney");
+
+        train_getRootElement(page, rootElement);
+
+        // Answer for triggerEvent() which returns a boolean.
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_triggerPassivateEventForPageLink(rootElement, listener, holder);
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_encodeRedirectURL(response, "/barney/mylib/stuff/foo/bar", ENCODED);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, null, contextValueEncoder,
+                                                  securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createPageLink(logicalName, false);
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        // Make sure the link was passed to the LinkFactoryListener
+
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void train_triggerPassivateEventForPageLink(ComponentPageElement rootElement, LinkFactoryListener listener,
+                                                        Holder<Link> holder)
+    {
+        IAnswer<Boolean> triggerEventAnswer = newAnswerForPassivateEventTrigger();
+
+        IAnswer<Void> createdPageLinkAnswer = newAnswerForCreatedLink(holder);
+
+        // Intercept the call to handle component event, and let the IAnswer
+        // do the work.
+
+        expect(rootElement.triggerEvent(eq(EventConstants.PASSIVATE), (Object[]) isNull(),
+                                        isA(ComponentEventCallback.class))).andAnswer(triggerEventAnswer);
+
+        listener.createdPageLink(isA(Link.class));
+        getMocksControl().andAnswer(createdPageLinkAnswer);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void train_triggerPassivateEventForActionLink(ComponentPageElement rootElement,
+                                                          LinkFactoryListener listener, Holder<Link> holder)
+    {
+        IAnswer<Boolean> triggerEventAnswer = newAnswerForPassivateEventTrigger();
+
+        IAnswer<Void> createdPageLinkAnswer = newAnswerForCreatedLink(holder);
+
+        // Intercept the call to handle component event, and let the IAnswer
+        // do the work.
+
+        expect(rootElement.triggerEvent(eq(EventConstants.PASSIVATE), (Object[]) isNull(),
+                                        isA(ComponentEventCallback.class))).andAnswer(triggerEventAnswer);
+
+        listener.createdActionLink(isA(Link.class));
+        getMocksControl().andAnswer(createdPageLinkAnswer);
+    }
+
+    private IAnswer<Void> newAnswerForCreatedLink(final Holder<Link> holder)
+    {
+        return new IAnswer<Void>()
+        {
+            public Void answer() throws Throwable
+            {
+                Link link = (Link) EasyMock.getCurrentArguments()[0];
+
+                holder.put(link);
+
+                return null;
+            }
+        };
+    }
+
+    private IAnswer<Boolean> newAnswerForPassivateEventTrigger()
+    {
+        return new IAnswer<Boolean>()
+        {
+            @SuppressWarnings("unchecked")
+            public Boolean answer() throws Throwable
+            {
+                ComponentEventCallback handler = (ComponentEventCallback) EasyMock
+                        .getCurrentArguments()[2];
+
+                handler.handleResult(new Object[] { "foo", "bar" });
+
+                return true;
+            }
+        };
+    }
+
+    @Test
+    public void action_with_context_that_contains_periods()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        PageRenderQueue queue = mockPageRenderQueue();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        String optimizedPath = "/optimized/path";
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_getLogicalName(page, "mypage");
+        train_getContextPath(request, "");
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_optimizePath(optimizer, "/mypage:myaction/1.2.3/4.5.6?t:ac=foo/bar", optimizedPath);
+
+        train_getRootElement(page, rootElement);
+        train_triggerPassivateEventForActionLink(rootElement, listener, holder);
+
+        train_getRenderingPage(queue, page);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocation.class));
+
+        train_encodeURL(response, "/optimized/path", ENCODED);
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  contextValueEncoder, securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createActionLink(page, null, "myaction", false, "1.2.3", "4.5.6");
+
+        assertEquals(link.toURI(), ENCODED);
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+    /**
+     * For good measure, we're going to also test a security change.
+     */
+    @Test
+    public void action_for_non_active_page()
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page containingPage = mockPage();
+        Page activePage = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        PageRenderQueue queue = mockPageRenderQueue();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_getLogicalName(containingPage, "MyPage");
+        train_getContextPath(request, "");
+
+
+        train_getRootElement(activePage, rootElement);
+        train_triggerPassivateEventForActionLink(rootElement, listener, holder);
+
+        train_getRenderingPage(queue, activePage);
+
+        train_getLogicalName(activePage, "ActivePage");
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocation.class));
+
+        train_getBaseURL(securityManager, activePage, "http://example.org");
+
+        train_encodeURL(response, "http://example.org/activepage:myaction?t:ac=foo/bar&t:cp=mypage", ENCODED);
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  contextValueEncoder, securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createActionLink(containingPage, null, "myaction", false);
+
+        assertEquals(link.toURI(), ENCODED);
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private void testActionLink(String contextPath, String logicalPageName, String nestedId, String eventName,
+                                String expectedURI, Object... context)
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        Page page = mockPage();
+        LinkFactoryListener listener = mockLinkFactoryListener();
+        ComponentInvocationMap map = mockComponentInvocationMap();
+        RequestPageCache cache = mockRequestPageCache();
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        PageRenderQueue queue = mockPageRenderQueue();
+        RequestSecurityManager securityManager = mockRequestSecurityManager();
+
+
+        String optimizedPath = "/optimized/path";
+
+        String generatedPath = String.format("%s?%s=foo/bar", expectedURI, InternalConstants.PAGE_CONTEXT_NAME);
+
+        final Holder<Link> holder = new Holder<Link>();
+
+        train_getLogicalName(page, logicalPageName);
+        train_getContextPath(request, contextPath);
+
+        train_optimizePath(optimizer, generatedPath, optimizedPath);
+
+        train_getRootElement(page, rootElement);
+        train_triggerPassivateEventForActionLink(rootElement, listener, holder);
+
+        train_getRenderingPage(queue, page);
+
+        // This needs to be refactored a bit to be more testable.
+
+        map.store(isA(Link.class), isA(ComponentInvocationImpl.class));
+
+        train_getBaseURL(securityManager, page, null);
+
+        train_encodeURL(response, optimizedPath, ENCODED);
+
+        replay();
+
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  contextValueEncoder, securityManager);
+        factory.addListener(listener);
+
+        Link link = factory.createActionLink(page, nestedId, eventName, false, context);
+
+        assertEquals(link.toURI(), ENCODED);
+        assertSame(link, holder.get());
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkImplTest.java
new file mode 100644
index 0000000..2a1e1c2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkImplTest.java
@@ -0,0 +1,259 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Response;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+public class LinkImplTest extends InternalBaseTestCase
+{
+    private static final String OPTIMIZED = "/optimized/path";
+
+    private static final String ENCODED = "*encoded*";
+
+
+    @Test
+    public void simple_redirect()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        train_encodeRedirectURL(response, "/foo/bar", ENCODED);
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+
+        assertEquals(link.toRedirectURI(), ENCODED);
+
+        verify();
+    }
+
+    @Test
+    public void to_string_same_as_to_uri()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        train_optimizePath(optimizer, "/foo/bar", OPTIMIZED);
+        train_encodeURL(response, OPTIMIZED, ENCODED);
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+
+        assertEquals(link.toString(), ENCODED);
+
+        verify();
+    }
+
+    @Test
+    public void url_with_parameters()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        train_optimizePath(optimizer, "/foo/bar?barney=rubble&fred=flintstone", OPTIMIZED);
+        train_encodeURL(response, OPTIMIZED, ENCODED);
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+        link.addParameter("fred", "flintstone");
+        link.addParameter("barney", "rubble");
+
+        assertEquals(link.toURI(), ENCODED);
+
+        verify();
+    }
+
+    @Test
+    public void retrieve_parameter_values()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "", "bar");
+
+        link.addParameter("fred", "flintstone");
+        link.addParameter("barney", "rubble");
+
+        assertEquals(link.getParameterValue("fred"), "flintstone");
+        assertEquals(link.getParameterValue("barney"), "rubble");
+        assertNull(link.getParameterValue("wilma"));
+
+        verify();
+    }
+
+    @Test
+    public void parameter_names_must_be_unique()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+        link.addParameter("fred", "flintstone");
+        try
+        {
+            link.addParameter("fred", "flintstone");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Parameter names are required to be unique.  Parameter 'fred' already has the value 'flintstone'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void to_form_URI_does_not_include_parameters()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        train_optimizePath(optimizer, "/foo/bar", OPTIMIZED);
+        train_encodeURL(response, OPTIMIZED, ENCODED);
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar", true);
+
+        link.addParameter("fred", "flintstone");
+        link.addParameter("barney", "rubble");
+
+        assertEquals(link.toURI(), ENCODED);
+
+        verify();
+    }
+
+    @Test
+    public void url_with_anchor()
+    {
+        url_with_anchor("wilma", "/foo/bar#wilma");
+    }
+
+    @Test
+    public void url_with_null_anchor()
+    {
+        url_with_anchor(null, "/foo/bar");
+    }
+
+    @Test
+    public void url_with_empty_anchor()
+    {
+        url_with_anchor("", "/foo/bar");
+    }
+
+    private void url_with_anchor(String anchor, String url)
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+
+        train_optimizePath(optimizer, url, OPTIMIZED);
+        train_encodeURL(response, OPTIMIZED, ENCODED);
+
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+        link.setAnchor(anchor);
+
+        assertSame(link.getAnchor(), anchor);
+
+        assertEquals(link.toURI(), ENCODED);
+
+        verify();
+    }
+
+    @Test
+    public void url_with_anchor_and_parameters()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+
+        train_optimizePath(optimizer, "/foo/bar?barney=rubble&fred=flintstone#wilma", OPTIMIZED);
+        train_encodeURL(response, OPTIMIZED, ENCODED);
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+        link.addParameter("fred", "flintstone");
+        link.addParameter("barney", "rubble");
+        link.setAnchor("wilma");
+
+        assertEquals(link.toURI(), ENCODED);
+
+        verify();
+    }
+
+
+    @Test
+    public void force_absolute_uri()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+
+        train_encodeURL(response, "/ctx/foo", ENCODED);
+
+        replay();
+
+
+        Link link = new LinkImpl(response, optimizer, null, "/ctx",
+                                 new ComponentInvocationImpl(new OpaqueConstantTarget("foo"), new String[0], null),
+                                 false);
+
+        assertEquals(link.toAbsoluteURI(), ENCODED);
+
+
+        verify();
+    }
+
+    @Test
+    public void parameter_names_are_returned_sorted()
+    {
+        RequestPathOptimizer optimizer = mockRequestPathOptimizer();
+        Response response = mockResponse();
+
+        replay();
+
+        Link link = new LinkImpl(response, optimizer, "/foo", "bar");
+
+        link.addParameter("fred", "flintstone");
+        link.addParameter("barney", "rubble");
+
+        assertEquals(link.getParameterNames(), Arrays.asList("barney", "fred"));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationFilterTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationFilterTest.java
new file mode 100644
index 0000000..75ddd32
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationFilterTest.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.RequestFilter;
+import org.apache.tapestry.services.RequestHandler;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Locale;
+
+public class LocalizationFilterTest extends TapestryTestCase
+{
+    @Test
+    public void set_locale_and_service() throws IOException
+    {
+        RequestHandler handler = mockRequestHandler();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        LocalizationSetter setter = newMock(LocalizationSetter.class);
+
+        train_getLocale(request, Locale.CANADA_FRENCH);
+
+        // We don't actually verify that setThreadLocale() occurs before service(),
+        // but sometimes you just have to trust that the code executes in the
+        // order its written.
+        setter.setThreadLocale(Locale.CANADA_FRENCH);
+
+        train_service(handler, request, response, true);
+
+        replay();
+
+        RequestFilter filter = new LocalizationFilter(setter);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationSetterImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationSetterImplTest.java
new file mode 100644
index 0000000..9a32ed8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LocalizationSetterImplTest.java
@@ -0,0 +1,155 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.services.PersistentLocale;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class LocalizationSetterImplTest extends Assert
+{
+    private PersistentLocale nullPersistentLocale = new PersistentLocale()
+    {
+        public boolean isSet()
+        {
+            return false;
+        }
+
+        public Locale get()
+        {
+            return null;
+        }
+
+        public void set(Locale locale)
+        {
+
+        }
+
+    };
+
+    private PersistentLocale frenchPersistentLocale = new PersistentLocale()
+    {
+        public boolean isSet()
+        {
+            return true;
+        }
+
+        public Locale get()
+        {
+            return Locale.FRENCH;
+        }
+
+        public void set(Locale locale)
+        {
+
+        }
+
+    };
+
+    private static class ThreadLocaleImpl implements ThreadLocale
+    {
+        public Locale _locale;
+
+        public void setLocale(Locale locale)
+        {
+            _locale = locale;
+        }
+
+        public Locale getLocale()
+        {
+            return _locale;
+        }
+
+    }
+
+    @Test
+    public void locale_split()
+    {
+        assertEquals(LocalizationSetterImpl.stripTerm("foo_bar_Baz"), "foo_bar");
+        assertEquals(LocalizationSetterImpl.stripTerm("foo_bar"), "foo");
+        assertEquals(LocalizationSetterImpl.stripTerm("foo"), "");
+    }
+
+    @Test
+    public void to_locale_is_cached()
+    {
+        LocalizationSetterImpl filter = new LocalizationSetterImpl(nullPersistentLocale, null,
+                                                                   "en");
+
+        Locale l1 = filter.toLocale("en");
+
+        assertEquals(l1.toString(), "en");
+
+        checkLocale(l1, "en", "", "");
+
+        assertSame(filter.toLocale("en"), l1);
+    }
+
+    private void checkLocale(Locale l, String expectedLanguage, String expectedCountry,
+                             String expectedVariant)
+    {
+        assertEquals(l.getLanguage(), expectedLanguage);
+        assertEquals(l.getCountry(), expectedCountry);
+        assertEquals(l.getVariant(), expectedVariant);
+    }
+
+    @Test
+    public void to_locale()
+    {
+        LocalizationSetterImpl filter = new LocalizationSetterImpl(nullPersistentLocale, null,
+                                                                   "en");
+
+        checkLocale(filter.toLocale("en"), "en", "", "");
+        checkLocale(filter.toLocale("klingon_Gach"), "klingon", "GACH", "");
+        checkLocale(filter.toLocale("klingon_Gach_snuff"), "klingon", "GACH", "snuff");
+    }
+
+    @Test
+    public void known_locale()
+    {
+        ThreadLocale threadLocale = new ThreadLocaleImpl();
+        threadLocale.setLocale(Locale.FRENCH);
+        LocalizationSetter setter = new LocalizationSetterImpl(nullPersistentLocale, threadLocale,
+                                                               "en,fr");
+        setter.setThreadLocale(Locale.CANADA_FRENCH);
+        assertEquals(threadLocale.getLocale(), Locale.FRENCH);
+
+    }
+
+    @Test
+    public void unknown_locale_uses_default_locale()
+    {
+        ThreadLocale threadLocale = new ThreadLocaleImpl();
+        threadLocale.setLocale(Locale.FRENCH);
+        LocalizationSetter setter = new LocalizationSetterImpl(nullPersistentLocale, threadLocale,
+                                                               "en,fr");
+        setter.setThreadLocale(Locale.JAPANESE);
+        assertEquals(threadLocale.getLocale(), Locale.ENGLISH);
+    }
+
+    @Test
+    public void use_persistent_locale()
+    {
+        ThreadLocale threadLocale = new ThreadLocaleImpl();
+        LocalizationSetter setter = new LocalizationSetterImpl(frenchPersistentLocale,
+                                                               threadLocale, "en,fr");
+        setter.setThreadLocale(Locale.ENGLISH);
+        assertEquals(threadLocale.getLocale(), Locale.FRENCH);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java
new file mode 100644
index 0000000..2ee7fd0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MarkupWriterImplTest.java
@@ -0,0 +1,308 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.MarkupWriterListener;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class MarkupWriterImplTest extends InternalBaseTestCase
+{
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void write_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.write("fail!");
+    }
+
+    @Test
+    public void write_whitespace_before_start_of_root_element_is_ignored()
+    {
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        w.write("  ");
+
+        w.element("root");
+        w.end();
+
+        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n<root/>");
+    }
+
+    @Test
+    public void write_whitespace_after_end_of_root_element_is_ignored()
+    {
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        w.element("root");
+        w.end();
+
+        w.write("  ");
+
+        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n<root/>");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void comment_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.comment("fail!");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void attribute_ns_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.attributeNS("foo", "bar", "baz");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void define_namespace_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.defineNamespace("foo", "bar");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void end_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.end();
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void attributes_with_no_current_element()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.attributes("fail", "now");
+    }
+
+    @Test
+    public void current_element_at_end_of_root_element_is_null()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+
+        assertNull(w.end());
+    }
+
+    @Test
+    public void element_nesting()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        Element root = w.element("root");
+
+        w.attributes("foo", "bar");
+
+        w.write("before child");
+
+        assertNotSame(w.element("nested"), root);
+
+        w.write("inner text");
+
+        assertSame(w.end(), root);
+
+        w.write("after child");
+
+        root.attribute("gnip", "gnop");
+
+        assertEquals(w.toString(),
+                     "<root foo=\"bar\" gnip=\"gnop\">before child<nested>inner text</nested>after child</root>");
+    }
+
+    @Test
+    public void element_with_attributes()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("img", "src", "foo.png", "width", 20, "height", 20);
+        w.end();
+
+        // img is a tag with an end tag style of omit, so no close tag is written.
+
+        assertEquals(w.toString(), "<img height=\"20\" src=\"foo.png\" width=\"20\">");
+    }
+
+    @Test
+    public void attributes()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+
+        w.attributes("foo", "bar", "gnip", "gnop");
+
+        assertEquals(w.toString(), "<root foo=\"bar\" gnip=\"gnop\"></root>");
+    }
+
+    @Test
+    public void comment()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+        w.comment("A comment");
+        w.end();
+
+        assertEquals(w.toString(), "<root><!-- A comment --></root>");
+    }
+
+    @Test
+    public void new_text_node_after_comment_node()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+        w.write("before");
+        w.comment("A comment");
+        w.write("after");
+        w.end();
+
+        assertEquals(w.toString(), "<root>before<!-- A comment -->after</root>");
+    }
+
+    @Test
+    public void null_write_is_ok()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+        w.write(null);
+        w.end();
+
+        assertEquals(w.toString(), "<root></root>");
+    }
+
+    @Test
+    public void writef()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+        w.writef("Test name: %s", "writef");
+
+        assertEquals(w.toString(), "<root>Test name: writef</root>");
+    }
+
+
+    @Test
+    public void write_raw()
+    {
+        MarkupWriter w = new MarkupWriterImpl();
+
+        w.element("root");
+        w.write("<");
+        w.writeRaw("&nbsp;");
+        w.write(">");
+        w.end();
+
+        assertEquals(w.toString(), "<root>&lt;&nbsp;&gt;</root>");
+    }
+
+    @Test
+    public void namespaced_elements_and_attributes()
+    {
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        Element root = w.elementNS("fredns", "root");
+
+        assertSame(root.defineNamespace("fredns", "fred"), root);
+
+        root.defineNamespace("barneyns", "barney");
+
+        assertSame(w.attributeNS("fredns", "foo", "bar"), root);
+
+        Element child = w.elementNS("barneyns", "child");
+
+        assertSame(child.getParent(), root);
+
+        w.end(); // child
+        w.end(); // root
+
+        assertEquals(w.toString(),
+                     "<?xml version=\"1.0\"?>\n<fred:root fred:foo=\"bar\" xmlns:barney=\"barneyns\" xmlns:fred=\"fredns\"><barney:child/></fred:root>");
+    }
+
+    @Test
+    public void cdata_content()
+    {
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        w.element("root");
+        w.write("Normal Text ");
+        w.cdata("< & >");
+        w.write("More Normal Text");
+
+        assertEquals(w.toString(),
+                     "<?xml version=\"1.0\"?>\n<root>Normal Text <![CDATA[< & >]]>More Normal Text</root>");
+    }
+
+    @Test
+    public void listeners()
+    {
+        MarkupWriter w = new MarkupWriterImpl(new XMLMarkupModel());
+
+        MarkupWriterListener l = new MarkupWriterListener()
+        {
+            public void elementDidStart(Element element)
+            {
+                element.text("[Start: " + element.getName() + "]");
+            }
+
+            public void elementDidEnd(Element element)
+            {
+                element.text("[End: " + element.getName() + "]");
+            }
+        };
+
+        w.element("root");
+        w.element("no-listener");
+
+        w.write("before listener");
+
+        w.addListener(l);
+
+        w.element("listener");
+        w.write("before n-w-l");
+        w.element("nested-with-listener");
+        w.write("n-w-l text");
+        w.end();
+        w.write("after n-w-l");
+        w.end();
+
+        w.removeListener(l);
+
+        w.write("after listener");
+
+        w.end();
+        w.end();
+
+        // Because we are invoking Element.text(), the text added by the listener is appended to the body of the element,
+        // which is correct but may not be what you'd expect.
+
+        assertEquals(w.toString(), "<?xml version=\"1.0\"?>\n" +
+                "<root><no-listener>before listener<listener>[Start: listener]before n-w-l<nested-with-listener>[Start: nested-with-listener]n-w-l text[End: nested-with-listener]</nested-with-listener>after n-w-l[End: listener]</listener>after listener</no-listener></root>");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java
new file mode 100644
index 0000000..eb80725
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/MetaDataLocatorImplTest.java
@@ -0,0 +1,311 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class MetaDataLocatorImplTest extends InternalBaseTestCase
+{
+    private TypeCoercer typeCoercer;
+
+    @BeforeClass
+    public void setup()
+    {
+        typeCoercer = getService(TypeCoercer.class);
+    }
+
+    @Test
+    public void found_in_component()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "foo.Bar:baz";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, value);
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = Collections.emptyMap();
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+
+        // And check that it's cached:
+
+        train_getCompleteId(resources, completeId);
+
+        replay();
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    @Test
+    public void found_in_container()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentResources containerResources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        ComponentModel containerModel = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "foo.Bar:baz";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, null);
+        train_getContainerResources(resources, containerResources);
+        train_getComponentModel(containerResources, containerModel);
+        train_getMeta(containerModel, key, value);
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = Collections.emptyMap();
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    @Test
+    public void found_via_high_level_default()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "Bar";
+        String logicalPageName = completeId;
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, null);
+        train_getContainerResources(resources, null);
+
+        train_getPageName(resources, logicalPageName);
+
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = newMap();
+        configuration.put(key, value);
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+
+        // And check that it's cached:
+
+        train_getCompleteId(resources, completeId);
+
+        replay();
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    @Test
+    public void default_matching_is_case_insensitive()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "foo.Bar";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, null);
+        train_getContainerResources(resources, null);
+
+        train_getPageName(resources, "foo/Bar");
+
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = newMap();
+        configuration.put(key.toUpperCase(), value);
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+
+        // And check that it's cached:
+
+        train_getCompleteId(resources, completeId);
+
+        replay();
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    @Test
+    public void subfolder_default_overrides_high_level_default()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "foo.Bar";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, null);
+        train_getContainerResources(resources, null);
+
+        train_getPageName(resources, "foo/Bar");
+
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = newMap();
+        configuration.put(key, "xxx");
+        configuration.put("foo:" + key, value);
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+
+        // And check that it's cached:
+
+        train_getCompleteId(resources, completeId);
+
+        replay();
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    @Test
+    public void test_cache_cleared()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "zaphod";
+        String completeId = "foo.Bar:baz";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, value);
+
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        Map<String, String> configuration = Collections.emptyMap();
+
+        MetaDataLocatorImpl locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+
+        // And check that it's cached:
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, value);
+
+        train_expandSymbols(symbolSource, value, value);
+
+        replay();
+
+        locator.objectWasInvalidated();
+
+        assertSame(locator.findMeta(key, resources, String.class), value);
+
+        verify();
+    }
+
+    /**
+     * Makes sense to test together to ensure that the expanded value is what's fed to the type coercer.
+     */
+    @Test
+    public void train_symbols_expanded_and_types_coerced()
+    {
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        String key = "foo.bar";
+        String value = "${zaphod}";
+        String expandedValue = "99";
+        String completeId = "foo.Bar:baz";
+
+        train_getCompleteId(resources, completeId);
+        train_getComponentModel(resources, model);
+        train_getMeta(model, key, value);
+        train_expandSymbols(symbolSource, value, expandedValue);
+
+        replay();
+
+        Map<String, String> configuration = Collections.emptyMap();
+
+        MetaDataLocator locator = new MetaDataLocatorImpl(symbolSource, typeCoercer, configuration);
+
+        assertEquals(locator.findMeta(key, resources, Integer.class), new Integer(99));
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/Named.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/Named.java
new file mode 100644
index 0000000..2ba746e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/Named.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+/**

+ * Used by {@link org.apache.tapestry.internal.services.ComponentInstantiatorSourceImplTest}.

+ */

+public interface Named

+{

+    String getName();

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NoOpCookieSource.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NoOpCookieSource.java
new file mode 100644
index 0000000..82c3952
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NoOpCookieSource.java
@@ -0,0 +1,63 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.services.Cookies;
+
+public class NoOpCookieSource implements Cookies
+{
+
+    public String readCookieValue(String name)
+    {
+        return null;
+    }
+
+    public void writeCookieValue(String name, String value)
+    {
+
+    }
+
+    public void writeCookieValue(String name, String value, int maxAge)
+    {
+
+    }
+
+    public void writeCookieValue(String name, String value, String path)
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void writeDomainCookieValue(String name, String value, String domain)
+    {
+
+    }
+
+    public void writeDomainCookieValue(String name, String value, String domain, int maxAge)
+    {
+
+    }
+
+    public void writeCookieValue(String name, String value, String path, String domain)
+    {
+
+    }
+
+    public void removeCookieValue(String name)
+    {
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NonVisualBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NonVisualBean.java
new file mode 100644
index 0000000..60d34e5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NonVisualBean.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.beaneditor.NonVisual;
+
+public class NonVisualBean
+{
+    private int id;
+
+    private String name;
+
+    @NonVisual
+    public int getId()
+    {
+        return id;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImplTest.java
new file mode 100644
index 0000000..159ab74
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/NullFieldStrategySourceImplTest.java
@@ -0,0 +1,68 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.NullFieldStrategy;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.NullFieldStrategySource;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class NullFieldStrategySourceImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void success()
+    {
+        NullFieldStrategy strategy = mockNullFieldStrategy();
+
+        replay();
+
+        Map<String, NullFieldStrategy> configuration = Collections.singletonMap("strat", strategy);
+
+        NullFieldStrategySource source = new NullFieldStrategySourceImpl(configuration);
+
+        assertSame(source.get("strat"), strategy);
+
+        verify();
+    }
+
+    @Test
+    public void failure()
+    {
+        Map<String, NullFieldStrategy> configuration = CollectionFactory.newCaseInsensitiveMap();
+
+        configuration.put("fred", mockNullFieldStrategy());
+        configuration.put("barney", mockNullFieldStrategy());
+
+        replay();
+
+        NullFieldStrategySource source = new NullFieldStrategySourceImpl(configuration);
+
+        try
+        {
+            source.get("wilma");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Unrecognized name 'wilma' locating a null field strategy.  Available strategies: barney, fred.");
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java
new file mode 100644
index 0000000..85d4294
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java
@@ -0,0 +1,60 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentEventResultProcessor;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class ObjectComponentEventResultProcessorTest extends TapestryTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void invocation_is_failure() throws Exception
+    {
+        ComponentResources resources = mockComponentResources();
+        Component component = mockComponent();
+        String result = "*INVALID*";
+
+        train_getComponentResources(component, resources);
+        train_getCompleteId(resources, "foo.Bar:gnip.gnop");
+
+        List classes = Arrays.asList(String.class, List.class, Map.class);
+
+        replay();
+
+        ComponentEventResultProcessor p = new ObjectComponentEventResultProcessor(classes);
+
+        try
+        {
+            p.processResultValue(result);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "A component event handler method returned the value *INVALID*.",
+                                  "Return type java.lang.String can not be handled.",
+                                  "Configured return types are java.lang.String, java.util.List, java.util.Map.");
+
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java
new file mode 100644
index 0000000..a449ff7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java
@@ -0,0 +1,93 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.dom.MarkupModel;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.parser.AttributeToken;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry5.services.ComponentMessagesSource;
+import org.testng.annotations.Test;
+
+public class PageElementFactoryImplTest extends InternalBaseTestCase
+{
+    private static MarkupModel xmlModel = new XMLMarkupModel();
+
+    @Test
+    public void attribute()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        MarkupWriter writer = new MarkupWriterImpl(xmlModel);
+        Location l = mockLocation();
+        RenderQueue queue = mockRenderQueue();
+
+        replay();
+
+        PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null, null, null);
+        AttributeToken token = new AttributeToken(null, "name", "value", l);
+
+        PageElement element = factory.newAttributeElement(null, token);
+
+        writer.element("root");
+
+        element.render(writer, queue);
+
+        verify();
+
+        assertEquals(writer.toString(), "<?xml version=\"1.0\"?>\n<root name=\"value\"/>");
+    }
+
+
+    @Test
+    public void unclosed_attribute_expression()
+    {
+        ComponentInstantiatorSource source = mockComponentInstantiatorSource();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        TypeCoercer typeCoercer = mockTypeCoercer();
+        BindingSource bindingSource = mockBindingSource();
+        ComponentMessagesSource messagesSource = newMock(ComponentMessagesSource.class);
+        ComponentResources resources = mockComponentResources();
+        Location location = mockLocation();
+
+        AttributeToken token = new AttributeToken(null, "fred", "${flintstone", location);
+
+        replay();
+
+        PageElementFactory factory = new PageElementFactoryImpl(source, resolver, typeCoercer, bindingSource, null);
+
+        try
+        {
+            factory.newAttributeElement(resources, token);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(), "Attribute expression \'${flintstone\' is missing a closing brace.");
+            assertSame(ex.getLocation(), location);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java
new file mode 100644
index 0000000..a0f03fc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java
@@ -0,0 +1,174 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.EndElementToken;
+import org.apache.tapestry.internal.parser.StartComponentToken;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.EmbeddedComponentModel;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.easymock.EasyMock;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+public class PageLoaderImplTest extends InternalBaseTestCase
+{
+    private static final String LOGICAL_PAGE_NAME = "Bar";
+
+    private static final String PAGE_CLASS_NAME = "foo.page.Bar";
+
+    private static final String CHILD_CLASS_NAME = "foo.component.Baz";
+
+    private static final Locale LOCALE = Locale.ENGLISH;
+
+    @Test
+    public void not_all_embedded_components_in_template()
+    {
+        ComponentTemplateSource templateSource = mockComponentTemplateSource();
+        PageElementFactory elementFactory = mockPageElementFactory();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        InternalComponentResources resources = mockInternalComponentResources();
+        ComponentModel model = mockComponentModel();
+        ComponentTemplate template = mockComponentTemplate();
+        Logger logger = mockLogger();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_resolvePageNameToClassName(resolver, LOGICAL_PAGE_NAME, PAGE_CLASS_NAME);
+
+        train_newRootComponentElement(elementFactory, PAGE_CLASS_NAME, rootElement, LOCALE);
+
+        train_getComponentResources(rootElement, resources);
+        train_getComponentModel(resources, model);
+
+        train_getComponentClassName(model, PAGE_CLASS_NAME);
+
+        train_getTemplate(templateSource, model, LOCALE, template);
+
+        train_isMissing(template, false);
+
+        train_getLogger(model, logger);
+
+        train_getEmbeddedIds(model, "foo", "bar", "baz");
+
+        train_getComponentIds(template, "baz", "biff");
+
+        logger.error(ServicesMessages.embeddedComponentsNotInTemplate(Arrays.asList("foo", "bar"), PAGE_CLASS_NAME));
+
+        train_getTokens(template);
+
+        replay();
+
+        PageLoader loader = new PageLoaderImpl(templateSource, elementFactory, null, null, resolver);
+
+        Page page = loader.loadPage(LOGICAL_PAGE_NAME, LOCALE);
+
+        assertSame(page.getLogicalName(), LOGICAL_PAGE_NAME);
+
+        verify();
+    }
+
+    @Test
+    public void type_conflict_between_template_and_class()
+    {
+        ComponentTemplateSource templateSource = mockComponentTemplateSource();
+        PageElementFactory elementFactory = mockPageElementFactory();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        InternalComponentResources resources = mockInternalComponentResources();
+        ComponentModel model = mockComponentModel();
+        ComponentModel childModel = mockComponentModel();
+        ComponentTemplate template = mockComponentTemplate();
+        Logger logger = mockLogger();
+        EmbeddedComponentModel emodel = mockEmbeddedComponentModel();
+        ComponentPageElement childElement = mockComponentPageElement();
+        InternalComponentResources childResources = mockInternalComponentResources();
+        Location l = mockLocation();
+        PageElement body = mockPageElement();
+        ComponentTemplate childTemplate = mockComponentTemplate();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_resolvePageNameToClassName(resolver, LOGICAL_PAGE_NAME, PAGE_CLASS_NAME);
+        train_newRootComponentElement(elementFactory, PAGE_CLASS_NAME, rootElement, LOCALE);
+
+        train_getComponentResources(rootElement, resources);
+        train_getComponentModel(resources, model);
+
+        train_getComponentClassName(model, PAGE_CLASS_NAME);
+
+        train_getTemplate(templateSource, model, LOCALE, template);
+
+
+        train_isMissing(template, false);
+
+        train_getLogger(model, logger);
+
+        train_getEmbeddedIds(model, "foo");
+
+        train_getComponentIds(template, "foo");
+
+        train_getTokens(template, new StartComponentToken(null, "foo", "Fred", null, l), new EndElementToken(null));
+
+        train_getEmbeddedComponentModel(model, "foo", emodel);
+
+        train_getComponentType(emodel, "Barney");
+
+        train_getMixinClassNames(emodel);
+
+        logger.error(ServicesMessages.compTypeConflict("foo", "Fred", "Barney"));
+
+        train_getComponentClassName(emodel, "foo.components.Barney");
+
+        train_newComponentElement(elementFactory, rootElement, "foo", "Barney", "foo.components.Barney", null, l,
+                                  childElement);
+
+        train_getCompleteId(childElement, PAGE_CLASS_NAME + "/Barney");
+
+        train_getInheritInformalParameters(emodel, false);
+
+        rootElement.addToTemplate(childElement);
+
+        train_getParameterNames(emodel);
+
+        // Alas, what comes next is the recursive call to load the child element
+
+        train_getComponentResources(childElement, childResources);
+        train_getComponentModel(childResources, childModel);
+        train_getComponentClassName(childModel, CHILD_CLASS_NAME);
+        train_getTemplate(templateSource, childModel, LOCALE, childTemplate);
+        train_isMissing(childTemplate, true);
+
+        // This will be the RenderBody element ...
+
+        childElement.addToTemplate(EasyMock.isA(PageElement.class));
+
+        replay();
+
+        PageLoader loader = new PageLoaderImpl(templateSource, elementFactory, null, null, resolver);
+
+        loader.loadPage(LOGICAL_PAGE_NAME, LOCALE);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLocatorTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLocatorTest.java
new file mode 100644
index 0000000..235fc2c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLocatorTest.java
@@ -0,0 +1,42 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class PageLocatorTest extends Assert
+{
+    @Test
+    public void equals()
+    {
+        PageLocator locator = new PageLocator("p1", Locale.ENGLISH);
+        assertEquals(locator, new PageLocator("p1", Locale.ENGLISH));
+        assertFalse(locator.equals(null));
+        assertFalse(locator.equals("p1"));
+        assertFalse(locator.equals(new PageLocator("p1", Locale.CHINESE)));
+        assertFalse(locator.equals(new PageLocator("p2", Locale.ENGLISH)));
+    }
+
+    @Test
+    public void to_string()
+    {
+        PageLocator locator = new PageLocator("p1", Locale.ENGLISH);
+        assertEquals(locator.toString(), "PageLocator[p1, en]");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolCacheTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolCacheTest.java
new file mode 100644
index 0000000..ddc9fc7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolCacheTest.java
@@ -0,0 +1,276 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class PagePoolCacheTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "mypage";
+    private static final Locale LOCALE = Locale.ENGLISH;
+
+    @Test
+    public void inside_of_soft_limit()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 5, 100, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        verify();
+    }
+
+    @Test
+    public void reuse_existing_page()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 5, 100, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        cache.release(page1);
+
+        assertSame(cache.checkout(), page1);
+
+        verify();
+    }
+
+    @Test
+    public void remove_does_not_reuse_page()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+        Page page3 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page3);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 5, 100, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        cache.remove(page1);
+
+        assertSame(cache.checkout(), page3);
+
+        verify();
+    }
+
+    @Test
+    public void new_instance_after_soft_wait()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 1, 500, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+
+        long start = System.currentTimeMillis();
+
+        assertSame(cache.checkout(), page2);
+
+        long elapsed = System.currentTimeMillis() - start;
+
+        // Fudging a bit because Java clocks are notoriously innaccurate
+
+        assertTrue(elapsed > 490, "A delay should have occured.");
+
+        verify();
+    }
+
+    @Test
+    public void hard_limit_failure()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 1, 10, 1, 1000);
+
+        assertSame(cache.checkout(), page1);
+
+        try
+        {
+            cache.checkout();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "The page pool for page 'mypage' (in locale en) has been exausted: there are 1 instances currently being used and no more can be created");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void page_released_by_other_thread() throws Exception
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        final Page page2 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+
+        replay();
+
+        final PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 1, 1000, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                sleep(20);
+
+                cache.release(page2);
+            }
+        };
+
+        new Thread(r).start();
+
+        assertSame(cache.checkout(), page2);
+
+        verify();
+    }
+
+    @Test
+    public void page_removed_by_other_thread_is_not_used()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        final Page page2 = mockPage();
+        Page page3 = mockPage();
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page3);
+
+        replay();
+
+        final PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 1, 100, 20, 1000);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                sleep(20);
+
+                cache.remove(page2);
+            }
+        };
+
+        new Thread(r).start();
+
+        assertSame(cache.checkout(), page3);
+
+        verify();
+    }
+
+    @Test
+    public void cleanup()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+        Page page3 = mockPage();
+
+
+        train_loadPage(loader, PAGE_NAME, LOCALE, page1);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page2);
+        train_loadPage(loader, PAGE_NAME, LOCALE, page3);
+
+        replay();
+
+        PagePoolCache cache = new PagePoolCache(PAGE_NAME, LOCALE, loader, 5, 100, 20, 50);
+
+        assertSame(cache.checkout(), page1);
+        assertSame(cache.checkout(), page2);
+
+        cache.release(page1);
+
+        // Sleep longer than the active window (10)
+
+        sleep(75);
+
+        cache.release(page2);
+
+        cache.cleanup();
+
+        assertSame(cache.checkout(), page2);
+
+        // Page3 is created because page1 was culled as too old.
+
+        assertSame(cache.checkout(), page3);
+
+        verify();
+    }
+
+    private static void sleep(long time)
+    {
+        try
+        {
+            Thread.sleep(time);
+        }
+        catch (Exception ex)
+        {
+            // Ignore.
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java
new file mode 100644
index 0000000..c149225
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PagePoolImplTest.java
@@ -0,0 +1,136 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.apache.tapestry.services.ComponentClassResolver;
+import static org.easymock.EasyMock.contains;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class PagePoolImplTest extends InternalBaseTestCase
+{
+    private static final String INPUT_PAGE_NAME = "mypage";
+
+    private static final String LOGICAL_PAGE_NAME = "MyPage";
+
+    // This will change once we start supporting application localization.
+
+    private final Locale locale = Locale.getDefault();
+
+    @Test
+    public void checkout_when_page_list_is_null()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page = mockPage();
+        ThreadLocale tl = mockThreadLocale();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        Logger logger = mockLogger();
+
+        train_canonicalizePageName(resolver, INPUT_PAGE_NAME, LOGICAL_PAGE_NAME);
+
+        train_getLocale(tl, locale);
+
+        train_loadPage(loader, LOGICAL_PAGE_NAME, locale, page);
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(logger, loader, tl, resolver, 5, 0, 20, 600000);
+
+        assertSame(page, pool.checkout(INPUT_PAGE_NAME));
+
+        verify();
+    }
+
+    @Test
+    public void checkout_when_page_list_is_empty()
+    {
+        Page page1 = mockPage();
+        Page page2 = mockPage();
+        PageLoader loader = mockPageLoader();
+        Logger logger = mockLogger();
+        ThreadLocale tl = mockThreadLocale();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_canonicalizePageName(resolver, INPUT_PAGE_NAME, LOGICAL_PAGE_NAME);
+
+        train_getLocale(tl, locale);
+
+        train_loadPage(loader, LOGICAL_PAGE_NAME, locale, page1);
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(logger, loader, tl, resolver, 5, 0, 20, 600000);
+
+        assertSame(pool.checkout(INPUT_PAGE_NAME), page1);
+
+        verify();
+
+        train_detached(page1, false);
+        train_getLogicalName(page1, LOGICAL_PAGE_NAME);
+        train_getLocale(page1, locale);
+
+        replay();
+
+        pool.release(page1);
+
+        verify();
+
+        train_canonicalizePageName(resolver, INPUT_PAGE_NAME, LOGICAL_PAGE_NAME);
+        train_getLocale(tl, locale);
+
+        train_canonicalizePageName(resolver, INPUT_PAGE_NAME, LOGICAL_PAGE_NAME);
+        train_getLocale(tl, locale);
+
+        train_loadPage(loader, LOGICAL_PAGE_NAME, locale, page2);
+
+        replay();
+
+        assertSame(pool.checkout(INPUT_PAGE_NAME), page1);
+        assertSame(pool.checkout(INPUT_PAGE_NAME), page2);
+
+        verify();
+
+    }
+
+    @Test
+    public void dirty_pages_are_not_pooled()
+    {
+        PageLoader loader = mockPageLoader();
+        Page page = mockPage();
+        Logger logger = mockLogger();
+
+        train_detached(page, true);
+        train_getLogicalName(page, "dirty");
+        train_getLocale(page, Locale.ENGLISH);
+
+        logger.error(contains("is dirty, and will be discarded"));
+
+        // The fact that we don't ask
+        // the page for its name is our clue that it is not being cached.
+
+        replay();
+
+        PagePool pool = new PagePoolImpl(logger, loader, null, null, 5, 0, 20, 600000);
+
+        pool.release(page);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
new file mode 100644
index 0000000..842733d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
@@ -0,0 +1,253 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventConstants;
+import org.apache.tapestry.EventContext;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.*;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.easymock.IAnswer;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class PageRenderDispatcherTest extends InternalBaseTestCase
+{
+    private ContextValueEncoder contextValueEncoder;
+
+    @BeforeClass
+    public void setup()
+    {
+        contextValueEncoder = getService(ContextValueEncoder.class);
+    }
+
+    @Test
+    public void not_a_page_request() throws Exception
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        RequestPageCache cache = mockRequestPageCache();
+        PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, null, null);
+        Request request = mockRequest();
+        Response response = mockResponse();
+
+        stub_isPageName(resolver, false);
+
+        train_getPath(request, "/foo/Bar.baz");
+
+        replay();
+
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
+
+        assertFalse(d.dispatch(request, response));
+
+        verify();
+    }
+
+    // TAPESTRY-1343
+    @Test
+    public void empty_path() throws Exception
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        PageRenderRequestHandler handler = newMock(PageRenderRequestHandler.class);
+        Request request = mockRequest();
+        Response response = mockResponse();
+
+        train_getPath(request, "");
+
+        train_isPageName(resolver, "", false);
+
+        replay();
+
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
+
+        assertFalse(d.dispatch(request, response));
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-2226
+     */
+    @Test
+    public void page_activation_context_for_root_index_page() throws Exception
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+        PageResponseRenderer renderer = mockPageResponseRenderer();
+        RequestPageCache cache = mockRequestPageCache();
+        ComponentEventResultProcessor processor = newComponentEventResultProcessor();
+
+        train_getPath(request, "/foo/bar");
+
+        train_isPageName(resolver, "foo/bar", false);
+        train_isPageName(resolver, "foo", false);
+        train_isPageName(resolver, "", true);
+
+        train_get(cache, "", page);
+
+        train_getRootElement(page, rootElement);
+
+        train_triggerContextEvent(rootElement, EventConstants.ACTIVATE, new Object[] { "foo", "bar" }, false);
+
+        renderer.renderPageResponse(page);
+
+        replay();
+
+        PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, processor, renderer);
+
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, contextValueEncoder);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+
+    @Test
+    public void no_extra_context_without_final_slash() throws Exception
+    {
+        no_extra_context(false);
+    }
+
+    @Test
+    public void no_extra_context_with_final_slash() throws Exception
+    {
+        no_extra_context(true);
+    }
+
+    private void no_extra_context(boolean finalSlash) throws Exception
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        PageResponseRenderer renderer = mockPageResponseRenderer();
+        RequestPageCache cache = mockRequestPageCache();
+        ComponentEventResultProcessor processor = newComponentEventResultProcessor();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+
+        String path = "/foo/Bar" + (finalSlash ? "/" : "");
+        train_getPath(request, path);
+
+        train_isPageName(resolver, "foo/Bar", true);
+
+        train_get(cache, "foo/Bar", page);
+        train_getRootElement(page, rootElement);
+
+        train_triggerContextEvent(rootElement, EventConstants.ACTIVATE, new Object[0], false);
+
+        renderer.renderPageResponse(page);
+
+        replay();
+
+        PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, processor, renderer);
+
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    @Test
+    public void context_passed_in_path_without_final_slash() throws Exception
+    {
+        context_passed_in_path(false);
+    }
+
+    @Test
+    public void context_passed_in_path_with_final_slash() throws Exception
+    {
+        context_passed_in_path(true);
+    }
+
+    private void context_passed_in_path(boolean finalSlash) throws Exception
+    {
+        ComponentEventResultProcessor processor = newComponentEventResultProcessor();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        PageResponseRenderer renderer = mockPageResponseRenderer();
+        RequestPageCache cache = mockRequestPageCache();
+        Request request = mockRequest();
+        Response response = mockResponse();
+        Page page = mockPage();
+        ComponentPageElement rootElement = mockComponentPageElement();
+
+        String path = "/foo/Bar/zip/zoom" + (finalSlash ? "/" : "");
+        train_getPath(request, path);
+
+        train_isPageName(resolver, "foo/Bar/zip/zoom", false);
+
+        train_isPageName(resolver, "foo/Bar/zip", false);
+
+        train_isPageName(resolver, "foo/Bar", true);
+
+        train_get(cache, "foo/Bar", page);
+        train_getRootElement(page, rootElement);
+
+        train_triggerContextEvent(rootElement, EventConstants.ACTIVATE, new Object[] { "zip", "zoom" }, false);
+
+        renderer.renderPageResponse(page);
+
+        replay();
+
+        PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, processor, renderer);
+
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, contextValueEncoder);
+
+        assertTrue(d.dispatch(request, response));
+
+        verify();
+    }
+
+    protected ComponentEventResultProcessor newComponentEventResultProcessor()
+    {
+        return newMock(ComponentEventResultProcessor.class);
+    }
+
+    private void train_triggerContextEvent(ComponentPageElement element, String eventType, final Object[] context,
+                                           final boolean handled)
+    {
+        IAnswer<Boolean> answer = new IAnswer<Boolean>()
+        {
+            public Boolean answer() throws Throwable
+            {
+                Object[] arguments = EasyMock.getCurrentArguments();
+
+                EventContext ec = (EventContext) arguments[1];
+
+                assertEquals(ec.getCount(), context.length);
+
+                for (int i = 0; i < context.length; i++)
+                {
+                    assertEquals(ec.get(Object.class, i), context[i]);
+                }
+
+
+                return handled;
+            }
+        };
+
+        expect(element.triggerContextEvent(eq(eventType), isA(EventContext.class),
+                                           isA(ComponentEventCallback.class))).andAnswer(answer);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageTemplateLocatorImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageTemplateLocatorImplTest.java
new file mode 100644
index 0000000..8cc492d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageTemplateLocatorImplTest.java
@@ -0,0 +1,135 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class PageTemplateLocatorImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void not_a_page_class()
+    {
+        ComponentModel model = mockComponentModel();
+        Resource root = mockResource();
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_getComponentClassName(model, "foo.bar.Baz");
+
+        replay();
+
+        PageTemplateLocator locator = new PageTemplateLocatorImpl(root, resolver);
+
+        assertNull(locator.findPageTemplateResource(model, Locale.FRENCH));
+
+        verify();
+    }
+
+    @Test
+    public void template_found()
+    {
+        ComponentModel model = mockComponentModel();
+        Resource root = mockResource();
+        Resource withExtension = mockResource();
+        Resource forLocale = mockResource();
+        Locale locale = Locale.FRENCH;
+        String className = "myapp.pages.Foo";
+
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_getComponentClassName(model, className);
+
+        train_resolvePageClassNameToPageName(resolver, className, "Foo");
+
+        train_forFile(root, "Foo.tml", withExtension);
+        train_forLocale(withExtension, locale, forLocale);
+
+        replay();
+
+        PageTemplateLocator locator = new PageTemplateLocatorImpl(root, resolver);
+
+        assertSame(locator.findPageTemplateResource(model, locale), forLocale);
+
+        verify();
+    }
+
+    /**
+     * Because of how Tapestry maps class names to logical page names, part of the name may be have
+     * been stripped off and we want to make sure we get it back.
+     */
+    @Test
+    public void uses_simple_class_name_in_folders()
+    {
+        ComponentModel model = mockComponentModel();
+        Resource root = mockResource();
+        Resource withExtension = mockResource();
+        Resource forLocale = mockResource();
+        Locale locale = Locale.FRENCH;
+        String className = "myapp.pages.foo.CreateFoo";
+
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_getComponentClassName(model, className);
+
+        // Notice: foo/Create not foo/CreateFoo; we're simulating how the redundancy gets stripped
+        // out of the class name.
+        train_resolvePageClassNameToPageName(resolver, className, "foo/Create");
+
+        // Abnd here's where we're showing that PTLI stitches it back together.
+        train_forFile(root, "foo/CreateFoo.tml", withExtension);
+        train_forLocale(withExtension, locale, forLocale);
+
+        replay();
+
+        PageTemplateLocator locator = new PageTemplateLocatorImpl(root, resolver);
+
+        assertSame(locator.findPageTemplateResource(model, locale), forLocale);
+
+        verify();
+    }
+
+    @Test
+    public void template_not_found()
+    {
+        ComponentModel model = mockComponentModel();
+        Resource root = mockResource();
+        Resource withExtension = mockResource();
+        Locale locale = Locale.GERMAN;
+        String className = "myapp.pages.bar.Baz";
+
+        ComponentClassResolver resolver = mockComponentClassResolver();
+
+        train_getComponentClassName(model, className);
+
+        train_resolvePageClassNameToPageName(resolver, className, "bar/Baz");
+
+        train_forFile(root, "bar/Baz.tml", withExtension);
+        train_forLocale(withExtension, locale, null);
+
+        replay();
+
+        PageTemplateLocator locator = new PageTemplateLocatorImpl(root, resolver);
+
+        assertNull(locator.findPageTemplateResource(model, locale));
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ParserExperiment.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ParserExperiment.java
new file mode 100644
index 0000000..b3e3b65
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ParserExperiment.java
@@ -0,0 +1,181 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.xml.sax.Attributes;

+import org.xml.sax.InputSource;

+import org.xml.sax.Locator;

+import org.xml.sax.SAXException;

+import org.xml.sax.helpers.DefaultHandler;

+

+import javax.xml.parsers.SAXParser;

+import javax.xml.parsers.SAXParserFactory;

+import java.io.BufferedInputStream;

+import java.net.URL;

+

+/**

+ * Used to experiment with namespace aware SAX parsers.

+ */

+public class ParserExperiment extends DefaultHandler

+{

+    private Locator locator;

+

+    public static void main(String[] args) throws Exception

+    {

+        new ParserExperiment().parse("basic.tml");

+    }

+

+    public void parse(String file) throws Exception

+    {

+        parse(getClass().getResource(file));

+    }

+

+    public void parse(URL document) throws Exception

+    {

+        SAXParserFactory factory = SAXParserFactory.newInstance();

+

+        factory.setNamespaceAware(true);

+        // Equivalent:

+        // factory.setFeature("http://xml.org/sax/features/namespaces", true);

+

+        // Doesn't seem to do anything:

+        factory.setFeature("http://apache.org/xml/features/validation/schema/normalized-value", true);

+

+        // Doesn't seem to do anything:

+        factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);

+

+        // A non-validation parser is fine!

+

+        SAXParser parser = factory.newSAXParser();

+

+        InputSource source = new InputSource(new BufferedInputStream(document.openStream()));

+

+        parser.parse(source, this);

+    }

+

+    private void log(String methodName, String... details)

+    {

+        StringBuilder buffer = new StringBuilder();

+

+        buffer.append(String.format("%-25s:", methodName));

+

+        if (locator != null)

+        {

+            buffer.append(String.format(" [Line %d, column %d]", locator.getLineNumber(), locator

+                    .getColumnNumber()));

+        }

+

+        for (int i = 0; i < details.length; i++)

+        {

+            buffer.append("\n     ");

+            buffer.append(details[i]);

+        }

+

+        System.out.println(buffer.toString());

+    }

+

+    @Override

+    public void characters(char[] ch, int start, int length) throws SAXException

+    {

+        String string = new String(ch, start, length);

+        String loggable = string.replaceAll("![\\w -]", ".").trim();

+

+        log("characters", "start=" + start, "length=" + length, loggable);

+    }

+

+    @Override

+    public void endDocument() throws SAXException

+    {

+        log("endDocument");

+    }

+

+    @Override

+    public void endElement(String uri, String localName, String qName) throws SAXException

+    {

+        log("endElement", localName, "uri=" + uri, "qName=" + qName);

+    }

+

+    @Override

+    public void endPrefixMapping(String prefix) throws SAXException

+    {

+        log("endPrefixMapping", prefix);

+    }

+

+    @Override

+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException

+    {

+        log("ignorableWhitespace", "start=" + start, "length=" + length);

+    }

+

+    @Override

+    public void notationDecl(String name, String publicId, String systemId) throws SAXException

+    {

+        log("notationDecl", name, "publicId=" + publicId, "systemId=" + systemId);

+    }

+

+    @Override

+    public void processingInstruction(String target, String data) throws SAXException

+    {

+        log("pi", "target=" + target, "data=" + data);

+    }

+

+    @Override

+    public void setDocumentLocator(Locator locator)

+    {

+        this.locator = locator;

+

+        log("setDocumentLocator", "publicId=" + locator.getPublicId(), "systemId=" + locator.getSystemId());

+    }

+

+    @Override

+    public void skippedEntity(String name) throws SAXException

+    {

+        log("skippedEntity", name);

+    }

+

+    @Override

+    public void startDocument() throws SAXException

+    {

+        log("startDocument");

+    }

+

+    @Override

+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException

+    {

+        log("startElement", localName, "uri=" + uri, "qName=" + qName);

+

+        int count = attributes.getLength();

+

+        for (int i = 0; i < count; i++)

+        {

+            log("attribute", attributes.getLocalName(i), "value=" + attributes.getValue(i),

+                "qName=" + attributes.getQName(i));

+        }

+    }

+

+    @Override

+    public void startPrefixMapping(String prefix, String uri) throws SAXException

+    {

+        log("startPrefixMapping", "prefix=" + prefix, "uri=" + uri);

+    }

+

+    @Override

+    public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)

+            throws SAXException

+    {

+        log("unparsedEntityDecl", name, "publicId=" + publicId, "systemId=" + systemId);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldBundleImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldBundleImplTest.java
new file mode 100644
index 0000000..59e4d67
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldBundleImplTest.java
@@ -0,0 +1,63 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.internal.test.InternalBaseTestCase;

+import org.apache.tapestry.services.PersistentFieldBundle;

+import org.apache.tapestry.services.PersistentFieldChange;

+import org.testng.annotations.Test;

+

+import java.util.Arrays;

+import java.util.Collection;

+

+public class PersistentFieldBundleImplTest extends InternalBaseTestCase

+{

+    @Test

+    public void get_root_component_value()

+    {

+        String value = "FIELD-VALUE";

+

+        PersistentFieldChange change = new PersistentFieldChangeImpl("", "field", value);

+        Collection<PersistentFieldChange> changes = Arrays.asList(change);

+

+        PersistentFieldBundle bundle = new PersistentFieldBundleImpl(changes);

+

+        assertTrue(bundle.containsValue("", "field"));

+        assertTrue(bundle.containsValue(null, "field"));

+

+        assertSame(bundle.getValue("", "field"), value);

+        assertSame(bundle.getValue(null, "field"), value);

+

+        assertFalse(bundle.containsValue("", "other"));

+        assertFalse(bundle.containsValue(null, "other"));

+    }

+

+    @Test

+    public void get_nested_component_value()

+    {

+        String value = "FIELD-VALUE";

+

+        PersistentFieldChange change = new PersistentFieldChangeImpl("foo.bar", "field", value);

+        Collection<PersistentFieldChange> changes = Arrays.asList(change);

+

+        PersistentFieldBundle bundle = new PersistentFieldBundleImpl(changes);

+

+        assertTrue(bundle.containsValue("foo.bar", "field"));

+

+        assertSame(bundle.getValue("foo.bar", "field"), value);

+

+        assertFalse(bundle.containsValue("foo.bar", "other"));

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
new file mode 100644
index 0000000..ef04650
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentFieldManagerImplTest.java
@@ -0,0 +1,285 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.PersistentFieldBundle;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class PersistentFieldManagerImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void post_change_with_unknown_strategy()
+    {
+        String fieldName = "field";
+
+        PersistentFieldStrategy strat1 = newPersistentFieldStrategy();
+        PersistentFieldStrategy strat2 = newPersistentFieldStrategy();
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put("foo", strat1);
+        strategies.put("bar", strat2);
+
+        train_getComponentModel(resources, model);
+
+        train_getFieldPersistenceStrategy(model, fieldName, "braveheart");
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+        try
+        {
+            manager.postChange("foo.Bar", resources, fieldName, null);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "\'braveheart\' is not a defined persistent strategy.  Defined strategies: bar, foo.");
+        }
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1475
+     */
+    @Test
+    public void discard_changes()
+    {
+        PersistentFieldStrategy strat1 = newPersistentFieldStrategy();
+        PersistentFieldStrategy strat2 = newPersistentFieldStrategy();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put("foo", strat1);
+        strategies.put("bar", strat2);
+
+        String pageName = "gnip.gnop";
+
+        strat1.discardChanges(pageName);
+        strat2.discardChanges(pageName);
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+        manager.discardChanges(pageName);
+
+        verify();
+    }
+
+    @Test
+    public void post_change()
+    {
+        String pageName = "foo.Bar";
+        String nestedId = "nested";
+        String fieldName = "field";
+        String strategyName = "foo";
+
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        PersistentFieldStrategy strat = newPersistentFieldStrategy();
+        Object value = new Object();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put(strategyName, strat);
+
+        train_getComponentModel(resources, model);
+
+        train_getFieldPersistenceStrategy(model, fieldName, strategyName);
+
+        train_getNestedId(resources, nestedId);
+
+        strat.postChange(pageName, nestedId, fieldName, value);
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+        manager.postChange(pageName, resources, fieldName, value);
+
+        verify();
+    }
+
+    public void strategy_name_is_case_insensitive()
+    {
+        String pageName = "foo.Bar";
+        String nestedId = "nested";
+        String fieldName = "field";
+        String strategyName = "FOO";
+
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        PersistentFieldStrategy strat = newPersistentFieldStrategy();
+        Object value = new Object();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put("foo", strat);
+
+        train_getComponentModel(resources, model);
+
+        train_getFieldPersistenceStrategy(model, fieldName, strategyName);
+
+        train_getNestedId(resources, nestedId);
+
+        strat.postChange(pageName, nestedId, fieldName, value);
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+        manager.postChange(pageName, resources, fieldName, value);
+
+        verify();
+    }
+
+    @Test
+    public void post_change_strategy_by_meta_data()
+    {
+        String pageName = "foo.Bar";
+        String nestedId = "nested";
+        String fieldName = "field";
+        String strategyName = "foo";
+
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        PersistentFieldStrategy strat = newPersistentFieldStrategy();
+        MetaDataLocator locator = mockMetaDataLocator();
+
+        Object value = new Object();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put(strategyName, strat);
+
+        train_getComponentModel(resources, model);
+
+        train_getFieldPersistenceStrategy(model, fieldName, "");
+
+        train_findMeta(locator, PersistentFieldManagerImpl.META_KEY, resources, String.class, strategyName);
+
+        train_getNestedId(resources, nestedId);
+
+        strat.postChange(pageName, nestedId, fieldName, value);
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(locator, strategies);
+
+        manager.postChange(pageName, resources, fieldName, value);
+
+        verify();
+    }
+
+    @Test
+    public void post_change_with_ultimate_default_strategy()
+    {
+        String pageName = "foo.Bar";
+        String nestedId = "nested";
+        String fieldName = "field";
+
+        ComponentResources resources = mockComponentResources();
+        ComponentModel model = mockComponentModel();
+        MetaDataLocator locator = mockMetaDataLocator();
+
+        PersistentFieldStrategy strat = newPersistentFieldStrategy();
+        Object value = new Object();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+        strategies.put(PersistentFieldManagerImpl.DEFAULT_STRATEGY, strat);
+
+        train_getComponentModel(resources, model);
+
+        train_getFieldPersistenceStrategy(model, fieldName, "");
+
+        train_findMeta(
+                locator,
+                PersistentFieldManagerImpl.META_KEY,
+                resources, String.class,
+                PersistentFieldManagerImpl.DEFAULT_STRATEGY);
+
+        train_getNestedId(resources, nestedId);
+
+        strat.postChange(pageName, nestedId, fieldName, value);
+
+        replay();
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(locator, strategies);
+
+        manager.postChange(pageName, resources, fieldName, value);
+
+        verify();
+    }
+
+    protected final PersistentFieldStrategy newPersistentFieldStrategy()
+    {
+        return newMock(PersistentFieldStrategy.class);
+    }
+
+    @Test
+    public void gather_changes()
+    {
+        Object value1 = new Object();
+        Object value2 = new Object();
+
+        PersistentFieldStrategy strat1 = newPersistentFieldStrategy();
+
+        Collection<PersistentFieldChange> changes1 = newList();
+        changes1.add(new PersistentFieldChangeImpl("component", "field1", value1));
+
+        PersistentFieldStrategy strat2 = newPersistentFieldStrategy();
+
+        Collection<PersistentFieldChange> changes2 = newList();
+        changes2.add(new PersistentFieldChangeImpl("component", "field2", value2));
+
+        // We don't know the exact order the strategies will be ordered in the map,
+        // so we can't guarantee the order the strategies will be invoked.
+
+        getMocksControl().checkOrder(false);
+
+        expect(strat1.gatherFieldChanges("foo.Bar")).andReturn(changes1);
+
+        expect(strat2.gatherFieldChanges("foo.Bar")).andReturn(changes2);
+
+        replay();
+
+        Map<String, PersistentFieldStrategy> strategies = newMap();
+
+        strategies.put("alpha", strat1);
+        strategies.put("beta", strat2);
+
+        PersistentFieldManager manager = new PersistentFieldManagerImpl(null, strategies);
+
+        PersistentFieldBundle bundle = manager.gatherChanges("foo.Bar");
+
+        assertSame(bundle.getValue("component", "field1"), value1);
+        assertSame(bundle.getValue("component", "field2"), value2);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentLocaleImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentLocaleImplTest.java
new file mode 100644
index 0000000..8a5b586
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PersistentLocaleImplTest.java
@@ -0,0 +1,82 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.Cookies;
+import org.apache.tapestry.services.PersistentLocale;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Map;
+
+public class PersistentLocaleImplTest extends Assert
+{
+    @Test
+    public void get() throws IOException
+    {
+        Cookies cookieSource = new NoOpCookieSource()
+        {
+
+            @Override
+            public String readCookieValue(String name)
+            {
+                return name.equals("org.apache.tapestry.locale") ? "fr" : null;
+            }
+
+        };
+        PersistentLocale persistentLocale = new PersistentLocaleImpl(cookieSource);
+        assertEquals(persistentLocale.get(), Locale.FRENCH);
+    }
+
+    @Test
+    public void get_none() throws IOException
+    {
+        Cookies cookieSource = new NoOpCookieSource()
+        {
+
+            @Override
+            public String readCookieValue(String name)
+            {
+                return null;
+            }
+
+        };
+        PersistentLocale persistentLocale = new PersistentLocaleImpl(cookieSource);
+        assertNull(persistentLocale.get());
+    }
+
+    @Test
+    public void set() throws IOException
+    {
+        final Map<String, String> cookies = CollectionFactory.newMap();
+        Cookies cookieSource = new NoOpCookieSource()
+        {
+            @Override
+            public void writeCookieValue(String name, String value)
+            {
+                cookies.put(name, value);
+            }
+
+        };
+        PersistentLocale persistentLocale = new PersistentLocaleImpl(cookieSource);
+        persistentLocale.set(Locale.CANADA_FRENCH);
+        assertEquals(cookies.size(), 1);
+        assertEquals(cookies.get("org.apache.tapestry.locale"), "fr_CA");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java
new file mode 100644
index 0000000..813d1d7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PropertyConduitSourceImplTest.java
@@ -0,0 +1,193 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.PropertyConduit;
+import org.apache.tapestry.internal.bindings.PropBindingFactoryTest;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.services.PropertyConduitSource;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+
+/**
+ * Most of the testing occurs inside {@link PropBindingFactoryTest} (due to historical reasons).
+ */
+public class PropertyConduitSourceImplTest extends InternalBaseTestCase
+{
+    private PropertyConduitSource source;
+
+    @BeforeClass
+    public void setup()
+    {
+        source = getObject(PropertyConduitSource.class, null);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        source = null;
+    }
+
+    @Test
+    public void question_dot_operator_for_object_type()
+    {
+        PropertyConduit normal = source.create(CompositeBean.class, "simple.firstName");
+        PropertyConduit smart = source.create(CompositeBean.class, "simple?.firstName");
+
+        CompositeBean bean = new CompositeBean();
+        bean.setSimple(null);
+
+        try
+        {
+            normal.get(bean);
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            // Expected.
+        }
+
+        assertNull(smart.get(bean));
+
+        try
+        {
+            normal.set(bean, "Howard");
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            // Expected.
+        }
+
+        // This will be a no-op due to the null property in the expression
+
+        smart.set(bean, "Howard");
+    }
+
+    @Test
+    public void method_names_are_matched_caselessly()
+    {
+        PropertyConduit conduit = source.create(CompositeBean.class, "GETSIMPLE().firstName");
+
+        CompositeBean bean = new CompositeBean();
+        SimpleBean inner = new SimpleBean();
+        bean.setSimple(inner);
+
+        conduit.set(bean, "Howard");
+
+        assertEquals(inner.getFirstName(), "Howard");
+    }
+
+    /**
+     * Or call this the "Hibernate" case; Hibernate creates sub-classes of entity classes in its own class loader to do
+     * all sorts of proxying. This trips up Javassist.
+     */
+    @Test
+    public void handle_beans_from_unexpected_classloader() throws Exception
+    {
+        // First, create something that looks like a Hibernate proxy.
+
+        ClassFactory factory = new ClassFactoryImpl();
+
+        Class clazz = SimpleBean.class;
+
+        ClassFab cf = factory.newClass(clazz.getName() + "$$Proxy", clazz);
+
+        cf.addInterface(Serializable.class);
+
+        Class proxyClass = cf.createClass();
+
+        SimpleBean simple = (SimpleBean) proxyClass.newInstance();
+
+        assertTrue(simple instanceof Serializable);
+
+        simple.setFirstName("Howard");
+
+        PropertyConduit conduit = source.create(proxyClass, "firstName");
+
+        assertEquals(conduit.get(simple), "Howard");
+    }
+
+    @Test
+    public void generics()
+    {
+        String string = "surprise";
+        StringHolder stringHolder = new StringHolder();
+        stringHolder.put(string);
+        StringHolderBean bean = new StringHolderBean();
+        bean.setValue(stringHolder);
+
+        PropertyConduit conduit = source.create(StringHolderBean.class, "value.get()");
+
+        assertSame(conduit.get(bean), string);
+
+        assertSame(conduit.getPropertyType(), String.class);
+    }
+
+    @Test
+    public void null_root_object()
+    {
+        PropertyConduit conduit = source.create(StringHolderBean.class, "value.get()");
+
+        try
+        {
+            conduit.get(null);
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            assertEquals(ex.getMessage(), "Root object of property expression 'value.get()' is null.");
+        }
+    }
+
+    @Test
+    public void null_property_in_chain()
+    {
+        PropertyConduit conduit = source.create(CompositeBean.class, "simple.lastName");
+
+        CompositeBean bean = new CompositeBean();
+        bean.setSimple(null);
+
+        try
+        {
+            conduit.get(bean);
+            unreachable();
+        }
+        catch (NullPointerException ex)
+        {
+            assertMessageContains(ex, "Property 'simple' (within property expression 'simple.lastName', of",
+                                  ") is null.");
+        }
+    }
+
+    @Test
+    public void last_term_may_be_null()
+    {
+        PropertyConduit conduit = source.create(CompositeBean.class, "simple.firstName");
+
+        CompositeBean bean = new CompositeBean();
+
+        bean.getSimple().setFirstName(null);
+
+        assertNull(conduit.get(bean));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RemoveFieldBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RemoveFieldBean.java
new file mode 100644
index 0000000..ca0a37f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RemoveFieldBean.java
@@ -0,0 +1,24 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class RemoveFieldBean
+{
+    @SuppressWarnings("unused")
+    private String _fred;
+
+    @SuppressWarnings("unused")
+    private String _barney;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java
new file mode 100644
index 0000000..a82521b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderQueueImplTest.java
@@ -0,0 +1,115 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class RenderQueueImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void run_commands()
+    {
+        final RenderCommand command2 = newMock(RenderCommand.class);
+        RenderCommand command1 = new RenderCommand()
+        {
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                queue.push(command2);
+            }
+        };
+
+        Logger logger = mockLogger();
+        MarkupWriter writer = mockMarkupWriter();
+        RenderQueueImpl queue = new RenderQueueImpl(logger);
+
+        // There's only one check for trace enabled now.
+
+        train_isTraceEnabled(logger, false);
+        train_isDebugEnabled(logger, false);
+
+        command2.render(writer, queue);
+
+        replay();
+
+        queue.push(command1);
+        queue.run(writer);
+
+        verify();
+    }
+
+    @Test
+    public void command_failed()
+    {
+        ComponentResources foo = mockInternalComponentResources();
+        ComponentResources bar = mockInternalComponentResources();
+        ComponentResources baz = mockInternalComponentResources();
+
+        final RuntimeException t = new RuntimeException("Oops.");
+
+        RenderCommand rc = new RenderCommand()
+        {
+
+            public void render(MarkupWriter writer, RenderQueue queue)
+            {
+                throw t;
+            }
+
+            @Override
+            public String toString()
+            {
+                return "FailedCommand";
+            }
+        };
+
+        Logger logger = mockLogger();
+        MarkupWriter writer = mockMarkupWriter();
+
+        train_isTraceEnabled(logger, false);
+
+        logger.error("Render queue error in FailedCommand: Oops.", t);
+
+        replay();
+
+        RenderQueueImpl queue = new RenderQueueImpl(logger);
+
+        queue.startComponent(foo);
+        queue.startComponent(bar);
+        queue.endComponent();
+        queue.startComponent(baz);
+
+        queue.push(rc);
+
+        try
+        {
+            queue.run(writer);
+            unreachable();
+        }
+        catch (RenderQueueException ex)
+        {
+            assertSame(ex.getCause(), t);
+
+            assertArraysEqual(ex.getActiveComponents(), new Object[] { foo, baz });
+        }
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderSupportImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderSupportImplTest.java
new file mode 100644
index 0000000..7fb1146
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RenderSupportImplTest.java
@@ -0,0 +1,180 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.RenderSupport;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.services.AssetSource;
+import org.testng.annotations.Test;
+
+public class RenderSupportImplTest extends InternalBaseTestCase
+{
+    private static final String CORE_ASSET_PATH_UNEXPANDED = "${core}";
+
+    private static final String CORE_ASSET_PATH = "/org/apache/tapestry/core/core.png";
+
+    private static final String CORE_ASSET_URL = "/assets/core/core.png";
+
+    private static final String ASSET_URL = "/assets/foo/bar.pdf";
+
+    @Test
+    public void add_script_link_by_asset()
+    {
+        DocumentLinker linker = mockDocumentLinker();
+        Asset asset = mockAsset();
+
+        train_toClientURL(asset, ASSET_URL);
+        linker.addScriptLink(ASSET_URL);
+
+        replay();
+
+        RenderSupport support = new RenderSupportImpl(linker, null, null);
+
+        support.addScriptLink(asset);
+
+        verify();
+    }
+
+    @Test
+    public void core_assets_added()
+    {
+        getMocksControl().checkOrder(true);
+
+        Asset coreAsset = mockAsset();
+        DocumentLinker linker = mockDocumentLinker();
+        Asset asset = mockAsset();
+        AssetSource assetSource = mockAssetSource();
+        SymbolSource symbolSource = mockSymbolSource();
+
+        train_expandSymbols(symbolSource, CORE_ASSET_PATH_UNEXPANDED, CORE_ASSET_PATH);
+        train_getAsset(assetSource, null, CORE_ASSET_PATH, null, coreAsset);
+
+        train_toClientURL(coreAsset, CORE_ASSET_URL);
+        linker.addScriptLink(CORE_ASSET_URL);
+
+        train_toClientURL(asset, ASSET_URL);
+        linker.addScriptLink(ASSET_URL);
+
+        replay();
+
+        RenderSupport support = new RenderSupportImpl(linker, symbolSource, assetSource,
+                                                      CORE_ASSET_PATH_UNEXPANDED);
+
+        support.addScriptLink(asset);
+
+        verify();
+    }
+
+    @Test
+    public void add_script()
+    {
+        DocumentLinker linker = mockDocumentLinker();
+
+        linker.addScript("Tapestry.Foo(\"bar\");");
+
+        replay();
+
+        RenderSupport support = new RenderSupportImpl(linker, null, null);
+
+        support.addScript("Tapestry.Foo(\"%s\");", "bar");
+
+        verify();
+    }
+
+    @Test
+    public void add_classpath_script_link()
+    {
+        String path = "${root}/foo/bar.pdf";
+        String expanded = "org/apache/tapestry/foo/bar.pdf";
+
+        DocumentLinker linker = mockDocumentLinker();
+        Asset asset = mockAsset();
+        SymbolSource source = mockSymbolSource();
+        AssetSource assetSource = mockAssetSource();
+
+        train_expandSymbols(source, path, expanded);
+
+        train_getAsset(assetSource, null, expanded, null, asset);
+
+        train_toClientURL(asset, ASSET_URL);
+        linker.addScriptLink(ASSET_URL);
+
+        replay();
+
+        RenderSupport support = new RenderSupportImpl(linker, source, assetSource);
+
+        support.addClasspathScriptLink(path);
+
+        verify();
+    }
+
+    @Test
+    public void add_stylesheet_link()
+    {
+        String media = "print";
+        DocumentLinker linker = mockDocumentLinker();
+        Asset asset = mockAsset();
+
+        train_toClientURL(asset, ASSET_URL);
+        linker.addStylesheetLink(ASSET_URL, media);
+
+        replay();
+
+        RenderSupport support = new RenderSupportImpl(linker, null, null);
+
+        support.addStylesheetLink(asset, media);
+
+        verify();
+    }
+
+    @Test
+    public void add_init_with_single_string_parameter()
+    {
+        DocumentLinker linker = mockDocumentLinker();
+
+        linker.addScript("Tapestry.init({\"foo\":[\"fred\",\"barney\"]});");
+
+        replay();
+
+        RenderSupportImpl support = new RenderSupportImpl(linker, null, null);
+
+        support.addInit("foo", "fred");
+        support.addInit("foo", "barney");
+
+        support.commit();
+
+        verify();
+    }
+
+    @Test
+    public void add_multiple_string_init_parameters()
+    {
+        DocumentLinker linker = mockDocumentLinker();
+
+        linker.addScript("Tapestry.init({\"foo\":[[\"fred\",\"barney\"]]});");
+
+        replay();
+
+        RenderSupportImpl support = new RenderSupportImpl(linker, null, null);
+
+        support.addInit("foo", "fred", "barney");
+
+        support.commit();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImplTest.java
new file mode 100644
index 0000000..942af7b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestEncodingInitializerImplTest.java
@@ -0,0 +1,95 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.Test;
+
+public class RequestEncodingInitializerImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void encoding_in_content_type()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ComponentPageElement element = mockComponentPageElement();
+        InternalComponentResources resources = mockInternalComponentResources();
+        MetaDataLocator locator = mockMetaDataLocator();
+        Request request = mockRequest();
+        String pageName = "MyPage";
+
+        train_get(cache, pageName, page);
+        train_getRootElement(page, element);
+        train_getComponentResources(element, resources);
+
+        train_findMeta(
+                locator,
+                MetaDataConstants.RESPONSE_CONTENT_TYPE,
+                resources,
+                String.class,
+                "text/html;charset=zebra");
+
+        request.setEncoding("zebra");
+
+        replay();
+
+        RequestEncodingInitializer init = new RequestEncodingInitializerImpl(cache, locator,
+                                                                             request);
+
+        init.initializeRequestEncoding(pageName);
+
+        verify();
+    }
+
+    @Test
+    public void encoding_on_second_meta_data()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+        ComponentPageElement element = mockComponentPageElement();
+        InternalComponentResources resources = mockInternalComponentResources();
+        MetaDataLocator locator = mockMetaDataLocator();
+        Request request = mockRequest();
+        String pageName = "MyPage";
+        String encoding = "ostritch";
+
+        train_get(cache, pageName, page);
+        train_getRootElement(page, element);
+        train_getComponentResources(element, resources);
+
+        train_findMeta(locator, MetaDataConstants.RESPONSE_CONTENT_TYPE, resources, String.class, "text/html");
+
+        train_findMeta(locator, MetaDataConstants.RESPONSE_ENCODING, resources, String.class, encoding);
+
+        request.setEncoding(encoding);
+
+        replay();
+
+        RequestEncodingInitializer init = new RequestEncodingInitializerImpl(cache, locator,
+                                                                             request);
+
+        init.initializeRequestEncoding(pageName);
+
+        verify();
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java
new file mode 100644
index 0000000..87b6ee5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java
@@ -0,0 +1,191 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.UnsupportedEncodingException;
+
+public class RequestImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void get_session_doesnt_exist()
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        train_getSession(sr, false, null);
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+
+        assertNull(request.getSession(false));
+
+        verify();
+    }
+
+    @Test
+    public void force_session_create()
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+        HttpSession ss = mockHttpSession();
+
+        train_getSession(sr, true, ss);
+
+        train_getAttribute(ss, "foo", "bar");
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+        Session session = request.getSession(true);
+
+        assertEquals(session.getAttribute("foo"), "bar");
+
+        verify();
+    }
+
+    @Test
+    public void set_encoding_success() throws Exception
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        String encoding = "the-encoding";
+
+        sr.setCharacterEncoding(encoding);
+
+        replay();
+
+        new RequestImpl(sr).setEncoding(encoding);
+
+        verify();
+    }
+
+    @Test
+    public void set_encoding_failure() throws Exception
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        String encoding = "the-encoding";
+        UnsupportedEncodingException exception = new UnsupportedEncodingException("Oops.");
+
+        sr.setCharacterEncoding(encoding);
+        getMocksControl().andThrow(exception);
+
+        replay();
+
+        try
+        {
+            new RequestImpl(sr).setEncoding(encoding);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertSame(ex.getCause(), exception);
+        }
+
+        verify();
+    }
+
+    @Test(dataProvider = "xhr_inputs")
+    public void is_xhr_request(String headerValue, boolean expected)
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        expect(sr.getHeader(RequestImpl.REQUESTED_WITH_HEADER)).andReturn(headerValue);
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+
+        assertEquals(request.isXHR(), expected);
+
+        verify();
+    }
+
+    @DataProvider(name = "xhr_inputs")
+    public Object[][] xhr_inputs()
+    {
+        return new Object[][]{{null, false}, {"", false}, {"some other value", false}, {"XMLHttpRequest", true}};
+    }
+
+    @Test
+    public void get_path_for_normal_servlet_container()
+    {
+        String path = "/foo/bar";
+
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        train_getPathInfo(sr, null);
+        expect(sr.getServletPath()).andReturn(path);
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+
+        assertEquals(request.getPath(), path);
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1713
+     */
+    @Test
+    public void get_path_for_websphere_with_empty_path()
+    {
+        String path = "/foo/bar";
+
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        train_getPathInfo(sr, path);
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+
+        assertEquals(request.getPath(), path);
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1713
+     */
+    public void get_path_for_websphere_with_nonempty_path()
+    {
+        HttpServletRequest sr = mockHttpServletRequest();
+
+        train_getPathInfo(sr, "");
+
+        replay();
+
+        Request request = new RequestImpl(sr);
+
+        assertEquals(request.getPath(), "/");
+
+        verify();
+    }
+
+    protected final void train_getPathInfo(HttpServletRequest request, String pathInfo)
+    {
+        expect(request.getPathInfo()).andReturn(pathInfo).atLeastOnce();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java
new file mode 100644
index 0000000..cfcd6ce
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPageCacheImplTest.java
@@ -0,0 +1,60 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class RequestPageCacheImplTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "MyPage";
+
+    @Test
+    public void get_is_cached()
+    {
+        PagePool pool = mockPagePool();
+        Page page = mockPage();
+
+        expect(pool.checkout(PAGE_NAME)).andReturn(page);
+
+        page.attached();
+
+        replay();
+
+        RequestPageCacheImpl cache = new RequestPageCacheImpl(pool);
+
+        assertSame(cache.get(PAGE_NAME), page);
+
+        verify();
+
+        replay();
+
+        // Again, same object, but no PagePool this time.
+        assertSame(cache.get(PAGE_NAME), page);
+
+        verify();
+
+        pool.release(page);
+
+        replay();
+
+        // Now, trigger the release()
+
+        cache.threadDidCleanup();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPathOptimizerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPathOptimizerImplTest.java
new file mode 100644
index 0000000..dae45be
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestPathOptimizerImplTest.java
@@ -0,0 +1,135 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RequestPathOptimizerImplTest extends InternalBaseTestCase
+{
+    @DataProvider(name = "uri_optimization")
+    public Object[][] uri_optimization_data()
+    {
+        return new Object[][]{{"/context", "/foo/bar.png", "/context/foo/baz.png", "baz.png"},
+
+                {"/context", "/foo/bar.gif", "/context/foo//baz.gif", "baz.gif"},
+
+                {"/context", "/foo//bar.css", "/context/foo/baz.css", "baz.css"},
+
+                {"", "/foo/bar.css", "/foo/baz.css", "baz.css"},
+
+                {"/reallylongcontexttoensureitisrelative", "/foo/bar/baz/biff.gif",
+                        "/reallylongcontexttoensureitisrelative/gnip/gnop.gif", "../../../gnip/gnop.gif"},
+
+                {"", "/foo/bar/baz/biff/yepthisissolongthatabsoluteurlisshorter/dude", "/gnip/gnop",
+                        "/gnip/gnop"},
+
+                {"", "/foo/bar", "/foo/bar/baz/bif", "bar/baz/bif"},
+
+                {"", "/foo/bar/baz/bif", "/foo", "/foo"},
+
+                {"/ctx", "/foo/bar/baz/bif", "/ctx/foo", "/ctx/foo"},
+
+                {"/anotherobnoxiouslylongcontextthatiwllforcerelative", "/foo/bar/baz/bif",
+                        "/anotherobnoxiouslylongcontextthatiwllforcerelative/foo", "../../../foo"},
+
+                // A couple of better examples, see TAPESTRY-2033
+
+                {"/manager", "", "/manager/asset/foo.gif", "asset/foo.gif"},
+
+                {"", "", "/asset/foo.gif", "asset/foo.gif"},
+
+                {"", "/griddemo.grid.columns.sort/title", "/assets/default.css", "/assets/default.css"},
+
+                {"/example", "/", "/example/assets/tapestry/default.css", "assets/tapestry/default.css"},
+
+                {"/example", "/newaccount", "/example/assets/tapestry/default.css",
+                        "assets/tapestry/default.css"},
+
+                {"/verylongcontextname", "/style/app.css", "/verylongcontextname/asset/foo.gif",
+                        "../asset/foo.gif"},
+
+                {"", "/eventhandlerdemo.barney/one", "/eventhandlerdemo.clear/anything",
+                        "/eventhandlerdemo.clear/anything"},
+
+                {"/verylongcontextname", "/eventhandlerdemo.barney/one",
+                        "/verylongcontextname/eventhandlerdemo.clear/anything",
+                        "../eventhandlerdemo.clear/anything"},
+
+                {"/verylongcontextname", "/page", "/verylongcontextname/page:sort/foo",
+                        "./page:sort/foo"},
+
+                {"", "/page", "/page:sort/foo", "/page:sort/foo"},
+
+                // TAPESTRY-2046
+
+                {"/attendance", "/view/sites", "/attendance/assets/tapestry/tapestry.js",
+                        "../assets/tapestry/tapestry.js"},
+
+                // TAPESTRY-2095
+
+                {"", "/", "/component:event", "/component:event"},
+                
+                // TAPESTRY-2333
+                
+                {"", "/nested/actiondemo/", "/nested/actiondemo.actionlink/2", "../actiondemo.actionlink/2"},
+
+                // Make sure the ./ prefix is added even when the relative path doesn't contain
+                // a slash ... otherwise, invalid URL component:event (i.e., "component" protocol, not "http").
+
+                {"/verylongcontextname", "/", "/verylongcontextname/component:event", "./component:event"}
+
+        };
+    }
+
+    @Test(dataProvider = "uri_optimization")
+    public void uri_optimization(String contextPath, String requestPath, String path, String expectedURI)
+    {
+        Request request = mockRequest();
+
+        train_isXHR(request, false);
+
+        train_getContextPath(request, contextPath);
+        train_getPath(request, requestPath);
+
+        replay();
+
+        RequestPathOptimizer optimizer = new RequestPathOptimizerImpl(request, false);
+
+        assertEquals(optimizer.optimizePath(path), expectedURI);
+
+        verify();
+    }
+
+    @Test
+    public void force_absolute_is_a_pass_through()
+    {
+        Request request = mockRequest();
+        String path = "/some/path";
+
+        train_isXHR(request, true);
+
+        replay();
+
+        RequestPathOptimizer optimizer = new RequestPathOptimizerImpl(request, false);
+
+        assertSame(optimizer.optimizePath(path), path);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestSecurityManagerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestSecurityManagerImplTest.java
new file mode 100644
index 0000000..d57d504
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestSecurityManagerImplTest.java
@@ -0,0 +1,165 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BaseURLSource;
+import org.apache.tapestry.services.MetaDataLocator;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RequestSecurityManagerImplTest extends InternalBaseTestCase
+{
+    private static final String PAGE_NAME = "Whatever";
+
+    @Test
+    public void check_request_is_secure() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        LinkFactory linkFactory = mockLinkFactory();
+        MetaDataLocator locator = mockMetaDataLocator();
+        BaseURLSource source = mockBaseURLSource();
+        RequestPageCache cache = mockRequestPageCache();
+
+        train_isSecure(request, true);
+
+        replay();
+
+        RequestSecurityManager manager
+                = new RequestSecurityManagerImpl(request, response, linkFactory, locator, source, cache);
+
+        assertFalse(manager.checkForInsecureRequest(PAGE_NAME));
+
+        verify();
+    }
+
+    @Test
+    public void check_page_not_secure() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        LinkFactory linkFactory = mockLinkFactory();
+        MetaDataLocator locator = mockMetaDataLocator();
+        BaseURLSource source = mockBaseURLSource();
+        RequestPageCache cache = mockRequestPageCache();
+        Page page = mockPage();
+
+        train_isSecure(request, false);
+
+        train_get(cache, PAGE_NAME, page);
+
+        train_isSecure(locator, page, false);
+
+        replay();
+
+        RequestSecurityManager manager
+                = new RequestSecurityManagerImpl(request, response, linkFactory, locator, source, cache);
+
+        assertFalse(manager.checkForInsecureRequest(PAGE_NAME));
+
+        verify();
+    }
+
+    @Test
+    public void check_redirect_needed() throws Exception
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        LinkFactory linkFactory = mockLinkFactory();
+        MetaDataLocator locator = mockMetaDataLocator();
+        BaseURLSource source = mockBaseURLSource();
+        Page page = mockPage();
+        Link link = mockLink();
+        RequestPageCache cache = mockRequestPageCache();
+
+        train_isSecure(request, false);
+
+        train_get(cache, PAGE_NAME, page);
+
+        train_isSecure(locator, page, true);
+
+        train_createPageLink(linkFactory, page, link);
+
+        response.sendRedirect(link);
+
+        replay();
+
+        RequestSecurityManager manager
+                = new RequestSecurityManagerImpl(request, response, linkFactory, locator, source, cache);
+
+        assertTrue(manager.checkForInsecureRequest(PAGE_NAME));
+
+        verify();
+    }
+
+    @DataProvider(name = "base_URL_data")
+    public Object[][] base_URL_data()
+    {
+        return new Object[][] {
+                { true, true, null },
+                { false, false, null },
+                { true, false, "http://example.org" },
+                { false, true, "https://example.org" }
+        };
+    }
+
+    @Test(dataProvider = "base_URL_data")
+    public void get_base_URL(boolean secureRequest, boolean securePage, String expectedURL)
+    {
+        Request request = mockRequest();
+        Response response = mockResponse();
+        LinkFactory linkFactory = mockLinkFactory();
+        MetaDataLocator locator = mockMetaDataLocator();
+        BaseURLSource source = mockBaseURLSource();
+        Page page = mockPage();
+
+        train_isSecure(request, secureRequest);
+        train_isSecure(locator, page, securePage);
+
+        if (expectedURL != null)
+            train_getBaseURL(source, securePage, expectedURL);
+
+        replay();
+
+        RequestSecurityManager manager
+                = new RequestSecurityManagerImpl(request, response, linkFactory, locator, source, null);
+
+        assertEquals(manager.getBaseURL(page), expectedURL);
+
+        verify();
+    }
+
+
+    private void train_isSecure(MetaDataLocator locator, Page page, boolean secure)
+    {
+        Component component = mockComponent();
+        ComponentResources resources = mockInternalComponentResources();
+
+        train_getRootComponent(page, component);
+        train_getComponentResources(component, resources);
+
+        train_findMeta(locator, MetaDataConstants.SECURE_PAGE, resources, Boolean.class, secure);
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceCacheImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceCacheImplTest.java
new file mode 100644
index 0000000..0f5f7a7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceCacheImplTest.java
@@ -0,0 +1,176 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.services.ResourceDigestGenerator;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+public class ResourceCacheImplTest extends InternalBaseTestCase
+{
+    private static final String PATH = "foo/Bar.gif";
+
+    private static final String DIGEST = "abc123";
+
+    @Test
+    public void properties_for_simple_resource() throws Exception
+    {
+        ResourceDigestGenerator generator = mockResourceDigestGenerator();
+
+        File f = createTestFile();
+        URL url = f.toURL();
+        Resource r = mockResource();
+
+        long lastUpdated = f.lastModified();
+        lastUpdated -= lastUpdated % 1000;
+
+        train_getPath(r, PATH);
+        train_toURL(r, url);
+
+        train_requiresDigest(generator, PATH, false);
+
+        replay();
+
+        ResourceCacheImpl cache = new ResourceCacheImpl(generator);
+
+        assertEquals(cache.requiresDigest(r), false);
+        assertEquals(cache.getTimeModified(r), lastUpdated);
+        assertEquals(cache.getDigest(r), null);
+
+        verify();
+    }
+
+    @Test
+    public void properties_for_missing_resource() throws Exception
+    {
+        ResourceDigestGenerator generator = mockResourceDigestGenerator();
+
+        Resource r = mockResource();
+
+        train_getPath(r, PATH);
+        train_toURL(r, null);
+
+        train_requiresDigest(generator, PATH, true);
+
+        replay();
+
+        ResourceCacheImpl cache = new ResourceCacheImpl(generator);
+
+        assertEquals(cache.requiresDigest(r), true);
+        assertEquals(cache.getTimeModified(r), ResourceCacheImpl.MISSING_RESOURCE_TIME_MODIFIED);
+        assertEquals(cache.getDigest(r), null);
+
+        verify();
+    }
+
+    @Test
+    public void properties_for_protected_resource() throws Exception
+    {
+        ResourceDigestGenerator generator = mockResourceDigestGenerator();
+
+        File f = createTestFile();
+        URL url = f.toURL();
+        Resource r = mockResource();
+
+        long lastUpdated = f.lastModified();
+        lastUpdated -= lastUpdated % 1000;
+
+        train_getPath(r, PATH);
+        train_toURL(r, url);
+
+        train_requiresDigest(generator, PATH, true);
+        train_generateChecksum(generator, url, DIGEST);
+
+        replay();
+
+        ResourceCacheImpl cache = new ResourceCacheImpl(generator);
+
+        assertEquals(cache.requiresDigest(r), true);
+        assertEquals(cache.getTimeModified(r), lastUpdated);
+        assertEquals(cache.getDigest(r), DIGEST);
+
+        verify();
+    }
+
+    @Test
+    public void caching_and_invalidation() throws Exception
+    {
+        ResourceDigestGenerator generator = mockResourceDigestGenerator();
+        InvalidationListener listener = mockInvalidationListener();
+        File f = createTestFile();
+        URL url = f.toURL();
+        Resource r = mockResource();
+
+        long lastUpdated = f.lastModified();
+        lastUpdated -= lastUpdated % 1000;
+
+        train_getPath(r, PATH);
+        train_toURL(r, url);
+
+        train_requiresDigest(generator, PATH, true);
+        train_generateChecksum(generator, url, DIGEST);
+
+        replay();
+
+        ResourceCacheImpl cache = new ResourceCacheImpl(generator);
+        cache.addInvalidationListener(listener);
+
+        assertEquals(cache.requiresDigest(r), true);
+        assertEquals(cache.getTimeModified(r), lastUpdated);
+        assertEquals(cache.getDigest(r), DIGEST);
+
+        // No updates yet.
+
+        cache.checkForUpdates();
+
+        verify();
+
+        Thread.sleep(1500);
+        touch(f);
+
+        lastUpdated = f.lastModified();
+        lastUpdated -= lastUpdated % 1000;
+
+        String expectedDigest = "FREDBARNEY";
+
+        train_getPath(r, PATH);
+        train_toURL(r, url);
+        train_requiresDigest(generator, PATH, true);
+        train_generateChecksum(generator, url, expectedDigest);
+
+        listener.objectWasInvalidated();
+
+        replay();
+
+        cache.checkForUpdates();
+
+        assertEquals(cache.requiresDigest(r), true);
+        assertEquals(cache.getTimeModified(r), lastUpdated);
+        assertEquals(cache.getDigest(r), expectedDigest);
+
+        verify();
+    }
+
+    private File createTestFile() throws IOException
+    {
+        return File.createTempFile("ResourceCacheImplTest.", ".tst");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImplTest.java
new file mode 100644
index 0000000..acf8a79
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceDigestGeneratorImplTest.java
@@ -0,0 +1,78 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ResourceDigestGenerator;
+import org.testng.annotations.Test;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Arrays;
+
+public class ResourceDigestGeneratorImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void typical_file() throws Exception
+    {
+        URL url = getClass().getResource("ResourceDigestGeneratorImplTest.class");
+
+        ResourceDigestGenerator g = new ResourceDigestGeneratorImpl(Arrays.asList("class"));
+
+        String digest = g.generateDigest(url);
+
+        assertTrue(digest.length() > 0);
+
+        String checksum2 = g.generateDigest(url);
+
+        assertEquals(checksum2, digest);
+    }
+
+    @Test
+    public void digest_changes_with_changes_to_file() throws Exception
+    {
+        File file = File.createTempFile("digest.", ".dat");
+
+        URL url = file.toURL();
+
+        ResourceDigestGenerator g = new ResourceDigestGeneratorImpl(Arrays.asList("class"));
+
+        String prevDigest = g.generateDigest(url);
+
+        for (int i = 0; i < 5; i++)
+        {
+            writeJunkTofile(file);
+
+            String digest = g.generateDigest(url);
+
+            assertFalse(digest.equals(prevDigest));
+
+            prevDigest = digest;
+
+        }
+    }
+
+    private void writeJunkTofile(File file) throws IOException
+    {
+        OutputStream os = new BufferedOutputStream(new FileOutputStream(file, true));
+
+        OutputStreamWriter writer = new OutputStreamWriter(os);
+
+        for (int i = 0; i < 1000; i++)
+            writer.write("All work and no play makes Jack a dull boy. ");
+
+        writer.close();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceStreamerImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceStreamerImplTest.java
new file mode 100644
index 0000000..dae45d9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResourceStreamerImplTest.java
@@ -0,0 +1,90 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Response;
+import org.apache.tapestry5.services.RequestGlobals;
+import static org.easymock.EasyMock.*;
+import org.testng.annotations.Test;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Tests for the {@link ResourceStreamerImpl} class.
+ */
+public class ResourceStreamerImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void content_type_css() throws IOException
+    {
+        content_type("text/css", "test.css");
+    }
+
+    @Test
+    public void content_type_js() throws IOException
+    {
+        content_type("text/javascript", "test.js");
+    }
+
+    @Test
+    public void content_type_gif() throws IOException
+    {
+        content_type("image/gif", "test.gif");
+    }
+
+    private void content_type(String contentType, String fileName) throws IOException
+    {
+        Request request = mockRequest();
+        HttpServletResponse hsr = mockHttpServletResponse();
+
+        train_setContentLength(hsr, anyInt());
+        train_setDateHeader(hsr, eq("Last-Modified"), anyLong());
+        train_setDateHeader(hsr, eq("Expires"), anyLong());
+        train_setContentType(hsr, contentType);
+        train_getOutputStream(hsr, new TestServletOutputStream());
+
+        replay();
+
+        Response response = new ResponseImpl(hsr);
+        ResourceStreamer streamer = getService(ResourceStreamer.class);
+        RequestGlobals globals = getService(RequestGlobals.class);
+
+        globals.storeRequestResponse(request, response);
+
+        String path = getClass().getPackage().getName().replace('.', '/') + "/" + fileName;
+
+        Resource resource = new ClasspathResource(path);
+
+        streamer.streamResource(resource);
+
+        verify();
+    }
+
+    private static class TestServletOutputStream extends ServletOutputStream
+    {
+        @Override
+        public void write(int b) throws IOException
+        {
+            // Empty.
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResponseRendererImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResponseRendererImplTest.java
new file mode 100644
index 0000000..b6b5a17
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ResponseRendererImplTest.java
@@ -0,0 +1,76 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.ContentType;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.Response;
+import org.testng.annotations.Test;
+
+public class ResponseRendererImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void content_type_from_component()
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        PageContentTypeAnalyzer analyzer = mockPageContentTypeAnalyzer();
+        Component component = mockComponent();
+        String pageName = "foo/bar";
+        Page page = mockPage();
+        ContentType contentType = new ContentType("zig/zag");
+        ComponentResources resources = mockComponentResources();
+
+        train_getComponentResources(component, resources);
+        train_getPageName(resources, pageName);
+        train_get(cache, pageName, page);
+
+        train_findContentType(analyzer, page, contentType);
+
+        replay();
+
+        ResponseRenderer renderer = new ResponseRendererImpl(cache, analyzer, null);
+
+        assertSame(renderer.findContentType(component), contentType);
+
+        verify();
+    }
+
+    @Test
+    public void render_page_markup() throws Exception
+    {
+        RequestPageCache cache = mockRequestPageCache();
+        PageContentTypeAnalyzer analyzer = mockPageContentTypeAnalyzer();
+        String pageName = "foo/bar";
+        Page page = mockPage();
+        PageResponseRenderer pageResponseRenderer = mockPageResponseRenderer();
+        Response response = mockResponse();
+
+        train_get(cache, pageName, page);
+
+        pageResponseRenderer.renderPageResponse(page);
+
+        replay();
+
+        ResponseRenderer renderer = new ResponseRendererImpl(cache, analyzer, pageResponseRenderer);
+
+        renderer.renderPageMarkupResponse(pageName);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProviderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProviderTest.java
new file mode 100644
index 0000000..1603ffd
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ServiceAnnotationObjectProviderTest.java
@@ -0,0 +1,70 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotation.Service;
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class ServiceAnnotationObjectProviderTest extends TapestryTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void no_annotation()
+    {
+        Class objectType = Runnable.class;
+        AnnotationProvider provider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+
+        train_getAnnotation(provider, Service.class, null);
+
+        replay();
+
+        ObjectProvider objectProvider = new ServiceAnnotationObjectProvider();
+
+        assertNull(objectProvider.provide(objectType, provider, locator));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void annotation_present()
+    {
+        Class objectType = Runnable.class;
+        AnnotationProvider provider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        Service service = newMock(Service.class);
+        String serviceId = "JiffyPop";
+        Runnable instance = mockRunnable();
+
+        train_getAnnotation(provider, Service.class, service);
+
+        expect(service.value()).andReturn(serviceId);
+
+        train_getService(locator, serviceId, objectType, instance);
+
+        replay();
+
+        ObjectProvider objectProvider = new ServiceAnnotationObjectProvider();
+
+        assertSame(objectProvider.provide(objectType, provider, locator), instance);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategyTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategyTest.java
new file mode 100644
index 0000000..74e297d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionApplicationStatePersistenceStrategyTest.java
@@ -0,0 +1,129 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.pages.ReadOnlyBean;
+import org.apache.tapestry.services.ApplicationStateCreator;
+import org.apache.tapestry.services.ApplicationStatePersistenceStrategy;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+import org.testng.annotations.Test;
+
+public class SessionApplicationStatePersistenceStrategyTest extends InternalBaseTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void get_aso_already_exists()
+    {
+        Request request = mockRequest();
+        Session session = mockSession();
+        Class asoClass = ReadOnlyBean.class;
+        Object aso = new ReadOnlyBean();
+        String key = "aso:" + asoClass.getName();
+        ApplicationStateCreator creator = mockApplicationStateCreator();
+
+        train_getSession(request, true, session);
+        train_getAttribute(session, key, aso);
+
+        replay();
+
+        ApplicationStatePersistenceStrategy strategy = new SessionApplicationStatePersistenceStrategy(request);
+
+        assertSame(strategy.get(asoClass, creator), aso);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void check_exists_does_not_create_session()
+    {
+        Request request = mockRequest();
+        Class asoClass = ReadOnlyBean.class;
+
+        train_getSession(request, false, null);
+
+        replay();
+
+        ApplicationStatePersistenceStrategy strategy = new SessionApplicationStatePersistenceStrategy(request);
+
+        assertFalse(strategy.exists(asoClass));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void get_aso_needs_to_be_created()
+    {
+        Request request = mockRequest();
+        Session session = mockSession();
+        Class asoClass = ReadOnlyBean.class;
+        Object aso = new ReadOnlyBean();
+        String key = "aso:" + asoClass.getName();
+        ApplicationStateCreator creator = mockApplicationStateCreator();
+
+        // First for exists()
+        train_getSession(request, false, session);
+        train_getAttribute(session, key, null);
+
+        // Second for get()
+        train_getSession(request, true, session);
+        train_getAttribute(session, key, null);
+
+        train_create(creator, aso);
+
+        session.setAttribute(key, aso);
+
+        // Then for exists() after
+        train_getSession(request, false, session);
+        train_getAttribute(session, key, aso);
+
+        replay();
+
+        ApplicationStatePersistenceStrategy strategy = new SessionApplicationStatePersistenceStrategy(request);
+
+        assertFalse(strategy.exists(asoClass));
+
+        assertSame(strategy.get(asoClass, creator), aso);
+
+        assertTrue(strategy.exists(asoClass));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void set_aso()
+    {
+        Request request = mockRequest();
+        Session session = mockSession();
+        Class asoClass = ReadOnlyBean.class;
+        Object aso = new ReadOnlyBean();
+        String key = "aso:" + asoClass.getName();
+
+        train_getSession(request, true, session);
+        session.setAttribute(key, aso);
+
+        replay();
+
+        ApplicationStatePersistenceStrategy strategy = new SessionApplicationStatePersistenceStrategy(request);
+
+        strategy.set(asoClass, aso);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionImplTest.java
new file mode 100644
index 0000000..7760b8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionImplTest.java
@@ -0,0 +1,111 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.Session;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpSession;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+
+public class SessionImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void get_attribute_names()
+    {
+        Enumeration e = Collections.enumeration(Arrays.asList("fred", "barney"));
+        HttpSession hs = mockHttpSession();
+
+        expect(hs.getAttributeNames()).andReturn(e);
+
+        replay();
+
+        Session session = new SessionImpl(hs);
+
+        assertEquals(session.getAttributeNames(), Arrays.asList("barney", "fred"));
+
+        verify();
+    }
+
+    @Test
+    public void get_attribute_names_by_prefix()
+    {
+        Enumeration e = Collections.enumeration(Arrays.asList("fred", "barney", "fanny"));
+        HttpSession hs = mockHttpSession();
+
+        expect(hs.getAttributeNames()).andReturn(e);
+
+        replay();
+
+        Session session = new SessionImpl(hs);
+
+        assertEquals(session.getAttributeNames("f"), Arrays.asList("fanny", "fred"));
+
+        verify();
+    }
+
+    @Test
+    public void invalidate()
+    {
+        HttpSession hs = mockHttpSession();
+
+        hs.invalidate();
+
+        replay();
+
+        Session session = new SessionImpl(hs);
+
+        session.invalidate();
+
+        verify();
+    }
+
+    @Test
+    public void set_max_inactive()
+    {
+        HttpSession hs = mockHttpSession();
+        int seconds = 999;
+
+        hs.setMaxInactiveInterval(seconds);
+
+        replay();
+
+        Session session = new SessionImpl(hs);
+
+        session.setMaxInactiveInterval(seconds);
+
+        verify();
+    }
+
+    @Test
+    public void get_max_inactive()
+    {
+        HttpSession hs = mockHttpSession();
+        int seconds = 999;
+
+        expect(hs.getMaxInactiveInterval()).andReturn(seconds);
+
+        replay();
+
+        Session session = new SessionImpl(hs);
+
+        assertEquals(session.getMaxInactiveInterval(), seconds);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java
new file mode 100644
index 0000000..ed325a6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SessionPersistentFieldStrategyTest.java
@@ -0,0 +1,169 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.Session;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+public class SessionPersistentFieldStrategyTest extends InternalBaseTestCase
+{
+    @Test
+    public void post_change_to_root_component()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+        Object value = new Object();
+
+        train_getSession(request, true, session);
+
+        session.setAttribute("state:foo.Bar::field", value);
+
+        replay();
+
+        SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+        strategy.postChange("foo.Bar", null, "field", value);
+
+        verify();
+    }
+
+    @Test
+    public void post_change_to_nested_component()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+        Object value = new Object();
+
+        train_getSession(request, true, session);
+
+        session.setAttribute("state:foo.Bar:fee.fum:field", value);
+
+        replay();
+
+        SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+        strategy.postChange("foo.Bar", "fee.fum", "field", value);
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1475
+     */
+    @Test
+    public void discard_changes_with_no_session()
+    {
+        Request request = mockRequest();
+
+        train_getSession(request, false, null);
+
+        replay();
+
+        SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+        strategy.discardChanges("foo.Bar");
+
+        verify();
+    }
+
+    /**
+     * TAPESTRY-1475
+     */
+    @Test
+    public void discard_changes()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+
+        train_getSession(request, false, session);
+
+        train_getAttributeNames(session, "state:foo.Bar:", "state:foo.Bar:baz:field");
+
+        session.setAttribute("state:foo.Bar:baz:field", null);
+
+        replay();
+
+        SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+        strategy.discardChanges("foo.Bar");
+
+        verify();
+    }
+
+    @Test
+    public void gather_changes_with_no_session()
+    {
+        Request request = mockRequest();
+
+        train_getSession(request, false, null);
+
+        replay();
+
+        SessionPersistentFieldStrategy strategy = new SessionPersistentFieldStrategy(request);
+
+        Collection<PersistentFieldChange> changes = strategy.gatherFieldChanges("foo.Bar");
+
+        assertTrue(changes.isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void gather_changes_with_active_session()
+    {
+        Session session = mockSession();
+        Request request = mockRequest();
+
+        train_getSession(request, false, session);
+        train_getAttributeNames(
+                session,
+                "state:foo.Bar:",
+                "state:foo.Bar::root",
+                "state:foo.Bar:nested:down");
+
+        train_getAttribute(session, "state:foo.Bar::root", "ROOT");
+        train_getAttribute(session, "state:foo.Bar:nested:down", "DOWN");
+
+        replay();
+
+        SessionPersistentFieldStrategy stategy = new SessionPersistentFieldStrategy(request);
+
+        Collection<PersistentFieldChange> changes = stategy.gatherFieldChanges("foo.Bar");
+
+        assertEquals(changes.size(), 2);
+
+        Iterator<PersistentFieldChange> i = changes.iterator();
+
+        PersistentFieldChange change1 = i.next();
+
+        assertEquals(change1.getComponentId(), "");
+        assertEquals(change1.getFieldName(), "root");
+        assertEquals(change1.getValue(), "ROOT");
+
+        PersistentFieldChange change2 = i.next();
+
+        assertEquals(change2.getComponentId(), "nested");
+        assertEquals(change2.getFieldName(), "down");
+        assertEquals(change2.getValue(), "DOWN");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleASO.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleASO.java
new file mode 100644
index 0000000..f7588d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleASO.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class SimpleASO
+{
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public String getReadOnly()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java
new file mode 100644
index 0000000..0d55d79
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleBean.java
@@ -0,0 +1,58 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.beaneditor.Width;
+
+public class SimpleBean
+{
+    private String firstName;
+
+    private String lastName;
+
+    private int age;
+
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    @Width(2)
+    public int getAge()
+    {
+        return age;
+    }
+
+    public void setAge(int age)
+    {
+        this.age = age;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleLayoutComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleLayoutComponent.java
new file mode 100644
index 0000000..9598444
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/SimpleLayoutComponent.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+ * Created on Mar 15, 2007
+ * 
+ * 
+ */
+package org.apache.tapestry.internal.services;
+
+public class SimpleLayoutComponent
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StaticFilesFilterTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StaticFilesFilterTest.java
new file mode 100644
index 0000000..c770eb1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StaticFilesFilterTest.java
@@ -0,0 +1,173 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.*;
+import org.testng.annotations.Test;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URL;
+
+public class StaticFilesFilterTest extends InternalBaseTestCase
+{
+    @Test
+    public void request_for_favicon() throws IOException
+    {
+        Request request = newRequest("/favicon.ico");
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertFalse(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void path_does_not_contain_a_period() throws Exception
+    {
+        Request request = newRequest("/start");
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        train_service(handler, request, response, true);
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void existing_file() throws Exception
+    {
+        URL url = new URL("file://.");
+        String path = "/cell.gif";
+
+        Request request = newRequest(path);
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        train_getResource(context, path, url);
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertFalse(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void existing_template_file() throws Exception
+    {
+        URL url = new URL("file://.");
+        String path = "/cell.tml";
+
+        Request request = newRequest(path);
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        train_getResource(context, path, url);
+
+        response.sendError(
+                HttpServletResponse.SC_FORBIDDEN,
+                "URI /cell.tml may not be accessed remotely.");
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void existing_template_file_case_insenitive() throws Exception
+    {
+        URL url = new URL("file://.");
+        String path = "/cell.TML";
+
+        Request request = newRequest(path);
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        train_getResource(context, path, url);
+
+        response.sendError(
+                HttpServletResponse.SC_FORBIDDEN,
+                "URI /cell.TML may not be accessed remotely.");
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    @Test
+    public void not_a_static_file_request() throws Exception
+    {
+        String path = "/start.update";
+
+        Request request = newRequest(path);
+        Response response = mockResponse();
+        RequestHandler handler = mockRequestHandler();
+        Context context = mockContext();
+
+        train_getResource(context, path, null);
+        train_service(handler, request, response, true);
+
+        replay();
+
+        RequestFilter filter = new StaticFilesFilter(context);
+
+        assertTrue(filter.service(request, response, handler));
+
+        verify();
+    }
+
+    protected final void train_getResource(Context context, String path, URL url)
+    {
+        expect(context.getResource(path)).andReturn(url);
+    }
+
+    protected final Request newRequest(String path)
+    {
+        Request request = mockRequest();
+
+        train_getPath(request, path);
+
+        return request;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java
new file mode 100644
index 0000000..fc14e82
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StoogeBean.java
@@ -0,0 +1,66 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.beaneditor.OrderAfter;
+import org.apache.tapestry.beaneditor.OrderBefore;
+
+public class StoogeBean
+{
+    private int moe, larry, curly, shemp;
+
+    public int getMoe()
+    {
+        return moe;
+    }
+
+    @OrderAfter("shemp")
+    public int getCurly()
+    {
+        return curly;
+    }
+
+    @OrderBefore("moe")
+    public int getLarry()
+    {
+        return larry;
+    }
+
+    public int getShemp()
+    {
+        return shemp;
+    }
+
+    public void setCurly(int curly)
+    {
+        this.curly = curly;
+    }
+
+    public void setLarry(int larry)
+    {
+        this.larry = larry;
+    }
+
+    public void setMoe(int moe)
+    {
+        this.moe = moe;
+    }
+
+    public void setShemp(int shemp)
+    {
+        this.shemp = shemp;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringArrayBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringArrayBean.java
new file mode 100644
index 0000000..3a22371
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringArrayBean.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class StringArrayBean
+{
+    private String[] array;
+
+    public String[] getArray()
+    {
+        return array;
+    }
+
+    public void setArray(String[] array)
+    {
+        this.array = array;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolder.java
new file mode 100644
index 0000000..f3c5203
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolder.java
@@ -0,0 +1,21 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.util.Holder;
+
+public class StringHolder extends Holder<String>
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolderBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolderBean.java
new file mode 100644
index 0000000..c8a30ec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/StringHolderBean.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class StringHolderBean extends GenericBean<StringHolder>
+{
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
new file mode 100644
index 0000000..d0689ba
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
@@ -0,0 +1,788 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.parser.*;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.test.TapestryTestConstants;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.lang.String.format;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This is used to test the template parser ... and in some cases, the underlying behavior of the
+ * SAX APIs.
+ */
+public class TemplateParserImplTest extends InternalBaseTestCase
+{
+
+    private TemplateParser getParser()
+    {
+        return this.getService(TemplateParser.class);
+    }
+
+    private synchronized ComponentTemplate parse(String file)
+    {
+        Resource resource = getResource(file);
+
+        return getParser().parseTemplate(resource);
+    }
+
+    private synchronized List<TemplateToken> tokens(String file)
+    {
+        Resource resource = getResource(file);
+
+        return getParser().parseTemplate(resource).getTokens();
+    }
+
+    private Resource getResource(String file)
+    {
+        String packageName = getClass().getPackage().getName();
+
+        String path = packageName.replace('.', '/') + "/" + file;
+
+        ClassLoader loader = getClass().getClassLoader();
+
+        return new ClasspathResource(loader, path);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T extends TemplateToken> T get(List l, int index)
+    {
+        Object raw = l.get(index);
+
+        return (T) raw;
+    }
+
+    private void checkLine(Locatable l, int expectedLineNumber)
+    {
+        assertEquals(l.getLocation().getLine(), expectedLineNumber);
+    }
+
+    @Test
+    public void just_HTML()
+    {
+        Resource resource = getResource("justHTML.tml");
+
+        ComponentTemplate template = getParser().parseTemplate(resource);
+
+        assertSame(template.getResource(), resource);
+
+        List<TemplateToken> tokens = template.getTokens();
+
+        // They add up quick ...
+
+        assertEquals(tokens.size(), 20);
+
+        StartElementToken t0 = get(tokens, 0);
+
+        // Spot check a few things ...
+
+        assertEquals(t0.getName(), "html");
+        assertEquals(t0.getNamespaceURI(), "");
+        checkLine(t0, 1);
+
+        TextToken t1 = get(tokens, 1);
+        // Concerned this may not work cross platform.
+        assertEquals(t1.getText(), "\n    ");
+
+        StartElementToken t2 = get(tokens, 2);
+        assertEquals(t2.getName(), "head");
+        checkLine(t2, 2);
+
+        TextToken t5 = get(tokens, 5);
+        assertEquals(t5.getText(), "title");
+        checkLine(t5, 3);
+
+        get(tokens, 6);
+
+        StartElementToken t12 = get(tokens, 12);
+        assertEquals(t12.getName(), "p");
+
+        AttributeToken t13 = get(tokens, 13);
+        assertEquals(t13.getName(), "class");
+        assertEquals(t13.getValue(), "important");
+        assertEquals(t13.getNamespaceURI(), "");
+
+        TextToken t14 = get(tokens, 14);
+        // Simplify the text, converting consecutive whitespace to just a single space.
+        assertEquals(t14.getText().replaceAll("\\s+", " ").trim(), "Tapestry rocks! Line 2");
+
+        // Line number is the *start* line of the whole text block.
+        checkLine(t14, 6);
+    }
+
+    @Test
+    public void namespaced_element()
+    {
+        Resource resource = getResource("namespaced_element.tml");
+
+        ComponentTemplate template = getParser().parseTemplate(resource);
+
+        assertSame(template.getResource(), resource);
+
+        List<TemplateToken> tokens = template.getTokens();
+
+        // They add up quick ...
+
+        assertEquals(tokens.size(), 8);
+
+        StartElementToken t0 = get(tokens, 0);
+
+        String expectedURI = "http://foo.com";
+
+        assertEquals(t0.getNamespaceURI(), expectedURI);
+        assertEquals(t0.getName(), "bar");
+
+        DefineNamespacePrefixToken t1 = get(tokens, 1);
+
+        assertEquals(t1.getNamespacePrefix(), "foo");
+        assertEquals(t1.getNamespaceURI(), expectedURI);
+
+        AttributeToken t2 = get(tokens, 2);
+
+        assertEquals(t2.getName(), "biff");
+        assertEquals(t2.getValue(), "baz");
+        assertEquals(t2.getNamespaceURI(), expectedURI);
+
+        StartElementToken t4 = get(tokens, 4);
+
+        assertEquals(t4.getNamespaceURI(), "");
+        assertEquals(t4.getName(), "gnip");
+
+        // The rest are close tokens
+    }
+
+    @Test
+    public void container_element()
+    {
+        List<TemplateToken> tokens = tokens("container_element.tml");
+
+        assertEquals(tokens.size(), 4);
+
+        TextToken t0 = get(tokens, 0);
+
+        assertEquals(t0.getText().trim(), "A bit of text.");
+
+        StartElementToken t1 = get(tokens, 1);
+
+        assertEquals(t1.getName(), "foo");
+
+        EndElementToken t2 = get(tokens, 2);
+
+        assertNotNull(t2); // Keep compiler happy
+
+        TextToken t3 = get(tokens, 3);
+
+        assertEquals(t3.getText().trim(), "Some more text.");
+    }
+
+    @Test
+    public void xml_entity()
+    {
+        List<TemplateToken> tokens = tokens("xmlEntity.tml");
+
+        assertEquals(tokens.size(), 3);
+
+        TextToken t = get(tokens, 1);
+
+        // This is OK because the org.apache.tapestry.dom.Text will convert the characters back into
+        // XML entities.
+
+        assertEquals(t.getText().trim(), "lt:< gt:> amp:&");
+    }
+
+    @Test
+    public void html_entity()
+    {
+        String expectedURI = "http://www.w3.org/1999/xhtml";
+
+        List<TemplateToken> tokens = tokens("html_entity.tml");
+
+        assertEquals(tokens.size(), 5);
+
+        DTDToken t0 = get(tokens, 0);
+
+        assertEquals(t0.getName(), "html");
+        assertEquals(t0.getPublicId(), "-//W3C//DTD XHTML 1.0 Transitional//EN");
+        assertEquals(t0.getSystemId(), "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
+
+        StartElementToken t1 = get(tokens, 1);
+
+        assertEquals(t1.getNamespaceURI(), expectedURI);
+        assertEquals(t1.getName(), "html");
+
+        DefineNamespacePrefixToken t2 = get(tokens, 2);
+
+        assertEquals(t2.getNamespaceURI(), expectedURI);
+        assertEquals(t2.getNamespacePrefix(), "");
+
+
+        TextToken t = get(tokens, 3);
+
+        // HTML entities are parsed into values that will ultimately
+        // be output as numeric entities. This is less than ideal; would like
+        // to find a way to keep the entities in their original form (possibly
+        // involving a new type of token), but SAX seems to be fighting me on this.
+        // You have to have a DOCTYPE just to parse a template that uses
+        // an HTML entity.
+
+        assertEquals(t.getText().trim(), "nbsp:[\u00a0]");
+    }
+
+    @Test
+    public void cdata()
+    {
+        List<TemplateToken> tokens = tokens("cdata.tml");
+
+        // Whitespace text tokens around the CDATA
+
+        assertEquals(tokens.size(), 5);
+
+        CDATAToken t = get(tokens, 2);
+
+        assertEquals(t.getContent(), "CDATA: &lt;foo&gt; &amp; &lt;bar&gt; and <baz>");
+        checkLine(t, 2);
+    }
+
+    @Test
+    public void comment()
+    {
+        List<TemplateToken> tokens = tokens("comment.tml");
+
+        // Again, whitespace before and after the comment adds some tokens
+
+        assertEquals(tokens.size(), 3);
+
+        CommentToken token1 = get(tokens, 1);
+
+        // Comments are now trimmed of leading and trailing whitespace. This may mean
+        // that the output isn't precisely what's in the template, but a) its a comment
+        // and b) that's pretty much true of everything in the templates.
+
+        assertEquals(token1.getComment(), "Single line comment");
+    }
+
+    @Test
+    public void multiline_comment()
+    {
+        List<TemplateToken> tokens = tokens("multilineComment.tml");
+
+        // Again, whitespace before and after the comment adds some tokens
+
+        assertEquals(tokens.size(), 5);
+
+        CommentToken t = get(tokens, 2);
+
+        String comment = t.getComment().trim().replaceAll("\\s+", " ");
+
+        assertEquals(comment, "Line one Line two Line three");
+    }
+
+    @Test
+    public void component()
+    {
+        List<TemplateToken> tokens = tokens("component.tml");
+
+        assertEquals(tokens.size(), 6);
+
+        StartComponentToken t = get(tokens, 2);
+        assertEquals(t.getId(), "fred");
+        assertEquals(t.getComponentType(), "somecomponent");
+        assertNull(t.getMixins());
+        checkLine(t, 2);
+
+        get(tokens, 3);
+    }
+
+    @Test
+    public void component_with_body()
+    {
+        List<TemplateToken> tokens = tokens("componentWithBody.tml");
+
+        assertEquals(tokens.size(), 7);
+
+        get(tokens, 2);
+
+        TextToken t = get(tokens, 3);
+
+        assertEquals(t.getText().trim(), "fred's body");
+
+        get(tokens, 4);
+    }
+
+    @Test
+    public void root_element_is_component()
+    {
+        List<TemplateToken> tokens = tokens("root_element_is_component.tml");
+
+        assertEquals(tokens.size(), 3);
+
+        StartComponentToken start = get(tokens, 0);
+
+        assertEquals(start.getId(), "fred");
+        assertEquals(start.getComponentType(), "Fred");
+        assertNull(start.getElementName());
+
+        AttributeToken attr = get(tokens, 1);
+
+        assertEquals(attr.getName(), "param");
+        assertEquals(attr.getValue(), "value");
+
+        assertTrue(EndElementToken.class.isInstance(tokens.get(2)));
+    }
+
+    @Test
+    public void instrumented_element()
+    {
+        ComponentTemplate template = parse("instrumented_element.tml");
+        List<TemplateToken> tokens = template.getTokens();
+
+        assertEquals(tokens.size(), 3);
+
+        StartComponentToken start = get(tokens, 0);
+
+        assertEquals(start.getId(), "fred");
+        assertEquals(start.getComponentType(), "Fred");
+        assertEquals(start.getElementName(), "html");
+
+        AttributeToken attr = get(tokens, 1);
+
+        assertEquals(attr.getName(), "param");
+        assertEquals(attr.getValue(), "value");
+
+        assertTrue(EndElementToken.class.isInstance(tokens.get(2)));
+
+        assertEquals(template.getComponentIds(), Arrays.asList("fred"));
+    }
+
+    @Test
+    public void body_element()
+    {
+        List<TemplateToken> tokens = tokens("body_element.tml");
+
+        // start(html), text, body, text, end(html)
+        assertEquals(tokens.size(), 5);
+
+        // javac bug requires use of isInstance() instead of instanceof
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
+        assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
+    }
+
+    @Test
+    public void content_within_body_element()
+    {
+        List<TemplateToken> tokens = parse("content_within_body_element.tml").getTokens();
+
+        assertEquals(tokens.size(), 5);
+
+        // javac bug is requires use of isInstance() instead of instanceof
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=113218
+
+        assertTrue(BodyToken.class.isInstance(get(tokens, 2)));
+        assertTrue(TextToken.class.isInstance(get(tokens, 3)));
+        assertTrue(EndElementToken.class.isInstance(get(tokens, 4)));
+    }
+
+    @Test
+    public void component_with_parameters()
+    {
+        List<TemplateToken> tokens = tokens("componentWithParameters.tml");
+
+        assertEquals(tokens.size(), 9);
+
+        TemplateToken templateToken = get(tokens, 2);
+        Location l = templateToken.getLocation();
+
+        AttributeToken t1 = get(tokens, 3);
+
+        // TODO: Not sure what order the attributes appear in. Order in the XML? Sorted
+        // alphabetically? Random 'cause they're hashed?
+
+        assertEquals(t1.getName(), "cherry");
+        assertEquals(t1.getValue(), "bomb");
+        assertSame(t1.getLocation(), l);
+
+        AttributeToken t2 = get(tokens, 4);
+        assertEquals(t2.getName(), "align");
+        assertEquals(t2.getValue(), "right");
+        assertSame(t2.getLocation(), l);
+
+        TextToken t3 = get(tokens, 5);
+
+        assertEquals(t3.getText().trim(), "fred's body");
+
+        get(tokens, 6);
+    }
+
+    @Test
+    public void component_with_mixins()
+    {
+        List<TemplateToken> tokens = tokens("component_with_mixins.tml");
+
+        assertEquals(tokens.size(), 4);
+
+        StartComponentToken token1 = get(tokens, 1);
+
+        assertEquals(token1.getId(), "fred");
+        assertEquals(token1.getComponentType(), "comp");
+        assertEquals(token1.getMixins(), "Barney");
+    }
+
+    @Test
+    public void empty_string_mixins_is_null()
+    {
+        List<TemplateToken> tokens = tokens("empty_string_mixins_is_null.tml");
+
+        assertEquals(tokens.size(), 6);
+
+        StartComponentToken t = get(tokens, 2);
+
+        assertEquals(t.getId(), "fred");
+        // We also check that empty string type is null ..
+        assertNull(t.getComponentType());
+        assertNull(t.getMixins());
+    }
+
+    @Test
+    public void component_ids()
+    {
+        ComponentTemplate template = parse("component_ids.tml");
+
+        Set<String> ids = template.getComponentIds();
+
+        assertEquals(ids, newSet(Arrays.asList("bomb", "border", "zebra")));
+    }
+
+    @Test
+    public void expansions_in_normal_text()
+    {
+        List<TemplateToken> tokens = tokens("expansions_in_normal_text.tml");
+
+        assertEquals(tokens.size(), 7);
+
+        TextToken t1 = get(tokens, 1);
+
+        assertEquals(t1.getText().trim(), "Expansion #1[");
+
+        ExpansionToken t2 = get(tokens, 2);
+        assertEquals(t2.getExpression(), "expansion1");
+
+        TextToken t3 = get(tokens, 3);
+        assertEquals(t3.getText().replaceAll("\\s+", " "), "] Expansion #2[");
+
+        ExpansionToken t4 = get(tokens, 4);
+        assertEquals(t4.getExpression(), "expansion2");
+
+        TextToken t5 = get(tokens, 5);
+        assertEquals(t5.getText().trim(), "]");
+    }
+
+    @Test
+    public void expansions_must_be_on_one_line()
+    {
+        List<TemplateToken> tokens = tokens("expansions_must_be_on_one_line.tml");
+
+        assertEquals(tokens.size(), 3);
+
+        TextToken t1 = get(tokens, 1);
+
+        assertEquals(t1.getText().replaceAll("\\s+", " "), " ${expansions must be on a single line} ");
+
+    }
+
+    @Test
+    public void multiple_expansions_on_one_line()
+    {
+        List<TemplateToken> tokens = tokens("multiple_expansions_on_one_line.tml");
+
+        assertEquals(tokens.size(), 10);
+
+        ExpansionToken token3 = get(tokens, 3);
+
+        assertEquals(token3.getExpression(), "classLoader");
+
+        TextToken token4 = get(tokens, 4);
+
+        assertEquals(token4.getText(), " [");
+
+        ExpansionToken token5 = get(tokens, 5);
+
+        assertEquals(token5.getExpression(), "classLoader.class.name");
+
+        TextToken token6 = get(tokens, 6);
+
+        assertEquals(token6.getText(), "]");
+    }
+
+    @Test
+    public void expansions_not_allowed_in_cdata()
+    {
+        List<TemplateToken> tokens = tokens("expansions_not_allowed_in_cdata.tml");
+
+        assertEquals(tokens.size(), 5);
+
+        CDATAToken t2 = get(tokens, 2);
+
+        assertEquals(t2.getContent(), "${not-an-expansion}");
+    }
+
+    @Test
+    public void expansions_not_allowed_in_attributes()
+    {
+        List<TemplateToken> tokens = tokens("expansions_not_allowed_in_attributes.tml");
+
+        assertEquals(tokens.size(), 3);
+
+        AttributeToken token1 = get(tokens, 1);
+
+        assertEquals(token1.getName(), "exp");
+        assertEquals(token1.getValue(), "${not-an-expansion}");
+    }
+
+    @Test
+    public void parameter_element()
+    {
+        List<TemplateToken> tokens = tokens("parameter_element.tml");
+
+        ParameterToken token4 = get(tokens, 4);
+        assertEquals(token4.getName(), "fred");
+
+        CommentToken token6 = get(tokens, 6);
+        assertEquals(token6.getComment(), "fred content");
+
+        TemplateToken token8 = get(tokens, 8);
+
+        assertEquals(token8.getTokenType(), TokenType.END_ELEMENT);
+    }
+
+    @Test
+    public void complex_component_type()
+    {
+        List<TemplateToken> tokens = tokens("complex_component_type.tml");
+
+        assertEquals(tokens.size(), 4);
+
+        StartComponentToken token1 = get(tokens, 1);
+
+        assertEquals(token1.getComponentType(), "subfolder/nifty");
+    }
+
+    @Test
+    public void block_element()
+    {
+        List<TemplateToken> tokens = tokens("block_element.tml");
+
+        BlockToken token1 = get(tokens, 1);
+        assertEquals(token1.getId(), "block0");
+
+        CommentToken token2 = get(tokens, 2);
+        assertEquals(token2.getComment(), "block0 content");
+
+        BlockToken token4 = get(tokens, 4);
+        assertNull(token4.getId());
+
+        CommentToken token5 = get(tokens, 5);
+        assertEquals(token5.getComment(), "anon block content");
+    }
+
+    @DataProvider(name = "parse_failure_data")
+    public Object[][] parse_failure_data()
+    {
+        return new Object[][]{
+
+                {"mixin_requires_id_or_type.tml",
+                 "You may not specify mixins for element <span> because it does not represent a component (which requires either an id attribute or a type attribute).",
+                 2},
+
+                {"illegal_nesting_within_body_element.tml", "Element 'xyz' is nested within a Tapestry body element",
+                 2},
+
+                {"unexpected_attribute_in_parameter_element.tml",
+                 "Element <parameter> does not support an attribute named 'grok'. The only allowed attribute name is 'name'.",
+                 4},
+
+                {"name_attribute_of_parameter_element_omitted.tml",
+                 "The name attribute of the <parameter> element must be specified.", 4},
+
+                {"name_attribute_of_parameter_element_blank.tml",
+                 "The name attribute of the <parameter> element must be specified.", 4},
+
+                {"unexpected_attribute_in_block_element.tml",
+                 "Element <block> does not support an attribute named 'name'. The only allowed attribute name is 'id'.",
+                 3},
+
+        };
+    }
+
+    @Test(dataProvider = "parse_failure_data")
+    public void parse_failure(String fileName, String errorMessageSubstring, int expectedLine)
+    {
+        try
+        {
+            parse(fileName);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            if (!ex.getMessage().contains(errorMessageSubstring))
+            {
+                throw new AssertionError(format("Message [%s] does not contain substring [%s].", ex.getMessage(),
+                                                errorMessageSubstring));
+            }
+
+            assertEquals(ex.getLocation().getLine(), expectedLine);
+        }
+    }
+
+    @DataProvider(name = "doctype_parsed_correctly_data")
+    public Object[][] doctype_parsed_correctly_data()
+    {
+        return new Object[][]{{"xhtml1_strict_doctype.tml"}, {"xhtml1_transitional_doctype.tml"},
+                              {"xhtml1_frameset_doctype.tml"}};
+    }
+
+    @Test(dataProvider = "doctype_parsed_correctly_data")
+    public void doctype_parsed_correctly(String fileName) throws Exception
+    {
+        List<TemplateToken> tokens = tokens(fileName);
+        assertEquals(tokens.size(), 12);
+        TextToken t = get(tokens, 9);
+        assertEquals(t.getText().trim(), "<Test>");
+    }
+
+    @DataProvider(name = "doctype_token_added_correctly_data")
+    public Object[][] doctype_token_added_correctly_data()
+    {
+        return new Object[][]{
+
+                {"xhtml1_strict_doctype.tml", "html", "-//W3C//DTD XHTML 1.0 Strict//EN",
+                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"},
+
+                {"xhtml1_transitional_doctype.tml", "html", "-//W3C//DTD XHTML 1.0 Transitional//EN",
+                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"},
+
+                {"xhtml1_frameset_doctype.tml", "html", "-//W3C//DTD XHTML 1.0 Frameset//EN",
+                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"},
+
+                {"html4_strict_doctype.tml", "HTML", "-//W3C//DTD HTML 4.01//EN",
+                 "http://www.w3.org/TR/html4/strict.dtd"},
+
+                {"html4_transitional_doctype.tml", "HTML", "-//W3C//DTD HTML 4.01 Transitional//EN",
+                 "http://www.w3.org/TR/html4/loose.dtd"},
+
+                {"html4_frameset_doctype.tml", "HTML", "-//W3C//DTD HTML 4.01 Frameset//EN",
+                 "http://www.w3.org/TR/html4/frameset.dtd"},
+
+                {"system_doctype.xml", "foo", null,
+                 "src/test/resources/org/apache/tapestry/internal/services/simple.dtd"}};
+    }
+
+    @Test(dataProvider = "doctype_token_added_correctly_data")
+    public void doctype_added_correctly(String fileName, String name, String publicId, String systemId) throws Exception
+    {
+        System.setProperty("user.dir", TapestryTestConstants.MODULE_BASE_DIR_PATH);
+
+        List<TemplateToken> tokens = tokens(fileName);
+        DTDToken t2 = get(tokens, 0);
+        assertEquals(t2.getName(), name);
+        assertEquals(t2.getPublicId(), publicId);
+        assertEquals(t2.getSystemId(), systemId);
+    }
+
+    @Test
+    public void invalid_component_id() throws Exception
+    {
+        try
+        {
+            parse("invalid_component_id.tml");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Component id 'not-valid' is not valid");
+        }
+    }
+
+    @Test
+    public void invalid_block_id() throws Exception
+    {
+        try
+        {
+            parse("invalid_block_id.tml");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Block id 'not-valid' is not valid");
+        }
+    }
+
+    /**
+     * Because of common code, this covers t:block and t:parameter.
+     */
+    @Test
+    public void space_preserved_in_block() throws Exception
+    {
+        List<TemplateToken> tokens = tokens("space_preserved_in_block.tml");
+
+        TextToken token1 = get(tokens, 1);
+
+        assertEquals(token1.getText(), "\n" + "        line in the middle\n" + "    ");
+    }
+
+    /**
+     * t:container is a bit of a different code path than t:block/t:parameter
+     */
+    @Test
+    public void space_preserved_in_container() throws Exception
+    {
+        List<TemplateToken> tokens = tokens("space_preserved_in_container.tml");
+
+        TextToken token0 = get(tokens, 0);
+        assertEquals(token0.getText(), "\n" + "    ");
+
+        TextToken token2 = get(tokens, 2);
+        assertEquals(token2.getText(), "\n" + "        some text\n" + "    ");
+
+    }
+
+    @Test
+    public void minimal_whitespace_maintained_inside_tags() throws Exception
+    {
+        List<TemplateToken> tokens = tokens("minimal_whitespace_maintained_inside_tags.tml");
+
+        // A line feed or carriage return surrounded by other whitespace is reduced to
+        // just a line feed.
+
+        TextToken token1 = get(tokens, 1);
+        assertEquals(token1.getText(), "\nWhitespace\n");
+
+
+        TextToken token5 = get(tokens, 5);
+        assertEquals(token5.getText(), "\nis maintained.\n");
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TranslatorSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TranslatorSourceImplTest.java
new file mode 100644
index 0000000..c3f2f11
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TranslatorSourceImplTest.java
@@ -0,0 +1,248 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Translator;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.services.TranslatorSource;
+import org.apache.tapestry.services.ValidationMessagesSource;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+
+public class TranslatorSourceImplTest extends InternalBaseTestCase
+{
+    private TranslatorSource source;
+
+    private ValidationMessagesSource messagesSource;
+
+    @BeforeClass
+    public void setup()
+    {
+        source = getService(TranslatorSource.class);
+        messagesSource = getService(ValidationMessagesSource.class);
+    }
+
+
+    @Test
+    public void found_translator_by_name()
+    {
+        Translator translator = mockTranslator();
+
+        train_getType(translator, String.class);
+
+        Map<String, Translator> configuration = Collections.singletonMap("mock", translator);
+
+        replay();
+
+        TranslatorSource source = new TranslatorSourceImpl(configuration);
+
+        assertSame(source.get("mock"), translator);
+
+        verify();
+    }
+
+    protected final void train_getType(Translator translator, Class type)
+    {
+        expect(translator.getType()).andReturn(type).atLeastOnce();
+    }
+
+    @Test
+    public void unknown_translator_is_failure()
+    {
+        Translator fred = mockTranslator();
+        Translator barney = mockTranslator();
+
+        train_getType(fred, Long.class);
+        train_getType(barney, String.class);
+
+        Map<String, Translator> configuration = CollectionFactory.newMap();
+
+        configuration.put("fred", fred);
+        configuration.put("barney", barney);
+
+        replay();
+
+        TranslatorSource source = new TranslatorSourceImpl(configuration);
+
+        try
+        {
+            source.get("wilma");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Unknown translator type 'wilma'.  Configured translators are barney, fred.");
+        }
+
+    }
+
+
+    @DataProvider(name = "to_client_data")
+    public Object[][] to_client_data()
+    {
+        return new Object[][] {
+
+                { Byte.class, (byte) 65, "65" },
+
+                { Integer.class, 997, "997" },
+
+                { Long.class, 12345l, "12345" },
+
+                { Double.class, 123.45d, "123.45" },
+
+                { String.class, "abcd", "abcd" },
+
+                { Float.class, (float) -22.7, "-22.7" }
+
+        };
+    }
+
+    @Test(dataProvider = "to_client_data")
+    public void to_client(Class type, Object value, String expected)
+    {
+        Translator t = source.getByType(type);
+
+        String actual = t.toClient(value);
+
+        assertEquals(actual, expected);
+    }
+
+    @DataProvider(name = "parse_client_success_data")
+    public Object[][] parse_client_success_data()
+    {
+        return new Object[][] {
+
+                { Byte.class, " 23 ", (byte) 23 },
+
+                { Integer.class, " 123 ", 123 },
+
+                { Long.class, "  -1234567 ", -1234567l },
+
+                { Double.class, " 3.14 ", 3.14d },
+
+                { String.class, " abcdef ", " abcdef " },
+
+                { Float.class, " 28.95 ", (float) 28.95 },
+
+        };
+    }
+
+    @Test(dataProvider = "parse_client_success_data")
+    public void parse_client(Class type, String input, Object expected) throws Exception
+    {
+        Translator t = source.getByType(type);
+
+        Object actual = t.parseClient(input, messagesSource.getValidationMessages(Locale.ENGLISH));
+
+        assertEquals(actual, expected);
+    }
+
+    @DataProvider(name = "parse_client_failure_data")
+    public Object[][] parse_client_failure_data()
+    {
+        return new Object[][] {
+
+                { Byte.class, "fred", "The input value 'fred' is not parseable as an integer value." },
+
+                { Integer.class, "fred", "The input value 'fred' is not parseable as an integer value." },
+
+                { Long.class, "fred", "The input value 'fred' is not parseable as an integer value." },
+
+                { Double.class, "fred", "The input value 'fred' is not parseable as a numeric value." },
+
+                { Float.class, "fred", "The input value 'fred' is not parseable as a numeric value." }
+
+        };
+    }
+
+    @Test(dataProvider = "parse_client_failure_data")
+    public void parse_client_failure(Class type, String input, String expectedMessage)
+    {
+
+        Translator t = source.getByType(type);
+
+        try
+        {
+            t.parseClient(input, messagesSource.getValidationMessages(Locale.ENGLISH));
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), expectedMessage);
+        }
+    }
+
+    @Test
+    public void find_by_type()
+    {
+        Translator t = mockTranslator();
+        Map<String, Translator> configuration = CollectionFactory.newMap();
+
+        configuration.put("string", t);
+
+        train_getType(t, String.class);
+
+        replay();
+
+        TranslatorSource source = new TranslatorSourceImpl(configuration);
+
+        assertSame(source.getByType(String.class), t);
+        assertSame(source.findByType(String.class), t);
+        assertNull(source.findByType(Integer.class));
+
+        verify();
+    }
+
+    @Test
+    public void get_by_type_not_found()
+    {
+        Translator string = mockTranslator();
+        Translator bool = mockTranslator();
+
+        Map<String, Translator> configuration = CollectionFactory.newMap();
+
+        configuration.put("string", string);
+        configuration.put("boolean", bool);
+
+        train_getType(string, String.class);
+        train_getType(bool, Boolean.class);
+
+        replay();
+
+        TranslatorSource source = new TranslatorSourceImpl(configuration);
+
+        try
+        {
+            source.getByType(Integer.class);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "No translator is defined for type java.lang.Integer.  Registered types: java.lang.Boolean, java.lang.String.");
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/UpdateListenerHubImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/UpdateListenerHubImplTest.java
new file mode 100644
index 0000000..b6cd0fc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/UpdateListenerHubImplTest.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.events.UpdateListener;
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+public class UpdateListenerHubImplTest extends TestBase
+{
+    @Test
+    public void add_listener_and_invoke() throws Exception
+    {
+        UpdateListener listener = newMock(UpdateListener.class);
+
+        UpdateListenerHub hub = new UpdateListenerHubImpl();
+
+        listener.checkForUpdates();
+
+        replay();
+
+        hub.addUpdateListener(listener);
+
+        hub.fireUpdateEvent();
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImplTest.java
new file mode 100644
index 0000000..c6c142a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ValidationMessagesSourceImplTest.java
@@ -0,0 +1,100 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.internal.util.ClasspathResource;
+import org.apache.tapestry.services.ValidationMessagesSource;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+public class ValidationMessagesSourceImplTest extends Assert
+{
+    private ValidationMessagesSource source;
+
+    @BeforeClass
+    public void setup()
+    {
+        Resource rootResource = new ClasspathResource("/");
+        source = new ValidationMessagesSourceImpl(Arrays.asList(
+                "org/apache/tapestry/internal/ValidationMessages",
+                "org/apache/tapestry/internal/ValidationTestMessages"), rootResource);
+    }
+
+    @Test
+    public void builtin_message()
+    {
+        Messages messages = source.getValidationMessages(Locale.ENGLISH);
+
+        assertEquals(
+                messages.format("required", "My Field"),
+                "You must provide a value for My Field.");
+    }
+
+    @Test
+    public void contributed_message()
+    {
+        Messages messages = source.getValidationMessages(Locale.ENGLISH);
+
+        assertEquals(
+                messages.get("contributed"),
+                "This message was contributed inside ValidationTestMessages.");
+    }
+
+    @Test
+    public void localization_of_message()
+    {
+        Messages messages = source.getValidationMessages(Locale.FRENCH);
+
+        assertEquals(messages.get("contributed"), "Zees eez Cohntributahd.");
+    }
+
+    @Test
+    public void contains()
+    {
+        Messages messages = source.getValidationMessages(Locale.ENGLISH);
+
+        assertEquals(messages.contains("required"), true);
+        assertEquals(messages.contains("contributed"), true);
+        assertEquals(messages.contains("this-key-does-not-exist-anywhere"), false);
+    }
+
+    @Test
+    public void message_formatter()
+    {
+        Messages messages = source.getValidationMessages(Locale.ENGLISH);
+
+        MessageFormatter formatter = messages.getFormatter("required");
+
+        assertEquals(formatter.format("My Field"), "You must provide a value for My Field.");
+    }
+
+    @Test
+    public void messages_instances_are_cached()
+    {
+        Messages english = source.getValidationMessages(Locale.ENGLISH);
+        Messages french = source.getValidationMessages(Locale.FRENCH);
+
+        assertSame(source.getValidationMessages(Locale.ENGLISH), english);
+        assertSame(source.getValidationMessages(Locale.FRENCH), french);
+        assertNotSame(french, english);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
new file mode 100644
index 0000000..8618053
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/VisibilityBean.java
@@ -0,0 +1,51 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.services;

+

+import org.apache.tapestry.annotation.Retain;

+

+/**

+ * Used to test some issues related to visibility.

+ */

+public class VisibilityBean

+{

+    // Got to some real effort to provoke some name collisions!

+

+    @Retain

+    public static int _$myStatic;

+

+    @Retain

+    protected String _$myProtected;

+

+    @Retain

+    String _$myPackagePrivate;

+

+    @Retain

+    public String _$myPublic;

+

+    @Retain

+    private long $myLong;

+

+    public long getMyLong()

+    {

+        return $myLong;

+    }

+

+    public void setMyLong(long myLong)

+    {

+        $myLong = myLong;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/WriteOnlyBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/WriteOnlyBean.java
new file mode 100644
index 0000000..ab300e2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/services/WriteOnlyBean.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+public class WriteOnlyBean
+{
+    public String getReadOnly()
+    {
+        return null;
+    }
+
+    public String getReadWrite()
+    {
+        return null;
+    }
+
+    public void setReadWrite(String value)
+    {
+    }
+
+    public void setWriteOnly(String value)
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/BlockImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/BlockImplTest.java
new file mode 100644
index 0000000..8cfd774
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/BlockImplTest.java
@@ -0,0 +1,61 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.testng.annotations.Test;
+
+public class BlockImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void empty_block()
+    {
+        BlockImpl block = new BlockImpl(null);
+        RenderQueue queue = mockRenderQueue();
+        MarkupWriter writer = mockMarkupWriter();
+
+        replay();
+
+        block.render(writer, queue);
+
+        verify();
+    }
+
+    @Test
+    public void body_pushed_to_queue_backwards()
+    {
+        BlockImpl block = new BlockImpl(null);
+        RenderQueue queue = mockRenderQueue();
+        MarkupWriter writer = mockMarkupWriter();
+        PageElement element1 = mockPageElement();
+        PageElement element2 = mockPageElement();
+
+        getMocksControl().checkOrder(true);
+
+        queue.push(element2);
+        queue.push(element1);
+
+        replay();
+
+        block.addToBody(element1);
+        block.addToBody(element2);
+
+        block.render(writer, queue);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
new file mode 100644
index 0000000..7e9b94e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
@@ -0,0 +1,572 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.Block;
+import org.apache.tapestry.BlockNotFoundException;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.ParameterModel;
+import org.apache.tapestry.runtime.Component;
+import org.easymock.EasyMock;
+import org.testng.annotations.Test;
+
+public class ComponentPageElementImplTest extends InternalBaseTestCase
+{
+    public static final String PAGE_NAME = "Foo";
+
+    private Page newPage(String pageName)
+    {
+        Page page = mockPage();
+
+        train_getLogicalName(page, pageName);
+
+        return page;
+    }
+
+    @Test
+    public void block_not_found()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        ComponentResources resources = cpe.getComponentResources();
+
+        try
+        {
+            resources.getBlock("notFound");
+            unreachable();
+        }
+        catch (BlockNotFoundException ex)
+        {
+            assertTrue(ex.getMessage().contains("does not contain a block with identifier 'notFound'."));
+        }
+
+        verify();
+    }
+
+    @Test
+    public void block_found()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+        Block block = mockBlock();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        ComponentResources resources = cpe.getComponentResources();
+
+        cpe.addBlock("known", block);
+
+        assertSame(resources.getBlock("known"), block);
+        // Caseless check
+        assertSame(resources.getBlock("KNOWN"), block);
+
+        verify();
+    }
+
+    @Test
+    public void parameter_is_bound()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        Binding binding = mockBinding();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterModel(model, "barney", null);
+
+        train_getSupportsInformalParameters(model, true);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        ComponentResources resources = cpe.getComponentResources();
+        assertFalse(resources.isBound("fred"));
+
+        cpe.bindParameter("barney", binding);
+
+        assertFalse(resources.isBound("fred"));
+        assertTrue(resources.isBound("barney"));
+
+        verify();
+    }
+
+    @Test
+    public void duplicate_block_id()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+        Block block1 = mockBlock();
+        Block block2 = mockBlock();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addBlock("myblock", block1);
+
+        try
+        {
+            cpe.addBlock("MyBlock", block2);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Component Foo already contains a block with id \'MyBlock\'. Block ids must be unique (excluding case, which is ignored).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void verify_required_parameters_all_are_bound()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        Binding binding = mockBinding();
+        TypeCoercer coercer = mockTypeCoercer();
+        ParameterModel pmodel = mockParameterModel();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterNames(model, "barney");
+        train_getParameterModel(model, "barney", pmodel);
+
+        component.containingPageDidLoad();
+
+        replay();
+
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.bindParameter("barney", binding);
+
+        cpe.containingPageDidLoad();
+
+        verify();
+    }
+
+    @Test
+    public void verify_required_parameters_unbound_but_not_required()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        ParameterModel pmodel = mockParameterModel();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterNames(model, "barney");
+        train_getParameterModel(model, "barney", pmodel);
+        train_isRequired(pmodel, false);
+
+        component.containingPageDidLoad();
+
+        replay();
+
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.containingPageDidLoad();
+
+        verify();
+    }
+
+    @Test
+    public void verify_required_parameters_unbound_and_required()
+    {
+        Page page = mockPage();
+        ComponentPageElement container = mockComponentPageElement();
+        InternalComponentResources containerResources = mockInternalComponentResources();
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        ParameterModel pmodel = mockParameterModel();
+        Location l = mockLocation();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getComponentResources(container, containerResources);
+
+        train_getNestedId(container, null);
+        train_getLogicalName(page, "MyPage");
+
+        train_getParameterNames(model, "wilma", "barney", "fred");
+        train_getParameterModel(model, "wilma", pmodel);
+        train_isRequired(pmodel, true);
+
+        train_getParameterModel(model, "barney", pmodel);
+        train_isRequired(pmodel, false);
+
+        train_getParameterModel(model, "fred", pmodel);
+        train_isRequired(pmodel, true);
+
+        // Now called *before* the check for unbound parametesr
+
+        component.containingPageDidLoad();
+
+        train_getComponentClassName(model, "foo.components.MyComponent");
+
+        replay();
+
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, container, "myid", null, ins, l, null);
+
+        try
+        {
+            cpe.containingPageDidLoad();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Parameter(s) 'fred, wilma' are required for foo.components.MyComponent, but have not been bound.");
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void is_invariant()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        Binding binding = mockBinding();
+        TypeCoercer coercer = mockTypeCoercer();
+        ParameterModel pmodel = mockParameterModel();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterModel(model, "barney", pmodel);
+
+        train_isInvariant(binding, true);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        assertFalse(cpe.getComponentResources().isInvariant("fred"));
+
+        cpe.bindParameter("barney", binding);
+
+        assertFalse(cpe.getComponentResources().isInvariant("fred"));
+        assertTrue(cpe.getComponentResources().isInvariant("barney"));
+
+        verify();
+    }
+
+    @Test
+    public void read_binding()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        Binding binding = mockBinding();
+        PageResources resources = mockPageResources();
+
+        train_getSupportsInformalParameters(model, true);
+
+        Long boundValue = new Long(23);
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterModel(model, "barney", null);
+
+        train_get(binding, boundValue);
+
+        train_coerce(resources, boundValue, Long.class, boundValue);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, resources);
+
+        cpe.bindParameter("barney", binding);
+
+        assertSame(cpe.getComponentResources().readParameter("barney", Long.class), boundValue);
+
+        verify();
+    }
+
+
+    @Test
+    public void write_binding()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        PageResources resources = mockPageResources();
+        Binding binding = mockBinding();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getParameterModel(model, "barney", null);
+
+        train_getSupportsInformalParameters(model, true);
+
+        expect(binding.getBindingType()).andReturn(Integer.class);
+
+        train_coerce(resources, 23, Integer.class, 23);
+
+        binding.set(23);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, resources);
+
+        cpe.bindParameter("barney", binding);
+
+        cpe.getComponentResources().writeParameter("barney", 23);
+
+        verify();
+    }
+
+    @Test
+    public void get_embedded_does_not_exist()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+        Instantiator ins2 = newInstantiator(component, model);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        cpe.addEmbeddedElement(new ComponentPageElementImpl(page, cpe, "nested", null, ins2, null, null));
+
+        try
+        {
+            cpe.getEmbeddedElement("unknown");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Component " + PAGE_NAME + " does not contain an embedded component with id 'unknown'. Available components: nested.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_existing_embedded_component()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement childElement = mockComponentPageElement();
+        Component childComponent = mockComponent();
+        TypeCoercer coercer = mockTypeCoercer();
+
+        Instantiator ins = newInstantiator(component, model);
+
+        train_getId(childElement, "child");
+        train_getComponent(childElement, childComponent);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addEmbeddedElement(childElement);
+
+        assertSame(cpe.getComponentResources().getEmbeddedComponent("child"), childComponent);
+
+        // Now check that the search is caseless.
+
+        assertSame(cpe.getComponentResources().getEmbeddedComponent("CHILD"), childComponent);
+
+        verify();
+    }
+
+    @Test
+    public void component_ids_must_be_unique_within_container()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component pageComponent = mockComponent();
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement child1 = mockComponentPageElement();
+        ComponentPageElement child2 = mockComponentPageElement();
+        TypeCoercer coercer = mockTypeCoercer();
+        Location l = mockLocation();
+
+        Instantiator ins = newInstantiator(pageComponent, model);
+
+        train_getId(child1, "Child");
+        train_getId(child2, "CHILD");
+
+        train_getLocation(child2, l);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addEmbeddedElement(child1);
+
+        try
+        {
+            cpe.addEmbeddedElement(child2);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertTrue(ex.getMessage().contains("already contains a child component with id 'CHILD'."));
+            assertSame(ex.getLocation(), l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_mixin_by_class_name()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+        final String mixinClassName = "foo.Bar";
+        Component mixin = mockComponent();
+        ComponentModel mixinModel = mockComponentModel();
+
+        Instantiator ins = newInstantiator(component, model);
+        Instantiator mixinIns = newInstantiator(mixin, mixinModel);
+
+        train_getComponentClassName(mixinModel, mixinClassName);
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addMixin(mixinIns);
+
+        assertSame(cpe.getMixinByClassName(mixinClassName), mixin);
+
+        verify();
+    }
+
+    @Test
+    public void get_mixin_by_unknown_class_name()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        TypeCoercer coercer = mockTypeCoercer();
+        Component mixin = mockComponent();
+        ComponentModel mixinModel = mockComponentModel();
+
+        Instantiator ins = newInstantiator(component, model);
+        Instantiator mixinIns = newInstantiator(mixin, mixinModel);
+
+        train_getComponentClassName(mixinModel, "foo.Bar");
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addMixin(mixinIns);
+
+        try
+        {
+            cpe.getMixinByClassName("foo.Baz");
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertTrue(ex.getMessage().endsWith(" does not contain a mixin of type foo.Baz."));
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void set_explicit_parameter_of_unknown_mixin()
+    {
+        Page page = newPage(PAGE_NAME);
+        Component component = mockComponent();
+        ComponentModel model = mockComponentModel();
+        ComponentModel mixinModel = mockComponentModel();
+        Component mixin = mockComponent();
+        TypeCoercer coercer = mockTypeCoercer();
+        Binding binding = mockBinding();
+
+        Instantiator ins = newInstantiator(component, model);
+        Instantiator mixinInstantiator = newInstantiator(mixin, mixinModel);
+
+        train_getComponentClassName(mixinModel, "foo.Fred");
+
+        replay();
+
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+
+        cpe.addMixin(mixinInstantiator);
+
+        try
+        {
+            cpe.bindParameter("Wilma.barney", binding);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            assertTrue(ex.getMessage().contains(
+                    "does not contain a mixin named 'Wilma' (setting parameter 'Wilma.barney')"));
+        }
+
+        verify();
+    }
+
+    private Instantiator newInstantiator(Component component, ComponentModel model)
+    {
+        Instantiator ins = newMock(Instantiator.class);
+
+        expect(ins.getModel()).andReturn(model).anyTimes();
+
+        expect(ins.newInstance(EasyMock.isA(InternalComponentResources.class)))
+                .andReturn(component);
+
+        return ins;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java
new file mode 100644
index 0000000..705d2e1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/ExpansionPageElementImplTest.java
@@ -0,0 +1,103 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;

+

+import org.apache.tapestry.Binding;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.testng.annotations.Test;
+

+public class ExpansionPageElementImplTest extends InternalBaseTestCase

+{

+    @Test

+    public void invariant_binding_is_cached()

+    {

+        Binding binding = mockBinding();

+        TypeCoercer coercer = mockTypeCoercer();

+        MarkupWriter writer = mockMarkupWriter();

+        RenderQueue queue = mockRenderQueue();

+

+        Object value = new Object();

+

+        train_isInvariant(binding, true);

+

+        replay();

+

+        PageElement element = new ExpansionPageElement(binding, coercer);

+

+        verify();

+

+        train_get(binding, value);

+        train_coerce(coercer, value, String.class, "STRING-VALUE");

+        writer.write("STRING-VALUE");

+

+        replay();

+

+        element.render(writer, queue);

+

+        verify();

+

+        // It is now cached ...

+

+        writer.write("STRING-VALUE");

+

+        replay();

+

+        element.render(writer, queue);

+

+        verify();

+    }

+

+    @Test

+    public void variant_binding_is_not_cached()

+    {

+        Binding binding = mockBinding();

+        TypeCoercer coercer = mockTypeCoercer();

+        MarkupWriter writer = mockMarkupWriter();

+        RenderQueue queue = mockRenderQueue();

+

+        Object value = new Object();

+

+        train_isInvariant(binding, false);

+

+        replay();

+

+        PageElement element = new ExpansionPageElement(binding, coercer);

+

+        verify();

+

+        train_get(binding, value);

+        train_coerce(coercer, value, String.class, "STRING-VALUE");

+        writer.write("STRING-VALUE");

+

+        replay();

+

+        element.render(writer, queue);

+

+        verify();

+

+        train_get(binding, value);

+        train_coerce(coercer, value, String.class, "STRING-VALUE2");

+        writer.write("STRING-VALUE2");

+

+        replay();

+

+        element.render(writer, queue);

+

+        verify();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImplTest.java
new file mode 100644
index 0000000..4d6940f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImplTest.java
@@ -0,0 +1,273 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.ParameterModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+import org.testng.annotations.Test;
+
+public class InternalComponentResourcesImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void render_informal_parameters_no_bindings()
+    {
+        ComponentPageElement element = mockComponentPageElement();
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        MarkupWriter writer = mockMarkupWriter();
+        TypeCoercer coercer = mockTypeCoercer();
+        ComponentModel model = mockComponentModel();
+
+        train_getModel(ins, model);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null,
+                                                                                  null, ins);
+
+        resources.renderInformalParameters(writer);
+
+        verify();
+    }
+
+    @Test
+    public void render_informal_parameters_skips_formal_parameters()
+    {
+        ComponentPageElement element = mockComponentPageElement();
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        MarkupWriter writer = mockMarkupWriter();
+        ComponentModel model = mockComponentModel();
+        ParameterModel pmodel = mockParameterModel();
+        Binding binding = mockBinding();
+
+        train_getModel(ins, model);
+
+        train_getParameterModel(model, "fred", pmodel);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null,
+                                                                                  null, ins);
+
+        resources.bindParameter("fred", binding);
+
+        resources.renderInformalParameters(writer);
+
+        verify();
+    }
+
+    @Test
+    public void render_an_informal_parameter()
+    {
+        ComponentPageElement element = mockComponentPageElement();
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        MarkupWriter writer = mockMarkupWriter();
+        ComponentModel model = mockComponentModel();
+        Binding binding = mockBinding();
+        Object rawValue = new Object();
+        String convertedValue = "*converted*";
+        PageResources pageResources = mockPageResources();
+
+        train_getModel(ins, model);
+
+        train_getParameterModel(model, "fred", null);
+
+        train_get(binding, rawValue);
+
+        train_coerce(pageResources, rawValue, String.class, convertedValue);
+
+        writer.attributes("fred", convertedValue);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, pageResources,
+                                                                                  null, null, ins);
+
+        resources.bindParameter("fred", binding);
+
+        resources.renderInformalParameters(writer);
+
+        verify();
+    }
+
+    @Test
+    public void get_render_variable_exists()
+    {
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement element = mockComponentPageElement();
+
+        Object value = new Object();
+
+        train_getModel(ins, model);
+
+        train_isRendering(element, true);
+
+        replay();
+
+        ComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null, null, ins);
+
+        resources.storeRenderVariable("myRenderVar", value);
+
+        assertSame(resources.getRenderVariable("myrendervar"), value);
+
+        verify();
+    }
+
+    protected final void train_isRendering(ComponentPageElement element, boolean isRendering)
+    {
+        expect(element.isRendering()).andReturn(isRendering);
+    }
+
+    @Test
+    public void get_render_variable_missing()
+    {
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement element = mockComponentPageElement();
+
+        train_getModel(ins, model);
+
+        train_isRendering(element, true);
+        train_isRendering(element, true);
+
+        replay();
+
+        ComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar", null,
+                                                                          ins);
+
+        resources.storeRenderVariable("fred", "FRED");
+        resources.storeRenderVariable("barney", "BARNEY");
+
+        try
+        {
+            resources.getRenderVariable("wilma");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Component Foo.bar does not contain a stored render variable with name 'wilma'.  Stored render variables: barney, fred.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void post_render_cleanup_removes_all_variables()
+    {
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement element = mockComponentPageElement();
+
+        train_getModel(ins, model);
+
+        train_isRendering(element, true);
+        train_isRendering(element, true);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar",
+                                                                                  null, ins);
+
+        resources.storeRenderVariable("fred", "FRED");
+        resources.storeRenderVariable("barney", "BARNEY");
+
+        resources.postRenderCleanup();
+
+        try
+        {
+            resources.getRenderVariable("fred");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Component Foo.bar does not contain a stored render variable with name 'fred'.  Stored render variables: (none).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void store_render_variable_when_not_rendering()
+    {
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement element = mockComponentPageElement();
+
+        train_getModel(ins, model);
+
+        train_isRendering(element, false);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar",
+                                                                                  null, ins);
+
+
+        try
+        {
+            resources.storeRenderVariable("fred", "FRED");
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Component Foo.bar is not rendering, so render variable 'fred' may not be updated.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void add_page_lifecycle_listener()
+    {
+        Component component = mockComponent();
+        Instantiator ins = mockInstantiator(component);
+        ComponentModel model = mockComponentModel();
+        ComponentPageElement element = mockComponentPageElement();
+        Page page = mockPage();
+        PageLifecycleListener listener = newMock(PageLifecycleListener.class);
+
+        train_getModel(ins, model);
+
+        page.addLifecycleListener(listener);
+
+        replay();
+
+        InternalComponentResources resources = new InternalComponentResourcesImpl(page, element, null, null, null,
+                                                                                  null, ins);
+
+        resources.addPageLifecycleListener(listener);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java
new file mode 100644
index 0000000..608fbc0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/structure/PageImplTest.java
@@ -0,0 +1,199 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.structure;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.PageLifecycleListener;
+import static org.easymock.EasyMock.contains;
+import static org.easymock.EasyMock.same;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class PageImplTest extends InternalBaseTestCase
+{
+    private final Locale locale = Locale.ENGLISH;
+
+    private static final String LOGICAL_PAGE_NAME = "MyPage";
+
+    @Test
+    public void accessor_methods()
+    {
+        ComponentPageElement root = mockComponentPageElement();
+
+        replay();
+
+        Page page = new PageImpl(LOGICAL_PAGE_NAME, locale, null, null);
+
+        assertNull(page.getRootElement());
+
+        page.setRootElement(root);
+
+        assertSame(page.getLocale(), locale);
+        assertSame(page.getRootElement(), root);
+        assertSame(page.getLogicalName(), LOGICAL_PAGE_NAME);
+
+        verify();
+    }
+
+    @Test
+    public void detach_notification()
+    {
+        PageLifecycleListener listener1 = newPageLifecycle();
+        PageLifecycleListener listener2 = newPageLifecycle();
+
+        listener1.containingPageDidDetach();
+        listener2.containingPageDidDetach();
+
+        replay();
+
+        Page page = new PageImpl(null, locale, null, null);
+
+        page.addLifecycleListener(listener1);
+        page.addLifecycleListener(listener2);
+
+        assertFalse(page.detached());
+
+        verify();
+    }
+
+    /**
+     * Also checks that listeners are invoked, even if the page is dirty.
+     */
+    @Test
+    public void detach_dirty_if_dirty_count_non_zero()
+    {
+        PageLifecycleListener listener = newPageLifecycle();
+
+        listener.containingPageDidDetach();
+
+        replay();
+
+        Page page = new PageImpl(null, locale, null, null);
+
+        page.addLifecycleListener(listener);
+
+        page.incrementDirtyCount();
+
+        assertTrue(page.detached());
+
+        verify();
+    }
+
+    /**
+     * Also checks that all listeners are invoked, even if one of them throws an exception.
+     */
+    @Test
+    public void detach_dirty_if_listener_throws_exception()
+    {
+        ComponentPageElement element = mockComponentPageElement();
+        Logger logger = mockLogger();
+        PageLifecycleListener listener1 = newPageLifecycle();
+        PageLifecycleListener listener2 = newPageLifecycle();
+        RuntimeException t = new RuntimeException("Listener detach exception.");
+
+        train_getLogger(element, logger);
+
+        listener1.containingPageDidDetach();
+        setThrowable(t);
+
+        logger.error(contains("failed during page detach"), same(t));
+
+        listener2.containingPageDidDetach();
+
+        replay();
+
+        Page page = new PageImpl(null, locale, null, null);
+        page.setRootElement(element);
+
+        page.addLifecycleListener(listener1);
+        page.addLifecycleListener(listener2);
+
+        assertTrue(page.detached());
+
+        verify();
+
+    }
+
+    protected final void train_getLogger(ComponentPageElement element, Logger logger)
+    {
+        expect(element.getLogger()).andReturn(logger);
+    }
+
+    @Test
+    public void attach_notification()
+    {
+
+        PageLifecycleListener listener1 = newPageLifecycle();
+        PageLifecycleListener listener2 = newPageLifecycle();
+
+        listener1.containingPageDidAttach();
+        listener2.containingPageDidAttach();
+
+        replay();
+
+        Page page = new PageImpl(null, locale, null, null);
+
+        page.addLifecycleListener(listener1);
+        page.addLifecycleListener(listener2);
+
+        page.attached();
+
+        verify();
+    }
+
+    private PageLifecycleListener newPageLifecycle()
+    {
+        return newMock(PageLifecycleListener.class);
+    }
+
+    @Test
+    public void load_notification()
+    {
+        PageLifecycleListener listener1 = newPageLifecycle();
+        PageLifecycleListener listener2 = newPageLifecycle();
+
+        listener1.containingPageDidLoad();
+        listener2.containingPageDidLoad();
+
+        replay();
+
+        Page page = new PageImpl(LOGICAL_PAGE_NAME, locale, null, null);
+
+        page.addLifecycleListener(listener1);
+        page.addLifecycleListener(listener2);
+
+        page.loaded();
+
+        verify();
+    }
+
+    @Test
+    public void get_by_nested_id_for_blank_value_returns_root_component()
+    {
+        ComponentPageElement root = mockComponentPageElement();
+
+        replay();
+
+        Page page = new PageImpl(LOGICAL_PAGE_NAME, locale, null, null);
+
+        page.setRootElement(root);
+
+        assertSame(page.getComponentElementByNestedId(""), root);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/CodeEqTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/CodeEqTest.java
new file mode 100644
index 0000000..8f472c9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/CodeEqTest.java
@@ -0,0 +1,69 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class CodeEqTest extends Assert
+{
+    @Test(enabled = false, dataProvider = "stripValues")
+    public void strip(String input, String expected)
+    {
+        assertEquals(CodeEq.strip(input), expected);
+    }
+
+    @DataProvider(name = "stripValues")
+    public Object[][] stripValues()
+    {
+        return new Object[][]
+                {
+                        {"foo", "foo"},
+                        {" foo\n", "foo"},
+                        {"  foo \nbar\n\n  \tbaz", "foo bar baz"},
+                        {"{\n  bar();\n  baz();\n  if (gnip())\n  {\n    gnop();\n  }\n}\n",
+                         "{bar(); baz(); if (gnip()){gnop();}}"}};
+    }
+
+    @Test(enabled = false)
+    public void to_string()
+    {
+        CodeEq eq = new CodeEq("{ foo(); bar(); baz(); }");
+
+        StringBuffer buffer = new StringBuffer();
+
+        eq.appendTo(buffer);
+
+        assertEquals(buffer.toString(), "codeEq({foo(); bar(); baz();})");
+    }
+
+    @Test(enabled = false, dataProvider = "matchValues")
+    public void matches(String pattern, String parameter, boolean matches)
+    {
+        CodeEq ceq = new CodeEq(pattern);
+
+        assertEquals(ceq.matches(parameter), matches);
+    }
+
+    @DataProvider(name = "matchValues")
+    public Object[][] matchValues()
+    {
+        return new Object[][]
+                {
+                        {"{ foo(); }", "{\n  foo();\n}", true},
+                        {" foo();", "foo ();", false},};
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
new file mode 100644
index 0000000..b54be93
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
@@ -0,0 +1,656 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.internal.*;
+import org.apache.tapestry.internal.events.InvalidationListener;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.TemplateToken;
+import org.apache.tapestry.internal.services.*;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.internal.structure.PageResources;
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.internal.InternalRegistry;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.EmbeddedComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.TapestryModule;
+import org.apache.tapestry.services.TranslatorSource;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * Contains additional factory and training methods related to internal interfaces.
+ */
+public class InternalBaseTestCase extends TapestryTestCase implements Registry
+{
+    private static Registry registry;
+
+    private Messages validationMessages;
+
+    @BeforeSuite
+    public final void setup_registry()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        builder.add(TapestryModule.class);
+
+        // A synthetic module to ensure that the tapestry.alias-mode is set correctly.
+
+        SymbolProvider provider = new SingleKeySymbolProvider(InternalConstants.TAPESTRY_ALIAS_MODE_SYMBOL, "servlet");
+        ContributionDef contribution = new SyntheticSymbolSourceContributionDef("AliasMode", provider,
+                                                                                "before:ApplicationDefaults");
+
+        ModuleDef module = new SyntheticModuleDef(contribution);
+
+        builder.add(module);
+
+        registry = builder.build();
+
+        // registry.getService(Alias.class).setMode("servlet");
+
+        registry.performRegistryStartup();
+    }
+
+    @AfterSuite
+    public final void shutdown_registry()
+    {
+        registry.shutdown();
+
+        registry = null;
+    }
+
+    @AfterMethod
+    public final void cleanupThread()
+    {
+        registry.cleanupThread();
+    }
+
+    public void performRegistryStartup()
+    {
+        registry.performRegistryStartup();
+    }
+
+    public final <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
+    {
+        return registry.getObject(objectType, annotationProvider);
+    }
+
+    public final <T> T getService(Class<T> serviceInterface)
+    {
+        return registry.getService(serviceInterface);
+    }
+
+    public final <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        return registry.getService(serviceId, serviceInterface);
+    }
+
+    public final <T> T autobuild(Class<T> clazz)
+    {
+        return registry.autobuild(clazz);
+    }
+
+    public <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass)
+    {
+        return registry.proxy(interfaceClass, implementationClass);
+    }
+
+    public final void shutdown()
+    {
+        throw new UnsupportedOperationException("No registry shutdown until @AfterSuite.");
+    }
+
+    protected final InternalComponentResources mockInternalComponentResources()
+    {
+        return newMock(InternalComponentResources.class);
+    }
+
+    protected final ComponentTemplate mockComponentTemplate()
+    {
+        return newMock(ComponentTemplate.class);
+    }
+
+    protected final <T> void train_getService(InternalRegistry registry, String serviceId, Class<T> serviceInterface,
+                                              T service)
+    {
+        expect(registry.getService(serviceId, serviceInterface)).andReturn(service);
+
+    }
+
+    protected final ComponentInstantiatorSource mockComponentInstantiatorSource()
+    {
+        return newMock(ComponentInstantiatorSource.class);
+    }
+
+    protected final Page mockPage()
+    {
+        return newMock(Page.class);
+    }
+
+    protected final PageLoader mockPageLoader()
+    {
+        return newMock(PageLoader.class);
+    }
+
+    protected final void train_loadPage(PageLoader loader, String pageName, Locale locale, Page page)
+    {
+        expect(loader.loadPage(pageName, locale)).andReturn(page);
+    }
+
+    protected final PagePool mockPagePool()
+    {
+        return newMock(PagePool.class);
+    }
+
+    protected RenderQueue mockRenderQueue()
+    {
+        return newMock(RenderQueue.class);
+    }
+
+    protected final void train_parseTemplate(TemplateParser parser, Resource resource, ComponentTemplate template)
+    {
+        expect(parser.parseTemplate(resource)).andReturn(template);
+    }
+
+    protected final TemplateParser mockTemplateParser()
+    {
+        return newMock(TemplateParser.class);
+    }
+
+    protected final ComponentPageElement mockComponentPageElement()
+    {
+        return newMock(ComponentPageElement.class);
+    }
+
+    protected final void train_getComponent(ComponentPageElement element, Component component)
+    {
+        expect(element.getComponent()).andReturn(component).atLeastOnce();
+    }
+
+    protected final void train_getId(ComponentResourcesCommon resources, String id)
+    {
+        expect(resources.getId()).andReturn(id).atLeastOnce();
+    }
+
+    protected final void train_getNestedId(ComponentResourcesCommon resources, String nestedId)
+    {
+        expect(resources.getNestedId()).andReturn(nestedId).atLeastOnce();
+    }
+
+    protected final void train_getContextPath(Request request, String contextPath)
+    {
+        expect(request.getContextPath()).andReturn(contextPath).atLeastOnce();
+    }
+
+    protected final void train_resolvePageClassNameToPageName(ComponentClassResolver resolver, String pageClassName,
+                                                              String pageName)
+    {
+        expect(resolver.resolvePageClassNameToPageName(pageClassName)).andReturn(pageName);
+    }
+
+    protected final void train_getContainingPage(ComponentPageElement element, Page page)
+    {
+        expect(element.getContainingPage()).andReturn(page).atLeastOnce();
+    }
+
+    protected final void train_getComponentResources(ComponentPageElement element, InternalComponentResources resources)
+    {
+        expect(element.getComponentResources()).andReturn(resources).atLeastOnce();
+    }
+
+    protected final void train_getComponentClassName(EmbeddedComponentModel model, String className)
+    {
+        expect(model.getComponentClassName()).andReturn(className).atLeastOnce();
+    }
+
+    protected final PageElement mockPageElement()
+    {
+        return newMock(PageElement.class);
+    }
+
+    protected final void train_getParameterNames(EmbeddedComponentModel model, String... names)
+    {
+        expect(model.getParameterNames()).andReturn(Arrays.asList(names));
+    }
+
+    protected final void train_newComponentElement(PageElementFactory elementFactory, ComponentPageElement container,
+                                                   String embeddedId, String embeddedType, String componentClassName,
+                                                   String elementName, Location location, ComponentPageElement embedded)
+    {
+        expect(elementFactory.newComponentElement(isA(Page.class), eq(container), eq(embeddedId), eq(embeddedType),
+                                                  eq(componentClassName), eq(elementName), eq(location))).andReturn(
+                embedded);
+    }
+
+    protected final void train_getComponentType(EmbeddedComponentModel emodel, String componentType)
+    {
+        expect(emodel.getComponentType()).andReturn(componentType).atLeastOnce();
+    }
+
+    protected final void train_getEmbeddedComponentModel(ComponentModel model, String embeddedId,
+                                                         EmbeddedComponentModel emodel)
+    {
+        expect(model.getEmbeddedComponentModel(embeddedId)).andReturn(emodel).atLeastOnce();
+    }
+
+    protected final EmbeddedComponentModel mockEmbeddedComponentModel()
+    {
+        return newMock(EmbeddedComponentModel.class);
+    }
+
+    protected final PageElementFactory mockPageElementFactory()
+    {
+        return newMock(PageElementFactory.class);
+    }
+
+    protected final ComponentTemplateSource mockComponentTemplateSource()
+    {
+        return newMock(ComponentTemplateSource.class);
+    }
+
+    protected final void train_getLogger(ComponentModel model, Logger logger)
+    {
+        expect(model.getLogger()).andReturn(logger).atLeastOnce();
+    }
+
+    protected final void train_getTokens(ComponentTemplate template, TemplateToken... tokens)
+    {
+        expect(template.getTokens()).andReturn(Arrays.asList(tokens));
+    }
+
+    protected final void train_getComponentIds(ComponentTemplate template, String... ids)
+    {
+        expect(template.getComponentIds()).andReturn(newSet(Arrays.asList(ids)));
+    }
+
+    protected final void train_getEmbeddedIds(ComponentModel model, String... ids)
+    {
+        expect(model.getEmbeddedComponentIds()).andReturn(Arrays.asList(ids));
+    }
+
+    protected void train_getTemplate(ComponentTemplateSource templateSource, ComponentModel model, Locale locale,
+                                     ComponentTemplate template)
+    {
+        expect(templateSource.getTemplate(model, locale)).andReturn(template);
+    }
+
+    protected final void train_getComponentModel(ComponentResources resources, ComponentModel model)
+    {
+        expect(resources.getComponentModel()).andReturn(model).atLeastOnce();
+    }
+
+    protected final void train_newRootComponentElement(PageElementFactory elementFactory, String className,
+                                                       ComponentPageElement rootElement, Locale locale)
+    {
+        expect(elementFactory.newRootComponentElement(isA(Page.class), eq(className), eq(locale))).andReturn(
+                rootElement);
+    }
+
+    protected final void train_getModel(Instantiator ins, ComponentModel model)
+    {
+        expect(ins.getModel()).andReturn(model).atLeastOnce();
+    }
+
+    protected final Instantiator mockInstantiator(Component component)
+    {
+        Instantiator ins = newMock(Instantiator.class);
+
+        expect(ins.newInstance(EasyMock.isA(InternalComponentResources.class)))
+                .andReturn(component);
+
+        return ins;
+    }
+
+    protected final RequestPageCache mockRequestPageCache()
+    {
+        return newMock(RequestPageCache.class);
+    }
+
+    protected final void train_getComponentElementByNestedId(Page page, String nestedId, ComponentPageElement element)
+    {
+        expect(page.getComponentElementByNestedId(nestedId)).andReturn(element).atLeastOnce();
+    }
+
+    protected final void train_getRootElement(Page page, ComponentPageElement element)
+    {
+        expect(page.getRootElement()).andReturn(element).atLeastOnce();
+    }
+
+    protected final void train_isMissing(ComponentTemplate template, boolean isMissing)
+    {
+        expect(template.isMissing()).andReturn(isMissing).atLeastOnce();
+    }
+
+    protected final void train_getMixinClassNames(EmbeddedComponentModel model, String... names)
+    {
+        expect(model.getMixinClassNames()).andReturn(Arrays.asList(names));
+    }
+
+    protected final void train_getRootComponent(Page page, Component component)
+    {
+        expect(page.getRootComponent()).andReturn(component).atLeastOnce();
+    }
+
+    protected final ResourceCache mockResourceCache()
+    {
+        return newMock(ResourceCache.class);
+    }
+
+    protected final void train_requiresDigest(ResourceCache cache, Resource resource, boolean requiresChecksum)
+    {
+        expect(cache.requiresDigest(resource)).andReturn(requiresChecksum);
+    }
+
+    protected final InvalidationListener mockInvalidationListener()
+    {
+        return newMock(InvalidationListener.class);
+    }
+
+    protected final void train_getTimeModified(ResourceCache cache, Resource resource, long timeModified)
+    {
+        expect(cache.getTimeModified(resource)).andReturn(timeModified).atLeastOnce();
+    }
+
+    protected final ResourceStreamer mockResourceStreamer()
+    {
+        return newMock(ResourceStreamer.class);
+    }
+
+    protected final void train_get(RequestPageCache cache, String pageName, Page page)
+    {
+        expect(cache.get(pageName)).andReturn(page).atLeastOnce();
+    }
+
+    protected final void train_findPageTemplateResource(PageTemplateLocator locator, ComponentModel model,
+                                                        Locale locale, Resource resource)
+    {
+        expect(locator.findPageTemplateResource(model, locale)).andReturn(resource).atLeastOnce();
+    }
+
+    protected final PageTemplateLocator mockPageTemplateLocator()
+    {
+        return newMock(PageTemplateLocator.class);
+    }
+
+    /**
+     * Returns the default validator messages.
+     */
+    protected final Messages validationMessages()
+    {
+        if (validationMessages == null)
+        {
+            ResourceBundle bundle = ResourceBundle
+                    .getBundle("org.apache.tapestry.internal.ValidationMessages");
+
+            validationMessages = new MessagesImpl(Locale.ENGLISH, bundle);
+        }
+
+        return validationMessages;
+    }
+
+    protected final LinkFactoryListener mockLinkFactoryListener()
+    {
+        return newMock(LinkFactoryListener.class);
+    }
+
+    protected final ComponentInvocationMap mockComponentInvocationMap()
+    {
+        return newMock(ComponentInvocationMap.class);
+    }
+
+    protected final LinkFactory mockLinkFactory()
+    {
+        return newMock(LinkFactory.class);
+    }
+
+    protected final void train_createPageLink(LinkFactory factory, Page page, Link link)
+    {
+        expect(factory.createPageLink(page, false)).andReturn(link);
+    }
+
+    protected final void train_isLoaded(InternalComponentResources resources, boolean isLoaded)
+    {
+        expect(resources.isLoaded()).andReturn(isLoaded);
+    }
+
+    protected final void stub_isPageName(ComponentClassResolver resolver, boolean result)
+    {
+        expect(resolver.isPageName(isA(String.class))).andStubReturn(result);
+    }
+
+    protected final void train_isPageName(ComponentClassResolver resolver, String pageName, boolean result)
+    {
+        expect(resolver.isPageName(pageName)).andReturn(result);
+    }
+
+    protected final PageResponseRenderer mockPageResponseRenderer()
+    {
+        return newMock(PageResponseRenderer.class);
+    }
+
+    /**
+     * Reads the content of a file into a string. Each line is trimmed of line separators and leading/trailing
+     * whitespace.
+     *
+     * @param trim trim each line of whitespace
+     */
+    protected final String readFile(String file) throws Exception
+    {
+        InputStream is = getClass().getResourceAsStream(file);
+        is = new BufferedInputStream(is);
+        Reader reader = new BufferedReader(new InputStreamReader(is));
+        LineNumberReader in = new LineNumberReader(reader);
+
+        StringBuilder buffer = new StringBuilder();
+
+        while (true)
+        {
+            String line = in.readLine();
+
+            if (line == null) break;
+
+            buffer.append(line);
+
+            buffer.append("\n");
+        }
+
+        in.close();
+
+        return buffer.toString().trim();
+    }
+
+    protected final DocumentLinker mockDocumentLinker()
+    {
+        return newMock(DocumentLinker.class);
+    }
+
+    protected final void train_canonicalizePageName(ComponentClassResolver resolver, String pageName,
+                                                    String canonicalized)
+    {
+        expect(resolver.canonicalizePageName(pageName)).andReturn(canonicalized);
+    }
+
+    protected final void train_getLogicalName(Page page, String logicalName)
+    {
+        expect(page.getLogicalName()).andReturn(logicalName).atLeastOnce();
+    }
+
+    protected final void train_resolvePageNameToClassName(ComponentClassResolver resolver, String pageName,
+                                                          String pageClassName)
+    {
+        expect(resolver.resolvePageNameToClassName(pageName)).andReturn(pageClassName)
+                .atLeastOnce();
+    }
+
+    protected final void train_getLocale(Page page, Locale locale)
+    {
+        expect(page.getLocale()).andReturn(locale).atLeastOnce();
+    }
+
+    protected final void train_detached(Page page, boolean dirty)
+    {
+        expect(page.detached()).andReturn(dirty);
+    }
+
+    protected void train_forName(ComponentClassCache cache, String className, Class cachedClass)
+    {
+        expect(cache.forName(className)).andReturn(cachedClass).atLeastOnce();
+    }
+
+    protected void train_forName(ComponentClassCache cache, Class cachedClass)
+    {
+        train_forName(cache, cachedClass.getName(), cachedClass);
+    }
+
+    protected final ComponentClassCache mockComponentClassCache()
+    {
+        return newMock(ComponentClassCache.class);
+    }
+
+    protected void train_findContentType(PageContentTypeAnalyzer analyzer, Page page, ContentType contentType)
+    {
+        expect(analyzer.findContentType(page)).andReturn(contentType).atLeastOnce();
+    }
+
+    protected final PageContentTypeAnalyzer mockPageContentTypeAnalyzer()
+    {
+        return newMock(PageContentTypeAnalyzer.class);
+    }
+
+
+    protected final RequestPathOptimizer mockRequestPathOptimizer()
+    {
+        return newMock(RequestPathOptimizer.class);
+    }
+
+    protected final void train_optimizePath(RequestPathOptimizer optimizer, String path, String optimizedPath)
+    {
+        expect(optimizer.optimizePath(path)).andReturn(optimizedPath);
+    }
+
+    protected final ActionRenderResponseGenerator mockActionRenderResponseGenerator()
+    {
+        return newMock(ActionRenderResponseGenerator.class);
+    }
+
+    protected final PageRenderQueue mockPageRenderQueue()
+    {
+        return newMock(PageRenderQueue.class);
+    }
+
+    protected final void train_getRenderingPage(PageRenderQueue queue, Page page)
+    {
+        expect(queue.getRenderingPage()).andReturn(page);
+    }
+
+    protected final PageResources mockPageResources()
+    {
+        return newMock(PageResources.class);
+    }
+
+    protected final void train_toClass(PageResources resources, String className, Class toClass)
+    {
+        expect(resources.toClass(className)).andReturn(toClass).atLeastOnce();
+    }
+
+    protected final <S, T> void train_coerce(PageResources pageResources, S input, Class<T> expectedType,
+                                             T coercedValue)
+    {
+        expect(pageResources.coerce(input, expectedType)).andReturn(coercedValue);
+    }
+
+    protected final EventContext mockEventContext()
+    {
+        return newMock(EventContext.class);
+    }
+
+    protected final <T> void train_get(EventContext context, Class<T> type, int index, T value)
+    {
+        expect(context.get(type, index)).andReturn(value);
+    }
+
+    protected final void train_getCount(EventContext context, int count)
+    {
+        expect(context.getCount()).andReturn(count).atLeastOnce();
+    }
+
+    protected final TranslatorSource mockTranslatorSource()
+    {
+        return newMock(TranslatorSource.class);
+    }
+
+    protected final void train_getPropertyAdapter(ClassPropertyAdapter classPropertyAdapter,
+                                                  String propertyName, PropertyAdapter propertyAdapter)
+    {
+        expect(classPropertyAdapter.getPropertyAdapter(propertyName)).andReturn(propertyAdapter)
+                .atLeastOnce();
+    }
+
+    protected final void train_getAdapter(PropertyAccess access, Object object,
+                                          ClassPropertyAdapter classPropertyAdapter)
+    {
+        expect(access.getAdapter(object)).andReturn(classPropertyAdapter);
+    }
+
+    protected final RequestSecurityManager mockRequestSecurityManager()
+    {
+        return newMock(RequestSecurityManager.class);
+    }
+
+    protected final void train_getBaseURL(RequestSecurityManager securityManager, Page page, String baseURL)
+    {
+        expect(securityManager.getBaseURL(page)).andReturn(baseURL).atLeastOnce();
+    }
+
+    protected final ClientBehaviorSupport mockClientBehaviorSupport()
+    {
+        return newMock(ClientBehaviorSupport.class);
+    }
+
+    protected final MutableComponentModel mockMutableComponentModel(Logger logger)
+    {
+        MutableComponentModel model = mockMutableComponentModel();
+        train_getLogger(model, logger);
+
+        return model;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterContextTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterContextTest.java
new file mode 100644
index 0000000..9c03451
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterContextTest.java
@@ -0,0 +1,50 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.test;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+public class PageTesterContextTest extends Assert
+{
+    @Test
+    public void to_URL() throws IOException
+    {
+        PageTesterContext context = new PageTesterContext("src/test/app2");
+        URL resource = context.getResource("/OpaqueResource.txt");
+        InputStream stream = resource.openStream();
+        stream.close();
+    }
+
+    @Test
+    public void to_URL_no_file() throws IOException
+    {
+        PageTesterContext context = new PageTesterContext("src/test/app2");
+        URL resource = context.getResource("/NonExisting.txt");
+        assertNull(resource);
+    }
+
+    @Test
+    public void to_URL_is_dir() throws IOException
+    {
+        PageTesterContext context = new PageTesterContext("src/test");
+        URL resource = context.getResource("/app2");
+        assertNull(resource);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java
new file mode 100644
index 0000000..b4241ed
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/test/PageTesterSessionTest.java
@@ -0,0 +1,68 @@
+// Copyright 2006, 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.test;

+

+import org.testng.Assert;

+import org.testng.annotations.BeforeMethod;

+import org.testng.annotations.Test;

+

+import java.util.Arrays;

+import java.util.Collections;

+

+public class PageTesterSessionTest extends Assert

+{

+    private PageTesterSession session;

+

+    @BeforeMethod

+    public void before()

+    {

+        session = new PageTesterSession();

+    }

+

+    @Test

+    public void empty()

+    {

+        assertEquals(session.getAttributeNames(), Collections.EMPTY_LIST);

+        assertNull(session.getAttribute("x"));

+    }

+

+    @Test

+    public void set_attributes()

+    {

+        session.setAttribute("b", 10);

+        session.setAttribute("a", 20);

+        assertEquals(session.getAttribute("a"), 20);

+        assertEquals(session.getAttribute("b"), 10);

+    }

+

+    @Test

+    public void remove_if_value_is_null()

+    {

+        session.setAttribute("b", 10);

+        session.setAttribute("a", 20);

+        assertEquals(session.getAttributeNames().size(), 2);

+        session.setAttribute("b", null);

+        assertEquals(session.getAttributeNames().size(), 1);

+    }

+

+    @Test

+    public void names_sorted()

+    {

+        session.setAttribute("b", 10);

+        session.setAttribute("a", 20);

+        session.setAttribute("c", 50);

+        assertEquals(session.getAttributeNames(), Arrays.asList("a", "b", "c"));

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ApplicationStateWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ApplicationStateWorkerTest.java
new file mode 100644
index 0000000..cce1d45
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ApplicationStateWorkerTest.java
@@ -0,0 +1,236 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import javassist.CtClass;
+import javassist.Loader;
+import javassist.LoaderClassPath;
+import javassist.NotFoundException;
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.services.*;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.pages.MaybeStateHolder;
+import org.apache.tapestry.internal.transform.pages.StateHolder;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryClassPool;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.internal.services.PropertyAccessImpl;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ApplicationStateManager;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ApplicationStateWorkerTest extends InternalBaseTestCase
+{
+    private final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+    private PropertyAccess access = new PropertyAccessImpl();
+
+    private ClassFactory classFactory;
+
+    private Loader loader;
+
+    private ClassFactoryClassPool classFactoryClassPool;
+
+    /**
+     * We need a new ClassPool for each individual test, since many of the tests will end up modifying one or more
+     * CtClass instances.
+     */
+    @BeforeMethod
+    public void setup_classpool()
+    {
+        //  _classPool = new ClassPool();
+
+        classFactoryClassPool = new ClassFactoryClassPool(contextClassLoader);
+
+        loader = new TestPackageAwareLoader(contextClassLoader, classFactoryClassPool);
+
+        // Inside Maven Surefire, the system classpath is not sufficient to find all
+        // the necessary files.
+        classFactoryClassPool.appendClassPath(new LoaderClassPath(loader));
+
+        Logger logger = LoggerFactory.getLogger(InternalClassTransformationImplTest.class);
+
+        classFactory = new ClassFactoryImpl(loader, classFactoryClassPool, logger);
+    }
+
+    private CtClass findCtClass(Class targetClass) throws NotFoundException
+    {
+        return classFactoryClassPool.get(targetClass.getName());
+    }
+
+    private Class toClass(CtClass ctClass) throws Exception
+    {
+        return classFactoryClassPool.toClass(ctClass, loader, null);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        access = null;
+    }
+
+    @Test
+    public void no_fields_with_annotation()
+    {
+        ApplicationStateManager manager = mockApplicationStateManager();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findFieldsWithAnnotation(ct, ApplicationState.class);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new ApplicationStateWorker(manager, null);
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void field_read_and_write() throws Exception
+    {
+        ApplicationStateManager manager = mockApplicationStateManager();
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel();
+        InternalComponentResources resources = mockInternalComponentResources();
+        ComponentClassCache cache = mockComponentClassCache();
+
+        train_getLogger(model, logger);
+
+        Class asoClass = SimpleASO.class;
+
+        CtClass ctClass = findCtClass(StateHolder.class);
+
+        train_forName(cache, asoClass);
+
+        replay();
+
+        InternalClassTransformation transformation = new InternalClassTransformationImpl(classFactory, ctClass, null,
+                                                                                         model, null);
+        new ApplicationStateWorker(manager, cache).transform(transformation, model);
+
+        verify();
+
+        transformation.finish();
+
+        Instantiator instantiator = transformation.createInstantiator();
+
+        Object component = instantiator.newInstance(resources);
+
+        // Test the companion flag field
+
+        expect(manager.exists(asoClass)).andReturn(true);
+
+        replay();
+
+        assertEquals(access.get(component, "beanExists"), true);
+
+        verify();
+
+        // Test read property (get from ASM)
+
+        Object aso = new SimpleASO();
+
+        train_get(manager, asoClass, aso);
+
+        replay();
+
+        assertSame(access.get(component, "bean"), aso);
+
+        verify();
+
+        // Test write property (set ASM)
+
+        Object aso2 = new SimpleASO();
+
+        manager.set(asoClass, aso2);
+
+        replay();
+
+        access.set(component, "bean", aso2);
+
+        verify();
+    }
+
+
+    @Test
+    public void read_field_with_create_disabled() throws Exception
+    {
+        ApplicationStateManager manager = mockApplicationStateManager();
+        Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel();
+        InternalComponentResources resources = mockInternalComponentResources();
+        ComponentClassCache cache = mockComponentClassCache();
+
+        train_getLogger(model, logger);
+
+        Class asoClass = SimpleASO.class;
+
+        CtClass ctClass = findCtClass(MaybeStateHolder.class);
+
+        train_forName(cache, asoClass);
+
+        replay();
+
+        InternalClassTransformation transformation = new InternalClassTransformationImpl(classFactory, ctClass, null,
+                                                                                         model, null);
+        new ApplicationStateWorker(manager, cache).transform(transformation, model);
+
+        verify();
+
+        transformation.finish();
+
+        Instantiator instantiator = transformation.createInstantiator();
+
+        Object component = instantiator.newInstance(resources);
+
+        // Test read property
+
+        train_getIfExists(manager, asoClass, null);
+
+        replay();
+
+        assertNull(access.get(component, "bean"));
+
+        verify();
+
+
+        Object aso = new SimpleASO();
+
+        train_getIfExists(manager, asoClass, aso);
+
+        replay();
+
+        assertSame(access.get(component, "bean"), aso);
+
+        verify();
+    }
+
+    protected final void train_getIfExists(ApplicationStateManager manager, Class asoClass, Object aso)
+    {
+        expect(manager.getIfExists(asoClass)).andReturn(aso);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/CachedWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/CachedWorkerTest.java
new file mode 100644
index 0000000..7d35ad6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/CachedWorkerTest.java
@@ -0,0 +1,71 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Cached;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.TransformMethodSignature;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+
+/**
+ * Mostly just testing error conditions here. Functionality testing in integration tests.
+ */
+@Test
+public class CachedWorkerTest extends TapestryTestCase
+{
+    public void must_have_return_type() throws Exception
+    {
+        ClassTransformation ct = mockClassTransformation();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "void", "getFoo", new String[0],
+                                                                    new String[0]);
+
+        expect(ct.findMethodsWithAnnotation(Cached.class)).andReturn(Arrays.asList(sig));
+
+        replay();
+        try
+        {
+            new CachedWorker(null).transform(ct, null);
+            fail("did not throw");
+        }
+        catch (IllegalArgumentException e)
+        {
+        }
+        verify();
+    }
+
+    public void must_not_have_parameters() throws Exception
+    {
+        ClassTransformation ct = mockClassTransformation();
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "java.lang.Object", "getFoo",
+                                                                    new String[] { "boolean" }, new String[0]);
+
+        expect(ct.findMethodsWithAnnotation(Cached.class)).andReturn(Arrays.asList(sig));
+
+        replay();
+        try
+        {
+            new CachedWorker(null).transform(ct, null);
+            fail("did not throw");
+        }
+        catch (IllegalArgumentException e)
+        {
+        }
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorkerTest.java
new file mode 100644
index 0000000..2e8bc91
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ComponentLifecycleMethodWorkerTest.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.SetupRender;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+import org.apache.tapestry.services.TransformMethodSignature;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * Of course, we're committing the cardinal sin of testing the code that's generated, rather than the *behavior* of the
+ * generated code. Fortunately, we back all this up with lots and lots of integration testing.
+ */
+public class ComponentLifecycleMethodWorkerTest extends TapestryTestCase
+{
+    @Test
+    public void no_methods_with_annotation()
+    {
+        ClassTransformation tf = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        TransformMethodSignature sig = new TransformMethodSignature("someRandomMethod");
+
+        train_findMethods(tf, sig);
+
+        train_getMethodAnnotation(tf, sig, SetupRender.class, null);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new ComponentLifecycleMethodWorker(
+                TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
+
+        worker.transform(tf, model);
+
+        verify();
+    }
+
+    @Test
+    public void added_lifecycle_method_is_ignored()
+    {
+        ClassTransformation tf = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findMethods(tf, TransformConstants.SETUP_RENDER_SIGNATURE);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new ComponentLifecycleMethodWorker(
+                TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
+
+        worker.transform(tf, model);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ContentTypeWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ContentTypeWorkerTest.java
new file mode 100644
index 0000000..d7551da
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ContentTypeWorkerTest.java
@@ -0,0 +1,63 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.annotation.ContentType;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class ContentTypeWorkerTest extends TapestryTestCase
+{
+
+    @Test
+    public void annotation_missing()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getAnnotation(ct, ContentType.class, null);
+
+        replay();
+
+        new ContentTypeWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void annotation_present()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        String value = "text/pdf";
+
+        ContentType annotation = newMock(ContentType.class);
+
+        train_getAnnotation(ct, ContentType.class, annotation);
+
+        expect(annotation.value()).andReturn(value);
+
+        model.setMeta(MetaDataConstants.RESPONSE_CONTENT_TYPE, value);
+
+        replay();
+
+        new ContentTypeWorker().transform(ct, model);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/FieldRemoval.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/FieldRemoval.java
new file mode 100644
index 0000000..b37c093
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/FieldRemoval.java
@@ -0,0 +1,21 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+public class FieldRemoval
+{
+    @SuppressWarnings("unused")
+    private int _fieldToRemove;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InheritedAnnotation.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InheritedAnnotation.java
new file mode 100644
index 0000000..3c7a845
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InheritedAnnotation.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+@Inherited
+public @interface InheritedAnnotation
+{
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectComponentWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectComponentWorkerTest.java
new file mode 100644
index 0000000..579d997
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectComponentWorkerTest.java
@@ -0,0 +1,86 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.InjectComponent;
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+import org.apache.tapestry.test.TapestryTestCase;
+import static org.easymock.EasyMock.contains;
+import static org.easymock.EasyMock.same;
+import org.testng.annotations.Test;
+
+public class InjectComponentWorkerTest extends TapestryTestCase
+{
+
+    private static final String CLASS_NAME = Grid.class.getName();
+
+    @Test
+    public void default_id_from_field_name()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        InjectComponent annotation = newMock(InjectComponent.class);
+        ComponentClassTransformWorker worker = new InjectComponentWorker();
+
+        train_findFieldsWithAnnotation(ct, InjectComponent.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", InjectComponent.class, annotation);
+        train_getFieldType(ct, "myfield", CLASS_NAME);
+        train_getResourcesFieldName(ct, "resources");
+        expect(annotation.value()).andReturn("");
+        ct.makeReadOnly("myfield");
+
+        ct.extendMethod(same(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE),
+                        contains(
+                                "myfield = (" + CLASS_NAME + ") resources.getEmbeddedComponent(\"myfield\");"));
+
+
+        replay();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void explicit_component_id_provided_as_annotation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        InjectComponent annotation = newMock(InjectComponent.class);
+        ComponentClassTransformWorker worker = new InjectComponentWorker();
+
+        train_findFieldsWithAnnotation(ct, InjectComponent.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", InjectComponent.class, annotation);
+        train_getFieldType(ct, "myfield", CLASS_NAME);
+        train_getResourcesFieldName(ct, "resources");
+        expect(annotation.value()).andReturn("id_provided_as_annotation").atLeastOnce();
+        ct.makeReadOnly("myfield");
+
+        ct.extendMethod(same(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE),
+                        contains(
+                                "myfield = (" + CLASS_NAME + ") resources.getEmbeddedComponent(\"id_provided_as_annotation\");"));
+
+        replay();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectWorkerTest.java
new file mode 100644
index 0000000..1246fcb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InjectWorkerTest.java
@@ -0,0 +1,131 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.InjectionProvider;
+import org.apache.tapestry.services.Request;
+import org.testng.annotations.Test;
+
+public class InjectWorkerTest extends InternalBaseTestCase
+{
+    private static final String REQUEST_CLASS_NAME = Request.class.getName();
+
+    @Test
+    public void anonymous_injection()
+    {
+        ObjectLocator locator = mockObjectLocator();
+        InjectionProvider ip = newMock(InjectionProvider.class);
+        Inject annotation = newInject();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+
+        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+
+        train_provideInjection(ip, "myfield", Request.class, locator, ct, model, true);
+
+        ct.claimField("myfield", annotation);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void anonymous_injection_not_provided()
+    {
+        ObjectLocator locator = mockObjectLocator();
+        InjectionProvider ip = newMock(InjectionProvider.class);
+        Inject annotation = newInject();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+
+        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+
+        train_provideInjection(ip, "myfield", Request.class, locator, ct, model, false);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
+
+        // Does the work but doesn't claim the field, since there was no match.
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void injection_provider_threw_exception()
+    {
+        ObjectLocator locator = mockObjectLocator();
+        InjectionProvider ip = newMock(InjectionProvider.class);
+        Inject annotation = newInject();
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        RuntimeException failure = new RuntimeException("Oops.");
+
+        train_findFieldsWithAnnotation(ct, Inject.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", Inject.class, annotation);
+
+        train_getFieldType(ct, "myfield", REQUEST_CLASS_NAME);
+        train_toClass(ct, REQUEST_CLASS_NAME, Request.class);
+
+        expect(ip.provideInjection("myfield", Request.class, locator, ct, model)).andThrow(failure);
+
+        train_getClassName(ct, "foo.bar.Baz");
+
+        replay();
+
+        ComponentClassTransformWorker worker = new InjectWorker(locator, ip);
+
+        try
+        {
+            worker.transform(ct, model);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Error obtaining injected value for field foo.bar.Baz.myfield: Oops.");
+            assertSame(ex.getCause(), failure);
+        }
+
+        verify();
+    }
+
+    protected final Inject newInject()
+    {
+        return newMock(Inject.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorkerTest.java
new file mode 100644
index 0000000..8fae399
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/InvokePostRenderCleanupOnResourcesWorkerTest.java
@@ -0,0 +1,69 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+import org.testng.annotations.Test;
+
+public class InvokePostRenderCleanupOnResourcesWorkerTest extends InternalBaseTestCase
+{
+    @Test
+    public void not_a_root_transformation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_isRootTransformation(ct, false);
+
+        replay();
+
+        ComponentClassTransformWorker worker = new InvokePostRenderCleanupOnResourcesWorker();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void invocation_added_for_root_transformation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_isRootTransformation(ct, true);
+
+        train_getResourcesFieldName(ct, "rez");
+
+        train_extendMethod(ct, TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, "rez.postRenderCleanup();");
+
+        replay();
+
+        ComponentClassTransformWorker worker = new InvokePostRenderCleanupOnResourcesWorker();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    protected final void train_isRootTransformation(ClassTransformation transformation, boolean isRoot)
+    {
+        expect(transformation.isRootTransformation()).andReturn(isRoot).atLeastOnce();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MetaWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MetaWorkerTest.java
new file mode 100644
index 0000000..67e9679
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MetaWorkerTest.java
@@ -0,0 +1,61 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.testng.annotations.Test;
+
+public class MetaWorkerTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_annotation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getAnnotation(ct, Meta.class, null);
+
+        replay();
+
+        new MetaWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void has_meta_data()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        Meta annotation = newMock(Meta.class);
+
+        train_getAnnotation(ct, Meta.class, annotation);
+
+        expect(annotation.value()).andReturn(new String[]
+                { "foo=bar", "baz=biff" });
+
+        model.setMeta("foo", "bar");
+        model.setMeta("baz", "biff");
+
+        replay();
+
+        new MetaWorker().transform(ct, model);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinAfterWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinAfterWorkerTest.java
new file mode 100644
index 0000000..3e8aae7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinAfterWorkerTest.java
@@ -0,0 +1,56 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.MixinAfter;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.testng.annotations.Test;
+
+public class MixinAfterWorkerTest extends InternalBaseTestCase
+{
+    @Test
+    public void annotation_not_present()
+    {
+        ClassTransformation transformation = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getAnnotation(transformation, MixinAfter.class, null);
+
+        replay();
+
+        new MixinAfterWorker().transform(transformation, model);
+
+        verify();
+    }
+
+    @Test
+    public void annotation_present()
+    {
+        ClassTransformation transformation = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        MixinAfter annotation = newMock(MixinAfter.class);
+
+        train_getAnnotation(transformation, MixinAfter.class, annotation);
+        model.setMixinAfter(true);
+
+        replay();
+
+        new MixinAfterWorker().transform(transformation, model);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinWorkerTest.java
new file mode 100644
index 0000000..70e6041
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/MixinWorkerTest.java
@@ -0,0 +1,124 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.Mixin;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.TransformConstants;
+import org.testng.annotations.Test;
+
+public class MixinWorkerTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_fields_with_mixin_annotation()
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        ClassTransformation transformation = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findFieldsWithAnnotation(transformation, Mixin.class);
+
+        replay();
+
+        new MixinWorker(resolver).transform(transformation, model);
+
+        verify();
+    }
+
+    @Test
+    public void field_with_explicit_type()
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        ClassTransformation transformation = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        Mixin annotation = newMixin("Bar");
+
+        train_findFieldsWithAnnotation(transformation, Mixin.class, "fred");
+        train_getFieldAnnotation(transformation, "fred", Mixin.class, annotation);
+        train_getFieldType(transformation, "fred", "foo.bar.Baz");
+
+        train_resolveMixinTypeToClassName(resolver, "Bar", "foo.bar.BazMixin");
+
+        model.addMixinClassName("foo.bar.BazMixin");
+
+        transformation.makeReadOnly("fred");
+
+        train_getResourcesFieldName(transformation, "rez");
+
+        train_extendMethod(
+                transformation,
+                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                "fred = (foo.bar.Baz) rez.getMixinByClassName(\"foo.bar.BazMixin\");");
+
+        transformation.claimField("fred", annotation);
+
+        replay();
+
+        new MixinWorker(resolver).transform(transformation, model);
+
+        verify();
+    }
+
+    @Test
+    public void field_with_no_specific_mixin_type()
+    {
+        ComponentClassResolver resolver = mockComponentClassResolver();
+        ClassTransformation transformation = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        Mixin annotation = newMixin("");
+
+        train_findFieldsWithAnnotation(transformation, Mixin.class, "fred");
+        train_getFieldAnnotation(transformation, "fred", Mixin.class, annotation);
+        train_getFieldType(transformation, "fred", "foo.bar.Baz");
+
+        model.addMixinClassName("foo.bar.Baz");
+
+        transformation.makeReadOnly("fred");
+
+        train_getResourcesFieldName(transformation, "rez");
+
+        train_extendMethod(
+                transformation,
+                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                "fred = (foo.bar.Baz) rez.getMixinByClassName(\"foo.bar.Baz\");");
+
+        transformation.claimField("fred", annotation);
+
+        replay();
+
+        new MixinWorker(resolver).transform(transformation, model);
+
+        verify();
+
+    }
+
+    protected final void train_resolveMixinTypeToClassName(ComponentClassResolver resolver,
+                                                           String mixinType, String mixinClassName)
+    {
+        expect(resolver.resolveMixinTypeToClassName(mixinType)).andReturn(mixinClassName);
+    }
+
+    private Mixin newMixin(String value)
+    {
+        Mixin annotation = newMock(Mixin.class);
+
+        expect(annotation.value()).andReturn(value);
+
+        return annotation;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ParameterWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ParameterWorkerTest.java
new file mode 100644
index 0000000..0f7bd35
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ParameterWorkerTest.java
@@ -0,0 +1,644 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import javassist.CtClass;
+import javassist.Loader;
+import javassist.LoaderClassPath;
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.BindingConstants;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.services.InternalClassTransformation;
+import org.apache.tapestry.internal.services.InternalClassTransformationImpl;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.internal.transform.components.DefaultParameterBindingMethodComponent;
+import org.apache.tapestry.internal.transform.components.DefaultParameterComponent;
+import org.apache.tapestry.internal.transform.components.ParameterComponent;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryClassPool;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.internal.services.PropertyAccessImpl;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.BindingSource;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+/**
+ * There's no point in trying to unit test the code generated by {@link org.apache.tapestry.internal.transform.ParameterWorker}.
+ * Instead, we excercize ParameterWorker, and test that the generated code works correctly in a number of scenarios.
+ */
+public class ParameterWorkerTest extends InternalBaseTestCase
+{
+    private final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+    private PropertyAccess access = new PropertyAccessImpl();
+
+    /**
+     * Accessed by DefaultParameterBindingMethodComponent.
+     */
+    public static Binding _binding;
+
+    @AfterClass
+    public void cleanup()
+    {
+        access = null;
+        _binding = null;
+    }
+
+    @Test
+    public void page_load_behavior() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        assertNotNull(setupForIntegrationTest(resources));
+    }
+
+    @Test
+    public void invariant_object_retained_after_detach() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        // On first invocation, the resources are queried.
+
+        String value = "To be in Tapestry in the spring time ...";
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "invariantObject", true);
+        train_readParameter(resources, "invariantObject", String.class, value);
+
+        replay();
+
+        assertSame(access.get(component, "invariantObject"), value);
+
+        verify();
+
+        // No further training needed here.
+
+        replay();
+
+        // Still cached ...
+
+        assertSame(access.get(component, "invariantObject"), value);
+
+        component.postRenderCleanup();
+
+        // Still cached ...
+
+        assertSame(access.get(component, "invariantObject"), value);
+
+        component.containingPageDidDetach();
+
+        // Still cached ...
+
+        assertSame(access.get(component, "invariantObject"), value);
+
+        verify();
+    }
+
+    @Test
+    public void invariant_primitive_retained_after_detach() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        // On first invocation, the resources are queried.
+
+        long value = 123456;
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "invariantPrimitive", true);
+        train_readParameter(resources, "invariantPrimitive", Long.class, value);
+
+        replay();
+
+        assertEquals(access.get(component, "invariantPrimitive"), value);
+
+        verify();
+
+        // No further training needed here.
+
+        replay();
+
+        // Still cached ...
+
+        assertEquals(access.get(component, "invariantPrimitive"), value);
+
+        component.postRenderCleanup();
+
+        // Still cached ...
+
+        assertEquals(access.get(component, "invariantPrimitive"), value);
+
+        verify();
+    }
+
+    /**
+     * This actually checks several things: <ul> <li>Changing a parameter property before the page loads doesn't update
+     * the binding</li> <li>Changing a parameter property changes the property AND the default value for the
+     * property</li> <li>Unbound parameters to do not attempt to read or update their bindings (they'll be
+     * optional)</li> </ul>
+     *
+     * @throws Exception
+     */
+    @Test
+    public void changes_before_load_become_defaults_and_dont_update_bindings() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        train_isLoaded(resources, false);
+
+        replay();
+
+        assertNull(access.get(component, "object"));
+
+        verify();
+
+        train_isLoaded(resources, false);
+
+        replay();
+
+        access.set(component, "object", "new-default");
+
+        verify();
+
+        train_isLoaded(resources, false);
+
+        replay();
+
+        assertEquals(access.get(component, "object"), "new-default");
+
+        verify();
+
+        trainForPageDidLoad(resources);
+
+        replay();
+
+        component.containingPageDidLoad();
+
+        verify();
+
+        // For the set ...
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", false);
+        train_isRendering(resources, false);
+
+        // For the first read ...
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", false);
+
+        // For the second read (after postRenderCleanup) ...
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", false);
+
+        replay();
+
+        access.set(component, "object", "new-value");
+        assertEquals(access.get(component, "object"), "new-value");
+
+        component.postRenderCleanup();
+
+        assertEquals(access.get(component, "object"), "new-default");
+
+        verify();
+    }
+
+    @Test
+    public void cached_object_read() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "first");
+        train_isRendering(resources, false);
+
+        replay();
+
+        assertEquals(access.get(component, "object"), "first");
+
+        verify();
+
+        // Keeps re-reading the parameter when not rendering.
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "second");
+        train_isRendering(resources, false);
+
+        replay();
+
+        assertEquals(access.get(component, "object"), "second");
+
+        verify();
+
+        // Now, when rendering is active, the value is cached
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "third");
+        train_isRendering(resources, true);
+
+        replay();
+
+        assertEquals(access.get(component, "object"), "third");
+
+        // Does not cause readParameter() to be invoked:
+
+        assertEquals(access.get(component, "object"), "third");
+
+        verify();
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "fourth");
+        train_isRendering(resources, false);
+
+        replay();
+
+        component.postRenderCleanup();
+
+        assertEquals(access.get(component, "object"), "fourth");
+
+        verify();
+    }
+
+    @Test
+    public void cached_object_write() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        resources.writeParameter("object", "first");
+        train_isRendering(resources, false);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "second");
+        train_isRendering(resources, false);
+
+        replay();
+
+        access.set(component, "object", "first");
+        assertEquals(access.get(component, "object"), "second");
+
+        verify();
+
+        // Now try during rendering ...
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        resources.writeParameter("object", "third");
+        train_isRendering(resources, true);
+
+        replay();
+
+        access.set(component, "object", "third");
+        assertEquals(access.get(component, "object"), "third");
+
+        verify();
+
+        // And the cached value is lost after rendering is complete.
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "object", true);
+        train_readParameter(resources, "object", String.class, "fourth");
+        train_isRendering(resources, false);
+
+        replay();
+
+        component.postRenderCleanup();
+
+        assertEquals(access.get(component, "object"), "fourth");
+
+        verify();
+    }
+
+    @Test
+    public void cached_primitive_write() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "primitive", true);
+        resources.writeParameter("primitive", 321);
+
+        train_isRendering(resources, false);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "primitive", true);
+        train_readParameter(resources, "primitive", Integer.class, 123);
+        train_isRendering(resources, false);
+
+        replay();
+
+        access.set(component, "primitive", 321);
+        assertEquals(access.get(component, "primitive"), 123);
+
+        verify();
+
+        // Now try during rendering ...
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "primitive", true);
+        resources.writeParameter("primitive", 567);
+        train_isRendering(resources, true);
+
+        replay();
+
+        access.set(component, "primitive", 567);
+        assertEquals(access.get(component, "primitive"), 567);
+
+        verify();
+
+        // And the cached value is lost after rendering is complete.
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "primitive", true);
+        train_readParameter(resources, "primitive", Integer.class, 890);
+        train_isRendering(resources, false);
+
+        replay();
+
+        component.postRenderCleanup();
+
+        assertEquals(access.get(component, "primitive"), 890);
+
+        verify();
+    }
+
+    @Test
+    public void uncached_object_read() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        // Notice no check for isRendering() since that is irrelevant to uncached parameters.
+        // Also note difference between field name and parameter name, due to Parameter.name() being
+        // specified.
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "uncached", true);
+        train_readParameter(resources, "uncached", String.class, "first");
+        train_isLoaded(resources, true);
+        train_isBound(resources, "uncached", true);
+        train_readParameter(resources, "uncached", String.class, "second");
+
+        replay();
+
+        assertEquals(access.get(component, "uncachedObject"), "first");
+        assertEquals(access.get(component, "uncachedObject"), "second");
+
+        verify();
+    }
+
+    protected void train_isBound(InternalComponentResources resources, String parameterName, boolean isBound)
+    {
+        expect(resources.isBound(parameterName)).andReturn(isBound);
+    }
+
+    @Test
+    public void uncached_object_write() throws Exception
+    {
+        InternalComponentResources resources = mockInternalComponentResources();
+
+        Component component = setupForIntegrationTest(resources);
+
+        // Notice no check for isRendering() since that is irrelevant to uncached parameters.
+        // Also note difference between field name and parameter name, due to Parameter.name() being
+        // specified.
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "uncached", true);
+        resources.writeParameter("uncached", "first");
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "uncached", true);
+        train_readParameter(resources, "uncached", String.class, "second");
+
+        replay();
+
+        access.set(component, "uncachedObject", "first");
+        assertEquals(access.get(component, "uncachedObject"), "second");
+
+        verify();
+    }
+
+    @Test
+    public void parameter_with_default() throws Exception
+    {
+        final BindingSource source = mockBindingSource();
+        final InternalComponentResources resources = mockInternalComponentResources();
+        final Binding binding = mockBinding();
+        String boundValue = "howdy!";
+        final Logger logger = mockLogger();
+
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        model.addParameter("value", false, BindingConstants.PROP);
+
+        Runnable phaseTwoTraining = new Runnable()
+        {
+            public void run()
+            {
+                train_isBound(resources, "value", false);
+
+                expect(source.newBinding("default value", resources, BindingConstants.PROP,
+                                         "literal:greeting")).andReturn(binding);
+
+                resources.bindParameter("value", binding);
+
+                train_isInvariant(resources, "value", true);
+
+                stub_isDebugEnabled(logger, false);
+            }
+        };
+
+        Component component = setupForIntegrationTest(resources, logger, DefaultParameterComponent.class.getName(),
+                                                      model, source, phaseTwoTraining);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "value", true);
+        train_readParameter(resources, "value", String.class, boundValue);
+        stub_isDebugEnabled(logger, false);
+
+        replay();
+
+        assertEquals(access.get(component, "value"), boundValue);
+
+        verify();
+    }
+
+    @Test
+    public void default_binding_method() throws Exception
+    {
+        BindingSource source = mockBindingSource();
+        final InternalComponentResources resources = mockInternalComponentResources();
+        _binding = mockBinding();
+        String boundValue = "yowza!";
+        final Logger logger = mockLogger();
+
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        model.addParameter("value", false, BindingConstants.PROP);
+
+        Runnable phaseTwoTraining = new Runnable()
+        {
+            public void run()
+            {
+                train_isBound(resources, "value", false);
+
+                // How can this happen? Only if the generated code invokes defaultValue().
+
+                resources.bindParameter("value", _binding);
+
+                train_isInvariant(resources, "value", true);
+                stub_isDebugEnabled(logger, false);
+            }
+        };
+
+
+        Component component = setupForIntegrationTest(resources, logger,
+                                                      DefaultParameterBindingMethodComponent.class.getName(), model,
+                                                      source, phaseTwoTraining);
+
+        train_isLoaded(resources, true);
+        train_isBound(resources, "value", true);
+        train_readParameter(resources, "value", String.class, boundValue);
+        stub_isDebugEnabled(logger, false);
+        replay();
+
+        assertEquals(access.get(component, "value"), boundValue);
+
+        verify();
+    }
+
+    protected final void train_isRendering(InternalComponentResources resources, boolean rendering)
+    {
+        expect(resources.isRendering()).andReturn(rendering);
+    }
+
+    protected final <T> void train_readParameter(InternalComponentResources resources, String parameterName,
+                                                 Class<T> expectedType, T value)
+    {
+        expect(resources.readParameter(parameterName, expectedType.getName())).andReturn(value);
+    }
+
+    /**
+     * This is for the majority of tests.
+     */
+    private Component setupForIntegrationTest(final InternalComponentResources resources) throws Exception
+    {
+        final Logger logger = mockLogger();
+        MutableComponentModel model = mockMutableComponentModel(logger);
+
+        model.addParameter("invariantObject", false, BindingConstants.PROP);
+        model.addParameter("invariantPrimitive", false, BindingConstants.PROP);
+        model.addParameter("object", false, BindingConstants.PROP);
+        model.addParameter("primitive", true, BindingConstants.PROP);
+        model.addParameter("uncached", false, BindingConstants.LITERAL);
+
+
+        Runnable phaseTwoTraining = new Runnable()
+        {
+            public void run()
+            {
+                trainForPageDidLoad(resources);
+                stub_isDebugEnabled(logger, false);
+            }
+        };
+
+
+        stub_isDebugEnabled(logger, false);
+
+        return setupForIntegrationTest(resources, logger, ParameterComponent.class.getName(), model,
+                                       mockBindingSource(), phaseTwoTraining);
+    }
+
+    private Component setupForIntegrationTest(InternalComponentResources resources, Logger logger,
+                                              String componentClassName, MutableComponentModel model,
+                                              BindingSource source, Runnable phaseTwoTraining) throws Exception
+    {
+        ClassFactoryClassPool pool = new ClassFactoryClassPool(contextClassLoader);
+
+        Loader loader = new TestPackageAwareLoader(contextClassLoader, pool);
+
+        pool.appendClassPath(new LoaderClassPath(loader));
+
+        ClassFactory cf = new ClassFactoryImpl(loader, pool, logger);
+
+        CtClass ctClass = pool.get(componentClassName);
+
+        replay();
+
+        InternalClassTransformation transformation = new InternalClassTransformationImpl(cf, ctClass, null, model,
+                                                                                         null);
+
+        new ParameterWorker(source).transform(transformation, model);
+
+        verify();
+
+
+        phaseTwoTraining.run();
+
+        replay();
+
+        transformation.finish();
+
+        Instantiator instantiator = transformation.createInstantiator();
+
+        Component component = instantiator.newInstance(resources);
+
+        component.containingPageDidLoad();
+
+        verify();
+
+        return component;
+    }
+
+    private void trainForPageDidLoad(InternalComponentResources resources)
+    {
+        train_isInvariant(resources, "invariantObject", true);
+        train_isInvariant(resources, "invariantPrimitive", true);
+        train_isInvariant(resources, "object", false);
+        train_isInvariant(resources, "primitive", false);
+        train_isInvariant(resources, "uncached", false);
+    }
+
+    protected final void train_isInvariant(InternalComponentResources resources, String parameterName,
+                                           boolean invariant)
+    {
+        expect(resources.isInvariant(parameterName)).andReturn(invariant);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ResponseEncodingWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ResponseEncodingWorkerTest.java
new file mode 100644
index 0000000..df09534
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/ResponseEncodingWorkerTest.java
@@ -0,0 +1,62 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.MetaDataConstants;
+import org.apache.tapestry.annotation.ResponseEncoding;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class ResponseEncodingWorkerTest extends TapestryTestCase
+{
+    @Test
+    public void annotation_missing()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getAnnotation(ct, ResponseEncoding.class, null);
+
+        replay();
+
+        new ResponseEncodingWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void annotation_present()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        String value = "UTF-8";
+
+        ResponseEncoding annotation = newMock(ResponseEncoding.class);
+
+        train_getAnnotation(ct, ResponseEncoding.class, annotation);
+
+        expect(annotation.value()).andReturn(value);
+
+        model.setMeta(MetaDataConstants.RESPONSE_ENCODING, value);
+
+        replay();
+
+        new ResponseEncodingWorker().transform(ct, model);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/RetainWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/RetainWorkerTest.java
new file mode 100644
index 0000000..c578aee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/RetainWorkerTest.java
@@ -0,0 +1,63 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform;

+

+import org.apache.tapestry.annotation.Retain;

+import org.apache.tapestry.internal.test.InternalBaseTestCase;

+import org.apache.tapestry.model.MutableComponentModel;

+import org.apache.tapestry.services.ClassTransformation;

+import org.testng.annotations.Test;

+

+public class RetainWorkerTest extends InternalBaseTestCase

+{

+    @Test

+    public void no_fields()

+    {

+        ClassTransformation ct = mockClassTransformation();

+        MutableComponentModel model = mockMutableComponentModel();

+

+        train_findFieldsWithAnnotation(ct, Retain.class);

+

+        replay();

+

+        RetainWorker worker = new RetainWorker();

+

+        worker.transform(ct, model);

+

+        verify();

+    }

+

+    @Test

+    public void normal()

+    {

+        ClassTransformation ct = mockClassTransformation();

+        MutableComponentModel model = mockMutableComponentModel();

+        Retain annotation = newMock(Retain.class);

+

+        train_findFieldsWithAnnotation(ct, Retain.class, "fred");

+

+        train_getFieldAnnotation(ct, "fred", Retain.class, annotation);

+

+        ct.claimField("fred", annotation);

+

+        replay();

+

+        RetainWorker worker = new RetainWorker();

+

+        worker.transform(ct, model);

+

+        verify();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorkerTest.java
new file mode 100644
index 0000000..101f627
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/SupportsInformalParametersWorkerTest.java
@@ -0,0 +1,58 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.annotation.SupportsInformalParameters;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.testng.annotations.Test;
+
+public class SupportsInformalParametersWorkerTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void annotation_present()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        SupportsInformalParameters annotation = newMock(SupportsInformalParameters.class);
+
+        train_getAnnotation(ct, SupportsInformalParameters.class, annotation);
+        model.enableSupportsInformalParameters();
+
+        replay();
+
+        new SupportsInformalParametersWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void annotation_missing()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_getAnnotation(ct, SupportsInformalParameters.class, null);
+
+        replay();
+
+        new SupportsInformalParametersWorker().transform(ct, model);
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/TestPackageAwareLoader.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/TestPackageAwareLoader.java
new file mode 100644
index 0000000..420b362
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/TestPackageAwareLoader.java
@@ -0,0 +1,39 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import javassist.ClassPool;
+import javassist.Loader;
+
+public class TestPackageAwareLoader extends Loader
+{
+    public TestPackageAwareLoader(ClassLoader parent, ClassPool cp)
+    {
+        super(parent, cp);
+    }
+
+    @Override
+    public Class findClass(String className) throws ClassNotFoundException
+    {
+        int lastdotx = className.lastIndexOf('.');
+        String packageName = className.substring(0, lastdotx);
+
+        if (packageName.startsWith("org.apache.tapestry.internal.transform.")) return super.findClass(className);
+
+        // Returning null forces delegation to the parent class loader.
+
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorkerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorkerTest.java
new file mode 100644
index 0000000..f323412
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/UnclaimedFieldWorkerTest.java
@@ -0,0 +1,90 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import static org.apache.tapestry.services.TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE;
+import static org.apache.tapestry.services.TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Modifier;
+
+public class UnclaimedFieldWorkerTest extends InternalBaseTestCase
+{
+    @Test
+    public void no_fields()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findUnclaimedFields(ct);
+
+        replay();
+
+        new UnclaimedFieldWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void normal()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findUnclaimedFields(ct, "_fred");
+
+        train_getFieldModifiers(ct, "_fred", Modifier.PRIVATE);
+
+        train_getFieldType(ct, "_fred", "foo.Bar");
+
+        expect(ct.addField(Modifier.PRIVATE, "foo.Bar", "_fred_default")).andReturn(
+                "_$fred_default");
+
+        ct.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, "_$fred_default = _fred;");
+        ct.extendMethod(CONTAINING_PAGE_DID_DETACH_SIGNATURE, "_fred = _$fred_default;");
+
+        replay();
+
+        new UnclaimedFieldWorker().transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void final_fields_are_skipped()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+
+        train_findUnclaimedFields(ct, "_fred");
+
+        train_getFieldModifiers(ct, "_fred", Modifier.PRIVATE | Modifier.FINAL);
+
+        replay();
+
+        new UnclaimedFieldWorker().transform(ct, model);
+
+        verify();
+    }
+
+    protected final void train_getFieldModifiers(ClassTransformation transformation,
+                                                 String fieldName, int modifiers)
+    {
+        expect(transformation.getFieldModifiers(fieldName)).andReturn(modifiers).atLeastOnce();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterBindingMethodComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterBindingMethodComponent.java
new file mode 100644
index 0000000..8b1d79b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterBindingMethodComponent.java
@@ -0,0 +1,35 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.components;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.annotation.Parameter;
+import org.apache.tapestry.internal.transform.ParameterWorkerTest;
+
+public class DefaultParameterBindingMethodComponent
+{
+    @Parameter
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    Binding defaultValue()
+    {
+        return ParameterWorkerTest._binding;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterComponent.java
new file mode 100644
index 0000000..e4c2380
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/DefaultParameterComponent.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.components;
+
+import org.apache.tapestry.annotation.Parameter;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.transform.ParameterWorkerTest}.
+ */
+public class DefaultParameterComponent
+{
+    @Parameter("literal:greeting")
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/ParameterComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/ParameterComponent.java
new file mode 100644
index 0000000..fab9686
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/components/ParameterComponent.java
@@ -0,0 +1,89 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform.components;

+

+import org.apache.tapestry.annotation.Parameter;

+

+/**

+ * Used by {@link org.apache.tapestry.internal.transform.ParameterWorkerTest}.

+ */

+public class ParameterComponent

+{

+    @Parameter

+    private String object;

+

+    @Parameter(cache = false, name = "uncached", defaultPrefix = "literal")

+    private String uncachedObject;

+

+    @Parameter(required = true)

+    private int primitive;

+

+    @Parameter

+    private String invariantObject;

+

+    @Parameter

+    private long invariantPrimitive;

+

+    public String getObject()

+    {

+        return object;

+    }

+

+    public void setObject(String object)

+    {

+        this.object = object;

+    }

+

+    public int getPrimitive()

+    {

+        return primitive;

+    }

+

+    public void setPrimitive(int primitive)

+    {

+        this.primitive = primitive;

+    }

+

+    public String getUncachedObject()

+    {

+        return uncachedObject;

+    }

+

+    public void setUncachedObject(String uncachedObject)

+    {

+        this.uncachedObject = uncachedObject;

+    }

+

+    public String getInvariantObject()

+    {

+        return invariantObject;

+    }

+

+    public void setInvariantObject(String invariantObject)

+    {

+        this.invariantObject = invariantObject;

+    }

+

+    public long getInvariantPrimitive()

+    {

+        return invariantPrimitive;

+    }

+

+    public void setInvariantPrimitive(long invariantPrimitive)

+    {

+        this.invariantPrimitive = invariantPrimitive;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java
new file mode 100644
index 0000000..04f2e9c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/AbstractFoo.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+import org.apache.tapestry.internal.services.FooInterface;

+

+/**

+ *

+ */

+public abstract class AbstractFoo implements FooInterface

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java
new file mode 100644
index 0000000..8e0b925
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BarImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+import org.apache.tapestry.internal.services.BarInterface;

+

+/**

+ *

+ */

+public class BarImpl extends FooImpl implements BarInterface

+{

+

+    public void bar()

+    {

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicComponent.java
new file mode 100644
index 0000000..38e5995
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicComponent.java
@@ -0,0 +1,48 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.Retain;
+
+/**
+ * Used to test retained vs. discard properties.
+ */
+public class BasicComponent
+{
+    private String value;
+
+    @Retain
+    private String retainedValue;
+
+    public final String getRetainedValue()
+    {
+        return retainedValue;
+    }
+
+    public final void setRetainedValue(String retainedValue)
+    {
+        this.retainedValue = retainedValue;
+    }
+
+    public final String getValue()
+    {
+        return value;
+    }
+
+    public final void setValue(String value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicSubComponent.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicSubComponent.java
new file mode 100644
index 0000000..ca24227
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/BasicSubComponent.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform.pages;

+

+/**  */

+public class BasicSubComponent extends BasicComponent

+{

+    private int intValue;

+

+    public final int getIntValue()

+    {

+        return intValue;

+    }

+

+    public final void setIntValue(int intValue)

+    {

+        this.intValue = intValue;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java
new file mode 100644
index 0000000..0b830a8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ChildClassInheritsAnnotation.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+/**

+ * Used to check that Javassist does make child classes inherit class annotations.

+ */

+public class ChildClassInheritsAnnotation extends ParentClass

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java
new file mode 100644
index 0000000..eb33d50
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ClaimedFields.java
@@ -0,0 +1,58 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+public class ClaimedFields

+{

+    // Make sure results are sorted by putting this first

+    // but expecting them last.

+

+    private int _zzfield;

+

+    private int _field1;

+

+    private String _field4;

+

+    public final int getField1()

+    {

+        return _field1;

+    }

+

+    public final void setField1(int field1)

+    {

+        _field1 = field1;

+    }

+

+    public final String getField4()

+    {

+        return _field4;

+    }

+

+    public final void setField4(String field4)

+    {

+        _field4 = field4;

+    }

+

+    public final int getZzfield()

+    {

+        return _zzfield;

+    }

+

+    public final void setZzfield(int zzfield)

+    {

+        _zzfield = zzfield;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/EventHandlerTarget.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/EventHandlerTarget.java
new file mode 100644
index 0000000..eedc3cb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/EventHandlerTarget.java
@@ -0,0 +1,25 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+
+public class EventHandlerTarget
+{
+    @OnEvent(value = "fred", component = "alpha")
+    public void handler()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FieldAccessBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FieldAccessBean.java
new file mode 100644
index 0000000..2e6bc33
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FieldAccessBean.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.internal.transform.pages;

+

+public class FieldAccessBean

+{

+    private String _foo;

+

+    private String _bar;

+

+    public String getBar()

+    {

+        return _bar;

+    }

+

+    public void setBar(String bar)

+    {

+        _bar = bar;

+    }

+

+    public String getFoo()

+    {

+        return _foo;

+    }

+

+    public void setFoo(String foo)

+    {

+        _foo = foo;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java
new file mode 100644
index 0000000..0162270
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/FooImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+import org.apache.tapestry.internal.services.FooInterface;

+

+/**

+ *

+ */

+public class FooImpl implements FooInterface

+{

+

+    public void foo()

+    {

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MaybeStateHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MaybeStateHolder.java
new file mode 100644
index 0000000..1bf2059
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MaybeStateHolder.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.internal.services.SimpleASO;
+
+public class MaybeStateHolder
+{
+    @ApplicationState(create = false)
+    private SimpleASO bean;
+
+
+    public SimpleASO getBean()
+    {
+        return bean;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java
new file mode 100644
index 0000000..ba59d13
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.OnEvent;
+
+public class MethodIdentifier
+{
+    @OnEvent
+    String makeWaves(String argument1, int[] argument2)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodPrefixTarget.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodPrefixTarget.java
new file mode 100644
index 0000000..8eb03c5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/MethodPrefixTarget.java
@@ -0,0 +1,32 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+public class MethodPrefixTarget
+{
+    // If this is final, then the read is inlined, defeating the test.
+    private int _targetField = 42;
+
+    public int getTargetValue()
+    {
+        return _targetField;
+    }
+
+    // Again, necessary to defeat inlining of the value.
+    public void setTargetField(int value)
+    {
+        _targetField = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java
new file mode 100644
index 0000000..096b00b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ParentClass.java
@@ -0,0 +1,77 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.Meta;
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.internal.transform.InheritedAnnotation;
+
+/**
+ * Test class used with {@link org.apache.tapestry.internal.services.InternalClassTransformationImplTest}
+ */
+@Meta("foo=bar")
+@InheritedAnnotation
+public class ParentClass
+{
+    private int _parentField;
+
+    // Named so that we can force a name conflict
+
+    private String _$conflictField;
+
+    @Retain
+    private boolean _annotatedField;
+
+    public void doNothingParentMethod()
+    {
+
+    }
+
+    public void _$conflictMethod()
+    {
+
+    }
+
+    public String get$conflictField()
+    {
+        return _$conflictField;
+    }
+
+    public void set$conflictField(String field)
+    {
+        _$conflictField = field;
+    }
+
+    public boolean isAnnotatedField()
+    {
+        return _annotatedField;
+    }
+
+    public void setAnnotatedField(boolean annotatedField)
+    {
+        _annotatedField = annotatedField;
+    }
+
+    public int getParentField()
+    {
+        return _parentField;
+    }
+
+    public void setParentField(int parentField)
+    {
+        _parentField = parentField;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ReadOnlyBean.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ReadOnlyBean.java
new file mode 100644
index 0000000..9e8480c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/ReadOnlyBean.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+public class ReadOnlyBean
+{
+    private String _value;
+
+    public String getValue()
+    {
+        return _value;
+    }
+
+    public void setValue(String value)
+    {
+        _value = value;
+    }
+
+    public String getReadOnly()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/StateHolder.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/StateHolder.java
new file mode 100644
index 0000000..3cc75fc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/StateHolder.java
@@ -0,0 +1,42 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotation.ApplicationState;
+import org.apache.tapestry.internal.services.SimpleASO;
+
+public class StateHolder
+{
+    @ApplicationState
+    private SimpleASO bean;
+
+    private boolean beanExists;
+
+    public SimpleASO getBean()
+    {
+        return bean;
+    }
+
+    public void setBean(SimpleASO bean)
+    {
+        this.bean = bean;
+    }
+
+    public boolean getBeanExists()
+    {
+        return beanExists;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java
new file mode 100644
index 0000000..c1857b1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObject.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+/**

+ * An empty object to which fields, methods and interfaces are added.

+ */

+public class TargetObject

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObjectSubclass.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObjectSubclass.java
new file mode 100644
index 0000000..49a3c09
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/transform/pages/TargetObjectSubclass.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.transform.pages;

+

+/**

+ * A subclass for TargetObject, used to check that values can be inherited from a base class.

+ */

+public class TargetObjectSubclass extends TargetObject

+{

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java
new file mode 100644
index 0000000..78289a5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/Base64Tests.java
@@ -0,0 +1,118 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;

+import org.testng.Assert;

+import org.testng.annotations.Test;

+

+import java.io.EOFException;

+import java.io.InputStream;

+import java.io.ObjectInputStream;

+import java.io.ObjectOutputStream;

+import java.util.Map;

+

+/**

+ * Tests for {@link Base64InputStream} and {@link Base64OutputStream}, etc.

+ */

+public class Base64Tests extends Assert

+{

+    @SuppressWarnings("unchecked")

+    @Test

+    public void round_trip_is_equal() throws Exception

+    {

+        Map input = newMap();

+

+        input.put("fred", "flintstone");

+        input.put("barney", "rubble");

+

+        Base64OutputStream bos = new Base64OutputStream();

+        ObjectOutputStream oos = new ObjectOutputStream(bos);

+

+        oos.writeObject(input);

+

+        oos.close();

+

+        String base64 = bos.toBase64();

+

+        InputStream is = new Base64InputStream(base64);

+        ObjectInputStream ois = new ObjectInputStream(is);

+

+        Map output = (Map) ois.readObject();

+

+        assertEquals(output, input);

+        assertNotSame(output, input);

+    }

+

+    @Test

+    @SuppressWarnings("unchecked")

+    public void round_trip_is_equal_via_object_wrappers() throws Exception

+    {

+        Map input = newMap();

+

+        input.put("fred", "flintstone");

+        input.put("barney", "rubble");

+

+        Base64ObjectOutputStream os = new Base64ObjectOutputStream();

+

+        os.writeObject(input);

+

+        os.close();

+

+        String base64 = os.toBase64();

+

+        ObjectInputStream ois = new Base64ObjectInputStream(base64);

+

+        Map output = (Map) ois.readObject();

+

+        assertEquals(output, input);

+        assertNotSame(output, input);

+    }

+

+    @Test

+    public void checks_for_eof() throws Exception

+    {

+        String[] values = {"fred", "barney", "wilma"};

+

+        Base64ObjectOutputStream os = new Base64ObjectOutputStream();

+

+        for (String value : values)

+            os.writeObject(value);

+

+        os.close();

+

+        String base64 = os.toBase64();

+

+        ObjectInputStream ois = new Base64ObjectInputStream(base64);

+

+        for (int i = 0; i < 3; i++)

+        {

+            String value = (String) ois.readObject();

+

+            assertEquals(value, values[i]);

+        }

+

+        try

+        {

+            ois.readObject();

+            fail("Unreachable.");

+        }

+        catch (EOFException ex)

+        {

+            // Expected.

+        }

+

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/IntegerRangeTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/IntegerRangeTest.java
new file mode 100644
index 0000000..7f101ee
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/IntegerRangeTest.java
@@ -0,0 +1,142 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Iterator;
+
+public class IntegerRangeTest extends Assert
+{
+    @Test
+    public void start_less_than_finish()
+    {
+        IntegerRange r = new IntegerRange(1, 3);
+
+        assertEquals(r.toString(), "1..3");
+
+        assertEquals(r.getStart(), 1);
+        assertEquals(r.getFinish(), 3);
+
+        Iterator<Integer> i = r.iterator();
+
+        assertEquals(i.next().intValue(), 1);
+        assertEquals(i.next().intValue(), 2);
+
+        assertTrue(i.hasNext());
+
+        assertEquals(i.next().intValue(), 3);
+
+        assertFalse(i.hasNext());
+
+        try
+        {
+            i.next();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+        }
+    }
+
+    @Test
+    public void start_same_as_finish()
+    {
+        IntegerRange r = new IntegerRange(3, 3);
+
+        Iterator<Integer> i = r.iterator();
+
+        assertTrue(i.hasNext());
+
+        assertEquals(i.next().intValue(), 3);
+
+        assertFalse(i.hasNext());
+    }
+
+    @Test
+    public void finish_less_than_start()
+    {
+        IntegerRange r = new IntegerRange(3, 1);
+
+        assertEquals(r.toString(), "3..1");
+
+        Iterator<Integer> i = r.iterator();
+
+        assertEquals(i.next().intValue(), 3);
+        assertEquals(i.next().intValue(), 2);
+
+        assertTrue(i.hasNext());
+
+        assertEquals(i.next().intValue(), 1);
+
+        assertFalse(i.hasNext());
+
+        try
+        {
+            i.next();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+        }
+    }
+
+    @Test
+    public void hash_code_and_equals()
+    {
+        IntegerRange r1 = new IntegerRange(1, 100);
+        IntegerRange r2 = new IntegerRange(1, 100);
+        IntegerRange r3 = new IntegerRange(1, 10);
+
+        assertEquals(r1.hashCode(), r2.hashCode());
+        assertFalse(r1.hashCode() == r3.hashCode());
+
+        assertTrue(r1.equals(r1));
+        assertEquals(r1, r2);
+
+        assertFalse(r1.equals(r3));
+        assertFalse(r1.equals(this));
+        assertFalse(r1.equals(null));
+        assertFalse(r1.equals(new IntegerRange(3, 30)));
+    }
+
+    @Test
+    public void iterator_remove_not_supported()
+    {
+        IntegerRange r = new IntegerRange(1, 3);
+
+        Iterator<Integer> i = r.iterator();
+
+        assertEquals(i.next(), new Integer(1));
+
+        try
+        {
+            i.remove();
+            unreachable();
+        }
+        catch (UnsupportedOperationException ex)
+        {
+            // Expected, ignored.
+        }
+
+        assertEquals(i.next(), new Integer(2));
+    }
+
+    private final void unreachable()
+    {
+        throw new AssertionError("This code should be unreachable.");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java
new file mode 100644
index 0000000..d5713ef
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MethodInvocationBuilderTest.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;

+

+import org.apache.tapestry.MarkupWriter;

+import org.apache.tapestry.services.ClassTransformation;

+import org.apache.tapestry.services.TransformMethodSignature;

+import org.apache.tapestry.test.TapestryTestCase;

+import org.testng.annotations.Test;

+

+import java.lang.reflect.Modifier;

+

+public class MethodInvocationBuilderTest extends TapestryTestCase

+{

+    private static final String LOCALE_CLASS_NAME = "java.util.Locale";

+

+    private static final String MARKUP_WRITER_CLASS_NAME = MarkupWriter.class.getName();

+

+    @Test

+    public void known_parameter_type()

+    {

+        ClassTransformation transformation = mockClassTransformation();

+

+        replay();

+

+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "void", "myMethod",

+                                                                    new String[]{MARKUP_WRITER_CLASS_NAME}, null);

+

+        MethodInvocationBuilder invoker = new MethodInvocationBuilder();

+

+        invoker.addParameter(MARKUP_WRITER_CLASS_NAME, "$1");

+

+        assertEquals(invoker.buildMethodInvocation(sig, transformation), "myMethod($1)");

+

+        verify();

+    }

+

+    @Test

+    public void unknown_parameter_type()

+    {

+        ClassTransformation transformation = mockClassTransformation();

+

+        replay();

+

+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "void", "myMethod",

+                                                                    new String[]{MARKUP_WRITER_CLASS_NAME}, null);

+

+        MethodInvocationBuilder invoker = new MethodInvocationBuilder();

+

+        assertEquals(invoker.buildMethodInvocation(sig, transformation), "myMethod(null)");

+

+        verify();

+    }

+

+    @Test

+    public void multiple_parameters_for_method()

+    {

+        ClassTransformation transformation = mockClassTransformation();

+

+        replay();

+

+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "void", "myMethod", new String[]{

+                MARKUP_WRITER_CLASS_NAME, LOCALE_CLASS_NAME}, null);

+

+        MethodInvocationBuilder invoker = new MethodInvocationBuilder();

+

+        invoker.addParameter(MARKUP_WRITER_CLASS_NAME, "$1");

+        invoker.addParameter(LOCALE_CLASS_NAME, "$2");

+

+        assertEquals(invoker.buildMethodInvocation(sig, transformation), "myMethod($1, $2)");

+

+        verify();

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MultiKeyTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MultiKeyTest.java
new file mode 100644
index 0000000..881b59c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/MultiKeyTest.java
@@ -0,0 +1,75 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class MultiKeyTest extends Assert
+{
+    @Test
+    public void same_values_same_hash_codes()
+    {
+        MultiKey key1 = new MultiKey(1, 3, "foo");
+        MultiKey key2 = new MultiKey(1, 3, "foo");
+        MultiKey key3 = new MultiKey(1, 3);
+        MultiKey key4 = new MultiKey(1, 3, "bar");
+        MultiKey key5 = new MultiKey(1, 3, "foo", "bar");
+
+        assertEquals(key2.hashCode(), key1.hashCode());
+        assertFalse(key3.hashCode() == key1.hashCode());
+        assertFalse(key4.hashCode() == key1.hashCode());
+        assertFalse(key5.hashCode() == key1.hashCode());
+    }
+
+    @Test
+    public void comparisons_against_not_multi_key()
+    {
+        MultiKey key = new MultiKey(1, 3, "foo");
+
+        assertFalse(key.equals(null));
+        assertFalse(key.equals("foo"));
+    }
+
+    @Test
+    public void comparison_against_self()
+    {
+        MultiKey key = new MultiKey(1, 3, "foo");
+
+        assertTrue(key.equals(key));
+    }
+
+    @Test
+    public void comparisons_against_other_keys()
+    {
+        MultiKey key1 = new MultiKey(1, 3, "foo");
+        MultiKey key2 = new MultiKey(1, 3, "foo");
+        MultiKey key3 = new MultiKey(1, 3);
+        MultiKey key4 = new MultiKey(1, 3, "bar");
+        MultiKey key5 = new MultiKey(1, 3, "foo", "bar");
+
+        assertEquals(key2, key1);
+        assertFalse(key3.equals(key1));
+        assertFalse(key4.equals(key1));
+        assertFalse(key5.equals(key1));
+    }
+
+    @Test
+    public void to_string()
+    {
+        assertEquals(new MultiKey("fred").toString(), "MultiKey[fred]");
+        assertEquals(new MultiKey("fred", "barney").toString(), "MultiKey[fred, barney]");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/NotificationEventCallbackTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/NotificationEventCallbackTest.java
new file mode 100644
index 0000000..3523a47
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/NotificationEventCallbackTest.java
@@ -0,0 +1,77 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.runtime.Component;
+import org.testng.annotations.Test;
+
+public class NotificationEventCallbackTest extends InternalBaseTestCase
+{
+    private static final String EVENT_TYPE = "myEventType";
+
+    private static final String COMPLETE_ID = "foo.bar.baz";
+
+    private static final String METHOD = "foo.components.Baz.bar()";
+
+    @Test
+    public void true_is_allowed()
+    {
+        Component component = mockComponent();
+
+        replay();
+
+        NotificationEventCallback callback = new NotificationEventCallback(EVENT_TYPE, COMPLETE_ID);
+
+        assertTrue(callback.handleResult(Boolean.TRUE));
+
+        verify();
+    }
+
+    @Test
+    public void false_is_allowed()
+    {
+        Component component = mockComponent();
+
+        replay();
+
+        NotificationEventCallback callback = new NotificationEventCallback(EVENT_TYPE, COMPLETE_ID);
+
+        assertFalse(callback.handleResult(Boolean.FALSE));
+
+        verify();
+    }
+
+    @Test
+    public void other_values_force_exception()
+    {
+        String result = "*RESULT*";
+
+        NotificationEventCallback callback = new NotificationEventCallback(EVENT_TYPE, COMPLETE_ID);
+
+        try
+        {
+            callback.handleResult(result);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertMessageContains(ex,
+                                  "Event 'myEventType' from foo.bar.baz received an event handler method return value of *RESULT*.",
+                                  "This type of event does not support return values from event handler methods.");
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/URLChangeTrackerTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/URLChangeTrackerTest.java
new file mode 100644
index 0000000..c55a813
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/internal/util/URLChangeTrackerTest.java
@@ -0,0 +1,193 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.util;
+
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.net.URL;
+
+public class URLChangeTrackerTest extends TapestryTestCase
+{
+    @Test
+    public void contains_change_when_empty()
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        assertFalse(t.containsChanges());
+    }
+
+    @Test
+    public void add_null_returns_zero()
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        assertEquals(t.add(null), 0l);
+    }
+
+    @Test
+    public void contains_changes() throws Exception
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        File f = File.createTempFile("changetracker0", ".tmp");
+        URL url = f.toURL();
+
+        t.add(url);
+
+        // The file, and the directory containing the file.
+
+        assertEquals(t.trackedFileCount(), 2);
+
+        assertFalse(t.containsChanges());
+
+        boolean changed = false;
+
+        // Because of clock accuracy, we need to try a couple of times
+        // to ensure that the change to the file is visible in the
+        // lastUpdated time stamp on the URL.
+
+        for (int i = 0; i < 10 && !changed; i++)
+        {
+            Thread.sleep(100);
+
+            touch(f);
+
+            changed = t.containsChanges();
+        }
+
+        assertTrue(changed);
+
+        // And, once a change has been observed ...
+
+        assertFalse(t.containsChanges());
+    }
+
+    @Test
+    public void creating_a_new_file_is_a_change() throws Exception
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        File f = File.createTempFile("changetracker0", ".tmp");
+        URL url = f.toURL();
+
+        t.add(url);
+
+        assertFalse(t.containsChanges());
+
+        File dir = f.getParentFile();
+
+        // Create another file in the temporary directory.
+
+        long timestamp = dir.lastModified();
+
+        while (true)
+        {
+            File.createTempFile("changetracker1", ".tmp");
+
+            if (dir.lastModified() != timestamp) break;
+
+            // Sometime Java need a moment to catch up in terms of
+            // file system changes. Sleep for a few milliseconds
+            // and wait for it to catch up.
+
+            Thread.sleep(100);
+        }
+
+        assertTrue(t.containsChanges());
+    }
+
+    @Test
+    public void non_file_URLs_are_ignored() throws Exception
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        URL url = new URL("ftp://breeblebrox.com");
+
+        t.add(url);
+
+        assertEquals(t.trackedFileCount(), 0);
+    }
+
+    @Test
+    public void caching() throws Exception
+    {
+        URLChangeTracker t = new URLChangeTracker();
+
+        File f = File.createTempFile("changetracker0", ".tmp");
+        URL url = f.toURL();
+
+        long initial = t.add(url);
+
+        touch(f);
+
+        long current = t.add(url);
+
+        assertEquals(current, initial);
+
+        assertTrue(t.containsChanges());
+
+        t.clear();
+
+        current = t.add(url);
+
+        assertFalse(current == initial);
+    }
+
+    @Test
+    public void deleted_files_show_as_changes() throws Exception
+    {
+        File f = File.createTempFile("changetracker0", ".tmp");
+        URL url = f.toURL();
+
+        URLChangeTracker t = new URLChangeTracker();
+
+        long timeModified = t.add(url);
+
+        assertTrue(timeModified > 0);
+
+        // File + Directory
+        assertEquals(t.trackedFileCount(), 2);
+
+        assertFalse(t.containsChanges());
+
+        assertTrue(f.delete());
+
+        assertTrue(t.containsChanges());
+    }
+
+    @Test
+    public void second_level_granularity() throws Exception
+    {
+        URLChangeTracker t = new URLChangeTracker(true);
+
+        File f = File.createTempFile("changetracker0", ".tmp");
+        URL url = f.toURL();
+
+        touch(f);
+        long timestamp1 = t.add(url);
+        assertEquals(0, timestamp1 % 1000);
+        assertFalse(t.containsChanges());
+
+        Thread.sleep(1500);
+
+        touch(f);
+        long timestamp2 = t.add(url);
+        assertEquals(0, timestamp2 % 1000);
+        assertTrue(t.containsChanges());
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/AliasContributionTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/AliasContributionTest.java
new file mode 100644
index 0000000..cb894e9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/AliasContributionTest.java
@@ -0,0 +1,67 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class AliasContributionTest extends TapestryTestCase
+{
+    @Test
+    public void default_for_mode()
+    {
+        Runnable r = mockRunnable();
+
+        replay();
+
+        AliasContribution contribution = AliasContribution.create(Runnable.class, r);
+
+        assertSame(contribution.getContributionType(), Runnable.class);
+        assertEquals(contribution.getMode(), "");
+        assertSame(contribution.getObject(), r);
+
+        verify();
+    }
+
+    @Test
+    public void specific_mode()
+    {
+        Runnable r = mockRunnable();
+
+        replay();
+
+        AliasContribution contribution = new AliasContribution<Runnable>(Runnable.class, "mode", r);
+
+        assertEquals(contribution.getContributionType(), Runnable.class);
+        assertEquals(contribution.getMode(), "mode");
+        assertSame(contribution.getObject(), r);
+
+        verify();
+    }
+
+    @Test
+    public void to_string()
+    {
+        AliasContribution contribution = AliasContribution.create(String.class, "FRED");
+
+        assertEquals(contribution.toString(), "<AliasContribution: java.lang.String FRED>");
+
+        contribution = new AliasContribution<String>(String.class, "servlet", "FRED");
+
+        assertEquals(
+                contribution.toString(),
+                "<AliasContribution: java.lang.String mode:servlet FRED>");
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java
new file mode 100644
index 0000000..ee17d9b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/SyncCostBench.java
@@ -0,0 +1,211 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.services;

+

+import org.apache.tapestry.ioc.internal.util.ConcurrentBarrier;

+

+import static java.lang.String.format;

+import static java.lang.System.out;

+import java.util.concurrent.locks.ReadWriteLock;

+import java.util.concurrent.locks.ReentrantReadWriteLock;

+

+/**

+ * Tests single-thread synchronization overhead using different techniques. Note that we're fudging things a bit by

+ * getting a read lock for a write operation .... it's just that I'm more concerned about read locks (which will be very

+ * common) than about write locks (very rare). Another concern is that hotspot is going to mess up our synchronization

+ * when it see we're not really doing anything multi-threaded.

+ * <p/>

+ * The results show that using the {@link org.apache.tapestry.internal.annotations.Concurrent} aspect (which used a

+ * {@link java.util.concurrent.locks.ReentrantReadWriteLock} under the covers) is about 4x as expensive as just using

+ * the synchronized keyword. There are some anomolous results ... for example, ReadWriteLockRunner is consistently

+ * slower than ReadWriteLockAspectRunner (one would expect it to be the other way around ... must be something about how

+ * AspectJ weaves the code ... and it's use of static methods in many cases).

+ * <p/>

+ * Well, the Concurrent aspect is gone, replaced with the {@link ConcurrentBarrier} utility.

+ */

+public class SyncCostBench

+{

+    /**

+     * Calculates a fibunacci series.

+     */

+    static class Worker implements Runnable

+    {

+        private long[] series = { 1, 1 };

+

+        public void run()

+        {

+            long value = series[0] + series[1];

+

+            // Now shift the values down to prepare for the next iteration.

+

+            series[0] = series[1];

+            series[1] = value;

+        }

+    }

+

+    static class SimpleRunner implements Runnable

+    {

+        private final Runnable delegate;

+

+        public SimpleRunner(Runnable delegate)

+        {

+            this.delegate = delegate;

+        }

+

+        public void run()

+        {

+            delegate.run();

+        }

+    }

+

+    static class SynchronizedRunner implements Runnable

+    {

+        private final Runnable delegate;

+

+        public SynchronizedRunner(Runnable delegate)

+        {

+            this.delegate = delegate;

+        }

+

+        public synchronized void run()

+        {

+            delegate.run();

+        }

+    }

+

+    static class ReadWriteLockAspectRunner implements Runnable

+    {

+        private final ConcurrentBarrier barrier = new ConcurrentBarrier();

+

+        private final Runnable delegate;

+

+        public ReadWriteLockAspectRunner(Runnable delegate)

+        {

+            this.delegate = delegate;

+        }

+

+        public void run()

+        {

+            barrier.withRead(delegate);

+        }

+    }

+

+    static class ReadWriteLockRunner implements Runnable

+    {

+        private final Runnable delegate;

+

+        private final ReadWriteLock lock = new ReentrantReadWriteLock();

+

+        public ReadWriteLockRunner(Runnable delegate)

+        {

+            this.delegate = delegate;

+        }

+

+        public void run()

+        {

+

+            try

+            {

+                lock.readLock().lock();

+

+                delegate.run();

+            }

+            finally

+            {

+                lock.readLock().unlock();

+            }

+

+        }

+    }

+

+    private static final int WARMUP_BLOCK_SIZE = 1000;

+

+    private static final int BLOCK_SIZE = 5 * 1000 * 1000;

+

+    static class BlockRunner implements Runnable

+    {

+        private final Runnable delegate;

+

+        private final int blockSize;

+

+        public BlockRunner(int blockSize, Runnable delegate)

+        {

+            this.blockSize = blockSize;

+            this.delegate = delegate;

+        }

+

+        public void run()

+        {

+            for (int i = 0; i < blockSize; i++)

+                delegate.run();

+        }

+    }

+

+    public static void main(String[] args) throws Exception

+    {

+        Runnable simple = new SimpleRunner(new Worker());

+        Runnable synched = new SynchronizedRunner(new Worker());

+        Runnable rw = new ReadWriteLockRunner(new Worker());

+        Runnable aspect = new ReadWriteLockAspectRunner(new Worker());

+

+        out.println(format("%40s %9s %9s %9s", ",simple", ",synched", ",rw", ",aspect"));

+

+        stage("warmup");

+

+        go(WARMUP_BLOCK_SIZE, simple);

+        go(WARMUP_BLOCK_SIZE, synched);

+        go(WARMUP_BLOCK_SIZE, rw);

+        go(WARMUP_BLOCK_SIZE, aspect);

+

+        out.println();

+

+        for (int i = 0; i < 10; i++)

+        {

+            Thread.sleep(5 * 1000);

+            System.gc();

+

+            stage(format("stage #%d", i + 1));

+            go(BLOCK_SIZE, simple);

+            go(BLOCK_SIZE, synched);

+            go(BLOCK_SIZE, rw);

+            go(BLOCK_SIZE, aspect);

+

+            out.println();

+        }

+    }

+

+    private static void stage(String name)

+    {

+        out.print(format("%30s", name));

+    }

+

+    private static void go(int blockSize, Runnable runner) throws InterruptedException

+    {

+

+        Thread t = new Thread(new BlockRunner(blockSize, runner));

+

+        long tick = System.nanoTime();

+

+        t.start();

+

+        // Now wait for it to finish.

+

+        t.join();

+

+        long tock = System.nanoTime();

+

+        out.print(format(",%9d", tock - tick));

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformMethodSignatureTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformMethodSignatureTest.java
new file mode 100644
index 0000000..d5e8eca
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformMethodSignatureTest.java
@@ -0,0 +1,187 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class TransformMethodSignatureTest extends Assert
+{
+
+    @Test
+    public void signature_toString()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething",
+                                                                    new String[]
+                                                                            {"java.lang.String", "int"}, new String[]
+                {"java.lang.RuntimeException", "org.foo.FredException"});
+
+        assertEquals(
+                sig.toString(),
+                "public int doSomething(java.lang.String, int) throws java.lang.RuntimeException, org.foo.FredException");
+
+        sig = new TransformMethodSignature(Modifier.ABSTRACT + Modifier.PROTECTED, "boolean", "misoHapi",
+                                           new String[0], new String[0]);
+
+        assertEquals(sig.toString(), "protected abstract boolean misoHapi()");
+    }
+
+    @Test
+    public void medium_description()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething",
+                                                                    new String[]
+                                                                            {"java.lang.String", "int"}, new String[]
+                {"java.lang.RuntimeException", "org.foo.FredException"});
+
+        assertEquals(sig.getMediumDescription(), "doSomething(java.lang.String, int)");
+    }
+
+    @Test
+    public void package_private_toString()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature(0, "int", "packagePrivate", null, null);
+
+        assertEquals(sig.toString(), "int packagePrivate()");
+    }
+
+    @Test
+    public void null_value_for_parameters_and_exceptions()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething", null, null);
+
+        assertEquals(sig.toString(), "public int doSomething()");
+
+        assertEquals(sig.getParameterTypes(), new String[0]);
+        assertEquals(sig.getExceptionTypes(), new String[0]);
+    }
+
+    @Test
+    public void getters()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething",
+                                                                    new String[]
+                                                                            {"java.lang.String", "int"}, new String[]
+                {"java.lang.RuntimeException", "org.foo.FredException"});
+
+        assertEquals(sig.getModifiers(), Modifier.PUBLIC);
+        assertEquals(sig.getReturnType(), "int");
+        assertEquals(sig.getMethodName(), "doSomething");
+        assertEquals(sig.getParameterTypes(), new String[]
+                {"java.lang.String", "int"});
+        assertEquals(sig.getExceptionTypes(), new String[]
+                {"java.lang.RuntimeException", "org.foo.FredException"});
+    }
+
+    @Test
+    public void sorting()
+    {
+        TransformMethodSignature foo = new TransformMethodSignature(Modifier.PUBLIC, "void", "foo", null, null);
+        TransformMethodSignature bar = new TransformMethodSignature(Modifier.PUBLIC, "void", "bar", null, null);
+        TransformMethodSignature baz0 = new TransformMethodSignature(Modifier.PUBLIC, "void", "baz", null, null);
+        TransformMethodSignature baz1 = new TransformMethodSignature(Modifier.PUBLIC, "void", "baz", new String[]
+                {"int"}, null);
+
+        List<TransformMethodSignature> list = CollectionFactory.newList(Arrays.asList(foo, bar, baz0, baz1));
+
+        Collections.sort(list);
+
+        assertEquals(list, Arrays.asList(bar, baz1, baz0, foo));
+    }
+
+    @Test
+    public void hash_code_and_equals()
+    {
+        TransformMethodSignature sig1 = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething",
+                                                                     new String[]
+                                                                             {"int"}, new String[]
+                {"org.foo.BarException"});
+        int hashCode1 = sig1.hashCode();
+
+        // Check that same value returned each time.
+
+        assertEquals(sig1.hashCode(), hashCode1);
+
+        TransformMethodSignature sig2 = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething",
+                                                                     new String[]
+                                                                             {"int"}, new String[]
+                {"org.foo.BarException"});
+
+        assertEquals(sig2.hashCode(), hashCode1);
+        assertEquals(sig2, sig1);
+
+        // Now work through the different properties, changing each one.
+
+        sig2 = new TransformMethodSignature(Modifier.PRIVATE, "int", "doSomething", new String[]
+                {"int"}, new String[]
+                {"org.foo.BarException"});
+
+        assertFalse(sig2.hashCode() == hashCode1);
+        assertFalse(sig2.equals(sig1));
+
+        sig2 = new TransformMethodSignature(Modifier.PUBLIC, "long", "doSomething", new String[]
+                {"int"}, new String[]
+                {"org.foo.BarException"});
+
+        assertFalse(sig2.hashCode() == hashCode1);
+        assertFalse(sig2.equals(sig1));
+
+        sig2 = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomethingElse", new String[]
+                {"int"}, new String[]
+                {"org.foo.BarException"});
+
+        assertFalse(sig2.hashCode() == hashCode1);
+        assertFalse(sig2.equals(sig1));
+
+        sig2 = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething", new String[]
+                {"long"}, new String[]
+                {"org.foo.BarException"});
+
+        assertFalse(sig2.hashCode() == hashCode1);
+        assertFalse(sig2.equals(sig1));
+
+        sig2 = new TransformMethodSignature(Modifier.PUBLIC, "int", "doSomething", new String[]
+                {"int"}, new String[0]);
+
+        assertFalse(sig2.hashCode() == hashCode1);
+        assertFalse(sig2.equals(sig1));
+
+        // Other equality checks
+
+        assertFalse(sig1.equals(null));
+        assertFalse(sig1.equals(""));
+    }
+
+    /**
+     * Tests the simple, no arguments constructor.
+     */
+    @Test
+    public void short_constructor()
+    {
+        TransformMethodSignature sig = new TransformMethodSignature("pageLoad");
+
+        assertEquals(sig.getModifiers(), Modifier.PUBLIC);
+        assertEquals(sig.getReturnType(), "void");
+        assertEquals(sig.getMethodName(), "pageLoad");
+        assertEquals(sig.getParameterTypes(), new String[0]);
+        assertEquals(sig.getExceptionTypes(), new String[0]);
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java
new file mode 100644
index 0000000..fab6efb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/services/TransformUtilsTest.java
@@ -0,0 +1,63 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.services;

+

+import static org.apache.tapestry.services.TransformUtils.*;

+import org.testng.Assert;

+import org.testng.annotations.Test;

+

+import java.util.Map;

+

+/**

+ *

+ */

+public class TransformUtilsTest extends Assert

+{

+    @Test

+    public void wrapper_type_by_name()

+    {

+        assertEquals(getWrapperTypeName("char"), "java.lang.Character");

+        assertEquals(getWrapperTypeName("java.util.Map"), "java.util.Map");

+    }

+

+    @Test

+    public void wrapper_type_by_class()

+    {

+        assertEquals(getWrapperType(char.class), Character.class);

+        assertEquals(getWrapperType(Map.class), Map.class);

+    }

+

+    @Test

+    public void default_value()

+    {

+        assertEquals(getDefaultValue("long"), "0L");

+        assertEquals(getDefaultValue("java.util.Map"), "null");

+    }

+

+    @Test

+    public void is_primitive()

+    {

+        assertTrue(isPrimitive("int"));

+        assertFalse(isPrimitive("java.lang.Integer"));

+    }

+

+    @Test

+    public void unwrapper_method_name()

+    {

+        assertEquals(getUnwrapperMethodName("boolean"), "booleanValue");

+        assertEquals(getUnwrapperMethodName("int"), "intValue");

+        assertNull(getUnwrapperMethodName("java.lang.Integer"));

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java
new file mode 100644
index 0000000..8be5a81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/DefaultPrimaryKeyEncoderTest.java
@@ -0,0 +1,195 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+public class DefaultPrimaryKeyEncoderTest extends InternalBaseTestCase
+{
+    static class IntStringEncoder extends DefaultPrimaryKeyEncoder<Integer, String>
+    {
+
+    }
+
+    ;
+
+    private final int FRED_ID = 1;
+
+    private final String FRED = "FRED";
+
+    private final int BARNEY_ID = 2;
+
+    private final String BARNEY = "BARNEY";
+
+    private final int WILMA_ID = 3;
+
+    private final String WILMA = "WILMA";
+
+    @Test
+    public void empty_encoder_has_no_values()
+    {
+        IntStringEncoder encoder = new IntStringEncoder();
+
+        assertTrue(encoder.getValues().isEmpty());
+    }
+
+    @Test
+    public void keys_must_be_unique()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        try
+        {
+            encoder.add(FRED_ID, "NewFred");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Key 1 may not be added with value NewFred, as an existing value, FRED, is already present.");
+        }
+    }
+
+    @Test
+    public void extract_key_for_missing_value()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        try
+        {
+            encoder.toKey("BETTY");
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Key for value BETTY not found. Available values: BARNEY, FRED, WILMA");
+        }
+    }
+
+    @Test
+    public void value_orderer_maintained()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertEquals(encoder.getValues(), Arrays.asList(BARNEY, FRED, WILMA));
+    }
+
+    @Test
+    public void value_to_key()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertEquals(encoder.toKey(FRED).intValue(), FRED_ID);
+        assertEquals(encoder.toKey(BARNEY).intValue(), BARNEY_ID);
+    }
+
+    @Test
+    public void known_key_to_value()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertEquals(encoder.toValue(FRED_ID), FRED);
+        assertEquals(encoder.toValue(BARNEY_ID), BARNEY);
+    }
+
+    @Test
+    public void unknown_key_to_value()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertNull(encoder.toValue(99), null);
+    }
+
+    @Test
+    public void missing_key_to_provided_object()
+    {
+        final int bettyId = 5;
+        final String betty = "BETTY";
+
+        IntStringEncoder encoder = new IntStringEncoder()
+        {
+            @Override
+            protected String provideMissingObject(Integer key)
+            {
+                assertEquals(key, new Integer(bettyId));
+
+                return betty;
+            }
+        };
+
+        assertSame(encoder.toValue(bettyId), betty);
+    }
+
+    @Test
+    public void set_delete_false_when_nothing_yet_deleted()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertSame(FRED, encoder.toValue(FRED_ID));
+
+        encoder.setDeleted(false);
+
+        assertEquals(encoder.getValues(), encoder.getAllValues());
+    }
+
+    @Test
+    public void difference_between_get_values_and_get_all_values()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertSame(FRED, encoder.toValue(FRED_ID));
+
+        assertFalse(encoder.isDeleted());
+
+        encoder.setDeleted(true);
+
+        assertTrue(encoder.isDeleted());
+
+        assertEquals(encoder.getValues(), Arrays.asList(BARNEY, WILMA));
+
+        assertEquals(encoder.getAllValues(), Arrays.asList(BARNEY, FRED, WILMA));
+    }
+
+    @Test
+    public void undelete_a_value()
+    {
+        IntStringEncoder encoder = newEncoder();
+
+        assertSame(FRED, encoder.toValue(FRED_ID));
+
+        encoder.setDeleted(true);
+        encoder.setDeleted(false);
+
+        assertEquals(encoder.getValues(), encoder.getAllValues());
+    }
+
+    private IntStringEncoder newEncoder()
+    {
+        IntStringEncoder encoder = new IntStringEncoder();
+
+        encoder.add(BARNEY_ID, BARNEY);
+        encoder.add(FRED_ID, FRED);
+        encoder.add(WILMA_ID, WILMA);
+
+        return encoder;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/EnumSelectModelTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/EnumSelectModelTest.java
new file mode 100644
index 0000000..ac5df14
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/EnumSelectModelTest.java
@@ -0,0 +1,106 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import org.apache.tapestry.OptionModel;
+import org.apache.tapestry.SelectModel;
+import org.apache.tapestry.Stooge;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+public class EnumSelectModelTest extends TapestryTestCase
+{
+    @Test
+    public void generated_labels()
+    {
+        Messages messages = mockMessages();
+        stub_contains(messages, false);
+
+        replay();
+
+        SelectModel model = new EnumSelectModel(Stooge.class, messages);
+
+        List<OptionModel> options = model.getOptions();
+
+        assertEquals(options.size(), 3);
+
+        checkOption(options, 0, "Moe", Stooge.MOE);
+        checkOption(options, 1, "Larry", Stooge.LARRY);
+        checkOption(options, 2, "Curly Joe", Stooge.CURLY_JOE);
+
+        verify();
+    }
+
+    @Test
+    public void prefixed_name_in_message_catalog()
+    {
+        Messages messages = mockMessages();
+        stub_contains(messages, false);
+
+        train_contains(messages, "Stooge.LARRY", true);
+        train_get(messages, "Stooge.LARRY", "Mr. Larry Fine");
+
+        replay();
+
+        SelectModel model = new EnumSelectModel(Stooge.class, messages);
+
+        List<OptionModel> options = model.getOptions();
+
+        assertEquals(options.size(), 3);
+
+        checkOption(options, 0, "Moe", Stooge.MOE);
+        checkOption(options, 1, "Mr. Larry Fine", Stooge.LARRY);
+        checkOption(options, 2, "Curly Joe", Stooge.CURLY_JOE);
+
+        verify();
+    }
+
+    @Test
+    public void unprefixed_name_in_message_catalog()
+    {
+        Messages messages = mockMessages();
+        stub_contains(messages, false);
+
+        train_contains(messages, "MOE", true);
+        train_get(messages, "MOE", "Sir Moe Howard");
+
+        replay();
+
+        SelectModel model = new EnumSelectModel(Stooge.class, messages);
+
+        List<OptionModel> options = model.getOptions();
+
+        assertEquals(options.size(), 3);
+
+        checkOption(options, 0, "Sir Moe Howard", Stooge.MOE);
+        checkOption(options, 1, "Larry", Stooge.LARRY);
+        checkOption(options, 2, "Curly Joe", Stooge.CURLY_JOE);
+
+        verify();
+    }
+
+    private void checkOption(List<OptionModel> options, int i, String label, Stooge value)
+    {
+        OptionModel model = options.get(i);
+
+        assertEquals(model.getLabel(), label);
+        assertFalse(model.isDisabled());
+        assertSame(model.getValue(), value);
+        assertNull(model.getAttributes());
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java
new file mode 100644
index 0000000..442c2ca
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/FindTheParameterizedType.java
@@ -0,0 +1,75 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;

+

+import org.apache.tapestry.ioc.internal.util.Orderer;

+

+import static java.lang.System.out;

+import java.lang.reflect.Method;

+import java.lang.reflect.ParameterizedType;

+import java.lang.reflect.Type;

+import java.util.List;

+import java.util.Map;

+

+public class FindTheParameterizedType

+{

+

+    /**

+     * @param args

+     */

+    public static void main(String[] args) throws Exception

+    {

+        Method m = FindTheParameterizedType.class.getMethod("method", Map.class, List.class);

+

+        out.println(m.toString());

+        out.println(m.toGenericString());

+

+        Type[] types = m.getGenericParameterTypes();

+        ParameterizedType pt = (ParameterizedType) types[0];

+

+        Type keyType = pt.getActualTypeArguments()[0];

+        Type valueType = pt.getActualTypeArguments()[1];

+

+        out.printf("   key type: %s\n", rawType(keyType));

+        out.printf(" value type: %s\n", rawType(valueType));

+

+        Type listType = types[1];

+

+        out.printf("  list type: %s\n", rawType(listType));

+    }

+

+    private static Class rawType(Type type)

+    {

+        if (type instanceof ParameterizedType)

+        {

+            ParameterizedType pt = (ParameterizedType) type;

+

+            return rawType(pt.getRawType());

+        }

+

+        if (type instanceof Class)

+        {

+            return (Class) type;

+        }

+

+        throw new IllegalArgumentException();

+    }

+

+    public void method(Map<String, Orderer<Runnable>> configuration, List list)

+    {

+

+    }

+

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/IdentifyTransformer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/IdentifyTransformer.java
new file mode 100644
index 0000000..768fc4f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/IdentifyTransformer.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;

+

+public class IdentifyTransformer<T> implements Transformer<T>

+{

+    public T transform(T input)

+    {

+        return input;

+    }

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java
new file mode 100644
index 0000000..a974d4b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/StringToEnumCoercionTest.java
@@ -0,0 +1,58 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;
+
+import junit.framework.AssertionFailedError;
+import org.apache.tapestry.Stooge;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class StringToEnumCoercionTest extends Assert
+{
+    @Test
+    public void value_found()
+    {
+        StringToEnumCoercion<Stooge> coercion = new StringToEnumCoercion<Stooge>(Stooge.class);
+
+        assertSame(coercion.coerce("moe"), Stooge.MOE);
+        assertSame(coercion.coerce("curly_joe"), Stooge.CURLY_JOE);
+    }
+
+    @Test
+    public void blank_is_null()
+    {
+        StringToEnumCoercion<Stooge> coercion = new StringToEnumCoercion<Stooge>(Stooge.class);
+
+        assertNull(coercion.coerce(""));
+    }
+
+    @Test
+    public void value_not_found()
+    {
+        StringToEnumCoercion<Stooge> coercion = new StringToEnumCoercion<Stooge>(Stooge.class);
+
+        try
+        {
+            coercion.coerce("shemp");
+            throw new AssertionFailedError("unreachable");
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Input \'shemp\' does not identify a value from enumerated type org.apache.tapestry.Stooge. Available values: CURLY_JOE, LARRY, MOE.");
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/Transformer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/Transformer.java
new file mode 100644
index 0000000..5290b2b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/Transformer.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;

+

+public interface Transformer<T>

+{

+    T transform(T input);

+}

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/UppercaseTransformer.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/UppercaseTransformer.java
new file mode 100644
index 0000000..af0068f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/util/UppercaseTransformer.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.util;

+

+

+public class UppercaseTransformer implements Transformer<String>

+{

+    public String transform(String input)

+    {

+        return input.toUpperCase();

+    }

+}

+

diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxLengthTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxLengthTest.java
new file mode 100644
index 0000000..e69c704
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxLengthTest.java
@@ -0,0 +1,69 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+public class MaxLengthTest extends InternalBaseTestCase
+{
+    @Test
+    public void short_enough() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        String value = "Now the student has become the master.";
+
+        replay();
+
+        MaxLength validator = new MaxLength();
+
+        validator.validate(field, value.length(), formatter, value);
+
+        verify();
+    }
+
+    @Test
+    public void long_value() throws Exception
+    {
+        String label = "My Field";
+        Field field = mockFieldWithLabel(label);
+        MessageFormatter formatter = mockMessageFormatter();
+        String value = "Now the student has become the master.";
+        String message = "{message}";
+        Integer constraint = value.length() - 1;
+
+        train_format(formatter, message, constraint, label);
+
+        replay();
+
+        MaxLength validator = new MaxLength();
+
+        try
+        {
+            validator.validate(field, constraint, formatter, value);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), message);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxTest.java
new file mode 100644
index 0000000..599b01d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MaxTest.java
@@ -0,0 +1,70 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+public class MaxTest extends InternalBaseTestCase
+{
+    @Test
+    public void small_enough() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Long constraint = 50L;
+
+        replay();
+
+        Max validator = new Max();
+
+        for (int value = 48; value <= 50; value++)
+            validator.validate(field, constraint, formatter, value);
+
+        verify();
+    }
+
+    @Test
+    public void value_too_large() throws Exception
+    {
+        String label = "My Field";
+        Field field = mockFieldWithLabel(label);
+        MessageFormatter formatter = mockMessageFormatter();
+        String message = "{message}";
+        Long constraint = 100l;
+        Number value = 101;
+
+        train_format(formatter, message, constraint, label);
+
+        replay();
+
+        Max validator = new Max();
+
+        try
+        {
+            validator.validate(field, constraint, formatter, value);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), message);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinLengthTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinLengthTest.java
new file mode 100644
index 0000000..80a2e9d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinLengthTest.java
@@ -0,0 +1,70 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+public class MinLengthTest extends InternalBaseTestCase
+{
+
+    @Test
+    public void long_enough() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        String value = "Now the student has become the master.";
+
+        replay();
+
+        MinLength validator = new MinLength();
+
+        validator.validate(field, value.length(), formatter, value);
+
+        verify();
+    }
+
+    @Test
+    public void short_value() throws Exception
+    {
+        String label = "My Field";
+        Field field = mockFieldWithLabel(label);
+        MessageFormatter formatter = mockMessageFormatter();
+        String value = "Now the student has become the master.";
+        String message = "{message}";
+        Integer constraint = value.length() + 1;
+
+        train_format(formatter, message, constraint, label);
+
+        replay();
+
+        MinLength validator = new MinLength();
+
+        try
+        {
+            validator.validate(field, constraint, formatter, value);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), message);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinTest.java
new file mode 100644
index 0000000..35dfd78
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/MinTest.java
@@ -0,0 +1,70 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+public class MinTest extends InternalBaseTestCase
+{
+    @Test
+    public void large_enough() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Long constraint = 50L;
+
+        replay();
+
+        Min validator = new Min();
+
+        for (int value = 50; value < 52; value++)
+            validator.validate(field, constraint, formatter, value);
+
+        verify();
+    }
+
+    @Test
+    public void value_too_small() throws Exception
+    {
+        String label = "My Field";
+        Field field = mockFieldWithLabel(label);
+        MessageFormatter formatter = mockMessageFormatter();
+        String message = "{message}";
+        Long constraint = 100l;
+        Number value = 99;
+
+        train_format(formatter, message, constraint, label);
+
+        replay();
+
+        Min validator = new Min();
+
+        try
+        {
+            validator.validate(field, constraint, formatter, value);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), message);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RegexpTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RegexpTest.java
new file mode 100644
index 0000000..47a028c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RegexpTest.java
@@ -0,0 +1,75 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.testng.annotations.Test;
+
+import java.util.regex.Pattern;
+
+/**
+ * These are getting tedious; I'd rather do it via integration tests.
+ */
+public class RegexpTest extends InternalBaseTestCase
+{
+    @Test
+    public void matching_pattern() throws Exception
+    {
+        Field field = mockField();
+        MessageFormatter formatter = mockMessageFormatter();
+        Pattern constraint = Pattern.compile("\\d{4}");
+
+        replay();
+
+        Regexp validator = new Regexp();
+
+        validator.validate(field, constraint, formatter, "1234");
+
+        verify();
+    }
+
+    @Test
+    public void input_mismatch() throws Exception
+    {
+        String label = "My Field";
+        Field field = mockFieldWithLabel(label);
+        MessageFormatter formatter = mockMessageFormatter();
+        String message = "{message}";
+        Pattern constraint = Pattern.compile("\\d{4}");
+        String value = "abc";
+
+        train_format(formatter, message, constraint.toString(), label);
+
+        replay();
+
+        Regexp validator = new Regexp();
+
+        try
+        {
+            validator.validate(field, constraint, formatter, value);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), message);
+        }
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RequiredTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RequiredTest.java
new file mode 100644
index 0000000..4876e03
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry/validator/RequiredTest.java
@@ -0,0 +1,83 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.validator;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.ValidationException;
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class RequiredTest extends TapestryTestCase
+{
+    @Test
+    public void null_value()
+    {
+        Field field = mockFieldWithLabel("My Field");
+        MessageFormatter formatter = mockMessageFormatter();
+
+        train_format(formatter, "{message}", "My Field");
+
+        replay();
+
+        try
+        {
+            new Required().validate(field, null, formatter, null);
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), "{message}");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void blank_value()
+    {
+        MessageFormatter formatter = mockMessageFormatter();
+        Field field = mockFieldWithLabel("My Field");
+
+        train_format(formatter, "{message}", "My Field");
+
+        replay();
+
+        try
+        {
+            new Required().validate(field, null, formatter, "");
+            unreachable();
+        }
+        catch (ValidationException ex)
+        {
+            assertEquals(ex.getMessage(), "{message}");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void non_blank_value() throws Exception
+    {
+        MessageFormatter formatter = mockMessageFormatter();
+        Field field = mockField();
+
+        replay();
+
+        new Required().validate(field, null, formatter, "not null");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
new file mode 100644
index 0000000..fd977d5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
@@ -0,0 +1,387 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.json;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+/**
+ * Tests JSONObject, particularily in terms of parsing and writing JSON streams.
+ */
+public class JSONObjectTest extends Assert
+{
+    @Test
+    public void copy_from_object_constructor()
+    {
+        JSONObject master = new JSONObject().put("fred", "flintstone").put("barney", "rubble");
+
+        JSONObject emptyCopy = new JSONObject(master);
+
+        assertTrue(emptyCopy.keys().isEmpty(), "No properties should have been copied.");
+
+        JSONObject limitedCopy = new JSONObject(master, "fred");
+
+        assertEquals(limitedCopy.keys().size(), 1);
+        assertEquals(limitedCopy.get("fred").toString(), "flintstone");
+
+        JSONObject fullCopy = new JSONObject(master, "fred", "barney");
+
+        assertEquals(fullCopy.toString(), "{\"fred\":\"flintstone\",\"barney\":\"rubble\"}");
+
+        JSONObject limitedCopy2 = new JSONObject(master, "fred", "wilma");
+        assertEquals(limitedCopy2.keys().size(), 1);
+    }
+
+    @Test
+    public void array_from_string()
+    {
+        JSONArray array = new JSONArray("[ 'foo', 'bar', \"baz\" ]");
+
+        assertEquals(array.length(), 3);
+        assertEquals(array.getString(0), "foo");
+        assertEquals(array.getString(1), "bar");
+        assertEquals(array.getString(2), "baz");
+    }
+
+    private void unreachable()
+    {
+        throw new AssertionError("This code should not be reachable.");
+    }
+
+    @Test
+    public void get_not_found()
+    {
+        JSONObject master = new JSONObject().put("fred", "flintstone");
+
+        assertEquals(master.get("fred"), "flintstone");
+
+        try
+        {
+            master.get("barney");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"barney\"] not found.");
+        }
+    }
+
+    @Test(dataProvider = "boolean_inputs")
+    public void get_boolean(Object value, boolean expected)
+    {
+        JSONObject object = new JSONObject().put("mykey", value);
+
+        assertEquals(object.getBoolean("mykey"), expected);
+    }
+
+    @DataProvider(name = "boolean_inputs")
+    public Object[][] boolean_inputs()
+    {
+        return new Object[][] { { "true", true }, { "TRUE", true }, { "false", false }, { "FALSE", false },
+                { Boolean.TRUE, true },
+                { Boolean.FALSE, false } };
+    }
+
+    @Test
+    public void not_a_boolean_value()
+    {
+        JSONObject object = new JSONObject().put("somekey", 37);
+
+        try
+        {
+            object.getBoolean("somekey");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"somekey\"] is not a Boolean.");
+        }
+    }
+
+    @Test
+    public void accumulate_simple_values()
+    {
+        JSONObject object = new JSONObject();
+
+        String key = "key";
+
+        object.accumulate(key, "alpha");
+        object.accumulate(key, "beta");
+        object.accumulate(key, "gamma");
+
+        assertEquals(object.toString(), "{\"key\":[\"alpha\",\"beta\",\"gamma\"]}");
+
+        JSONArray array = object.getJSONArray(key);
+
+        assertEquals(array.length(), 3);
+    }
+
+    @Test
+    public void accumulate_with_initial_array()
+    {
+        JSONArray array = new JSONArray();
+
+        array.put("alpha");
+
+        String key = "key";
+
+        JSONObject object = new JSONObject();
+
+        object.accumulate(key, array);
+        object.accumulate(key, "beta");
+
+        array.put("gamma");
+
+        assertEquals(object.toString(), "{\"key\":[\"alpha\",\"beta\",\"gamma\"]}");
+    }
+
+    @Test
+    public void object_from_string()
+    {
+        JSONObject object = new JSONObject("{ fred: \"flintstone\", caveman: true, friends: [\"barney\"] }");
+
+        assertEquals(object.get("fred"), "flintstone");
+        assertEquals(object.getBoolean("caveman"), true);
+
+        JSONArray array = object.getJSONArray("friends");
+
+        assertEquals(array.length(), 1);
+        assertEquals(array.get(0), "barney");
+    }
+
+    @Test
+    public void append()
+    {
+        JSONObject object = new JSONObject();
+        String key = "fubar";
+
+        object.append(key, "alpha");
+
+        assertEquals(object.toString(), "{\"fubar\":[\"alpha\"]}");
+
+        object.append(key, "beta");
+
+        assertEquals(object.toString(), "{\"fubar\":[\"alpha\",\"beta\"]}");
+    }
+
+    @Test
+    public void append_existng_key_not_an_array()
+    {
+        JSONObject object = new JSONObject();
+        String key = "fubar";
+
+        object.put(key, "existing");
+
+        try
+        {
+            object.append(key, "additional");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"fubar\"] is not a JSONArray.");
+        }
+    }
+
+    @Test(dataProvider = "double_inputs")
+    public void double_to_string(double input, String expected)
+    {
+        String actual = JSONObject.doubleToString(input);
+
+        assertEquals(actual, expected);
+    }
+
+    @DataProvider(name = "double_inputs")
+    public Object[][] double_inputs()
+    {
+        return new Object[][] { { 3d, "3" }, { -22.5d, "-22.5" }, { 0d, "0" }, { Double.NEGATIVE_INFINITY, "null" },
+                { Double.POSITIVE_INFINITY, "null" }, { Double.NaN, "null" }, };
+    }
+
+    @Test(dataProvider = "get_double_inputs")
+    public void get_double(Object value, double expected)
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("key", value);
+
+        assertEquals(object.getDouble("key"), expected);
+    }
+
+    @DataProvider(name = "get_double_inputs")
+    public Object[][] getDoubleInputs()
+    {
+        return new Object[][] { { new Double(3.5), 3.5d }, { new Long(1000), 1000d }, { "-101.7", -101.7d } };
+    }
+
+    @Test
+    public void get_double_not_a_string()
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("notstring", Boolean.FALSE);
+
+        try
+        {
+            object.getDouble("notstring");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"notstring\"] is not a number.");
+        }
+    }
+
+    @Test
+    public void get_double_string_invalid_format()
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("badstring", "google");
+
+        try
+        {
+            object.getDouble("badstring");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"badstring\"] is not a number.");
+        }
+    }
+
+    @Test(dataProvider = "get_int_inputs")
+    public void get_int(Object value, int expected)
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("intkey", value);
+
+        assertEquals(object.getInt("intkey"), expected);
+    }
+
+    @DataProvider(name = "get_int_inputs")
+    public Object[][] get_int_inputs()
+    {
+        return new Object[][] { { "3", 3 }, { new Long(97), 97 }, { "-8.76", -8 } };
+    }
+
+    @Test
+    public void has()
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("fred", "flintstone");
+
+        assertTrue(object.has("fred"));
+        assertFalse(object.has("barney"));
+    }
+
+    @Test
+    public void get_json_array()
+    {
+        JSONArray array = new JSONArray();
+
+        JSONObject object = new JSONObject();
+
+        object.put("arraykey", array);
+        object.put("boolkey", true);
+
+        assertSame(object.getJSONArray("arraykey"), array);
+
+        try
+        {
+            object.getJSONArray("boolkey");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"boolkey\"] is not a JSONArray.");
+        }
+
+    }
+
+    @Test
+    public void get_json_object()
+    {
+        JSONObject child = new JSONObject();
+        JSONObject root = new JSONObject();
+
+        root.put("child", child);
+        root.put("boolkey", false);
+
+        assertSame(root.getJSONObject("child"), child);
+
+        try
+        {
+            root.getJSONObject("boolkey");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "JSONObject[\"boolkey\"] is not a JSONObject.");
+        }
+    }
+
+    @Test
+    public void length()
+    {
+        JSONObject object = new JSONObject();
+
+        assertEquals(object.length(), 0);
+
+        object.put("key", "fred");
+
+        assertEquals(object.length(), 1);
+
+        object.accumulate("key", "barney");
+        assertEquals(object.length(), 1);
+
+        object.put("key2", "wilma");
+
+        assertEquals(object.length(), 2);
+    }
+
+    @Test
+    public void names_is_null_if_no_properties()
+    {
+        JSONObject object = new JSONObject();
+
+        assertNull(object.names());
+    }
+
+    @Test
+    public void names()
+    {
+        JSONObject object = new JSONObject();
+
+        object.put("fred", "flintstone");
+        object.put("barney", "rubble");
+
+        JSONArray array = object.names();
+
+        assertEquals(array.length(), 2);
+
+        Object[] names = array.toArray();
+
+        Arrays.sort(names);
+
+        assertEquals(names, new String[] { "barney", "fred" });
+
+    }
+}
diff --git a/hlship-20080520/tapestry-core/src/test/resources/log4j.properties b/hlship-20080520/tapestry-core/src/test/resources/log4j.properties
new file mode 100644
index 0000000..57e6ee4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/log4j.properties
@@ -0,0 +1,27 @@
+# Copyright 2005, 2006, 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootCategory=INFO, A1
+
+# A1 is set to be a ConsoleAppender. 
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern= %d{HH:mm:ss,SSS} [%p] %c{1} %m%n
+
+log4j.category.org.apache.tapestry.integration.app1=debug
+
+
+
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt
new file mode 100644
index 0000000..347e5f1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/blank_label.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option value="">Make a selection</option><option value="fred">Fred Flintstone</option><option selected="selected" value="barney">Barney Rubble</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/current_selection_from_validation_tracker.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/current_selection_from_validation_tracker.txt
new file mode 100644
index 0000000..bfbc0a8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/current_selection_from_validation_tracker.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option selected="selected" value="fred">Fred Flintstone</option><option value="barney">Barney Rubble</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/disabled_option.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/disabled_option.txt
new file mode 100644
index 0000000..a4cf604
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/disabled_option.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option class="pixie" disabled="disabled" value="fred">Fred</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/just_options.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/just_options.txt
new file mode 100644
index 0000000..5b2171a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/just_options.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option value="fred">Fred Flintstone</option><option selected="selected" value="barney">Barney Rubble</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_attributes.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_attributes.txt
new file mode 100644
index 0000000..ab453ed
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_attributes.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><option class="pixie" value="fred">Fred</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_group_attributes.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_group_attributes.txt
new file mode 100644
index 0000000..f0cff6b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_group_attributes.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><optgroup class="pixie" label="Husbands"><option selected="selected" value="Fred">Fred</option><option value="Barney">Barney</option></optgroup></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups.txt
new file mode 100644
index 0000000..3035c4a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><optgroup label="Husbands"><option selected="selected" value="Fred">Fred</option><option value="Barney">Barney</option></optgroup><optgroup disabled="disabled" label="Wives"><option value="Wilma">Wilma</option><option value="Betty">Betty</option></optgroup></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups_precede_ungroup_options.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups_precede_ungroup_options.txt
new file mode 100644
index 0000000..7d49d8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/corelib/components/option_groups_precede_ungroup_options.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<select><optgroup label="Husbands"><option selected="selected" value="Fred">Fred</option><option value="Barney">Barney</option></optgroup><option value="Wilma">Wilma</option><option value="Betty">Betty</option></select>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/document_with_root_element_and_attributes.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/document_with_root_element_and_attributes.txt
new file mode 100644
index 0000000..6986059
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/document_with_root_element_and_attributes.txt
@@ -0,0 +1 @@
+<has-attributes barney="rubble" fred="flintstone"></has-attributes>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/namespaced_elements.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/namespaced_elements.txt
new file mode 100644
index 0000000..1186a88
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/namespaced_elements.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<f:root xmlns:b="barneyns" xmlns:f="fredns"><f:nested><b:deepest/></f:nested></f:root>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/nested_elements.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/nested_elements.txt
new file mode 100644
index 0000000..3ae42da
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/dom/nested_elements.txt
@@ -0,0 +1 @@
+<population><person first-name="Fred" last-name="Flintstone"></person><person first-name="Barney" last-name="Rubble"></person></population>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/base/GenericEditor.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/base/GenericEditor.tml
new file mode 100644
index 0000000..f655385
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/base/GenericEditor.tml
@@ -0,0 +1,7 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Editor for ${beanType}</h1>
+
+    <form t:id="form"/>
+
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Border.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Border.tml
new file mode 100644
index 0000000..5777171
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Border.tml
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <head>

+        <title>Tapestry Integration Test Application #1</title>

+    </head>

+    <body>

+        <div id="wrap">

+

+            <div id="header">

+                <h1>Tapestry Integration Test Application</h1>

+            </div>

+

+            <div id="content">

+                <div id="topspread">

+                    <t:body/>

+                </div>

+

+

+                <div id="right">

+                    <div class="menu">

+                        <h4>Navigation</h4>

+                        <ul>

+                            <li>

+                                Page:

+                                <span id="activePageName">${componentResources.pageName}</span>

+                            </li>

+                            <li>Access:

+                                <span id="secure">${secure}</span>

+                            </li>

+                            <li>

+                                <t:pagelink page="start">Back to index</t:pagelink>

+                            </li>

+                        </ul>

+

+                        <h4>Fabricated classes:</h4>

+

+                        <dl>

+                            <dt>IOC Layer: ${iocClassFactory.createdClassCount}</dt>

+                            <dd>Service proxies and interceptors</dd>

+

+                            <dt>Component Layer: ${componentClassFactory.createdClassCount}</dt>

+                            <dd>For the most part, this is going to be prop: bindings</dd>

+                        </dl>

+

+                    </div>

+                </div>

+

+                <div id="left">

+                    <h3>Request info:</h3>

+

+                    <t:renderobject object="request"/>

+

+                </div>

+

+

+                <div style="clear:both;"></div>

+

+

+            </div>

+            <div id="footer">

+                &copy; 2008

+                <a href="http://apache.org/">Apache Software Foundation</a>

+            </div>

+

+            <div id="bottom"/>

+

+        </div>

+

+

+    </body>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.tml
new file mode 100644
index 0000000..5f0dfec
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.tml
@@ -0,0 +1,3 @@
+<span xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <t:inner innerValue="inherit:outerValue"/>
+</span>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/OuterAny.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/OuterAny.tml
new file mode 100644
index 0000000..de36e81
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/OuterAny.tml
@@ -0,0 +1,6 @@
+<t:container
+        xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <span t:id="innerAny">
+        <t:body/>
+    </span>
+</t:container>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Recursive.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Recursive.tml
new file mode 100644
index 0000000..9f68845
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Recursive.tml
@@ -0,0 +1,9 @@
+<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+  <p>
+    This component is <t:recursive>recursive</t:recursive>, so we'll see a failure.
+  </p>
+  
+  <t:body/>
+  
+</div>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ActionPage.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ActionPage.tml
new file mode 100644
index 0000000..624a03a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ActionPage.tml
@@ -0,0 +1,15 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+    <p> Choose a number from 1 to 10: </p>
+
+    <p>
+        <t:count  end="10" value="index">
+            <a t:id="choose" t:type="ActionLink" context="index" class="linkClass">${index}</a>
+        </t:count>
+    </p>
+
+    <t:if test="value">
+        <p> <strong>You chose: ${value}</strong>.</p>
+    </t:if>
+
+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.properties
new file mode 100644
index 0000000..246e490
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/AttributeExpansionsDemo.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cssClassPrefix=goober-
+alert=expansions work inside formal component parameters as well
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BadTemplate.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BadTemplate.tml
new file mode 100644
index 0000000..627acb9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BadTemplate.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+    <p>
+        This template is not well formed.</p>

+    

+    <t:foobar>content from template</foobar>

+    

+    <p>
+        This page is used to test exception reporting.
+    </p>

+    

+</html>   
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Barney.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Barney.tml
new file mode 100644
index 0000000..9b01b71
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Barney.tml
@@ -0,0 +1,14 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p>
+        You clicked Barney.
+    </p>
+    
+    <p>
+        In this case, @InjectPage determined the target page via the value attribute of the annotation.
+    </p>
+    
+    <p>
+        [<a t:type="PageLink" t:page="InjectDemo">Back</a>]
+    </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties
new file mode 100644
index 0000000..bd19280
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/BeanEditorDemo.properties
@@ -0,0 +1,17 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+birthYear-label=Year of Birth
+lastName-required-message=Everyone has to have a last name!
+citizen-label=U.S. Citizen
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/CachedPage.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/CachedPage.tml
new file mode 100644
index 0000000..9c62288
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/CachedPage.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+	<h1>@Cached tests</h1>
+	<p>This page tests method result caching.</p>
+	
+	<span id="value">${value}${value}${value}</span>
+	<span id="value2size">${value2.size()}${value2.size()}${value2.size()}</span>
+	
+	${incrWatchValue()}
+	<span class="watch">${value3}</span>
+	<span class="watch">${value3}</span>
+	${incrWatchValue()}
+	<span class="watch">${value3}</span>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Countdown.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Countdown.tml
new file mode 100644
index 0000000..ba70550
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Countdown.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <p>This component demonstrates embedded components defined in the component class using the @Component annotation.

+    </p>

+    <p>Countdown:

+        <div t:id="count" xml:space="preserve">

+            ${countValue}

+        </div>

+    </p>

+

+    <p>

+        Brought to you by the ${component:count} component.

+    </p>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.tml
new file mode 100644
index 0000000..dcd53c1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.tml
@@ -0,0 +1,9 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+
+    <t:RenderableProvider>
+        <p> This page demonstrates how components can use the Environment service, and the @Environmental annotation, to
+            coordinate behavior. </p>
+
+        <p> RenderableUser:[<t:RenderableUser/>]</p>
+    </t:RenderableProvider>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Expansion.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Expansion.tml
new file mode 100644
index 0000000..e779e22
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Expansion.tml
@@ -0,0 +1,7 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    

+    <p>
+        This page contains no components, but does contain a [${expansionValue}].
+    </p>

+

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Fred.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Fred.tml
new file mode 100644
index 0000000..5e123ab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Fred.tml
@@ -0,0 +1,14 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p>
+        You clicked Fred.
+    </p>
+    
+    <p>
+        In this case, @InjectPage determined the target page via the field type.
+    </p>
+    
+    <p>
+        [<a t:type="PageLink" t:page="InjectDemo">Back</a>]
+    </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridEnumDemo.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridEnumDemo.properties
new file mode 100644
index 0000000..f68fcf5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridEnumDemo.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+high=Ultra Important
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridFormDemo.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridFormDemo.properties
new file mode 100644
index 0000000..cfd6b86
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/GridFormDemo.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+high=Top Priority
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.tml
new file mode 100644
index 0000000..851b5eb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.tml
@@ -0,0 +1,5 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:beaneditform t:id="form" object="this"/>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.tml
new file mode 100644
index 0000000..9259b82
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectContainerMismatch.tml
@@ -0,0 +1,7 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p>
+        This page should never be rendered because of the InjectComponent mismatch inside it.
+    </p>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml
new file mode 100644
index 0000000..6c6a4a7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectDemo.tml
@@ -0,0 +1,17 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p> Demonstrates the use of the @Inject annotation. </p>
+    <p>WebRequest: ${request}</p>
+    <p>ComponentResources: ${resources}</p>
+    <p>BindingSource: ${bindingSource}</p>
+    <p>Injected Symbol: ${injectedSymbol}</p>
+    <p>Injection via Marker: ${greeting}</p>
+    
+    
+    <p>
+        ActionLinks used to demonstrate the use of @InjectPage:
+    </p>
+    
+    <p><a t:id="fred" t:type="ActionLink">Fred</a></p>
+    <p><a t:id="barney" t:type="ActionLink">Barney</a></p>
+    <p><a t:id="wilma" t:type="ActionLink">Wilma</a></p>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InstanceMixin.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InstanceMixin.tml
new file mode 100644
index 0000000..d202407
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/InstanceMixin.tml
@@ -0,0 +1,26 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+
+    <p> Date #1: [<t:output 

+        t:mixins="Emphasis" 

+        value="date1" 

+        test="showEmphasis"
+        format="format"/>]
+    </p>

+    

+    <p>
+        Date #2: [<span t:id="output2"/>]  (via @Mixins)
+    </p>

+    

+    <p>
+        Date #3: [<span t:id="output3"/>] (via @MixinClasses)
+    </p>
+
+    <p>
+        <a t:id="toggle" t:type="ActionLink">Toggle emphasis</a>
+    </p>

+    

+    <p>
+        Show emphasis: ${showEmphasis}
+    </p>
+
+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.properties
new file mode 100644
index 0000000..81537f6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.properties
@@ -0,0 +1,16 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+via-inject=Accessed via injected Messages
+via-prefix=Accessed via message: binding prefix
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.tml
new file mode 100644
index 0000000..69d94e2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Localization.tml
@@ -0,0 +1,25 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Localization</h1>
+
+
+    <p>Demonstrates a few ways that component message catalogs can be accessed in code and in the
+        template.
+    </p>
+
+
+    <p>Via injected Messages property: [${injectedMessage}]</p>
+
+    <p>Via message: binding prefix: [${message:via-prefix}]</p>
+
+    <p>From Application Message Catalog: [${message:app-catalog-status}]</p>
+
+    <p>Page locale: [${locale}]</p>
+
+    <p>Request locale: [${request.locale}]</p>
+
+    <a t:type="ActionLink" t:id="french">French</a>
+
+    <a t:type="ActionLink" t:id="english">English</a>
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.tml
new file mode 100644
index 0000000..3d0f099
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/NumberSelect.tml
@@ -0,0 +1,17 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Number Selection</h1>
+    
+    <p>  Demonstration of passivate/activate page logic.</p>
+
+    <p>
+        Select a number from this list:
+        
+        <t:loop  source="1..10" value="index">
+            <t:if  test="notFirst"> - </t:if>
+            <a t:type="ActionLink" t:id="select" context="index">${index}</a>
+        </t:loop> 
+    </p>
+    
+    
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterConflict.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterConflict.tml
new file mode 100644
index 0000000..4be1603
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterConflict.tml
@@ -0,0 +1,8 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+    <p>This component demonstrates that template values are overriden by

+        bindings inside the @Component annotation, in the component class.

+    </p>

+

+    Output:

+    <span t:id="echo" value="literal:TemplateValue"/>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterDefault.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterDefault.tml
new file mode 100644
index 0000000..75c31ff
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ParameterDefault.tml
@@ -0,0 +1,6 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+
+  Echo component default: [<t:echo t:id="echo"/>]
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RegexpDemo.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RegexpDemo.properties
new file mode 100644
index 0000000..73b402e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RegexpDemo.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+zipcode-regexp=\\d{5}(\-\\d{4})?
+zipcode-regexp-message=A zip code consists of five or nine digits, eg: 02134 or 90125-4472.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.tml
new file mode 100644
index 0000000..e5b2c27
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/RenderPhaseOrder.tml
@@ -0,0 +1,15 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+    <p>

+        This page demonstrates the order of render phase operations. Certains later phases

+        will execute in the exact opposite order from the earlier phases, to ensure

+        that output operations balance.

+    </p>

+

+    <p>

+        [<t:Tracer t:mixins="TracerMixin" xml:space="preserve">

+        BODY

+    </t:Tracer>]

+    </p>

+

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SecurePage.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SecurePage.tml
new file mode 100644
index 0000000..25a7cdc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SecurePage.tml
@@ -0,0 +1,46 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Secure Page Access</h1>
+
+
+    <t:if test="message">
+        <p>
+            Message:
+            <span id="message">${message}</span>
+        </p>
+    </t:if>
+
+    <p>
+        <t:actionlink t:id="secureLink">click</t:actionlink>
+    </p>
+
+    <p>
+        <t:form>
+            <input type="submit" value="Secure Submit"/>
+        </t:form>
+    </p>
+
+    <p>
+        We're also demonstrating the ability to send assets via insecure access.
+    </p>
+
+    <p>
+        The Tapestry banner:
+    </p>
+
+    <img id="icon" src="${icon}"/>
+
+    <p>
+        A classpath asset:
+    </p>
+
+    <img id="button" src="${button}"/>
+
+
+    <p>
+        Relative asset via asset: binding
+    </p>
+
+    <img src="${asset:smiley.png}"/>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.tml
new file mode 100644
index 0000000..bff1b2e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ShowSelection.tml
@@ -0,0 +1,10 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Number Selection</h1>
+    
+    <p>  You chose ${selected}.</p>
+    
+    <p>
+        [<a t:type="PageLink" t:page="NumberSelect">Back</a>]
+    </p>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties
new file mode 100644
index 0000000..c70148a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/SimpleForm.properties
@@ -0,0 +1,31 @@
+# Copyright 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+urgent-label=Urgent Processing Requested
+
+operatingSystem-blanklabel=Select ...
+os-values=\
+  winnt=Windows NT, \
+  winxp=Windows XP, \
+  vista=Windows Vista, \
+  os9=Mac OS 9, \
+  osx=Mac OS X, \
+  linux=Linux
+
+department-blanklabel=Select...
+  
+# Correct some of the labels for the drop down list
+SALES_AND_MARKETING=Sales/Marketing
+RESEARCH_AND_DESIGN=R&D
+IT=IT
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties
new file mode 100644
index 0000000..8f2fcc1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.properties
@@ -0,0 +1,15 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+message-required-message=Please provide a detailed description of the incident.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.tml
new file mode 100644
index 0000000..579c495
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ValidForm.tml
@@ -0,0 +1,38 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>Valid Form</h1>
+
+  <p> Tapestry 5 form support with server-side validation. </p>
+
+  <t:form clientValidation="false">
+    <t:errors/>
+    <t:label for="email">This isn't used</t:label>: <input t:type="TextField" t:id="email"
+      value="incident.email" size="50" t:validate="required"/>
+    <br/>
+    <t:label for="message"/>: <textarea t:type="TextArea" t:id="message"
+      t:label="Incident Message" value="incident.message" cols="50" rows="10"> You can put text
+      here, but it isn't used. </textarea>
+    <br/>
+    <input t:type="Checkbox" t:id="urgent" value="incident.urgent"/>
+    <t:label for="urgent"/>
+    <br/>
+    <t:label for="hours"/>: <input t:type="TextField" t:id="hours"
+      value="incident.hours" size="10" t:validate="required"/>
+    <br/>
+    <input type="submit"/>
+  </t:form>
+
+
+  <hr/>
+
+  <p> Entered data: </p>
+
+  <ul>
+    <li>email: [${incident.email}]</li>
+    <li>message: [${incident.message}]</li>
+    <li>urgent: [${incident.urgent}]</li>
+    <li>hours: [${incident.hours}]</li>
+  </ul>
+
+
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/VarBindingDemo.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/VarBindingDemo.tml
new file mode 100644
index 0000000..7f17451
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/VarBindingDemo.tml
@@ -0,0 +1,18 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>var: Binding Prefix Demo</h1>
+
+    <p>var: allows a
+        <em>render variable</em>
+        associated with a component
+        to be read and updated from its embedded components.
+    </p>
+
+    <p>
+        Counting from 1 to 3:
+    </p>
+    <ul>
+        <li t:type="loop" source="1..3" value="var:index">${var:index}</li>
+    </ul>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ViewRegistration.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ViewRegistration.properties
new file mode 100644
index 0000000..59700b7
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/ViewRegistration.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+citizen-label=Citizenship
+male=100% He-Man
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Wilma.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Wilma.tml
new file mode 100644
index 0000000..5af9803
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/Wilma.tml
@@ -0,0 +1,14 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <p>
+        You clicked Wilma.
+    </p>
+    
+    <p>
+        In this case the component event handler method returned the name of the page to activate, as a String.
+    </p>
+    
+    <p>
+        [<a t:type="PageLink" t:page="InjectDemo">Back</a>]
+    </p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.tml
new file mode 100644
index 0000000..ef4413e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/AssetDemo.tml
@@ -0,0 +1,26 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <p>
+        This page demonstrates the ability to inject assets into components and pass them around as parameters.
+    </p>
+
+    <p>
+        The Tapestry banner:
+    </p>
+
+    <img id="icon" src="${icon}"/>
+
+    <p>
+        A classpath asset:
+    </p>
+
+    <img id="button" src="${button}"/>
+
+
+    <p>
+        Relative asset via asset: binding
+    </p>
+
+    <img src="${asset:../smiley.png}"/>
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/tapestry-button.png b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/tapestry-button.png
new file mode 100644
index 0000000..86d9a64
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/nested/tapestry-button.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/smiley.png b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/smiley.png
new file mode 100644
index 0000000..e8aca0d
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/pages/smiley.png
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/PropertyList-1.0.dtd b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/PropertyList-1.0.dtd
new file mode 100644
index 0000000..e16ceae
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/PropertyList-1.0.dtd
@@ -0,0 +1,20 @@
+<!ENTITY % plistObject "(array | data | date | dict | real | integer | string | true | false )" >

+<!ELEMENT plist %plistObject;>

+<!ATTLIST plist version CDATA "1.0" >

+

+<!-- Collections -->

+<!ELEMENT array (%plistObject;)*>

+<!ELEMENT dict (key, %plistObject;)*>

+<!ELEMENT key (#PCDATA)>

+

+<!--- Primitive types -->

+<!ELEMENT string (#PCDATA)>

+<!ELEMENT data (#PCDATA)> <!-- Contents interpreted as Base-64 encoded -->

+<!ELEMENT date (#PCDATA)> <!-- Contents should conform to a subset of ISO 8601 (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with a loss of precision) -->

+

+<!-- Numerical primitives -->

+<!ELEMENT true EMPTY>  <!-- Boolean constant true -->

+<!ELEMENT false EMPTY> <!-- Boolean constant false -->

+<!ELEMENT real (#PCDATA)> <!-- Contents should represent a floating point number matching ("+" | "-")? d+ ("."d*)? ("E" ("+" | "-") d+)? where d is a digit 0-9.  -->

+<!ELEMENT integer (#PCDATA)> <!-- Contents should represent a (possibly signed) integer number in base 10 -->

+

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/iTunes.xml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/iTunes.xml
new file mode 100644
index 0000000..2b09e2b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/services/iTunes.xml
@@ -0,0 +1,64235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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 plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>Major Version</key><integer>1</integer>
+	<key>Minor Version</key><integer>1</integer>
+	<key>Application Version</key><string>7.0.2</string>
+	<key>Features</key><integer>1</integer>
+	<key>Music Folder</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/</string>
+	<key>Library Persistent ID</key><string>094531DBEC195A73</string>
+	<key>Tracks</key>
+	<dict>
+		<key>294</key>
+		<dict>
+			<key>Track ID</key><integer>294</integer>
+			<key>Name</key><string>Bug Juice</string>
+			<key>Artist</key><string>45 Dip</string>
+			<key>Album Artist</key><string>45 Dip</string>
+			<key>Composer</key><string>C. Bemand</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3646633</integer>
+			<key>Total Time</key><integer>227500</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253344667</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:51:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-25T17:23:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A09</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/45%20Dip/Late%20Lounge%20(2%20of%202)/12%20Bug%20Juice.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>295</key>
+		<dict>
+			<key>Track ID</key><integer>295</integer>
+			<key>Name</key><string>Warehouse 5am</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9305262</integer>
+			<key>Total Time</key><integer>574529</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-04-14T18:35:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252123089</integer>
+			<key>Play Date UTC</key><date>2007-01-20T15:31:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A0C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/01%20Warehouse%205am.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>296</key>
+		<dict>
+			<key>Track ID</key><integer>296</integer>
+			<key>Name</key><string>Bathdub</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11100356</integer>
+			<key>Total Time</key><integer>685451</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-04-14T18:37:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253543174</integer>
+			<key>Play Date UTC</key><date>2007-02-06T01:59:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A0F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/02%20Bathdub.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>297</key>
+		<dict>
+			<key>Track ID</key><integer>297</integer>
+			<key>Name</key><string>The Calling</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4993935</integer>
+			<key>Total Time</key><integer>308080</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-04-14T18:37:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252482741</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:25:41Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T18:32:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A11</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/03%20The%20Calling.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>298</key>
+		<dict>
+			<key>Track ID</key><integer>298</integer>
+			<key>Name</key><string>Pleidean Communication</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7069366</integer>
+			<key>Total Time</key><integer>436347</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-04-14T18:38:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251377989</integer>
+			<key>Play Date UTC</key><date>2007-01-12T00:33:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A13</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/04%20Pleidean%20Communication.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>299</key>
+		<dict>
+			<key>Track ID</key><integer>299</integer>
+			<key>Name</key><string>Lighten Up</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6420129</integer>
+			<key>Total Time</key><integer>396223</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-04-14T18:39:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253348903</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:01:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A15</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/05%20Lighten%20Up.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>300</key>
+		<dict>
+			<key>Track ID</key><integer>300</integer>
+			<key>Name</key><string>Spacehopper</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10017175</integer>
+			<key>Total Time</key><integer>618531</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-04-14T18:40:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253425630</integer>
+			<key>Play Date UTC</key><date>2007-02-04T17:20:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:51Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A17</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/06%20Spacehopper.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>301</key>
+		<dict>
+			<key>Track ID</key><integer>301</integer>
+			<key>Name</key><string>Hypnosystem</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10777235</integer>
+			<key>Total Time</key><integer>665505</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-04-14T18:41:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252502511</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:55:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A19</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/07%20Hypnosystem.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>302</key>
+		<dict>
+			<key>Track ID</key><integer>302</integer>
+			<key>Name</key><string>Aquasonic</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Album</key><string>Synaesthetic</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8129984</integer>
+			<key>Total Time</key><integer>501897</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-04-14T18:42:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253351299</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:41:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A1B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A%20Positive%20Life/Synaesthetic/08%20Aquasonic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>303</key>
+		<dict>
+			<key>Track ID</key><integer>303</integer>
+			<key>Name</key><string>Woke Up This Morning (Chosen One Mix)</string>
+			<key>Artist</key><string>A3</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5066582</integer>
+			<key>Total Time</key><integer>316630</integer>
+			<key>Start Time</key><integer>90000</integer>
+			<key>Date Modified</key><date>2007-01-09T17:51:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Volume Adjustment</key><integer>22</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253715617</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:53:37Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-04T23:21:24Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85A1D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/A3/Unknown%20Album/Woke%20Up%20This%20Morning%20(Chosen%20One%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>304</key>
+		<dict>
+			<key>Track ID</key><integer>304</integer>
+			<key>Name</key><string>Show You Something</string>
+			<key>Artist</key><string>Afterlife</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6187470</integer>
+			<key>Total Time</key><integer>386324</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251379939</integer>
+			<key>Play Date UTC</key><date>2007-01-12T01:05:39Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-25T17:23:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A21</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Afterlife/Late%20Lounge%20(1%20of%202)/11%20Show%20You%20Something.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>305</key>
+		<dict>
+			<key>Track ID</key><integer>305</integer>
+			<key>Name</key><string>Save Me</string>
+			<key>Artist</key><string>Aimee Mann</string>
+			<key>Composer</key><string>Mann, Aimee</string>
+			<key>Album</key><string>Live At St. Ann's Warehouse</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4542925</integer>
+			<key>Total Time</key><integer>283794</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:59:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253676470</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:01:10Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85A24</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Aimee%20Mann/Live%20At%20St.%20Ann's%20Warehouse/06%20Save%20Me.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>306</key>
+		<dict>
+			<key>Track ID</key><integer>306</integer>
+			<key>Name</key><string>Another Morning</string>
+			<key>Artist</key><string>American Music Club</string>
+			<key>Composer</key><string>Mark Eitzel</string>
+			<key>Album</key><string>Love Songs For Patriots</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4831548</integer>
+			<key>Total Time</key><integer>201221</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:59:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252545503</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:51:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A27</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/American%20Music%20Club/Love%20Songs%20For%20Patriots/02%20Another%20Morning.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>307</key>
+		<dict>
+			<key>Track ID</key><integer>307</integer>
+			<key>Name</key><string>The Lighthouse</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5238431</integer>
+			<key>Total Time</key><integer>305364</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T18:58:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>35</integer>
+			<key>Play Date</key><integer>3253707165</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:32:45Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T06:15:32Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A2A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/01%20The%20Lighthouse.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>308</key>
+		<dict>
+			<key>Track ID</key><integer>308</integer>
+			<key>Name</key><string>Ruthless</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5402089</integer>
+			<key>Total Time</key><integer>315580</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T18:58:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253711051</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:37:31Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A2D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/02%20Ruthless.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>309</key>
+		<dict>
+			<key>Track ID</key><integer>309</integer>
+			<key>Name</key><string>Theme from Battery</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4669651</integer>
+			<key>Total Time</key><integer>266145</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T18:59:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253546210</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:50:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A2F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/03%20Theme%20from%20Battery.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>310</key>
+		<dict>
+			<key>Track ID</key><integer>310</integer>
+			<key>Name</key><string>Kokubo Sosho Stealth</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3675893</integer>
+			<key>Total Time</key><integer>205959</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T18:59:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3249469879</integer>
+			<key>Play Date UTC</key><date>2006-12-20T22:31:19Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/04%20Kokubo%20Sosho%20Stealth.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>311</key>
+		<dict>
+			<key>Track ID</key><integer>311</integer>
+			<key>Name</key><string>El Cargo</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4240809</integer>
+			<key>Total Time</key><integer>263916</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T18:59:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253536728</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:12:08Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A33</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/05%20El%20Cargo.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>312</key>
+		<dict>
+			<key>Track ID</key><integer>312</integer>
+			<key>Name</key><string>Displaced</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6864986</integer>
+			<key>Total Time</key><integer>418723</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T19:00:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A35</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/06%20Displaced.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>313</key>
+		<dict>
+			<key>Track ID</key><integer>313</integer>
+			<key>Name</key><string>Ruthless (Reprise)</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4599715</integer>
+			<key>Total Time</key><integer>267004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T19:00:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3250693424</integer>
+			<key>Play Date UTC</key><date>2007-01-04T02:23:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A37</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/07%20Ruthless%20(Reprise).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>314</key>
+		<dict>
+			<key>Track ID</key><integer>314</integer>
+			<key>Name</key><string>Kokubo Sosho Battle</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4483348</integer>
+			<key>Total Time</key><integer>256439</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T19:01:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252556913</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:01:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A39</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/08%20Kokubo%20Sosho%20Battle.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>315</key>
+		<dict>
+			<key>Track ID</key><integer>315</integer>
+			<key>Name</key><string>Hokkaido</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3282473</integer>
+			<key>Total Time</key><integer>181067</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T19:01:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253026493</integer>
+			<key>Play Date UTC</key><date>2007-01-31T02:28:13Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A3B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/09%20Hokkaido.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>316</key>
+		<dict>
+			<key>Track ID</key><integer>316</integer>
+			<key>Name</key><string>The Clean Up</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Chaos Theory: Splinter Cell 3 (Soundtrack from the Video Game)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6853421</integer>
+			<key>Total Time</key><integer>420117</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-04-03T19:02:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253627993</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:33:13Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A3D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Chaos%20Theory_%20Splinter%20Cell%203%20(Soundtrack%20from%20the%20Video%20Game)/10%20The%20Clean%20Up.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>317</key>
+		<dict>
+			<key>Track ID</key><integer>317</integer>
+			<key>Name</key><string>A Nervous Tic Motion Of The Head To The Left</string>
+			<key>Artist</key><string>Andrew Bird</string>
+			<key>Album</key><string>&#38; The Mysterious Producton Of Eggs</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4797890</integer>
+			<key>Total Time</key><integer>299728</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:27:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247573136</integer>
+			<key>Play Date UTC</key><date>2006-11-28T23:38:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A3F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Andrew%20Bird/&#38;%20The%20Mysterious%20Producton%20Of%20Eggs/03%20A%20Nervous%20Tic%20Motion%20Of%20The%20Head%20To%20The%20Left.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>318</key>
+		<dict>
+			<key>Track ID</key><integer>318</integer>
+			<key>Name</key><string>Studying Stones</string>
+			<key>Artist</key><string>Ani DiFranco</string>
+			<key>Album</key><string>Knuckle Down</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5616415</integer>
+			<key>Total Time</key><integer>233926</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-02-23T20:30:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249296052</integer>
+			<key>Play Date UTC</key><date>2006-12-18T22:14:12Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A42</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Ani%20DiFranco/Knuckle%20Down/02%20Studying%20Stones.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>319</key>
+		<dict>
+			<key>Track ID</key><integer>319</integer>
+			<key>Name</key><string>Why</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7139296</integer>
+			<key>Total Time</key><integer>293865</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:57:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253549827</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:50:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A45</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/01%20Why.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>320</key>
+		<dict>
+			<key>Track ID</key><integer>320</integer>
+			<key>Name</key><string>Walking On Broken Glass</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6154768</integer>
+			<key>Total Time</key><integer>253204</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253353834</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:23:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A48</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/02%20Walking%20On%20Broken%20Glass.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>321</key>
+		<dict>
+			<key>Track ID</key><integer>321</integer>
+			<key>Name</key><string>Precious</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7492046</integer>
+			<key>Total Time</key><integer>308436</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250599322</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:15:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A4A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/03%20Precious.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>322</key>
+		<dict>
+			<key>Track ID</key><integer>322</integer>
+			<key>Name</key><string>Legend In My Living Room</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox/Peter-John Vittese</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5490266</integer>
+			<key>Total Time</key><integer>225641</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247666050</integer>
+			<key>Play Date UTC</key><date>2006-11-30T01:27:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A4C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/04%20Legend%20In%20My%20Living%20Room.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>323</key>
+		<dict>
+			<key>Track ID</key><integer>323</integer>
+			<key>Name</key><string>Cold</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6359043</integer>
+			<key>Total Time</key><integer>261652</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250709385</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:49:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A4E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/05%20Cold.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>324</key>
+		<dict>
+			<key>Track ID</key><integer>324</integer>
+			<key>Name</key><string>Money Can't Buy It</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7287031</integer>
+			<key>Total Time</key><integer>299966</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253376471</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:41:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A50</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/06%20Money%20Can't%20Buy%20It.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>325</key>
+		<dict>
+			<key>Track ID</key><integer>325</integer>
+			<key>Name</key><string>Little Bird</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6740080</integer>
+			<key>Total Time</key><integer>279166</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252492538</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:08:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A52</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/07%20Little%20Bird.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>326</key>
+		<dict>
+			<key>Track ID</key><integer>326</integer>
+			<key>Name</key><string>Primitive</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6303329</integer>
+			<key>Total Time</key><integer>259348</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253531316</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:41:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A54</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/08%20Primitive.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>327</key>
+		<dict>
+			<key>Track ID</key><integer>327</integer>
+			<key>Name</key><string>Stay By Me</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9436575</integer>
+			<key>Total Time</key><integer>388734</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247373827</integer>
+			<key>Play Date UTC</key><date>2006-11-26T16:17:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A56</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/09%20Stay%20By%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>328</key>
+		<dict>
+			<key>Track ID</key><integer>328</integer>
+			<key>Name</key><string>The Gift</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Annie Lennox/The Blue Nile</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7125274</integer>
+			<key>Total Time</key><integer>294484</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253266414</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:06:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A58</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/10%20The%20Gift.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>329</key>
+		<dict>
+			<key>Track ID</key><integer>329</integer>
+			<key>Name</key><string>Keep Young And Beautiful</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Al Dublin/Harry Warren</string>
+			<key>Album</key><string>Diva</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3349370</integer>
+			<key>Total Time</key><integer>137598</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T15:58:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252537789</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:43:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A5A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Diva/11%20Keep%20Young%20And%20Beautiful.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>330</key>
+		<dict>
+			<key>Track ID</key><integer>330</integer>
+			<key>Name</key><string>No More "I Love You's"</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>D. Freeman &#38; J. Hughes</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7102647</integer>
+			<key>Total Time</key><integer>292905</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253363119</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:58:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A5C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/01%20No%20More%20_I%20Love%20You's_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>331</key>
+		<dict>
+			<key>Track ID</key><integer>331</integer>
+			<key>Name</key><string>Take Me To The River</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>A. Green/M. Hodges</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5183527</integer>
+			<key>Total Time</key><integer>213225</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253554007</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:00:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A5F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/02%20Take%20Me%20To%20The%20River.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>332</key>
+		<dict>
+			<key>Track ID</key><integer>332</integer>
+			<key>Name</key><string>A Whiter Shade Of Pale</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>G. Brooker &#38; K. Reid</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7686037</integer>
+			<key>Total Time</key><integer>316606</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252560815</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:06:55Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-16T17:19:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A61</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/03%20A%20Whiter%20Shade%20Of%20Pale.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>333</key>
+		<dict>
+			<key>Track ID</key><integer>333</integer>
+			<key>Name</key><string>Don't Let It Bring You Down</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>N. Young</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5299055</integer>
+			<key>Total Time</key><integer>218729</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A63</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/04%20Don't%20Let%20It%20Bring%20You%20Down.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>334</key>
+		<dict>
+			<key>Track ID</key><integer>334</integer>
+			<key>Name</key><string>Train In Vain</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>Jones &#38; Strummer</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6881215</integer>
+			<key>Total Time</key><integer>284436</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253367727</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:15:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A65</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/05%20Train%20In%20Vain.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>335</key>
+		<dict>
+			<key>Track ID</key><integer>335</integer>
+			<key>Name</key><string>I Can't Get Next To You</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>B. Strong &#38; N. Whitfield</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4601590</integer>
+			<key>Total Time</key><integer>188777</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252552777</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:52:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A67</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/06%20I%20Can't%20Get%20Next%20To%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>336</key>
+		<dict>
+			<key>Track ID</key><integer>336</integer>
+			<key>Name</key><string>Downtown Lights</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>P. Buchanan</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9791936</integer>
+			<key>Total Time</key><integer>404606</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253365940</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:45:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A69</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/07%20Downtown%20Lights.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>337</key>
+		<dict>
+			<key>Track ID</key><integer>337</integer>
+			<key>Name</key><string>Thin Line Between Love And Hate</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>J. Members/R. Poindexter</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7165637</integer>
+			<key>Total Time</key><integer>295124</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253027306</integer>
+			<key>Play Date UTC</key><date>2007-01-31T02:41:46Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A6B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/08%20Thin%20Line%20Between%20Love%20And%20Hate.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>338</key>
+		<dict>
+			<key>Track ID</key><integer>338</integer>
+			<key>Name</key><string>Waiting In Vain</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>B. Marley</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8271029</integer>
+			<key>Total Time</key><integer>340777</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253365535</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:38:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A6D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/09%20Waiting%20In%20Vain.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>339</key>
+		<dict>
+			<key>Track ID</key><integer>339</integer>
+			<key>Name</key><string>Something So Right</string>
+			<key>Artist</key><string>Annie Lennox</string>
+			<key>Composer</key><string>P. Simon</string>
+			<key>Album</key><string>Medusa</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5730961</integer>
+			<key>Total Time</key><integer>236500</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-01T16:14:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249272720</integer>
+			<key>Play Date UTC</key><date>2006-12-18T15:45:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A6F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Annie%20Lennox/Medusa/10%20Something%20So%20Right.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>340</key>
+		<dict>
+			<key>Track ID</key><integer>340</integer>
+			<key>Name</key><string>| SPRING 1. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5075923</integer>
+			<key>Total Time</key><integer>209129</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:17:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247250113</integer>
+			<key>Play Date UTC</key><date>2006-11-25T05:55:13Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-07T00:25:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A71</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/01%20_%20SPRING%201.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>341</key>
+		<dict>
+			<key>Track ID</key><integer>341</integer>
+			<key>Name</key><string>|  2. Largo</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3550631</integer>
+			<key>Total Time</key><integer>145641</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:19:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250601441</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:50:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A74</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/02%20_%20%202.%20Largo.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>342</key>
+		<dict>
+			<key>Track ID</key><integer>342</integer>
+			<key>Name</key><string>|  3. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5920798</integer>
+			<key>Total Time</key><integer>244308</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:22:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253367443</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:10:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-19T21:42:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A76</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/03%20_%20%203.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>343</key>
+		<dict>
+			<key>Track ID</key><integer>343</integer>
+			<key>Name</key><string>| SUMMER 4. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8107814</integer>
+			<key>Total Time</key><integer>334633</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:26:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249571614</integer>
+			<key>Play Date UTC</key><date>2006-12-22T02:46:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A78</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/04%20_%20SUMMER%204.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>344</key>
+		<dict>
+			<key>Track ID</key><integer>344</integer>
+			<key>Name</key><string>|  5. Adagio</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3554800</integer>
+			<key>Total Time</key><integer>145812</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:27:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247074997</integer>
+			<key>Play Date UTC</key><date>2006-11-23T05:16:37Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A7A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/05%20_%20%205.%20Adagio.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>345</key>
+		<dict>
+			<key>Track ID</key><integer>345</integer>
+			<key>Name</key><string>|  6. Presto</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4243035</integer>
+			<key>Total Time</key><integer>174462</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:29:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247244497</integer>
+			<key>Play Date UTC</key><date>2006-11-25T04:21:37Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A7C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/06%20_%20%206.%20Presto.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>346</key>
+		<dict>
+			<key>Track ID</key><integer>346</integer>
+			<key>Name</key><string>AUTUMN 7. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6836461</integer>
+			<key>Total Time</key><integer>282132</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:33:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253460057</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:54:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A7E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/07%20AUTUMN%207.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>347</key>
+		<dict>
+			<key>Track ID</key><integer>347</integer>
+			<key>Name</key><string>|  8. Adagio</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4326981</integer>
+			<key>Total Time</key><integer>177961</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:35:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253509644</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:40:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A80</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/08%20_%20%208.%20Adagio.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>348</key>
+		<dict>
+			<key>Track ID</key><integer>348</integer>
+			<key>Name</key><string>|  9. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4896055</integer>
+			<key>Total Time</key><integer>201641</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:37:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253526411</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:20:11Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-17T05:44:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A82</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/09%20_%20%209.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>349</key>
+		<dict>
+			<key>Track ID</key><integer>349</integer>
+			<key>Name</key><string>WINTER 10. Allegro Non Molto</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4915411</integer>
+			<key>Total Time</key><integer>202452</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:40:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249563069</integer>
+			<key>Play Date UTC</key><date>2006-12-22T00:24:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A84</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/10%20WINTER%2010.%20Allegro%20Non%20Molto.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>350</key>
+		<dict>
+			<key>Track ID</key><integer>350</integer>
+			<key>Name</key><string>|  11. Largo</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2886031</integer>
+			<key>Total Time</key><integer>117972</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:41:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251632449</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:14:09Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A86</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/11%20_%20%2011.%20Largo.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>351</key>
+		<dict>
+			<key>Track ID</key><integer>351</integer>
+			<key>Name</key><string>|  12. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4788003</integer>
+			<key>Total Time</key><integer>197140</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:43:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247043862</integer>
+			<key>Play Date UTC</key><date>2006-11-22T20:37:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A88</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/12%20_%20%2012.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>352</key>
+		<dict>
+			<key>Track ID</key><integer>352</integer>
+			<key>Name</key><string>Concerto For Flute in G Minor, OP 10 No.2, La Notte 13. Largo</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3650789</integer>
+			<key>Total Time</key><integer>149801</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:45:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B85A8A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/13%20Concerto%20For%20Flute%20in%20G%20Minor,%20OP%2010%20No.2,%20La%20Notte%2013.%20Largo.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>353</key>
+		<dict>
+			<key>Track ID</key><integer>353</integer>
+			<key>Name</key><string>|  14. Presto Largo</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2962517</integer>
+			<key>Total Time</key><integer>121150</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:47:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253267889</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:31:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A8C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/14%20_%20%2014.%20Presto%20Largo.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>354</key>
+		<dict>
+			<key>Track ID</key><integer>354</integer>
+			<key>Name</key><string>|  15. Presto</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1676811</integer>
+			<key>Total Time</key><integer>67625</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:48:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252512067</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:34:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A8E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/15%20_%20%2015.%20Presto.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>355</key>
+		<dict>
+			<key>Track ID</key><integer>355</integer>
+			<key>Name</key><string>|  16. Largo</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2974327</integer>
+			<key>Total Time</key><integer>121641</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:49:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-13T20:51:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A90</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/16%20_%20%2016.%20Largo.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>356</key>
+		<dict>
+			<key>Track ID</key><integer>356</integer>
+			<key>Name</key><string>|  17. Allegro</string>
+			<key>Artist</key><string>Antonio Vivaldi</string>
+			<key>Album</key><string>The Four Seasons</string>
+			<key>Genre</key><string>Classical</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4079260</integer>
+			<key>Total Time</key><integer>167636</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-05-04T15:51:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252402473</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:07:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Antonio%20Vivaldi/The%20Four%20Seasons/17%20_%20%2017.%20Allegro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>357</key>
+		<dict>
+			<key>Track ID</key><integer>357</integer>
+			<key>Name</key><string>Sur Tes Pas [Corny Dream Mix]</string>
+			<key>Artist</key><string>Autour de Lucie</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>V. Leulliot</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3644586</integer>
+			<key>Total Time</key><integer>300120</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251433561</integer>
+			<key>Play Date UTC</key><date>2007-01-12T15:59:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A94</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Autour%20de%20Lucie/Plastic%20Compilation,%20Vol.%202/10%20Sur%20Tes%20Pas%20%5BCorny%20Dream%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>358</key>
+		<dict>
+			<key>Track ID</key><integer>358</integer>
+			<key>Name</key><string>The Season [Swag's Vocal Mix]</string>
+			<key>Artist</key><string>Beanfield</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7054318</integer>
+			<key>Total Time</key><integer>440502</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251435432</integer>
+			<key>Play Date UTC</key><date>2007-01-12T16:30:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A97</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beanfield/Late%20Lounge%20(1%20of%202)/15%20The%20Season%20%5BSwag's%20Vocal%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>359</key>
+		<dict>
+			<key>Track ID</key><integer>359</integer>
+			<key>Name</key><string>August Day Song [King Britt Remix]</string>
+			<key>Artist</key><string>Bebel Gilberto</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Bebel Gilberto/Chris Franck/Nina Miranda</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3962350</integer>
+			<key>Total Time</key><integer>247222</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253263160</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:12:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85A9A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Bebel%20Gilberto/Late%20Lounge%20(2%20of%202)/10%20August%20Day%20Song%20%5BKing%20Britt%20Remix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>360</key>
+		<dict>
+			<key>Track ID</key><integer>360</integer>
+			<key>Name</key><string>Stolen Car</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7886232</integer>
+			<key>Total Time</key><integer>325758</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:14:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251436570</integer>
+			<key>Play Date UTC</key><date>2007-01-12T16:49:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B85A9D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/01%20Stolen%20Car.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>361</key>
+		<dict>
+			<key>Track ID</key><integer>361</integer>
+			<key>Name</key><string>Sweetest Decline</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8216205</integer>
+			<key>Total Time</key><integer>339412</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:15:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251436909</integer>
+			<key>Play Date UTC</key><date>2007-01-12T16:55:09Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AA0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/02%20Sweetest%20Decline.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>362</key>
+		<dict>
+			<key>Track ID</key><integer>362</integer>
+			<key>Name</key><string>Couldn't Cause Me Harm</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6981523</integer>
+			<key>Total Time</key><integer>288382</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:16:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252506964</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:09:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AA2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/03%20Couldn't%20Cause%20Me%20Harm.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>363</key>
+		<dict>
+			<key>Track ID</key><integer>363</integer>
+			<key>Name</key><string>So Much More</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8274013</integer>
+			<key>Total Time</key><integer>341801</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:17:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253619383</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:09:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AA4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/04%20So%20Much%20More.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>364</key>
+		<dict>
+			<key>Track ID</key><integer>364</integer>
+			<key>Name</key><string>Pass In Time</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10598345</integer>
+			<key>Total Time</key><integer>437865</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:19:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251438093</integer>
+			<key>Play Date UTC</key><date>2007-01-12T17:14:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AA6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/05%20Pass%20In%20Time.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>365</key>
+		<dict>
+			<key>Track ID</key><integer>365</integer>
+			<key>Name</key><string>Central Reservation (Original Version)</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7020771</integer>
+			<key>Total Time</key><integer>290004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:20:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251438383</integer>
+			<key>Play Date UTC</key><date>2007-01-12T17:19:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AA8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/06%20Central%20Reservation%20(Original%20Version).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>366</key>
+		<dict>
+			<key>Track ID</key><integer>366</integer>
+			<key>Name</key><string>Stars All Seem To Weep</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6775571</integer>
+			<key>Total Time</key><integer>279870</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:20:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251438663</integer>
+			<key>Play Date UTC</key><date>2007-01-12T17:24:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AAA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/07%20Stars%20All%20Seem%20To%20Weep.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>367</key>
+		<dict>
+			<key>Track ID</key><integer>367</integer>
+			<key>Name</key><string>Love Like Laughter</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4556123</integer>
+			<key>Total Time</key><integer>187668</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:21:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253509466</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:37:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AAC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/08%20Love%20Like%20Laughter.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>368</key>
+		<dict>
+			<key>Track ID</key><integer>368</integer>
+			<key>Name</key><string>Blood Red River</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6191772</integer>
+			<key>Total Time</key><integer>255742</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:22:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252565471</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:24:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AAE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/09%20Blood%20Red%20River.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>369</key>
+		<dict>
+			<key>Track ID</key><integer>369</integer>
+			<key>Name</key><string>Devil Song</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7375871</integer>
+			<key>Total Time</key><integer>304681</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:23:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251439411</integer>
+			<key>Play Date UTC</key><date>2007-01-12T17:36:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AB0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/10%20Devil%20Song.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>370</key>
+		<dict>
+			<key>Track ID</key><integer>370</integer>
+			<key>Name</key><string>Feel To Believe</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5920091</integer>
+			<key>Total Time</key><integer>244500</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:24:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253294085</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:48:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AB2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/11%20Feel%20To%20Believe.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>371</key>
+		<dict>
+			<key>Track ID</key><integer>371</integer>
+			<key>Name</key><string>Central Reservation (Ben Watt Remix)</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album</key><string>Central Reservation</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5855579</integer>
+			<key>Total Time</key><integer>241812</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-04-20T18:25:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3250666366</integer>
+			<key>Play Date UTC</key><date>2007-01-03T18:52:46Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85AB4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Central%20Reservation/12%20Central%20Reservation%20(Ben%20Watt%20Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>372</key>
+		<dict>
+			<key>Track ID</key><integer>372</integer>
+			<key>Name</key><string>Stolen Car</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Barnes/Beth Orton/Read/William Blanchard</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5207868</integer>
+			<key>Total Time</key><integer>325067</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253533997</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:26:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AB6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Late%20Lounge%20(2%20of%202)/03%20Stolen%20Car.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>373</key>
+		<dict>
+			<key>Track ID</key><integer>373</integer>
+			<key>Name</key><string>Central Reservation [Ibadan Spiritual Life Radio Edit]</string>
+			<key>Artist</key><string>Beth Orton</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Beth Orton</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3885017</integer>
+			<key>Total Time</key><integer>242677</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T17:46:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AB8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Beth%20Orton/Plastic%20Compilation,%20Vol.%203/10%20Central%20Reservation%20%5BIbadan%20Spiritual%20Life%20Radio%20Edit%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>374</key>
+		<dict>
+			<key>Track ID</key><integer>374</integer>
+			<key>Name</key><string>Up and Down</string>
+			<key>Artist</key><string>Black Jazz Chronicles</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Chris Bemand</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4317045</integer>
+			<key>Total Time</key><integer>269400</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252474046</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:00:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ABB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Black%20Jazz%20Chronicles/Late%20Lounge%20(2%20of%202)/16%20Up%20and%20Down.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>375</key>
+		<dict>
+			<key>Track ID</key><integer>375</integer>
+			<key>Name</key><string>Firewater</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8420167</integer>
+			<key>Total Time</key><integer>525740</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>24</integer>
+			<key>Play Date</key><integer>3253109616</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:33:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-04T23:35:46Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ABD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/01%20Firewater.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>376</key>
+		<dict>
+			<key>Track ID</key><integer>376</integer>
+			<key>Name</key><string>Orbitus Teranium</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7824575</integer>
+			<key>Total Time</key><integer>488515</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250685888</integer>
+			<key>Play Date UTC</key><date>2007-01-04T00:18:08Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AC0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/02%20Orbitus%20Teranium.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>377</key>
+		<dict>
+			<key>Track ID</key><integer>377</integer>
+			<key>Name</key><string>Flaming June</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>Brian Transeau</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8278060</integer>
+			<key>Total Time</key><integer>516858</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253175797</integer>
+			<key>Play Date UTC</key><date>2007-02-01T19:56:37Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AC2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/03%20Flaming%20June.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>378</key>
+		<dict>
+			<key>Track ID</key><integer>378</integer>
+			<key>Name</key><string>Lullaby for Gaia</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>Brian Transeau/Jan Johnston</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5152562</integer>
+			<key>Total Time</key><integer>321515</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252566459</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:40:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AC4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/04%20Lullaby%20for%20Gaia.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>379</key>
+		<dict>
+			<key>Track ID</key><integer>379</integer>
+			<key>Name</key><string>Memories in a Sea of Forgetfulness</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7374015</integer>
+			<key>Total Time</key><integer>460355</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251443900</integer>
+			<key>Play Date UTC</key><date>2007-01-12T18:51:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AC6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/05%20Memories%20in%20a%20Sea%20of%20Forgetfulness.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>380</key>
+		<dict>
+			<key>Track ID</key><integer>380</integer>
+			<key>Name</key><string>Solar Plexus</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4069629</integer>
+			<key>Total Time</key><integer>253831</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250671326</integer>
+			<key>Play Date UTC</key><date>2007-01-03T20:15:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AC8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/06%20Solar%20Plexus.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>381</key>
+		<dict>
+			<key>Track ID</key><integer>381</integer>
+			<key>Name</key><string>Nectar</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5696327</integer>
+			<key>Total Time</key><integer>355500</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253380209</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:43:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ACA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/07%20Nectar.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>382</key>
+		<dict>
+			<key>Track ID</key><integer>382</integer>
+			<key>Name</key><string>Remember</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT/Jan Johnston</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7698351</integer>
+			<key>Total Time</key><integer>480626</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253713999</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:26:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ACC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/08%20Remember.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>383</key>
+		<dict>
+			<key>Track ID</key><integer>383</integer>
+			<key>Name</key><string>Love, Peace and Grease</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>Brian Transeau</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3726485</integer>
+			<key>Total Time</key><integer>232385</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252493091</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:18:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ACE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/09%20Love,%20Peace%20and%20Grease.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>384</key>
+		<dict>
+			<key>Track ID</key><integer>384</integer>
+			<key>Name</key><string>Content</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>ESCM</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10591882</integer>
+			<key>Total Time</key><integer>661472</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253253968</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:39:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AD0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/ESCM/10%20Content.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>385</key>
+		<dict>
+			<key>Track ID</key><integer>385</integer>
+			<key>Name</key><string>Never Gonna Come Back</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5558943</integer>
+			<key>Total Time</key><integer>347297</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251445495</integer>
+			<key>Play Date UTC</key><date>2007-01-12T19:18:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AD2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/02%20Never%20Gonna%20Come%20Back.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>386</key>
+		<dict>
+			<key>Track ID</key><integer>386</integer>
+			<key>Name</key><string>Dreaming</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT/Judie Tzuke/Mike Paxman/Paul Muggleton</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5118414</integer>
+			<key>Total Time</key><integer>319764</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251445815</integer>
+			<key>Play Date UTC</key><date>2007-01-12T19:23:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AD5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/03%20Dreaming.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>387</key>
+		<dict>
+			<key>Track ID</key><integer>387</integer>
+			<key>Name</key><string>Shame</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3218790</integer>
+			<key>Total Time</key><integer>201038</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251446016</integer>
+			<key>Play Date UTC</key><date>2007-01-12T19:26:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AD7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/04%20Shame.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>388</key>
+		<dict>
+			<key>Track ID</key><integer>388</integer>
+			<key>Name</key><string>Movement In Still Life</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT/C Chase/E. Fletcher/M Glover/S Robinson</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4322620</integer>
+			<key>Total Time</key><integer>270027</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253544588</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:23:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AD9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/05%20Movement%20In%20Still%20Life.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>389</key>
+		<dict>
+			<key>Track ID</key><integer>389</integer>
+			<key>Name</key><string>Satellite</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4989265</integer>
+			<key>Total Time</key><integer>311693</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2006-10-26T18:42:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252989968</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:19:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ADB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/06%20Satellite.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>390</key>
+		<dict>
+			<key>Track ID</key><integer>390</integer>
+			<key>Name</key><string>Godspeed</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>Brian Transeau</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4967949</integer>
+			<key>Total Time</key><integer>310360</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253614599</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:49:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ADD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/07%20Godspeed.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>391</key>
+		<dict>
+			<key>Track ID</key><integer>391</integer>
+			<key>Name</key><string>Running Down The Way Up</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT/Kirsty Hawkshaw/Mike Truman</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5618712</integer>
+			<key>Total Time</key><integer>351033</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253714350</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:32:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T17:28:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85ADF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/08%20Running%20Down%20The%20Way%20Up.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>392</key>
+		<dict>
+			<key>Track ID</key><integer>392</integer>
+			<key>Name</key><string>Mercury And Solace</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>BT/Jan Johnston</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4914868</integer>
+			<key>Total Time</key><integer>307043</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2006-10-26T18:41:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252413379</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:09:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AE1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/09%20Mercury%20And%20Solace.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>393</key>
+		<dict>
+			<key>Track ID</key><integer>393</integer>
+			<key>Name</key><string>Smartbomb</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Composer</key><string>Brian Transeau</string>
+			<key>Album</key><string>Movement In Still Life</string>
+			<key>Genre</key><string>General Trance</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4962934</integer>
+			<key>Total Time</key><integer>310047</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253612681</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:18:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AE3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Movement%20In%20Still%20Life/10%20Smartbomb.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>394</key>
+		<dict>
+			<key>Track ID</key><integer>394</integer>
+			<key>Name</key><string>Dreaming [Tiesto Mix]</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Brian Transeau/Judie Tzuke/Mike Paxman/Paul Muggleton</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7066940</integer>
+			<key>Total Time</key><integer>441547</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251447966</integer>
+			<key>Play Date UTC</key><date>2007-01-12T19:59:26Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AE5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/Plastic%20Compilation,%20Vol.%203/05%20Dreaming%20%5BTiesto%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>395</key>
+		<dict>
+			<key>Track ID</key><integer>395</integer>
+			<key>Name</key><string>All That Makes Us Human Continues</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8206785</integer>
+			<key>Total Time</key><integer>495721</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:31:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251448462</integer>
+			<key>Play Date UTC</key><date>2007-01-12T20:07:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AE7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/01%20All%20That%20Makes%20Us%20Human%20Continues.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>396</key>
+		<dict>
+			<key>Track ID</key><integer>396</integer>
+			<key>Name</key><string>Dynamic Symmetry</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>11259792</integer>
+			<key>Total Time</key><integer>683501</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:32:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253521345</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:55:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AEA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/02%20Dynamic%20Symmetry.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>397</key>
+		<dict>
+			<key>Track ID</key><integer>397</integer>
+			<key>Name</key><string>The Internal Locus</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>10353842</integer>
+			<key>Total Time</key><integer>627633</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:32:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253349531</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:12:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AEC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/03%20The%20Internal%20Locus.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>398</key>
+		<dict>
+			<key>Track ID</key><integer>398</integer>
+			<key>Name</key><string>1.618</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>11442725</integer>
+			<key>Total Time</key><integer>694089</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:32:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251450467</integer>
+			<key>Play Date UTC</key><date>2007-01-12T20:41:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AEE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/04%201.618.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>399</key>
+		<dict>
+			<key>Track ID</key><integer>399</integer>
+			<key>Name</key><string>See You On the Other Side</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>14195145</integer>
+			<key>Total Time</key><integer>863734</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:33:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251451331</integer>
+			<key>Play Date UTC</key><date>2007-01-12T20:55:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AF0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/05%20See%20You%20On%20the%20Other%20Side.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>400</key>
+		<dict>
+			<key>Track ID</key><integer>400</integer>
+			<key>Name</key><string>The Antikythera Mechanism</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>10006393</integer>
+			<key>Total Time</key><integer>606294</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:33:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252499411</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:03:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AF2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/06%20The%20Antikythera%20Mechanism.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>401</key>
+		<dict>
+			<key>Track ID</key><integer>401</integer>
+			<key>Name</key><string>Good Morning Kaia</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8166641</integer>
+			<key>Total Time</key><integer>491820</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:33:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253365195</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:33:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AF4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/07%20Good%20Morning%20Kaia.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>402</key>
+		<dict>
+			<key>Track ID</key><integer>402</integer>
+			<key>Name</key><string>Dynamic Symmetry</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected MPEG-4 video file</string>
+			<key>Size</key><integer>51850973</integer>
+			<key>Total Time</key><integer>669402</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:35:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AF6</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Has Video</key><true/>
+			<key>Music Video</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/08%20Dynamic%20Symmetry.m4v</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>403</key>
+		<dict>
+			<key>Track ID</key><integer>403</integer>
+			<key>Name</key><string>1.618</string>
+			<key>Artist</key><string>BT</string>
+			<key>Album Artist</key><string>BT</string>
+			<key>Album</key><string>This Binary Universe</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected MPEG-4 video file</string>
+			<key>Size</key><integer>55707454</integer>
+			<key>Total Time</key><integer>691558</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-04T23:36:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:40Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252514993</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:23:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AF8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Has Video</key><true/>
+			<key>Music Video</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT/This%20Binary%20Universe/09%201.618.m4v</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>404</key>
+		<dict>
+			<key>Track ID</key><integer>404</integer>
+			<key>Name</key><string>Break On Through (To the Other Side) [Remix]</string>
+			<key>Artist</key><string>BT vs. The Doors</string>
+			<key>Album Artist</key><string>BT vs. The Doors</string>
+			<key>Album</key><string>Break On Through (To the Other Side) [Remix] - Single</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6989135</integer>
+			<key>Total Time</key><integer>427176</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>1</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-29T19:13:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253028565</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:02:45Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85AFA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/BT%20vs.%20The%20Doors/Break%20On%20Through%20(To%20the%20Other%20Side)%20%5BRemix%5D%20-%20Single/01%20Break%20On%20Through%20(To%20the%20Other%20Side)%20%5BRemix%5D.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>405</key>
+		<dict>
+			<key>Track ID</key><integer>405</integer>
+			<key>Name</key><string>Trickshot</string>
+			<key>Artist</key><string>Ceasefire</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Ceasefire</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4730658</integer>
+			<key>Total Time</key><integer>196284</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251481885</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:24:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B85AFD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Ceasefire/Community%20Service/10%20Trickshot.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>406</key>
+		<dict>
+			<key>Track ID</key><integer>406</integer>
+			<key>Name</key><string>Charanga Cakewalk - La Negra Celina</string>
+			<key>Artist</key><string>Charanga Cakewalk</string>
+			<key>Album</key><string>Loteria De La Cumbia</string>
+			<key>Genre</key><string>Latin</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5441536</integer>
+			<key>Total Time</key><integer>271986</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:30:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252404914</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:48:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B85B00</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Charanga%20Cakewalk/Loteria%20De%20La%20Cumbia/07%20Charanga%20Cakewalk%20-%20La%20Negra%20Celina.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>407</key>
+		<dict>
+			<key>Track ID</key><integer>407</integer>
+			<key>Name</key><string>Perfect Weapon</string>
+			<key>Artist</key><string>Communique</string>
+			<key>Album</key><string>Poison Arrows</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3148141</integer>
+			<key>Total Time</key><integer>196623</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Date Modified</key><date>2005-02-23T21:00:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252534633</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:50:33Z</date>
+			<key>Persistent ID</key><string>87139F8602B85B03</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Communique/Poison%20Arrows/05%20Perfect%20Weapon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>408</key>
+		<dict>
+			<key>Track ID</key><integer>408</integer>
+			<key>Name</key><string>Behind The Sun (Deep Ambient Mix)</string>
+			<key>Artist</key><string>The Starseeds</string>
+			<key>Composer</key><string>The Starseeds</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10747415</integer>
+			<key>Total Time</key><integer>443625</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:47:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252480028</integer>
+			<key>Play Date UTC</key><date>2007-01-24T18:40:28Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B06</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/01%20Behind%20The%20Sun%20(Deep%20Ambient%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>409</key>
+		<dict>
+			<key>Track ID</key><integer>409</integer>
+			<key>Name</key><string>Autumn Leaves (Irresistable Force Mix Trip 2)</string>
+			<key>Artist</key><string>Coldcut</string>
+			<key>Composer</key><string>Coldcut</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10311886</integer>
+			<key>Total Time</key><integer>425641</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:48:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252400016</integer>
+			<key>Play Date UTC</key><date>2007-01-23T20:26:56Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B0B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/02%20Autumn%20Leaves%20(Irresistable%20Force%20Mix%20Trip%202).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>410</key>
+		<dict>
+			<key>Track ID</key><integer>410</integer>
+			<key>Name</key><string>Triangle</string>
+			<key>Artist</key><string>Sounds From The Ground</string>
+			<key>Composer</key><string>Sounds From The Ground</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>14771190</integer>
+			<key>Total Time</key><integer>609790</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:50:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251349211</integer>
+			<key>Play Date UTC</key><date>2007-01-11T16:33:31Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B0E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/03%20Triangle.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>411</key>
+		<dict>
+			<key>Track ID</key><integer>411</integer>
+			<key>Name</key><string>A Voyage On The Marie Celeste</string>
+			<key>Artist</key><string>Groove Corporation</string>
+			<key>Composer</key><string>The Groove Corporation</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6441361</integer>
+			<key>Total Time</key><integer>265812</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:51:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251523304</integer>
+			<key>Play Date UTC</key><date>2007-01-13T16:55:04Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B11</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/04%20A%20Voyage%20On%20The%20Marie%20Celeste.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>412</key>
+		<dict>
+			<key>Track ID</key><integer>412</integer>
+			<key>Name</key><string>Pleidean Communication</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Composer</key><string>A Positive Life</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10659078</integer>
+			<key>Total Time</key><integer>439977</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:52:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253459539</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:45:39Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B14</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/05%20Pleidean%20Communication.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>413</key>
+		<dict>
+			<key>Track ID</key><integer>413</integer>
+			<key>Name</key><string>Baby Interphase</string>
+			<key>Artist</key><string>Biosphere</string>
+			<key>Composer</key><string>Biosphere</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7671923</integer>
+			<key>Total Time</key><integer>316628</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:53:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251440301</integer>
+			<key>Play Date UTC</key><date>2007-01-12T17:51:41Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B17</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/06%20Baby%20Interphase.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>414</key>
+		<dict>
+			<key>Track ID</key><integer>414</integer>
+			<key>Name</key><string>Tortoise</string>
+			<key>Artist</key><string>The Higher Intelligence Agency</string>
+			<key>Composer</key><string>The Higher Intelligence Agency</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10650713</integer>
+			<key>Total Time</key><integer>439636</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:54:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247567284</integer>
+			<key>Play Date UTC</key><date>2006-11-28T22:01:24Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:31Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B1A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/07%20Tortoise.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>415</key>
+		<dict>
+			<key>Track ID</key><integer>415</integer>
+			<key>Name</key><string>Sunken Garden</string>
+			<key>Artist</key><string>Human Mesh Dance</string>
+			<key>Composer</key><string>Human Mesh Dance</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8980056</integer>
+			<key>Total Time</key><integer>370644</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:55:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252471226</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:13:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B1D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/08%20Sunken%20Garden.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>416</key>
+		<dict>
+			<key>Track ID</key><integer>416</integer>
+			<key>Name</key><string>Late Night</string>
+			<key>Artist</key><string>Insanity Sect</string>
+			<key>Composer</key><string>Insanity Sect</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7764964</integer>
+			<key>Total Time</key><integer>320468</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:56:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247667460</integer>
+			<key>Play Date UTC</key><date>2006-11-30T01:51:00Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B20</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/09%20Late%20Night.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>417</key>
+		<dict>
+			<key>Track ID</key><integer>417</integer>
+			<key>Name</key><string>Aquasonic</string>
+			<key>Artist</key><string>A Positive Life</string>
+			<key>Composer</key><string>A Positive Life</string>
+			<key>Album</key><string>A Waveform Compilation (Vol. 2 Ambient Dub)</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>12098291</integer>
+			<key>Total Time</key><integer>499412</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-06-21T13:58:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251375985</integer>
+			<key>Play Date UTC</key><date>2007-01-11T23:59:45Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B23</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/A%20Waveform%20Compilation%20(Vol.%202%20Ambient%20Dub)/10%20Aquasonic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>418</key>
+		<dict>
+			<key>Track ID</key><integer>418</integer>
+			<key>Name</key><string>Apparently Nothin'</string>
+			<key>Artist</key><string>Young Disciples</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3925511</integer>
+			<key>Total Time</key><integer>241973</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:05:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T22:47:13Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B26</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-01%20Apparently%20Nothin'.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>419</key>
+		<dict>
+			<key>Track ID</key><integer>419</integer>
+			<key>Name</key><string>Cantaloop (Flip Fantasia)</string>
+			<key>Artist</key><string>Us3</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3603508</integer>
+			<key>Total Time</key><integer>221888</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:06:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253376986</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:49:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B2B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-02%20Cantaloop%20(Flip%20Fantasia).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>420</key>
+		<dict>
+			<key>Track ID</key><integer>420</integer>
+			<key>Name</key><string>So Tired Of Waiting</string>
+			<key>Artist</key><string>Bah Samba</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4941244</integer>
+			<key>Total Time</key><integer>304899</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:08:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251434389</integer>
+			<key>Play Date UTC</key><date>2007-01-12T16:13:09Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B2E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-03%20So%20Tired%20Of%20Waiting.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>421</key>
+		<dict>
+			<key>Track ID</key><integer>421</integer>
+			<key>Name</key><string>Space Cowboy</string>
+			<key>Artist</key><string>Jamiroquai</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3549475</integer>
+			<key>Total Time</key><integer>218498</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:10:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253340325</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:38:45Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-04%20Space%20Cowboy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>422</key>
+		<dict>
+			<key>Track ID</key><integer>422</integer>
+			<key>Name</key><string>Live In The Light</string>
+			<key>Artist</key><string>Fertile Ground</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5808242</integer>
+			<key>Total Time</key><integer>358398</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:13:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252517668</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:07:48Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B34</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-05%20Live%20In%20The%20Light.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>423</key>
+		<dict>
+			<key>Track ID</key><integer>423</integer>
+			<key>Name</key><string>Blacker (The Good Times)</string>
+			<key>Artist</key><string>Ballistic Brothers</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5990813</integer>
+			<key>Total Time</key><integer>369706</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:15:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253381833</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:10:33Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B37</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-06%20Blacker%20(The%20Good%20Times).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>424</key>
+		<dict>
+			<key>Track ID</key><integer>424</integer>
+			<key>Name</key><string>Be Thankful</string>
+			<key>Artist</key><string>Omar Feat. Angie Stone</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3974750</integer>
+			<key>Total Time</key><integer>245015</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:17:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249490276</integer>
+			<key>Play Date UTC</key><date>2006-12-21T04:11:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B3A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-07%20Be%20Thankful.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>425</key>
+		<dict>
+			<key>Track ID</key><integer>425</integer>
+			<key>Name</key><string>Never Stop</string>
+			<key>Artist</key><string>The Brand New Heavies</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4577610</integer>
+			<key>Total Time</key><integer>282469</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:18:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251441422</integer>
+			<key>Play Date UTC</key><date>2007-01-12T18:10:22Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B3D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-08%20Never%20Stop.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>426</key>
+		<dict>
+			<key>Track ID</key><integer>426</integer>
+			<key>Name</key><string>Magic Wand Of Love</string>
+			<key>Artist</key><string>UFO</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6229210</integer>
+			<key>Total Time</key><integer>384404</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:20:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253377940</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:05:40Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B40</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-09%20Magic%20Wand%20Of%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>427</key>
+		<dict>
+			<key>Track ID</key><integer>427</integer>
+			<key>Name</key><string>Rebirth Of Slick (Cool Like Dat)</string>
+			<key>Artist</key><string>Digable Planets</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4265847</integer>
+			<key>Total Time</key><integer>263243</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:22:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B43</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-10%20Rebirth%20Of%20Slick%20(Cool%20Like%20Dat).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>428</key>
+		<dict>
+			<key>Track ID</key><integer>428</integer>
+			<key>Name</key><string>Tours Woman</string>
+			<key>Artist</key><string>The Subterraneans</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4010068</integer>
+			<key>Total Time</key><integer>247267</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:23:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B46</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-11%20Tours%20Woman.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>429</key>
+		<dict>
+			<key>Track ID</key><integer>429</integer>
+			<key>Name</key><string>Sunship</string>
+			<key>Artist</key><string>Sunship</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5177690</integer>
+			<key>Total Time</key><integer>319505</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:26:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252537406</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:36:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B49</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-12%20Sunship.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>430</key>
+		<dict>
+			<key>Track ID</key><integer>430</integer>
+			<key>Name</key><string>Something In My Eye</string>
+			<key>Artist</key><string>Corduroy Feat. Sherine</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3302483</integer>
+			<key>Total Time</key><integer>203057</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:27:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250601644</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:54:04Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B4C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-13%20Something%20In%20My%20Eye.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>431</key>
+		<dict>
+			<key>Track ID</key><integer>431</integer>
+			<key>Name</key><string>Girl Overboard</string>
+			<key>Artist</key><string>Snowboy Feat. Anna Ross</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7196454</integer>
+			<key>Total Time</key><integer>444126</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:30:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252495935</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:05:35Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B4F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-14%20Girl%20Overboard.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>432</key>
+		<dict>
+			<key>Track ID</key><integer>432</integer>
+			<key>Name</key><string>I Am The Black Gold Of The Sun</string>
+			<key>Artist</key><string>Nuyorican Soul</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 1]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5242227</integer>
+			<key>Total Time</key><integer>323522</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T05:33:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251489025</integer>
+			<key>Play Date UTC</key><date>2007-01-13T07:23:45Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B52</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%201%5D/1-15%20I%20Am%20The%20Black%20Gold%20Of%20The%20Sun.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>433</key>
+		<dict>
+			<key>Track ID</key><integer>433</integer>
+			<key>Name</key><string>Dream Come True</string>
+			<key>Artist</key><string>The Brand New Heavies</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5420739</integer>
+			<key>Total Time</key><integer>334481</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:12:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253466014</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:33:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B55</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-01%20Dream%20Come%20True.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>434</key>
+		<dict>
+			<key>Track ID</key><integer>434</integer>
+			<key>Name</key><string>Always There</string>
+			<key>Artist</key><string>Incognito Feat. Jocelyn Brown</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3500925</integer>
+			<key>Total Time</key><integer>215502</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:12:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251467584</integer>
+			<key>Play Date UTC</key><date>2007-01-13T01:26:24Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B5A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-02%20Always%20There.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>435</key>
+		<dict>
+			<key>Track ID</key><integer>435</integer>
+			<key>Name</key><string>Rock (Unplugged)</string>
+			<key>Artist</key><string>DJ Spinna</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4455923</integer>
+			<key>Total Time</key><integer>274969</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:13:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247499849</integer>
+			<key>Play Date UTC</key><date>2006-11-28T03:17:29Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B5D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-03%20Rock%20(Unplugged).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>436</key>
+		<dict>
+			<key>Track ID</key><integer>436</integer>
+			<key>Name</key><string>I'M The One</string>
+			<key>Artist</key><string>D’Influence</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3749087</integer>
+			<key>Total Time</key><integer>230944</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:13:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252393284</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:34:44Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B60</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-04%20I'M%20The%20One.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>437</key>
+		<dict>
+			<key>Track ID</key><integer>437</integer>
+			<key>Name</key><string>For Your Precious Love</string>
+			<key>Artist</key><string>Jestofunk</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5475708</integer>
+			<key>Total Time</key><integer>337872</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:14:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249279764</integer>
+			<key>Play Date UTC</key><date>2006-12-18T17:42:44Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B63</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-05%20For%20Your%20Precious%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>438</key>
+		<dict>
+			<key>Track ID</key><integer>438</integer>
+			<key>Name</key><string>Free Your Mind</string>
+			<key>Artist</key><string>James Taylor Quartet</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4785609</integer>
+			<key>Total Time</key><integer>295309</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:14:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252572256</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:17:36Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B66</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-06%20Free%20Your%20Mind.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>439</key>
+		<dict>
+			<key>Track ID</key><integer>439</integer>
+			<key>Name</key><string>Money</string>
+			<key>Artist</key><string>will.i.am</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3608067</integer>
+			<key>Total Time</key><integer>222097</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:14:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250599853</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:24:13Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B69</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-07%20Money.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>440</key>
+		<dict>
+			<key>Track ID</key><integer>440</integer>
+			<key>Name</key><string>People Everyday</string>
+			<key>Artist</key><string>Arrested Development</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4839538</integer>
+			<key>Total Time</key><integer>298630</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:15:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253354133</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:28:53Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B6C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-08%20People%20Everyday.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>441</key>
+		<dict>
+			<key>Track ID</key><integer>441</integer>
+			<key>Name</key><string>Spinning Wheel</string>
+			<key>Artist</key><string>New Jersey Kings</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5190249</integer>
+			<key>Total Time</key><integer>320294</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:15:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252558769</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:32:49Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B6F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-09%20Spinning%20Wheel.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>442</key>
+		<dict>
+			<key>Track ID</key><integer>442</integer>
+			<key>Name</key><string>Frederick Lies Still</string>
+			<key>Artist</key><string>Galliano</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4846287</integer>
+			<key>Total Time</key><integer>299048</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:16:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252517107</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:58:27Z</date>
+			<key>Skip Count</key><integer>3</integer>
+			<key>Skip Date</key><date>2007-02-06T21:12:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B72</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-10%20Frederick%20Lies%20Still.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>443</key>
+		<dict>
+			<key>Track ID</key><integer>443</integer>
+			<key>Name</key><string>Lovesick</string>
+			<key>Artist</key><string>Night Train</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4292915</integer>
+			<key>Total Time</key><integer>264891</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:16:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246081314</integer>
+			<key>Play Date UTC</key><date>2006-11-11T17:15:14Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B75</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-11%20Lovesick.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>444</key>
+		<dict>
+			<key>Track ID</key><integer>444</integer>
+			<key>Name</key><string>Trust Me</string>
+			<key>Artist</key><string>Vibraphonic Feat. Alison Limerick</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5228248</integer>
+			<key>Total Time</key><integer>322663</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:17:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B78</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-12%20Trust%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>445</key>
+		<dict>
+			<key>Track ID</key><integer>445</integer>
+			<key>Name</key><string>Time Of The Future</string>
+			<key>Artist</key><string>Mother Earth</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3656098</integer>
+			<key>Total Time</key><integer>225162</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:17:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250585973</integer>
+			<key>Play Date UTC</key><date>2007-01-02T20:32:53Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B7B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-13%20Time%20Of%20The%20Future.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>446</key>
+		<dict>
+			<key>Track ID</key><integer>446</integer>
+			<key>Name</key><string>Love Me To Death</string>
+			<key>Artist</key><string>A Man Called Adam</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3696199</integer>
+			<key>Total Time</key><integer>227693</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:17:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253717409</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:23:29Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-25T17:23:19Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B7E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-14%20Love%20Me%20To%20Death.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>447</key>
+		<dict>
+			<key>Track ID</key><integer>447</integer>
+			<key>Name</key><string>Mr. Jeckle</string>
+			<key>Artist</key><string>Max Beesley's High Vibes</string>
+			<key>Composer</key><string>Various Artists</string>
+			<key>Album</key><string>Acid Jazz The Essential Album [Disc 2]</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3965418</integer>
+			<key>Total Time</key><integer>244481</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-08-08T06:17:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B81</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Acid%20Jazz%20The%20Essential%20Album%20%5BDisc%202%5D/2-15%20Mr.%20Jeckle.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>448</key>
+		<dict>
+			<key>Track ID</key><integer>448</integer>
+			<key>Name</key><string>Are You Okay?</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>33396628</integer>
+			<key>Total Time</key><integer>270133</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2004-08-22T18:40:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>988</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252576105</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:21:45Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-03T16:31:00Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B84</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/01%20Are%20You%20Okay_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>449</key>
+		<dict>
+			<key>Track ID</key><integer>449</integer>
+			<key>Name</key><string>Papa Was A Rollin' Stone</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Barrett Strong/Whitfield, Norman</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>45664294</integer>
+			<key>Total Time</key><integer>401293</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-28T23:55:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>909</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252514301</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:11:41Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B89</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/02%20Papa%20Was%20A%20Rollin'%20Stone.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>450</key>
+		<dict>
+			<key>Track ID</key><integer>450</integer>
+			<key>Name</key><string>I Feel Better Than James Brown</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>33484846</integer>
+			<key>Total Time</key><integer>284906</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-24T19:15:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>939</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250678294</integer>
+			<key>Play Date UTC</key><date>2007-01-03T22:11:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B8C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/03%20I%20Feel%20Better%20Than%20James%20Brown.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>451</key>
+		<dict>
+			<key>Track ID</key><integer>451</integer>
+			<key>Name</key><string>How The Heart Behaves</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>40196871</integer>
+			<key>Total Time</key><integer>335093</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-28T22:12:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>959</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253352682</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:04:42Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B8F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/04%20How%20The%20Heart%20Behaves.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>452</key>
+		<dict>
+			<key>Track ID</key><integer>452</integer>
+			<key>Name</key><string>Maria Novarro</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23807060</integer>
+			<key>Total Time</key><integer>206973</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-26T19:07:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>919</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3245948534</integer>
+			<key>Play Date UTC</key><date>2006-11-10T04:22:14Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/05%20Maria%20Novarro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>453</key>
+		<dict>
+			<key>Track ID</key><integer>453</integer>
+			<key>Name</key><string>I Blew Up The United States</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26390823</integer>
+			<key>Total Time</key><integer>230893</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-08T19:01:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>913</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252414466</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:27:46Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-02-04T17:10:11Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B95</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/06%20I%20Blew%20Up%20The%20United%20States.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>454</key>
+		<dict>
+			<key>Track ID</key><integer>454</integer>
+			<key>Name</key><string>In K Mart Wardrobe</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31439918</integer>
+			<key>Total Time</key><integer>256133</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-26T16:40:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>981</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253356390</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:06:30Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B98</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/07%20In%20K%20Mart%20Wardrobe.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>455</key>
+		<dict>
+			<key>Track ID</key><integer>455</integer>
+			<key>Name</key><string>Elvis' Rolls Royce</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>21561041</integer>
+			<key>Total Time</key><integer>209733</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-07T00:00:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>821</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253382866</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:27:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B9B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/08%20Elvis'%20Rolls%20Royce.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>456</key>
+		<dict>
+			<key>Track ID</key><integer>456</integer>
+			<key>Name</key><string>Dressed To Be Killed</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/G Love E/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>30002159</integer>
+			<key>Total Time</key><integer>252666</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-10T22:51:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>949</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246642706</integer>
+			<key>Play Date UTC</key><date>2006-11-18T05:11:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85B9E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/09%20Dressed%20To%20Be%20Killed.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>457</key>
+		<dict>
+			<key>Track ID</key><integer>457</integer>
+			<key>Name</key><string>Just Another Couple Broken Hearts</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>36625979</integer>
+			<key>Total Time</key><integer>294866</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-03T14:35:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>993</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253028860</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:07:40Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BA1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/10%20Just%20Another%20Couple%20Broken%20Hearts.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>458</key>
+		<dict>
+			<key>Track ID</key><integer>458</integer>
+			<key>Name</key><string>You! You! You!</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Luis Resto/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>21455630</integer>
+			<key>Total Time</key><integer>208640</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-05T16:08:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>821</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T19:11:27Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BA4</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/11%20You!%20You!%20You!.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>459</key>
+		<dict>
+			<key>Track ID</key><integer>459</integer>
+			<key>Name</key><string>Look What's Back</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Don Was/Was, David</string>
+			<key>Album</key><string>Are You Okay?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>4362447</integer>
+			<key>Total Time</key><integer>43560</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-08T23:10:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>797</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247559747</integer>
+			<key>Play Date UTC</key><date>2006-11-28T19:55:47Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BA7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Are%20You%20Okay_/12%20Look%20What's%20Back.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>460</key>
+		<dict>
+			<key>Track ID</key><integer>460</integer>
+			<key>Name</key><string>Cannonball</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11123448</integer>
+			<key>Total Time</key><integer>459177</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-24T23:58:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253535749</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:55:49Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BAA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/01%20Cannonball.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>461</key>
+		<dict>
+			<key>Track ID</key><integer>461</integer>
+			<key>Name</key><string>Still In Love</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6714336</integer>
+			<key>Total Time</key><integer>277097</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-24T23:58:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252574054</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:47:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BAF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/02%20Still%20In%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>462</key>
+		<dict>
+			<key>Track ID</key><integer>462</integer>
+			<key>Name</key><string>No Inbetween</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6707320</integer>
+			<key>Total Time</key><integer>276798</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-24T23:59:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253029136</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:12:16Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T23:27:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BB2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/03%20No%20Inbetween.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>463</key>
+		<dict>
+			<key>Track ID</key><integer>463</integer>
+			<key>Name</key><string>Better Days</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9109095</integer>
+			<key>Total Time</key><integer>375977</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-25T00:00:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253462415</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:33:35Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:12Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BB5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/04%20Better%20Days.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>464</key>
+		<dict>
+			<key>Track ID</key><integer>464</integer>
+			<key>Name</key><string>Brother Where You Bound</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>24012211</integer>
+			<key>Total Time</key><integer>991401</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-25T00:03:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253525183</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:59:43Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BB8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/05%20Brother%20Where%20You%20Bound.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>465</key>
+		<dict>
+			<key>Track ID</key><integer>465</integer>
+			<key>Name</key><string>Ever Open Door</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Brother Where You Bound</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4446466</integer>
+			<key>Total Time</key><integer>182932</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1985</integer>
+			<key>Date Modified</key><date>2004-06-25T00:04:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246979262</integer>
+			<key>Play Date UTC</key><date>2006-11-22T02:41:02Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BBB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Brother%20Where%20You%20Bound/06%20Ever%20Open%20Door.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>466</key>
+		<dict>
+			<key>Track ID</key><integer>466</integer>
+			<key>Name</key><string>Good To Be Alive By DJ RAP</string>
+			<key>Artist</key><string>DJ Rap</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25534293</integer>
+			<key>Total Time</key><integer>221693</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T23:53:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>920</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>22</integer>
+			<key>Play Date</key><integer>3252899694</integer>
+			<key>Play Date UTC</key><date>2007-01-29T15:14:54Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-04T23:15:29Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BBE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/01%20Good%20To%20Be%20Alive%20By%20DJ%20RAP.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>467</key>
+		<dict>
+			<key>Track ID</key><integer>467</integer>
+			<key>Name</key><string>B-Boy Stance By Freestylers</string>
+			<key>Artist</key><string>Freestylers Feat. Tenor Fly</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28831725</integer>
+			<key>Total Time</key><integer>257640</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-10-01T14:49:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>894</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253456616</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:56:56Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T22:05:13Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BC3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/02%20B-Boy%20Stance%20By%20Freestylers.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>468</key>
+		<dict>
+			<key>Track ID</key><integer>468</integer>
+			<key>Name</key><string>Bubble Bath By $.10</string>
+			<key>Artist</key><string>10¢</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>18326229</integer>
+			<key>Total Time</key><integer>167093</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-10-17T15:55:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>875</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T23:13:05Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BC6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/03%20Bubble%20Bath%20By%20$.10.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>469</key>
+		<dict>
+			<key>Track ID</key><integer>469</integer>
+			<key>Name</key><string>Six By Mansun</string>
+			<key>Artist</key><string>Mansun</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>30740921</integer>
+			<key>Total Time</key><integer>236360</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-10-06T23:19:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1039</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>21</integer>
+			<key>Play Date</key><integer>3253539563</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:59:23Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-30T20:20:49Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BC9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/05%20Six%20By%20Mansun.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>470</key>
+		<dict>
+			<key>Track ID</key><integer>470</integer>
+			<key>Name</key><string>If You Tolerate This Your Children Will Be Ne</string>
+			<key>Artist</key><string>Manic Street Preachers</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>39223797</integer>
+			<key>Total Time</key><integer>288333</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T23:58:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1087</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252576394</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:26:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BCC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/06%20If%20You%20Tolerate%20This%20Your%20Children%20Will%20Be%20Ne.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>471</key>
+		<dict>
+			<key>Track ID</key><integer>471</integer>
+			<key>Name</key><string>Longevity</string>
+			<key>Artist</key><string>Bolt Upright</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24354173</integer>
+			<key>Total Time</key><integer>196266</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2004-10-08T02:53:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>991</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250667834</integer>
+			<key>Play Date UTC</key><date>2007-01-03T19:17:14Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:43:21Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BCF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/07%20Longevity.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>472</key>
+		<dict>
+			<key>Track ID</key><integer>472</integer>
+			<key>Name</key><string>Style By Orbital</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28554313</integer>
+			<key>Total Time</key><integer>244800</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T16:13:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>932</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252539101</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:05:01Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BD5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/11%20Style%20By%20Orbital.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>473</key>
+		<dict>
+			<key>Track ID</key><integer>473</integer>
+			<key>Name</key><string>Drunk Is Better Than Dead</string>
+			<key>Artist</key><string>The Push Stars</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>27265475</integer>
+			<key>Total Time</key><integer>217200</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T14:33:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1003</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246467154</integer>
+			<key>Play Date UTC</key><date>2006-11-16T04:25:54Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BD8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/12%20Drunk%20Is%20Better%20Than%20Dead.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>474</key>
+		<dict>
+			<key>Track ID</key><integer>474</integer>
+			<key>Name</key><string>Murder (Or A Heart Attack)</string>
+			<key>Artist</key><string>Old 97's</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29124849</integer>
+			<key>Total Time</key><integer>216466</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-10-17T14:28:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1075</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BDB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/13%20Murder%20(Or%20A%20Heart%20Attack).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>475</key>
+		<dict>
+			<key>Track ID</key><integer>475</integer>
+			<key>Name</key><string>Man With The Hex By Atomic Fireballs</string>
+			<key>Artist</key><string>The Atomic Fireballs</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24954841</integer>
+			<key>Total Time</key><integer>181133</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T23:57:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1100</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253688394</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:19:54Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BDE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/14%20Man%20With%20The%20Hex%20By%20Atomic%20Fireballs.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>476</key>
+		<dict>
+			<key>Track ID</key><integer>476</integer>
+			<key>Name</key><string>Do Something</string>
+			<key>Artist</key><string>Macy Gray</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28616734</integer>
+			<key>Total Time</key><integer>251200</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-26T16:36:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>910</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>25</integer>
+			<key>Play Date</key><integer>3253522969</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:22:49Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BE1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/15%20Do%20Something.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>477</key>
+		<dict>
+			<key>Track ID</key><integer>477</integer>
+			<key>Name</key><string>World Wide Funk</string>
+			<key>Artist</key><string>Expansion Union</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>55560305</integer>
+			<key>Total Time</key><integer>432133</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-28T23:53:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1028</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252483637</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:40:37Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BE4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/16%20World%20Wide%20Funk.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>478</key>
+		<dict>
+			<key>Track ID</key><integer>478</integer>
+			<key>Name</key><string>Goldrush</string>
+			<key>Artist</key><string>The Herbaliser</string>
+			<key>Album</key><string>CMJ New Music Monthly, Volume 70, June 1999</string>
+			<key>Genre</key><string>Unclassifiable</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>37448337</integer>
+			<key>Total Time</key><integer>368866</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Date Modified</key><date>2005-09-24T19:41:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>811</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253765854</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:50:54Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-02T14:03:43Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BE7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/CMJ%20New%20Music%20Monthly,%20Volume%2070,%20June%201999/17%20Goldrush.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>479</key>
+		<dict>
+			<key>Track ID</key><integer>479</integer>
+			<key>Name</key><string>04 04 04 04 04 Cowgirl (Irish Pub In Ky</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dirty Epic - Cowgirl (EP)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14086491</integer>
+			<key>Total Time</key><integer>704313</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250588617</integer>
+			<key>Play Date UTC</key><date>2007-01-02T21:16:57Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T18:58:55Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BEA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Dirty%20Epic%20-%20Cowgirl%20(EP)/04%2004%2004%2004%2004%20Cowgirl%20(Irish%20Pub%20In%20Ky.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>480</key>
+		<dict>
+			<key>Track ID</key><integer>480</integer>
+			<key>Name</key><string>Song of Life</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6248853</integer>
+			<key>Total Time</key><integer>260606</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:35:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250594604</integer>
+			<key>Play Date UTC</key><date>2007-01-02T22:56:44Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BEF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/01%20Song%20of%20Life.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>481</key>
+		<dict>
+			<key>Track ID</key><integer>481</integer>
+			<key>Name</key><string>Samurai</string>
+			<key>Artist</key><string>Jungle High</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10066662</integer>
+			<key>Total Time</key><integer>418324</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:37:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253361518</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:31:58Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BF4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/02%20Samurai.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>482</key>
+		<dict>
+			<key>Track ID</key><integer>482</integer>
+			<key>Name</key><string>Patients</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8662810</integer>
+			<key>Total Time</key><integer>362004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:38:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253289543</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:32:23Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BF7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/03%20Patients.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>483</key>
+		<dict>
+			<key>Track ID</key><integer>483</integer>
+			<key>Name</key><string>Angel of Love (Dub Pylon Mix)</string>
+			<key>Artist</key><string>Zexos</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9880943</integer>
+			<key>Total Time</key><integer>411134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:39:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253510328</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:52:08Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BFA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/04%20Angel%20of%20Love%20(Dub%20Pylon%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>484</key>
+		<dict>
+			<key>Track ID</key><integer>484</integer>
+			<key>Name</key><string>Young American Primitive (Angel's Hand Mix)</string>
+			<key>Artist</key><string>Young American Primitive</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9267001</integer>
+			<key>Total Time</key><integer>383977</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:40:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253691253</integer>
+			<key>Play Date UTC</key><date>2007-02-07T19:07:33Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85BFD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/05%20Young%20American%20Primitive%20(Angel's%20Hand%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>485</key>
+		<dict>
+			<key>Track ID</key><integer>485</integer>
+			<key>Name</key><string>LSD (Trippy Tribal Trance Dub)</string>
+			<key>Artist</key><string>Tripp</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9435510</integer>
+			<key>Total Time</key><integer>391700</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:51:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251885259</integer>
+			<key>Play Date UTC</key><date>2007-01-17T21:27:39Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C00</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/06%20LSD%20(Trippy%20Tribal%20Trance%20Dub).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>486</key>
+		<dict>
+			<key>Track ID</key><integer>486</integer>
+			<key>Name</key><string>A Great New Adventure (Trance Instrumental)</string>
+			<key>Artist</key><string>Q.B.N.Z.</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7984248</integer>
+			<key>Total Time</key><integer>329876</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:52:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252468403</integer>
+			<key>Play Date UTC</key><date>2007-01-24T15:26:43Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C03</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/07%20A%20Great%20New%20Adventure%20(Trance%20Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>487</key>
+		<dict>
+			<key>Track ID</key><integer>487</integer>
+			<key>Name</key><string>An Accident In Paradise</string>
+			<key>Artist</key><string>SVEN V TH</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9339466</integer>
+			<key>Total Time</key><integer>387134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T14:53:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253528872</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:01:12Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C06</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/08%20An%20Accident%20In%20Paradise.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>488</key>
+		<dict>
+			<key>Track ID</key><integer>488</integer>
+			<key>Name</key><string>Wind it Up (Forward Wind Mix)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8717892</integer>
+			<key>Total Time</key><integer>359828</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T16:45:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253336005</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:26:45Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C09</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/10%20Wind%20it%20Up%20(Forward%20Wind%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>489</key>
+		<dict>
+			<key>Track ID</key><integer>489</integer>
+			<key>Name</key><string>Butoh</string>
+			<key>Artist</key><string>Futurhythm</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8452424</integer>
+			<key>Total Time</key><integer>349438</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T16:46:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250592471</integer>
+			<key>Play Date UTC</key><date>2007-01-02T22:21:11Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:43:29Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C0C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/11%20Butoh.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>490</key>
+		<dict>
+			<key>Track ID</key><integer>490</integer>
+			<key>Name</key><string>Fall From Grace (Free Me Mix)</string>
+			<key>Artist</key><string>Eskimos &#38; Egypt</string>
+			<key>Album</key><string>Futurhythms</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8728822</integer>
+			<key>Total Time</key><integer>360468</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-26T16:47:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253373536</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:52:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C0F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Futurhythms/12%20Fall%20From%20Grace%20(Free%20Me%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>491</key>
+		<dict>
+			<key>Track ID</key><integer>491</integer>
+			<key>Name</key><string>La Sagrada Familia</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>12763078</integer>
+			<key>Total Time</key><integer>526868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:48:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249311005</integer>
+			<key>Play Date UTC</key><date>2006-12-19T02:23:25Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C12</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/01%20La%20Sagrada%20Familia.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>492</key>
+		<dict>
+			<key>Track ID</key><integer>492</integer>
+			<key>Name</key><string>Too Late</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6572277</integer>
+			<key>Total Time</key><integer>271230</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:49:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251635697</integer>
+			<key>Play Date UTC</key><date>2007-01-15T00:08:17Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-25T17:23:47Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C17</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/02%20Too%20Late.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>493</key>
+		<dict>
+			<key>Track ID</key><integer>493</integer>
+			<key>Name</key><string>Closer To Heaven</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8551093</integer>
+			<key>Total Time</key><integer>352937</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:50:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251380797</integer>
+			<key>Play Date UTC</key><date>2007-01-12T01:19:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C1A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/03%20Closer%20To%20Heaven.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>494</key>
+		<dict>
+			<key>Track ID</key><integer>494</integer>
+			<key>Name</key><string>Standing On Higher Ground</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7357129</integer>
+			<key>Total Time</key><integer>303636</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:51:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253361822</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:37:02Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C1D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/04%20Standing%20On%20Higher%20Ground.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>495</key>
+		<dict>
+			<key>Track ID</key><integer>495</integer>
+			<key>Name</key><string>Money Talks</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6455418</integer>
+			<key>Total Time</key><integer>266388</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:52:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253265444</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:50:44Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C20</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/05%20Money%20Talks.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>496</key>
+		<dict>
+			<key>Track ID</key><integer>496</integer>
+			<key>Name</key><string>Inside Looking Out</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9264519</integer>
+			<key>Total Time</key><integer>382398</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:53:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253600134</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:48:54Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C23</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/06%20Inside%20Looking%20Out.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>497</key>
+		<dict>
+			<key>Track ID</key><integer>497</integer>
+			<key>Name</key><string>Paseo De Gracia (Instrumental)</string>
+			<key>Artist</key><string>Alan Parsons Project</string>
+			<key>Album</key><string>Gaudi</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5508349</integer>
+			<key>Total Time</key><integer>227134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-06-22T23:53:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253766081</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:54:41Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T03:05:58Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C26</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Gaudi/07%20Paseo%20De%20Gracia%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>498</key>
+		<dict>
+			<key>Track ID</key><integer>498</integer>
+			<key>Name</key><string>Welcome to My Life</string>
+			<key>Artist</key><string>Simple Plan</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3591255</integer>
+			<key>Total Time</key><integer>203335</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-27T04:55:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252493294</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:21:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C29</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/02%20Welcome%20to%20My%20Life.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>499</key>
+		<dict>
+			<key>Track ID</key><integer>499</integer>
+			<key>Name</key><string>Gotta Get Up from Here</string>
+			<key>Artist</key><string>Ellie Lawson</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3748407</integer>
+			<key>Total Time</key><integer>219775</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T14:49:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>22</integer>
+			<key>Play Date</key><integer>3252901610</integer>
+			<key>Play Date UTC</key><date>2007-01-29T15:46:50Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/04%20Gotta%20Get%20Up%20from%20Here.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>500</key>
+		<dict>
+			<key>Track ID</key><integer>500</integer>
+			<key>Name</key><string>Lost Control</string>
+			<key>Artist</key><string>Unwritten Law</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3149351</integer>
+			<key>Total Time</key><integer>173033</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T06:21:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249199190</integer>
+			<key>Play Date UTC</key><date>2006-12-17T19:19:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C34</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/05%20Lost%20Control.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>501</key>
+		<dict>
+			<key>Track ID</key><integer>501</integer>
+			<key>Name</key><string>What You Want</string>
+			<key>Artist</key><string>John Butler Trio</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5517543</integer>
+			<key>Total Time</key><integer>320875</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-20T17:05:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253553794</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:56:34Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C37</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/06%20What%20You%20Want.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>502</key>
+		<dict>
+			<key>Track ID</key><integer>502</integer>
+			<key>Name</key><string>When I'm Gone (Sadie)</string>
+			<key>Artist</key><string>No Address</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4499655</integer>
+			<key>Total Time</key><integer>259342</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-04T02:56:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253591578</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:26:18Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C3A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/07%20When%20I'm%20Gone%20(Sadie).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>503</key>
+		<dict>
+			<key>Track ID</key><integer>503</integer>
+			<key>Name</key><string>Funny Little Feeling</string>
+			<key>Artist</key><string>Rock 'n' Roll Soldiers</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3054071</integer>
+			<key>Total Time</key><integer>167344</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-25T17:43:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250402552</integer>
+			<key>Play Date UTC</key><date>2006-12-31T17:35:52Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C3D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/08%20Funny%20Little%20Feeling.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>504</key>
+		<dict>
+			<key>Track ID</key><integer>504</integer>
+			<key>Name</key><string>Yesterday Never Tomorrows</string>
+			<key>Artist</key><string>The Stills</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5411111</integer>
+			<key>Total Time</key><integer>320782</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-20T07:30:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250620796</integer>
+			<key>Play Date UTC</key><date>2007-01-03T06:13:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C40</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/09%20Yesterday%20Never%20Tomorrows.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>505</key>
+		<dict>
+			<key>Track ID</key><integer>505</integer>
+			<key>Name</key><string>Louis XIV</string>
+			<key>Artist</key><string>Louis XIV</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2958039</integer>
+			<key>Total Time</key><integer>164651</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-18T01:28:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252476977</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:49:37Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C43</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/10%20Louis%20XIV.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>506</key>
+		<dict>
+			<key>Track ID</key><integer>506</integer>
+			<key>Name</key><string>Broken Promises</string>
+			<key>Artist</key><string>Moments In Grace</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3522935</integer>
+			<key>Total Time</key><integer>195905</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-28T04:15:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252533234</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:27:14Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C46</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/11%20Broken%20Promises.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>507</key>
+		<dict>
+			<key>Track ID</key><integer>507</integer>
+			<key>Name</key><string>You'll Never Guess Who Died</string>
+			<key>Artist</key><string>The Kinison</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3750855</integer>
+			<key>Total Time</key><integer>209233</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-17T00:57:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252481983</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:13:03Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C49</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/12%20You'll%20Never%20Guess%20Who%20Died.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>508</key>
+		<dict>
+			<key>Track ID</key><integer>508</integer>
+			<key>Name</key><string>Pressure</string>
+			<key>Artist</key><string>Skindred</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3743175</integer>
+			<key>Total Time</key><integer>208769</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-25T21:54:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249460059</integer>
+			<key>Play Date UTC</key><date>2006-12-20T19:47:39Z</date>
+			<key>Skip Count</key><integer>3</integer>
+			<key>Skip Date</key><date>2007-02-05T19:21:37Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C4C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/13%20Pressure.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>509</key>
+		<dict>
+			<key>Track ID</key><integer>509</integer>
+			<key>Name</key><string>On Your Porch</string>
+			<key>Artist</key><string>The Format</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5217095</integer>
+			<key>Total Time</key><integer>311703</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-17T21:38:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253534665</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:37:45Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C4F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/14%20On%20Your%20Porch.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>510</key>
+		<dict>
+			<key>Track ID</key><integer>510</integer>
+			<key>Name</key><string>Everyday</string>
+			<key>Artist</key><string>Toby Lightman</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3832823</integer>
+			<key>Total Time</key><integer>228320</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-09T14:20:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253177860</integer>
+			<key>Play Date UTC</key><date>2007-02-01T20:31:00Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T02:51:47Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C52</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/15%20Everyday.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>511</key>
+		<dict>
+			<key>Track ID</key><integer>511</integer>
+			<key>Name</key><string>Shallow</string>
+			<key>Artist</key><string>Porcupine Tree</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Album</key><string>iTunes New Music Sampler (Atlantic/Lava Edition)</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3839047</integer>
+			<key>Total Time</key><integer>214922</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-28T20:00:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253535964</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:59:24Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-02T22:10:52Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85C55</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/iTunes%20New%20Music%20Sampler%20(Atlantic_Lava%20Edition)/16%20Shallow.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>512</key>
+		<dict>
+			<key>Track ID</key><integer>512</integer>
+			<key>Name</key><string>All I Really Want</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6862589</integer>
+			<key>Total Time</key><integer>284606</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:26:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252529305</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:21:45Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C58</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/01%20All%20I%20Really%20Want.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>513</key>
+		<dict>
+			<key>Track ID</key><integer>513</integer>
+			<key>Name</key><string>You Oughta Know</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5998848</integer>
+			<key>Total Time</key><integer>249172</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:29:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249194651</integer>
+			<key>Play Date UTC</key><date>2006-12-17T18:04:11Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T01:40:46Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C5D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/02%20You%20Oughta%20Know.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>514</key>
+		<dict>
+			<key>Track ID</key><integer>514</integer>
+			<key>Name</key><string>Perfect</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4526119</integer>
+			<key>Total Time</key><integer>187860</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:31:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253284584</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:09:44Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T01:41:00Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C60</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/03%20Perfect.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>515</key>
+		<dict>
+			<key>Track ID</key><integer>515</integer>
+			<key>Name</key><string>Hand In My Pocket</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5309582</integer>
+			<key>Total Time</key><integer>221673</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:34:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247465147</integer>
+			<key>Play Date UTC</key><date>2006-11-27T17:39:07Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C63</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/04%20Hand%20In%20My%20Pocket.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>516</key>
+		<dict>
+			<key>Track ID</key><integer>516</integer>
+			<key>Name</key><string>Right Through You</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4234328</integer>
+			<key>Total Time</key><integer>175785</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:36:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253268065</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:34:25Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C66</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/05%20Right%20Through%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>517</key>
+		<dict>
+			<key>Track ID</key><integer>517</integer>
+			<key>Name</key><string>Forgiven</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7228766</integer>
+			<key>Total Time</key><integer>300244</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:40:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252562875</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:41:15Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C69</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/06%20Forgiven.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>518</key>
+		<dict>
+			<key>Track ID</key><integer>518</integer>
+			<key>Name</key><string>You Learn</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5799449</integer>
+			<key>Total Time</key><integer>239614</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:43:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252991257</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:40:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C6C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/07%20You%20Learn.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>519</key>
+		<dict>
+			<key>Track ID</key><integer>519</integer>
+			<key>Name</key><string>Head Over Feet</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6406580</integer>
+			<key>Total Time</key><integer>267241</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:46:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253461265</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:14:25Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:43Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C6F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/08%20Head%20Over%20Feet.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>520</key>
+		<dict>
+			<key>Track ID</key><integer>520</integer>
+			<key>Name</key><string>Mary Jane</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6755273</integer>
+			<key>Total Time</key><integer>280596</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:50:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252571639</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:07:19Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C72</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/09%20Mary%20Jane.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>521</key>
+		<dict>
+			<key>Track ID</key><integer>521</integer>
+			<key>Name</key><string>Ironic</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5535747</integer>
+			<key>Total Time</key><integer>229673</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:52:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252482971</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:29:31Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C75</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/10%20Ironic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>522</key>
+		<dict>
+			<key>Track ID</key><integer>522</integer>
+			<key>Name</key><string>Not The Doctor</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5481200</integer>
+			<key>Total Time</key><integer>227561</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:55:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253278389</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:26:29Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C78</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/11%20Not%20The%20Doctor.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>523</key>
+		<dict>
+			<key>Track ID</key><integer>523</integer>
+			<key>Name</key><string>Wake Up</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7117835</integer>
+			<key>Total Time</key><integer>293758</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T17:59:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251890989</integer>
+			<key>Play Date UTC</key><date>2007-01-17T23:03:09Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C7B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/12%20Wake%20Up.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>524</key>
+		<dict>
+			<key>Track ID</key><integer>524</integer>
+			<key>Name</key><string>You Oughta Know (Alternate)</string>
+			<key>Artist</key><string>Alanis Morissette</string>
+			<key>Composer</key><string>Music by Alanis Morissette and Glen Ballard. Lyrics by Alanis Morissette.</string>
+			<key>Album</key><string>Jagged Little Pill</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10752633</integer>
+			<key>Total Time</key><integer>492926</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-05-04T18:05:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C7E</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Jagged%20Little%20Pill/13%20You%20Oughta%20Know%20(Alternate).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>525</key>
+		<dict>
+			<key>Track ID</key><integer>525</integer>
+			<key>Name</key><string>Everything Counts (Bomb-Beyond-The-Yalu-Mix)</string>
+			<key>Artist</key><string>Depeche Mode</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8004931</integer>
+			<key>Total Time</key><integer>331198</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:06:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246430042</integer>
+			<key>Play Date UTC</key><date>2006-11-15T18:07:22Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C81</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/01%20Everything%20Counts%20(Bomb-Beyond-The-Yalu-Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>526</key>
+		<dict>
+			<key>Track ID</key><integer>526</integer>
+			<key>Name</key><string>In A Manner Of Speaking</string>
+			<key>Artist</key><string>Martin Gore</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6062591</integer>
+			<key>Total Time</key><integer>251028</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:06:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251631021</integer>
+			<key>Play Date UTC</key><date>2007-01-14T22:50:21Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C86</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/02%20In%20A%20Manner%20Of%20Speaking.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>527</key>
+		<dict>
+			<key>Track ID</key><integer>527</integer>
+			<key>Name</key><string>Accidentally 4th Street (Gloria) [Remix]</string>
+			<key>Artist</key><string>Figures On A Beach</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5934546</integer>
+			<key>Total Time</key><integer>245716</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:07:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252550712</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:18:32Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C89</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/03%20Accidentally%204th%20Street%20(Gloria)%20%5BRemix%5D.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>528</key>
+		<dict>
+			<key>Track ID</key><integer>528</integer>
+			<key>Name</key><string>Thrash</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6291505</integer>
+			<key>Total Time</key><integer>260606</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:08:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251888388</integer>
+			<key>Play Date UTC</key><date>2007-01-17T22:19:48Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C8C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/04%20Thrash.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>529</key>
+		<dict>
+			<key>Track ID</key><integer>529</integer>
+			<key>Name</key><string>Pistol</string>
+			<key>Artist</key><string>Erasure</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5013827</integer>
+			<key>Total Time</key><integer>207892</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:09:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252525950</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:25:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C8F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/05%20Pistol.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>530</key>
+		<dict>
+			<key>Track ID</key><integer>530</integer>
+			<key>Name</key><string>Insha-Allah</string>
+			<key>Artist</key><string>Nasa</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10533902</integer>
+			<key>Total Time</key><integer>436585</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:10:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249569375</integer>
+			<key>Play Date UTC</key><date>2006-12-22T02:09:35Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/06%20Insha-Allah.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>531</key>
+		<dict>
+			<key>Track ID</key><integer>531</integer>
+			<key>Name</key><string>Dizzy (Remix)</string>
+			<key>Artist</key><string>Throwing Muses</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5098951</integer>
+			<key>Total Time</key><integer>211582</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:11:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253545777</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:42:57Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-09T21:07:51Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C95</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/07%20Dizzy%20(Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>532</key>
+		<dict>
+			<key>Track ID</key><integer>532</integer>
+			<key>Name</key><string>Whistling For His Love (Remix)</string>
+			<key>Artist</key><string>Danielle Dax</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9079973</integer>
+			<key>Total Time</key><integer>376318</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:12:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250609798</integer>
+			<key>Play Date UTC</key><date>2007-01-03T03:09:58Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C98</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/08%20Whistling%20For%20His%20Love%20(Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>533</key>
+		<dict>
+			<key>Track ID</key><integer>533</integer>
+			<key>Name</key><string>Lucky Lisp</string>
+			<key>Artist</key><string>Morrissey</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4199053</integer>
+			<key>Total Time</key><integer>173993</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:12:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252541052</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:37:32Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C9B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/09%20Lucky%20Lisp.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>534</key>
+		<dict>
+			<key>Track ID</key><integer>534</integer>
+			<key>Name</key><string>Between Something and Nothing</string>
+			<key>Artist</key><string>The Ocean Blue</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5791606</integer>
+			<key>Total Time</key><integer>240660</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:13:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249296293</integer>
+			<key>Play Date UTC</key><date>2006-12-18T22:18:13Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85C9E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/10%20Between%20Something%20and%20Nothing.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>535</key>
+		<dict>
+			<key>Track ID</key><integer>535</integer>
+			<key>Name</key><string>Da'ale Da'ale (Remix)</string>
+			<key>Artist</key><string>Ofra Haza</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8821926</integer>
+			<key>Total Time</key><integer>365588</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:14:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249312965</integer>
+			<key>Play Date UTC</key><date>2006-12-19T02:56:05Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CA1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/11%20Da'ale%20Da'ale%20(Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>536</key>
+		<dict>
+			<key>Track ID</key><integer>536</integer>
+			<key>Name</key><string>Don't Say No (Remix)</string>
+			<key>Artist</key><string>Tom Tom Club</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5814665</integer>
+			<key>Total Time</key><integer>241129</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:15:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249544812</integer>
+			<key>Play Date UTC</key><date>2006-12-21T19:20:12Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CA4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/12%20Don't%20Say%20No%20(Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>537</key>
+		<dict>
+			<key>Track ID</key><integer>537</integer>
+			<key>Name</key><string>Nanana</string>
+			<key>Artist</key><string>Royal Crescent Mob</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5441747</integer>
+			<key>Total Time</key><integer>226089</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:16:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251862359</integer>
+			<key>Play Date UTC</key><date>2007-01-17T15:05:59Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CA7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/14%20Nanana.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>538</key>
+		<dict>
+			<key>Track ID</key><integer>538</integer>
+			<key>Name</key><string>Date to Church</string>
+			<key>Artist</key><string>The Replacements</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5535284</integer>
+			<key>Total Time</key><integer>229182</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:17:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249464271</integer>
+			<key>Play Date UTC</key><date>2006-12-20T20:57:51Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CAA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/15%20Date%20to%20Church.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>539</key>
+		<dict>
+			<key>Track ID</key><integer>539</integer>
+			<key>Name</key><string>Nowhere to Stand</string>
+			<key>Artist</key><string>k.d. lang</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6470557</integer>
+			<key>Total Time</key><integer>267497</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:18:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253550791</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:06:31Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T23:33:52Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CAD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/16%20Nowhere%20to%20Stand.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>540</key>
+		<dict>
+			<key>Track ID</key><integer>540</integer>
+			<key>Name</key><string>Strawman (Live)</string>
+			<key>Artist</key><string>Lou Reed</string>
+			<key>Album</key><string>Just Say Mao</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8866224</integer>
+			<key>Total Time</key><integer>365929</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2005-06-14T14:19:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249206222</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:17:02Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CB0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Just%20Say%20Mao/17%20Strawman%20(Live).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>541</key>
+		<dict>
+			<key>Track ID</key><integer>541</integer>
+			<key>Name</key><string>London</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2714578</integer>
+			<key>Total Time</key><integer>166299</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:27:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253513677</integer>
+			<key>Play Date UTC</key><date>2007-02-05T17:47:57Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CB3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/01%20London.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>542</key>
+		<dict>
+			<key>Track ID</key><integer>542</integer>
+			<key>Name</key><string>Restless (Featuring Toastie Taylor)</string>
+			<key>Artist</key><string>Evil Nine Featuring Toastie Taylor</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4767773</integer>
+			<key>Total Time</key><integer>294868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2006-07-08T06:28:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253557110</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:51:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CB8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/02%20Restless%20(Featuring%20Toastie%20Taylor).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>543</key>
+		<dict>
+			<key>Track ID</key><integer>543</integer>
+			<key>Name</key><string>Smoked</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3574926</integer>
+			<key>Total Time</key><integer>220030</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:28:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253680361</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:06:01Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CBB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/03%20Smoked.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>544</key>
+		<dict>
+			<key>Track ID</key><integer>544</integer>
+			<key>Name</key><string>Fire to Me</string>
+			<key>Artist</key><string>Hyper Vs. The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4467041</integer>
+			<key>Total Time</key><integer>276269</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:29:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>32</integer>
+			<key>Play Date</key><integer>3253030779</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:39:39Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CBE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/04%20Fire%20to%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>545</key>
+		<dict>
+			<key>Track ID</key><integer>545</integer>
+			<key>Name</key><string>Roboslut</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3538511</integer>
+			<key>Total Time</key><integer>217732</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:29:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>33</integer>
+			<key>Play Date</key><integer>3253030997</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:43:17Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CC1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/05%20Roboslut.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>546</key>
+		<dict>
+			<key>Track ID</key><integer>546</integer>
+			<key>Name</key><string>Defective</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4269079</integer>
+			<key>Total Time</key><integer>263359</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:30:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3246906311</integer>
+			<key>Play Date UTC</key><date>2006-11-21T06:25:11Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CC4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/06%20Defective.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>547</key>
+		<dict>
+			<key>Track ID</key><integer>547</integer>
+			<key>Name</key><string>Vice</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3752999</integer>
+			<key>Total Time</key><integer>231153</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:30:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252535555</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:05:55Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CC7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/07%20Vice.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>548</key>
+		<dict>
+			<key>Track ID</key><integer>548</integer>
+			<key>Name</key><string>Crime</string>
+			<key>Artist</key><string>Troy Bonnes</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2892168</integer>
+			<key>Total Time</key><integer>177399</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:30:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253768670</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:37:50Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CCA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/08%20Crime.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>549</key>
+		<dict>
+			<key>Track ID</key><integer>549</integer>
+			<key>Name</key><string>C'mon Children</string>
+			<key>Artist</key><string>Out Crowd</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4886921</integer>
+			<key>Total Time</key><integer>301834</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:31:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253031476</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:51:16Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-04T22:52:19Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CCD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/09%20C'mon%20Children.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>550</key>
+		<dict>
+			<key>Track ID</key><integer>550</integer>
+			<key>Name</key><string>Onesixteen</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4549967</integer>
+			<key>Total Time</key><integer>280913</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:31:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253031757</integer>
+			<key>Play Date UTC</key><date>2007-01-31T03:55:57Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T01:24:15Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CD0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/10%20Onesixteen.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>551</key>
+		<dict>
+			<key>Track ID</key><integer>551</integer>
+			<key>Name</key><string>Sucker Punch</string>
+			<key>Artist</key><string>Connie Price &#38; The Keystones</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4400528</integer>
+			<key>Total Time</key><integer>271555</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2006-07-08T06:32:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247043665</integer>
+			<key>Play Date UTC</key><date>2006-11-22T20:34:25Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CD3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/11%20Sucker%20Punch.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>552</key>
+		<dict>
+			<key>Track ID</key><integer>552</integer>
+			<key>Name</key><string>Glass Breaker</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4775860</integer>
+			<key>Total Time</key><integer>294613</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:32:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253767436</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:17:16Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CD6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/12%20Glass%20Breaker.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>553</key>
+		<dict>
+			<key>Track ID</key><integer>553</integer>
+			<key>Name</key><string>I Luv U</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1120579</integer>
+			<key>Total Time</key><integer>66802</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:32:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253363679</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:07:59Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CD9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/13%20I%20Luv%20U.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>554</key>
+		<dict>
+			<key>Track ID</key><integer>554</integer>
+			<key>Name</key><string>Nothing Like You and I</string>
+			<key>Artist</key><string>The Perishers</string>
+			<key>Album</key><string>London (Original Motion Picture Soundtrack)</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3434413</integer>
+			<key>Total Time</key><integer>211601</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-07-08T06:32:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253382045</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:14:05Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-29T23:10:40Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CDC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/London%20(Original%20Motion%20Picture%20Soundtrack)/14%20Nothing%20Like%20You%20and%20I.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>555</key>
+		<dict>
+			<key>Track ID</key><integer>555</integer>
+			<key>Name</key><string>Superdeformed</string>
+			<key>Artist</key><string>Matthew Sweet</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5720409</integer>
+			<key>Total Time</key><integer>238377</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:00:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253378812</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:20:12Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CDF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/01%20Superdeformed.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>556</key>
+		<dict>
+			<key>Track ID</key><integer>556</integer>
+			<key>Name</key><string>For All To See</string>
+			<key>Artist</key><string>Buffalo Tom</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5198431</integer>
+			<key>Total Time</key><integer>216169</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:01:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251453570</integer>
+			<key>Play Date UTC</key><date>2007-01-12T21:32:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CE4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/02%20For%20All%20To%20See.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>557</key>
+		<dict>
+			<key>Track ID</key><integer>557</integer>
+			<key>Name</key><string>Sexual Healing</string>
+			<key>Artist</key><string>Soul Asylum</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6822722</integer>
+			<key>Total Time</key><integer>285460</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:02:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253551399</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:16:39Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CE7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/03%20Sexual%20Healing.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>558</key>
+		<dict>
+			<key>Track ID</key><integer>558</integer>
+			<key>Name</key><string>Take A Walk</string>
+			<key>Artist</key><string>Urge Overkill</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6726354</integer>
+			<key>Total Time</key><integer>279337</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:03:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247717654</integer>
+			<key>Play Date UTC</key><date>2006-11-30T15:47:34Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T22:42:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CEA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/04%20Take%20A%20Walk.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>559</key>
+		<dict>
+			<key>Track ID</key><integer>559</integer>
+			<key>Name</key><string>All Your Jeans Were Too Tight</string>
+			<key>Artist</key><string>American Music Club</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5119665</integer>
+			<key>Total Time</key><integer>213694</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:03:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251864057</integer>
+			<key>Play Date UTC</key><date>2007-01-17T15:34:17Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CED</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/05%20All%20Your%20Jeans%20Were%20Too%20Tight.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>560</key>
+		<dict>
+			<key>Track ID</key><integer>560</integer>
+			<key>Name</key><string>Bitch</string>
+			<key>Artist</key><string>Goo Goo Dolls</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4720014</integer>
+			<key>Total Time</key><integer>196990</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:04:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253363316</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:01:56Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CF0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/06%20Bitch.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>561</key>
+		<dict>
+			<key>Track ID</key><integer>561</integer>
+			<key>Name</key><string>Unseen Power Of The Picket Fence</string>
+			<key>Artist</key><string>Pavement</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5634787</integer>
+			<key>Total Time</key><integer>233961</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:05:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252549017</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:50:17Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CF3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/07%20Unseen%20Power%20Of%20The%20Picket%20Fence.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>562</key>
+		<dict>
+			<key>Track ID</key><integer>562</integer>
+			<key>Name</key><string>Glynis</string>
+			<key>Artist</key><string>Smashing Pumpkins</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7061325</integer>
+			<key>Total Time</key><integer>293332</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:05:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252391018</integer>
+			<key>Play Date UTC</key><date>2007-01-23T17:56:58Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CF6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/08%20Glynis.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>563</key>
+		<dict>
+			<key>Track ID</key><integer>563</integer>
+			<key>Name</key><string>Can't Fight It</string>
+			<key>Artist</key><string>Bob Mould</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5505631</integer>
+			<key>Total Time</key><integer>229310</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:06:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253609962</integer>
+			<key>Play Date UTC</key><date>2007-02-06T20:32:42Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CF9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/09%20Can't%20Fight%20It.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>564</key>
+		<dict>
+			<key>Track ID</key><integer>564</integer>
+			<key>Name</key><string>Hold On</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6330240</integer>
+			<key>Total Time</key><integer>263593</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:07:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253527716</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:41:56Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CFC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/10%20Hold%20On.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>565</key>
+		<dict>
+			<key>Track ID</key><integer>565</integer>
+			<key>Name</key><string>Show Me</string>
+			<key>Artist</key><string>Soundgarden</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4054526</integer>
+			<key>Total Time</key><integer>168809</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:07:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249491630</integer>
+			<key>Play Date UTC</key><date>2006-12-21T04:33:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85CFF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/11%20Show%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>566</key>
+		<dict>
+			<key>Track ID</key><integer>566</integer>
+			<key>Name</key><string>Brittle</string>
+			<key>Artist</key><string>Straightjacket Fits</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4907511</integer>
+			<key>Total Time</key><integer>204841</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:08:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251307970</integer>
+			<key>Play Date UTC</key><date>2007-01-11T05:06:10Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D02</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/12%20Brittle.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>567</key>
+		<dict>
+			<key>Track ID</key><integer>567</integer>
+			<key>Name</key><string>Joed Out</string>
+			<key>Artist</key><string>Barbara Manning &#38; The San Francisco Seals</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5573866</integer>
+			<key>Total Time</key><integer>232425</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:09:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253280936</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:08:56Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T19:09:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D05</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/13%20Joed%20Out.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>568</key>
+		<dict>
+			<key>Track ID</key><integer>568</integer>
+			<key>Name</key><string>Heavy 33</string>
+			<key>Artist</key><string>Verlaines</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6284329</integer>
+			<key>Total Time</key><integer>261652</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:09:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T19:11:23Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D08</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/14%20Heavy%2033.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>569</key>
+		<dict>
+			<key>Track ID</key><integer>569</integer>
+			<key>Name</key><string>Effigy</string>
+			<key>Artist</key><string>Uncle Tupelo</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8667466</integer>
+			<key>Total Time</key><integer>359614</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:10:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247464127</integer>
+			<key>Play Date UTC</key><date>2006-11-27T17:22:07Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D0B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/15%20Effigy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>570</key>
+		<dict>
+			<key>Track ID</key><integer>570</integer>
+			<key>Name</key><string>New Style</string>
+			<key>Artist</key><string>The Beastie Boys</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3376911</integer>
+			<key>Total Time</key><integer>140564</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:11:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3251435572</integer>
+			<key>Play Date UTC</key><date>2007-01-12T16:32:52Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D0E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/16%20New%20Style.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>571</key>
+		<dict>
+			<key>Track ID</key><integer>571</integer>
+			<key>Name</key><string>Iris</string>
+			<key>Artist</key><string>The Breeders</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5383289</integer>
+			<key>Total Time</key><integer>224361</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:12:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251442602</integer>
+			<key>Play Date UTC</key><date>2007-01-12T18:30:02Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D11</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/17%20Iris.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>572</key>
+		<dict>
+			<key>Track ID</key><integer>572</integer>
+			<key>Name</key><string>Verse Chorus Verse</string>
+			<key>Artist</key><string>Nirvana</string>
+			<key>Album</key><string>No Alternative</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4957224</integer>
+			<key>Total Time</key><integer>205950</integer>
+			<key>Track Number</key><integer>19</integer>
+			<key>Track Count</key><integer>19</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-30T04:13:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D14</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/No%20Alternative/19%20Verse%20Chorus%20Verse.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>574</key>
+		<dict>
+			<key>Track ID</key><integer>574</integer>
+			<key>Name</key><string>Jump (Mutha Mix)</string>
+			<key>Artist</key><string>The Movement</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5635171</integer>
+			<key>Total Time</key><integer>233364</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:16:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251885688</integer>
+			<key>Play Date UTC</key><date>2007-01-17T21:34:48Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D1C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/02%20Jump%20(Mutha%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>575</key>
+		<dict>
+			<key>Track ID</key><integer>575</integer>
+			<key>Name</key><string>Get Ready For This (Ochrestral Mix)</string>
+			<key>Artist</key><string>2 Unlimited</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7912912</integer>
+			<key>Total Time</key><integer>327401</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:17:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251374312</integer>
+			<key>Play Date UTC</key><date>2007-01-11T23:31:52Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D1F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/03%20Get%20Ready%20For%20This%20(Ochrestral%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>576</key>
+		<dict>
+			<key>Track ID</key><integer>576</integer>
+			<key>Name</key><string>Can You Feel The Passion (Palladium Mix)</string>
+			<key>Artist</key><string>Blue Pearl</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8205127</integer>
+			<key>Total Time</key><integer>339305</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:18:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251440910</integer>
+			<key>Play Date UTC</key><date>2007-01-12T18:01:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D22</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/04%20Can%20You%20Feel%20The%20Passion%20(Palladium%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>577</key>
+		<dict>
+			<key>Track ID</key><integer>577</integer>
+			<key>Name</key><string>Dreamer, Dream</string>
+			<key>Artist</key><string>Code Red</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7249832</integer>
+			<key>Total Time</key><integer>300585</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:19:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D25</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/05%20Dreamer,%20Dream.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>578</key>
+		<dict>
+			<key>Track ID</key><integer>578</integer>
+			<key>Name</key><string>Stylophonia</string>
+			<key>Artist</key><string>Two Little Boys</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6073068</integer>
+			<key>Total Time</key><integer>250644</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:20:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249567629</integer>
+			<key>Play Date UTC</key><date>2006-12-22T01:40:29Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D28</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/06%20Stylophonia.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>579</key>
+		<dict>
+			<key>Track ID</key><integer>579</integer>
+			<key>Name</key><string>Injected With A Poison (MNO Power Mix)</string>
+			<key>Artist</key><string>Praga Khan Featuring Jade 4 U</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7291054</integer>
+			<key>Total Time</key><integer>301737</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:20:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253386064</integer>
+			<key>Play Date UTC</key><date>2007-02-04T06:21:04Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D2B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/07%20Injected%20With%20A%20Poison%20(MNO%20Power%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>580</key>
+		<dict>
+			<key>Track ID</key><integer>580</integer>
+			<key>Name</key><string>Green Man (Rum &#38; Black Mix)</string>
+			<key>Artist</key><string>Shut Up &#38; Dance</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9026658</integer>
+			<key>Total Time</key><integer>373801</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:22:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D2E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/08%20Green%20Man%20(Rum%20&#38;%20Black%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>581</key>
+		<dict>
+			<key>Track ID</key><integer>581</integer>
+			<key>Name</key><string>Take Control</string>
+			<key>Artist</key><string>Lords Of Acid</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6793322</integer>
+			<key>Total Time</key><integer>282004</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:22:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251353789</integer>
+			<key>Play Date UTC</key><date>2007-01-11T17:49:49Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/09%20Take%20Control.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>582</key>
+		<dict>
+			<key>Track ID</key><integer>582</integer>
+			<key>Name</key><string>A Million Colors</string>
+			<key>Artist</key><string>Channel X</string>
+			<key>Album</key><string>Rave 'Til Dawn</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8193299</integer>
+			<key>Total Time</key><integer>338260</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-07-18T18:23:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252518055</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:14:15Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T18:24:04Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D34</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Rave%20'Til%20Dawn/10%20A%20Million%20Colors.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>583</key>
+		<dict>
+			<key>Track ID</key><integer>583</integer>
+			<key>Name</key><string>Start Choppin'</string>
+			<key>Artist</key><string>Dinosaur Jr</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>33140611</integer>
+			<key>Total Time</key><integer>277800</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-28T23:55:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>953</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:23Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D37</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/01%20Start%20Choppin'.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>584</key>
+		<dict>
+			<key>Track ID</key><integer>584</integer>
+			<key>Name</key><string>What Can You Do For Me</string>
+			<key>Artist</key><string>Utah Saints</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>41606361</integer>
+			<key>Total Time</key><integer>368093</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-05T16:15:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>903</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>23</integer>
+			<key>Play Date</key><integer>3252903062</integer>
+			<key>Play Date UTC</key><date>2007-01-29T16:11:02Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D3C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/02%20What%20Can%20You%20Do%20For%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>585</key>
+		<dict>
+			<key>Track ID</key><integer>585</integer>
+			<key>Name</key><string>Blast</string>
+			<key>Artist</key><string>Pure</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29067214</integer>
+			<key>Total Time</key><integer>222933</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-29T16:43:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1042</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252565216</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:20:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D3F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/03%20Blast.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>586</key>
+		<dict>
+			<key>Track ID</key><integer>586</integer>
+			<key>Name</key><string>Arrows</string>
+			<key>Artist</key><string>Overwhelming Colorfast</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29399825</integer>
+			<key>Total Time</key><integer>232066</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-28T14:36:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1012</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246026832</integer>
+			<key>Play Date UTC</key><date>2006-11-11T02:07:12Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D42</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/04%20Arrows.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>587</key>
+		<dict>
+			<key>Track ID</key><integer>587</integer>
+			<key>Name</key><string>Feed The Tree</string>
+			<key>Artist</key><string>Belly</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29871727</integer>
+			<key>Total Time</key><integer>222906</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-08-22T05:49:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1071</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253274114</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:15:14Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D45</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/05%20Feed%20The%20Tree.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>588</key>
+		<dict>
+			<key>Track ID</key><integer>588</integer>
+			<key>Name</key><string>Explosion</string>
+			<key>Artist</key><string>Whipped Cream</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>32986989</integer>
+			<key>Total Time</key><integer>266466</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-07T01:59:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>989</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249560889</integer>
+			<key>Play Date UTC</key><date>2006-12-21T23:48:09Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D48</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/06%20Explosion.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>589</key>
+		<dict>
+			<key>Track ID</key><integer>589</integer>
+			<key>Name</key><string>Underwhelmed</string>
+			<key>Artist</key><string>Sloan</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>35953631</integer>
+			<key>Total Time</key><integer>285400</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-27T14:12:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1007</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249494098</integer>
+			<key>Play Date UTC</key><date>2006-12-21T05:14:58Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-29T23:52:33Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D4B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/07%20Underwhelmed.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>590</key>
+		<dict>
+			<key>Track ID</key><integer>590</integer>
+			<key>Name</key><string>Edge Of No Control, Part II</string>
+			<key>Artist</key><string>Meat Beat Manifesto</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23243507</integer>
+			<key>Total Time</key><integer>197226</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-28T13:22:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>941</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250686387</integer>
+			<key>Play Date UTC</key><date>2007-01-04T00:26:27Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D4E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/08%20Edge%20Of%20No%20Control,%20Part%20II.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>591</key>
+		<dict>
+			<key>Track ID</key><integer>591</integer>
+			<key>Name</key><string>Take Me Anywhere</string>
+			<key>Artist</key><string>School Of Fish</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>37264552</integer>
+			<key>Total Time</key><integer>286506</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-28T23:54:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1039</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252407815</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:36:55Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D51</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/09%20Take%20Me%20Anywhere.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>592</key>
+		<dict>
+			<key>Track ID</key><integer>592</integer>
+			<key>Name</key><string>Pickin' Flowers For</string>
+			<key>Artist</key><string>The Best Kissers In The World</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25778744</integer>
+			<key>Total Time</key><integer>200533</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-05T21:45:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1027</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252942079</integer>
+			<key>Play Date UTC</key><date>2007-01-30T03:01:19Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D54</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/10%20Pickin'%20Flowers%20For.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>593</key>
+		<dict>
+			<key>Track ID</key><integer>593</integer>
+			<key>Name</key><string>After This Time Is Gone</string>
+			<key>Artist</key><string>Eleventh Dream Day</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25239415</integer>
+			<key>Total Time</key><integer>219400</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-29T13:02:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>919</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253379853</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:37:33Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D57</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/11%20After%20This%20Time%20Is%20Gone.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>594</key>
+		<dict>
+			<key>Track ID</key><integer>594</integer>
+			<key>Name</key><string>Wembley</string>
+			<key>Artist</key><string>The Candy Skins</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>19888212</integer>
+			<key>Total Time</key><integer>158533</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-07T17:30:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1002</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251453729</integer>
+			<key>Play Date UTC</key><date>2007-01-12T21:35:29Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-02T17:20:32Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D5A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/13%20Wembley.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>595</key>
+		<dict>
+			<key>Track ID</key><integer>595</integer>
+			<key>Name</key><string>Warboys</string>
+			<key>Artist</key><string>Ghost Of An American Airman</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28527424</integer>
+			<key>Total Time</key><integer>232706</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-20T13:48:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>979</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253256870</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:27:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D5D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/14%20Warboys.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>596</key>
+		<dict>
+			<key>Track ID</key><integer>596</integer>
+			<key>Name</key><string>Susan Sleepwalking</string>
+			<key>Artist</key><string>The Pooh Sticks</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>19129596</integer>
+			<key>Total Time</key><integer>154693</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-09-28T23:55:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>987</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253518435</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:07:15Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D60</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/15%20Susan%20Sleepwalking.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>597</key>
+		<dict>
+			<key>Track ID</key><integer>597</integer>
+			<key>Name</key><string>Arrive</string>
+			<key>Artist</key><string>Boneclub</string>
+			<key>Album</key><string>Stolar Tracks Vol. 2</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31151768</integer>
+			<key>Total Time</key><integer>233266</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-10-18T16:58:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>1067</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D63</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stolar%20Tracks%20Vol.%202/17%20Arrive.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>598</key>
+		<dict>
+			<key>Track ID</key><integer>598</integer>
+			<key>Name</key><string>Purple Haze</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7780333</integer>
+			<key>Total Time</key><integer>321662</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:11:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252571961</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:12:41Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D66</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/01%20Purple%20Haze.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>599</key>
+		<dict>
+			<key>Track ID</key><integer>599</integer>
+			<key>Name</key><string>Stone Free</string>
+			<key>Artist</key><string>Eric Clapton</string>
+			<key>Composer</key><string>?</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6433132</integer>
+			<key>Total Time</key><integer>266793</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:12:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252558020</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:20:20Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D6B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/02%20Stone%20Free.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>600</key>
+		<dict>
+			<key>Track ID</key><integer>600</integer>
+			<key>Name</key><string>Spanish Castle Magic</string>
+			<key>Artist</key><string>Spin Doctors</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5997512</integer>
+			<key>Total Time</key><integer>247465</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:13:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252540548</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:29:08Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T23:33:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D6E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/03%20Spanish%20Castle%20Magic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>601</key>
+		<dict>
+			<key>Track ID</key><integer>601</integer>
+			<key>Name</key><string>Red House</string>
+			<key>Artist</key><string>Buddy Guy</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5521292</integer>
+			<key>Total Time</key><integer>229972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:13:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253602372</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:26:12Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D71</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/04%20Red%20House.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>602</key>
+		<dict>
+			<key>Track ID</key><integer>602</integer>
+			<key>Name</key><string>Hey Joe</string>
+			<key>Artist</key><string>Body Count</string>
+			<key>Composer</key><string>Billy Roberts</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6564041</integer>
+			<key>Total Time</key><integer>271785</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:14:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>27</integer>
+			<key>Play Date</key><integer>3253109090</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:24:50Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-13T22:51:19Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D74</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/05%20Hey%20Joe.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>603</key>
+		<dict>
+			<key>Track ID</key><integer>603</integer>
+			<key>Name</key><string>Manic Depression</string>
+			<key>Artist</key><string>Seal &#38; Jeff Beck</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7577098</integer>
+			<key>Total Time</key><integer>312681</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:15:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250598037</integer>
+			<key>Play Date UTC</key><date>2007-01-02T23:53:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D77</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/06%20Manic%20Depression.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>604</key>
+		<dict>
+			<key>Track ID</key><integer>604</integer>
+			<key>Name</key><string>Fire</string>
+			<key>Artist</key><string>Nigel Kennedy</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6812931</integer>
+			<key>Total Time</key><integer>281129</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:16:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247828423</integer>
+			<key>Play Date UTC</key><date>2006-12-01T22:33:43Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D7A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/07%20Fire.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>605</key>
+		<dict>
+			<key>Track ID</key><integer>605</integer>
+			<key>Name</key><string>Bold As Love</string>
+			<key>Artist</key><string>The Pretenders</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4964746</integer>
+			<key>Total Time</key><integer>204500</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:16:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:06:04Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D7D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/08%20Bold%20As%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>606</key>
+		<dict>
+			<key>Track ID</key><integer>606</integer>
+			<key>Name</key><string>You Got Me Floatin'</string>
+			<key>Artist</key><string>P.M. Dawn</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7012998</integer>
+			<key>Total Time</key><integer>289385</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:17:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250662497</integer>
+			<key>Play Date UTC</key><date>2007-01-03T17:48:17Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-25T00:20:03Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D80</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/09%20You%20Got%20Me%20Floatin'.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>607</key>
+		<dict>
+			<key>Track ID</key><integer>607</integer>
+			<key>Name</key><string>I Don't Live Today</string>
+			<key>Artist</key><string>Paul Rodgers &#38; Band Of Gypsys</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6545595</integer>
+			<key>Total Time</key><integer>272084</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:18:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253605850</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:24:10Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D83</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/10%20I%20Don't%20Live%20Today.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>608</key>
+		<dict>
+			<key>Track ID</key><integer>608</integer>
+			<key>Name</key><string>Are You Experienced</string>
+			<key>Artist</key><string>Belly</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5418005</integer>
+			<key>Total Time</key><integer>224361</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:19:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253508295</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:18:15Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-03T16:30:49Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D86</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/11%20Are%20You%20Experienced.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>609</key>
+		<dict>
+			<key>Track ID</key><integer>609</integer>
+			<key>Name</key><string>Crosstown Traffic</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4711130</integer>
+			<key>Total Time</key><integer>195476</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:19:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253520662</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:44:22Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D89</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/12%20Crosstown%20Traffic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>610</key>
+		<dict>
+			<key>Track ID</key><integer>610</integer>
+			<key>Name</key><string>Third Stone From The Sun</string>
+			<key>Artist</key><string>Pat Metheny</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8724469</integer>
+			<key>Total Time</key><integer>360382</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:21:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D8C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/13%20Third%20Stone%20From%20The%20Sun.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>611</key>
+		<dict>
+			<key>Track ID</key><integer>611</integer>
+			<key>Name</key><string>Hey Baby (Land Of The New Rising Sun)</string>
+			<key>Artist</key><string>M.A.C.C.</string>
+			<key>Composer</key><string>Jimi Hendrix</string>
+			<key>Album</key><string>Stone Free: A Tribute To Jimi Hendrix</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7984016</integer>
+			<key>Total Time</key><integer>330580</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2005-06-15T00:22:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253711381</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:43:01Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D8F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Stone%20Free_%20A%20Tribute%20To%20Jimi%20Hendrix/14%20Hey%20Baby%20(Land%20Of%20The%20New%20Rising%20Sun).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>612</key>
+		<dict>
+			<key>Track ID</key><integer>612</integer>
+			<key>Name</key><string>The District Sleeps Alone Tonight (DJ Downfall Persistent Beat Mix)</string>
+			<key>Artist</key><string>The Postal Service</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11541237</integer>
+			<key>Total Time</key><integer>410383</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>224</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253343276</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:27:56Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/01%20The%20District%20Sleeps%20Alone%20Tonight%20(DJ%20Downfall%20Persistent%20Beat%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>613</key>
+		<dict>
+			<key>Track ID</key><integer>613</integer>
+			<key>Name</key><string>Teardrop (Mad Professor Mazaruni Vocal Mix)</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9093001</integer>
+			<key>Total Time</key><integer>363154</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>200</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253705856</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:10:56Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D97</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/04%20Teardrop%20(Mad%20Professor%20Mazaruni%20Vocal%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>614</key>
+		<dict>
+			<key>Track ID</key><integer>614</integer>
+			<key>Name</key><string>Stupid (Mark Bell Mix)</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4611951</integer>
+			<key>Total Time</key><integer>206184</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:40:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>178</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246905114</integer>
+			<key>Play Date UTC</key><date>2006-11-21T06:05:14Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D9A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/05%20Stupid%20(Mark%20Bell%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>615</key>
+		<dict>
+			<key>Track ID</key><integer>615</integer>
+			<key>Name</key><string>Here With Me (Rollos Chiillin With The Family Mix)</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7299091</integer>
+			<key>Total Time</key><integer>307670</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:40:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>189</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250741570</integer>
+			<key>Play Date UTC</key><date>2007-01-04T15:46:10Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85D9D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/06%20Here%20With%20Me%20(Rollos%20Chiillin%20With%20The%20Family%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>616</key>
+		<dict>
+			<key>Track ID</key><integer>616</integer>
+			<key>Name</key><string>Center Of The Sun (Solarstones Chilled-out Remix)</string>
+			<key>Artist</key><string>Conjure One</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9764164</integer>
+			<key>Total Time</key><integer>367856</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:40:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>212</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246642153</integer>
+			<key>Play Date UTC</key><date>2006-11-18T05:02:33Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DA0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/08%20Center%20Of%20The%20Sun%20(Solarstones%20Chilled-out%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>617</key>
+		<dict>
+			<key>Track ID</key><integer>617</integer>
+			<key>Name</key><string>Elvis</string>
+			<key>Artist</key><string>Alpha</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4698843</integer>
+			<key>Total Time</key><integer>199967</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:40:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>187</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253450674</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:17:54Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DA3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/09%20Elvis.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>618</key>
+		<dict>
+			<key>Track ID</key><integer>618</integer>
+			<key>Name</key><string>Edge Of The Ocean (Duotone Remix)</string>
+			<key>Artist</key><string>Ivy</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6885760</integer>
+			<key>Total Time</key><integer>248764</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:40:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>221</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253708384</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:53:04Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-08T22:12:09Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DA6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/10%20Edge%20Of%20The%20Ocean%20(Duotone%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>619</key>
+		<dict>
+			<key>Track ID</key><integer>619</integer>
+			<key>Name</key><string>Chocolate</string>
+			<key>Artist</key><string>Lester</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7001431</integer>
+			<key>Total Time</key><integer>349126</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:41:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253179421</integer>
+			<key>Play Date UTC</key><date>2007-02-01T20:57:01Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DA9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/11%20Chocolate.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>620</key>
+		<dict>
+			<key>Track ID</key><integer>620</integer>
+			<key>Name</key><string>Finished Symphony</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7889469</integer>
+			<key>Total Time</key><integer>336718</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:41:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>187</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253688731</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:25:31Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DAC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/11%20Finished%20Symphony.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>621</key>
+		<dict>
+			<key>Track ID</key><integer>621</integer>
+			<key>Name</key><string>Silence (Michael Wood Remix)</string>
+			<key>Artist</key><string>Delerium</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11371717</integer>
+			<key>Total Time</key><integer>426605</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:41:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>213</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252939474</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:17:54Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DAF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/13%20Silence%20(Michael%20Wood%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>622</key>
+		<dict>
+			<key>Track ID</key><integer>622</integer>
+			<key>Name</key><string>Sings (Bonobo Mix)</string>
+			<key>Artist</key><string>Badmarsh and Shiri</string>
+			<key>Album</key><string>The Best of Chillout: Past and Present</string>
+			<key>Genre</key><string>Chillout</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6277709</integer>
+			<key>Total Time</key><integer>320208</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>156</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253343876</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:37:56Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DB2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Chillout_%20Past%20and%20Present/14%20Sings%20(Bonobo%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>623</key>
+		<dict>
+			<key>Track ID</key><integer>623</integer>
+			<key>Name</key><string>Harry Flowers</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Album Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Nitzsche</string>
+			<key>Album</key><string>The Best of Strange Cargos</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4601069</integer>
+			<key>Total Time</key><integer>270836</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-07-27T18:43:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253371331</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:15:31Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85DB5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Strange%20Cargos/09%20Harry%20Flowers.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>624</key>
+		<dict>
+			<key>Track ID</key><integer>624</integer>
+			<key>Name</key><string>Love My Way</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Album Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Ashton</string>
+			<key>Album</key><string>The Best of Strange Cargos</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2793149</integer>
+			<key>Total Time</key><integer>159101</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-07-21T02:15:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252991733</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:48:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T23:34:54Z</date>
+			<key>Compilation</key><true/>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85DBA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Best%20of%20Strange%20Cargos/10%20Love%20My%20Way.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>625</key>
+		<dict>
+			<key>Track ID</key><integer>625</integer>
+			<key>Name</key><string>Mission Impossible</string>
+			<key>Artist</key><string>James Taylor Quartet</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3263618</integer>
+			<key>Total Time</key><integer>203103</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:51:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253717763</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:29:23Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DBD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/01%20Mission%20Impossible.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>626</key>
+		<dict>
+			<key>Track ID</key><integer>626</integer>
+			<key>Name</key><string>Green Screen</string>
+			<key>Artist</key><string>New Jersey Kings</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4726870</integer>
+			<key>Total Time</key><integer>292546</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:52:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247837639</integer>
+			<key>Play Date UTC</key><date>2006-12-02T01:07:19Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DC2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/02%20Green%20Screen.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>627</key>
+		<dict>
+			<key>Track ID</key><integer>627</integer>
+			<key>Name</key><string>Throtte Back</string>
+			<key>Artist</key><string>Emperors New Clothes</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3211410</integer>
+			<key>Total Time</key><integer>198714</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:52:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250698889</integer>
+			<key>Play Date UTC</key><date>2007-01-04T03:54:49Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DC5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/03%20Throtte%20Back.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>628</key>
+		<dict>
+			<key>Track ID</key><integer>628</integer>
+			<key>Name</key><string>Manhattan Skyline</string>
+			<key>Artist</key><string>X Generation</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6430479</integer>
+			<key>Total Time</key><integer>397942</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:53:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253373175</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:46:15Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DC8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/04%20Manhattan%20Skyline.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>629</key>
+		<dict>
+			<key>Track ID</key><integer>629</integer>
+			<key>Name</key><string>The Arrival</string>
+			<key>Artist</key><string>Pathaan</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6956123</integer>
+			<key>Total Time</key><integer>431239</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:54:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250658585</integer>
+			<key>Play Date UTC</key><date>2007-01-03T16:43:05Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T20:55:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DCB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/05%20The%20Arrival.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>630</key>
+		<dict>
+			<key>Track ID</key><integer>630</integer>
+			<key>Name</key><string>A.P.B</string>
+			<key>Artist</key><string>A Man Called Adam</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3566320</integer>
+			<key>Total Time</key><integer>221911</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:54:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253374533</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:08:53Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DCE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/06%20A.P.B.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>631</key>
+		<dict>
+			<key>Track ID</key><integer>631</integer>
+			<key>Name</key><string>Stay This Way</string>
+			<key>Artist</key><string>The Brand New Heavies</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4115298</integer>
+			<key>Total Time</key><integer>255627</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:54:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:41Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253375461</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:24:21Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DD1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/07%20Stay%20This%20Way.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>632</key>
+		<dict>
+			<key>Track ID</key><integer>632</integer>
+			<key>Name</key><string>The Wah Classic</string>
+			<key>Artist</key><string>D'Influence</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4193014</integer>
+			<key>Total Time</key><integer>261014</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:55:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253474391</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:53:11Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DD4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/08%20The%20Wah%20Classic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>633</key>
+		<dict>
+			<key>Track ID</key><integer>633</integer>
+			<key>Name</key><string>Break 4 Jazz</string>
+			<key>Artist</key><string>Break 4 Jazz</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5899805</integer>
+			<key>Total Time</key><integer>365712</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:55:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251483326</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:48:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DD7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/09%20Break%204%20Jazz.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>634</key>
+		<dict>
+			<key>Track ID</key><integer>634</integer>
+			<key>Name</key><string>Sleep Walk</string>
+			<key>Artist</key><string>Cloud Nine</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4930953</integer>
+			<key>Total Time</key><integer>305433</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:56:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249384878</integer>
+			<key>Play Date UTC</key><date>2006-12-19T22:54:38Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DDA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/10%20Sleep%20Walk.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>635</key>
+		<dict>
+			<key>Track ID</key><integer>635</integer>
+			<key>Name</key><string>Riot On 103rd Street</string>
+			<key>Artist</key><string>Mother Earth</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2648714</integer>
+			<key>Total Time</key><integer>164001</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:56:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253464256</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:04:16Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DDD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/11%20Riot%20On%20103rd%20Street.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>636</key>
+		<dict>
+			<key>Track ID</key><integer>636</integer>
+			<key>Name</key><string>Quiet Dawn</string>
+			<key>Artist</key><string>Humble Soul</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6025880</integer>
+			<key>Total Time</key><integer>373746</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:56:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249292866</integer>
+			<key>Play Date UTC</key><date>2006-12-18T21:21:06Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DE0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/12%20Quiet%20Dawn.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>637</key>
+		<dict>
+			<key>Track ID</key><integer>637</integer>
+			<key>Name</key><string>Night In Tunisia (A Tribute To Dizzy)</string>
+			<key>Artist</key><string>Subterraneans</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5101992</integer>
+			<key>Total Time</key><integer>316579</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:57:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253376171</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:36:11Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DE3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/13%20Night%20In%20Tunisia%20(A%20Tribute%20To%20Dizzy).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>638</key>
+		<dict>
+			<key>Track ID</key><integer>638</integer>
+			<key>Name</key><string>Don't You Let Me Down</string>
+			<key>Artist</key><string>Planet</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4573203</integer>
+			<key>Total Time</key><integer>283281</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:57:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253718046</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:34:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T18:14:37Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DE6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/14%20Don't%20You%20Let%20Me%20Down.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>639</key>
+		<dict>
+			<key>Track ID</key><integer>639</integer>
+			<key>Name</key><string>Rollerball (Executive Party)</string>
+			<key>Artist</key><string>Akimbo</string>
+			<key>Album</key><string>The Funk Of Acid Jazz</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3774261</integer>
+			<key>Total Time</key><integer>234612</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2006-07-08T07:57:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252990549</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:29:09Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DE9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Funk%20Of%20Acid%20Jazz/15%20Rollerball%20(Executive%20Party).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>640</key>
+		<dict>
+			<key>Track ID</key><integer>640</integer>
+			<key>Name</key><string>Wadidyusay?</string>
+			<key>Artist</key><string>Zap Mama</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>20514600</integer>
+			<key>Total Time</key><integer>201000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-26T19:21:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>815</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-23T04:43:50Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DEC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/03%20Wadidyusay_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>641</key>
+		<dict>
+			<key>Track ID</key><integer>641</integer>
+			<key>Name</key><string>One Big Holiday</string>
+			<key>Artist</key><string>My Morning Jacket</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>39922271</integer>
+			<key>Total Time</key><integer>321853</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T00:34:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>991</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247663587</integer>
+			<key>Play Date UTC</key><date>2006-11-30T00:46:27Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T02:41:04Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DF1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/04%20One%20Big%20Holiday.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>642</key>
+		<dict>
+			<key>Track ID</key><integer>642</integer>
+			<key>Name</key><string>Relaxation Spa Treatment</string>
+			<key>Artist</key><string>Dan The Automator</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>13323487</integer>
+			<key>Total Time</key><integer>205306</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-26T23:49:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>518</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252556412</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:53:32Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DF4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/07%20Relaxation%20Spa%20Treatment.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>643</key>
+		<dict>
+			<key>Track ID</key><integer>643</integer>
+			<key>Name</key><string>Dc 3000</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>21788347</integer>
+			<key>Total Time</key><integer>267760</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-10-06T15:12:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>650</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253611819</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:03:39Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:42:46Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DF7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/08%20Dc%203000.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>644</key>
+		<dict>
+			<key>Track ID</key><integer>644</integer>
+			<key>Name</key><string>Looking Up In Heaven</string>
+			<key>Artist</key><string>Paul Westerberg</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23502577</integer>
+			<key>Total Time</key><integer>192226</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-10-19T23:10:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>977</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252397264</integer>
+			<key>Play Date UTC</key><date>2007-01-23T19:41:04Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-18T14:12:53Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DFA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/10%20Looking%20Up%20In%20Heaven.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>645</key>
+		<dict>
+			<key>Track ID</key><integer>645</integer>
+			<key>Name</key><string>No Meaning No</string>
+			<key>Artist</key><string>Chuck D With Fine Arts Militia</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24777454</integer>
+			<key>Total Time</key><integer>192813</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-10-11T19:57:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>1027</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252577657</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:47:37Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T19:40:26Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85DFD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/11%20No%20Meaning%20No.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>646</key>
+		<dict>
+			<key>Track ID</key><integer>646</integer>
+			<key>Name</key><string>Wataridori 2</string>
+			<key>Artist</key><string>Cornelius</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>43770434</integer>
+			<key>Total Time</key><integer>429880</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-29T12:42:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>813</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253475008</integer>
+			<key>Play Date UTC</key><date>2007-02-05T07:03:28Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E00</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/13%20Wataridori%202.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>647</key>
+		<dict>
+			<key>Track ID</key><integer>647</integer>
+			<key>Name</key><string>Oslodum 2004</string>
+			<key>Artist</key><string>DJ Dolores</string>
+			<key>Composer</key><string>CD Track Info PROvided courtesey of newParadime</string>
+			<key>Album</key><string>The Wired CD: Rip. Sample. Mash. Share.</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26826299</integer>
+			<key>Total Time</key><integer>240413</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-27T21:50:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>891</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251350802</integer>
+			<key>Play Date UTC</key><date>2007-01-11T17:00:02Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E03</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/The%20Wired%20CD_%20Rip.%20Sample.%20Mash.%20Share_/15%20Oslodum%202004.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>648</key>
+		<dict>
+			<key>Track ID</key><integer>648</integer>
+			<key>Name</key><string>We Have Explosive</string>
+			<key>Artist</key><string>The Future Sound Of London</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9068950</integer>
+			<key>Total Time</key><integer>374292</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:34:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253555018</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:16:58Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E09</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/01%20We%20Have%20Explosive.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>649</key>
+		<dict>
+			<key>Track ID</key><integer>649</integer>
+			<key>Name</key><string>Atom Bomb</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11573191</integer>
+			<key>Total Time</key><integer>477694</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:36:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253688005</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:13:25Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E0E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/02%20Atom%20Bomb.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>650</key>
+		<dict>
+			<key>Track ID</key><integer>650</integer>
+			<key>Name</key><string>Loops Of Fury</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6816710</integer>
+			<key>Total Time</key><integer>281726</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:37:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>40</integer>
+			<key>Play Date</key><integer>3253709283</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:08:03Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E11</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/03%20Loops%20Of%20Fury.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>651</key>
+		<dict>
+			<key>Track ID</key><integer>651</integer>
+			<key>Name</key><string>Tin There</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7271632</integer>
+			<key>Total Time</key><integer>300073</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:38:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252402305</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:05:05Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E14</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/04%20Tin%20There.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>652</key>
+		<dict>
+			<key>Track ID</key><integer>652</integer>
+			<key>Name</key><string>Leave Home (Underworld Mix1)</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7622449</integer>
+			<key>Total Time</key><integer>314729</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-06-14T17:40:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247668657</integer>
+			<key>Play Date UTC</key><date>2006-11-30T02:10:57Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E17</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/06%20Leave%20Home%20(Underworld%20Mix1).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>653</key>
+		<dict>
+			<key>Track ID</key><integer>653</integer>
+			<key>Name</key><string>We Have Explosive (Hero Killing)</string>
+			<key>Artist</key><string>The Future Sound Of London</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8302133</integer>
+			<key>Total Time</key><integer>342782</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:41:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E1A</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/07%20We%20Have%20Explosive%20(Hero%20Killing).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>654</key>
+		<dict>
+			<key>Track ID</key><integer>654</integer>
+			<key>Name</key><string>Firestarter (Instrumental)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6774131</integer>
+			<key>Total Time</key><integer>279828</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:41:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253598171</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:16:11Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E1D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/08%20Firestarter%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>655</key>
+		<dict>
+			<key>Track ID</key><integer>655</integer>
+			<key>Name</key><string>V Six</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7733393</integer>
+			<key>Total Time</key><integer>319145</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:42:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253763777</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:16:17Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E20</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/09%20V%20Six.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>656</key>
+		<dict>
+			<key>Track ID</key><integer>656</integer>
+			<key>Name</key><string>2097</string>
+			<key>Artist</key><string>Source Direct</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8118306</integer>
+			<key>Total Time</key><integer>335017</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:45:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253346683</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:24:43Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E23</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/11%202097.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>657</key>
+		<dict>
+			<key>Track ID</key><integer>657</integer>
+			<key>Name</key><string>Petrol</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2651580</integer>
+			<key>Total Time</key><integer>107326</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:46:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247377029</integer>
+			<key>Play Date UTC</key><date>2006-11-26T17:10:29Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E26</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/13%20Petrol.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>658</key>
+		<dict>
+			<key>Track ID</key><integer>658</integer>
+			<key>Name</key><string>Afro Ride</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album</key><string>Wipeout 2097</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6404336</integer>
+			<key>Total Time</key><integer>265214</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-06-14T17:47:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250673907</integer>
+			<key>Play Date UTC</key><date>2007-01-03T20:58:27Z</date>
+			<key>Compilation</key><true/>
+			<key>Persistent ID</key><string>87139F8602B85E29</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Compilations/Wipeout%202097/14%20Afro%20Ride.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>659</key>
+		<dict>
+			<key>Track ID</key><integer>659</integer>
+			<key>Name</key><string>Dude In The Moon (Luna Mix)</string>
+			<key>Artist</key><string>Dastrix</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Michael Clark/Mike Koglin</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8759366</integer>
+			<key>Total Time</key><integer>364146</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252402005</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:00:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E2C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dastrix/Community%20Service/07%20Dude%20In%20The%20Moon%20(Luna%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>660</key>
+		<dict>
+			<key>Track ID</key><integer>660</integer>
+			<key>Name</key><string>Mihalis</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5545151</integer>
+			<key>Total Time</key><integer>346435</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249550310</integer>
+			<key>Play Date UTC</key><date>2006-12-21T20:51:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E2E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/01%20Mihalis.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>661</key>
+		<dict>
+			<key>Track ID</key><integer>661</integer>
+			<key>Name</key><string>There's No Way Out Of Here</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4935348</integer>
+			<key>Total Time</key><integer>308323</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253291769</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:09:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/02%20There's%20No%20Way%20Out%20Of%20Here.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>662</key>
+		<dict>
+			<key>Track ID</key><integer>662</integer>
+			<key>Name</key><string>Cry From The Street</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5016014</integer>
+			<key>Total Time</key><integer>313364</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249308277</integer>
+			<key>Play Date UTC</key><date>2006-12-19T01:37:57Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E33</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/03%20Cry%20From%20The%20Street.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>663</key>
+		<dict>
+			<key>Track ID</key><integer>663</integer>
+			<key>Name</key><string>So Far Away</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5841902</integer>
+			<key>Total Time</key><integer>364982</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253464876</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:14:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E35</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/04%20So%20Far%20Away.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>664</key>
+		<dict>
+			<key>Track ID</key><integer>664</integer>
+			<key>Name</key><string>Short And Sweet</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5298555</integer>
+			<key>Total Time</key><integer>331023</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253276299</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:51:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E37</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/05%20Short%20And%20Sweet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>665</key>
+		<dict>
+			<key>Track ID</key><integer>665</integer>
+			<key>Name</key><string>Raise My Rent</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5340769</integer>
+			<key>Total Time</key><integer>333662</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253606477</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:34:37Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E39</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/06%20Raise%20My%20Rent.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>666</key>
+		<dict>
+			<key>Track ID</key><integer>666</integer>
+			<key>Name</key><string>No Way</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5316527</integer>
+			<key>Total Time</key><integer>332146</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253296679</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:31:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E3B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/07%20No%20Way.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>667</key>
+		<dict>
+			<key>Track ID</key><integer>667</integer>
+			<key>Name</key><string>It's Deafinitely</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4280406</integer>
+			<key>Total Time</key><integer>267389</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249529756</integer>
+			<key>Play Date UTC</key><date>2006-12-21T15:09:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E3D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/08%20It's%20Deafinitely.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>668</key>
+		<dict>
+			<key>Track ID</key><integer>668</integer>
+			<key>Name</key><string>I Can't Breathe Anymore</string>
+			<key>Artist</key><string>David Gilmour</string>
+			<key>Album</key><string>David Gilmour</string>
+			<key>Genre</key><string>Classic Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2968850</integer>
+			<key>Total Time</key><integer>185417</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252390254</integer>
+			<key>Play Date UTC</key><date>2007-01-23T17:44:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E3F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/David%20Gilmour/David%20Gilmour/09%20I%20Can't%20Breathe%20Anymore.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>669</key>
+		<dict>
+			<key>Track ID</key><integer>669</integer>
+			<key>Name</key><string>Silence [Sanctuary Mix]</string>
+			<key>Artist</key><string>Delerium</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5888650</integer>
+			<key>Total Time</key><integer>485590</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253342001</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:06:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85E41</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Delerium/Plastic%20Compilation,%20Vol.%202/02%20Silence%20%5BSanctuary%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>670</key>
+		<dict>
+			<key>Track ID</key><integer>670</integer>
+			<key>Name</key><string>Heaven's Earth [Matt Darey Remix]</string>
+			<key>Artist</key><string>Delerium</string>
+			<key>Album Artist</key><string>Various Artists</string>
+			<key>Composer</key><string>Bill Leeb/Kristy Thirsk/Rhys Fulber</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7968896</integer>
+			<key>Total Time</key><integer>497920</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246032240</integer>
+			<key>Play Date UTC</key><date>2006-11-11T03:37:20Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-25T00:20:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E44</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Delerium/Plastic%20Compilation,%20Vol.%203/03%20Heaven's%20Earth%20%5BMatt%20Darey%20Remix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>671</key>
+		<dict>
+			<key>Track ID</key><integer>671</integer>
+			<key>Name</key><string>Old Friends 4 Sale</string>
+			<key>Artist</key><string>Desert Eagle Discs</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4354719</integer>
+			<key>Total Time</key><integer>271777</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85E46</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Desert%20Eagle%20Discs/Late%20Lounge%20(2%20of%202)/04%20Old%20Friends%204%20Sale.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>672</key>
+		<dict>
+			<key>Track ID</key><integer>672</integer>
+			<key>Name</key><string>Here With Me</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Paul Statham, Pascal Gabriel</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6167264</integer>
+			<key>Total Time</key><integer>254569</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T13:12:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250684005</integer>
+			<key>Play Date UTC</key><date>2007-01-03T23:46:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E49</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/01%20Here%20With%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>673</key>
+		<dict>
+			<key>Track ID</key><integer>673</integer>
+			<key>Name</key><string>Hunter</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Rollo Armstrong</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5731365</integer>
+			<key>Total Time</key><integer>237225</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:15:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3250666881</integer>
+			<key>Play Date UTC</key><date>2007-01-03T19:01:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E4C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/02%20Hunter.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>674</key>
+		<dict>
+			<key>Track ID</key><integer>674</integer>
+			<key>Name</key><string>Don't Think Of Me</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Rollo Armstrong, Pauline Taylor &#38; Paulie Herman</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6599253</integer>
+			<key>Total Time</key><integer>272340</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:18:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252538856</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:00:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E4E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/03%20Don't%20Think%20Of%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>675</key>
+		<dict>
+			<key>Track ID</key><integer>675</integer>
+			<key>Name</key><string>My Lover's Gone</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, J. Catto</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6493547</integer>
+			<key>Total Time</key><integer>267966</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:22:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3250690606</integer>
+			<key>Play Date UTC</key><date>2007-01-04T01:36:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E50</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/04%20My%20Lover's%20Gone.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>676</key>
+		<dict>
+			<key>Track ID</key><integer>676</integer>
+			<key>Name</key><string>All You Want</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Paulie Herman, Rollo Armstrong</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5660839</integer>
+			<key>Total Time</key><integer>233598</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:25:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252122221</integer>
+			<key>Play Date UTC</key><date>2007-01-20T15:17:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E52</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/05%20All%20You%20Want.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>677</key>
+		<dict>
+			<key>Track ID</key><integer>677</integer>
+			<key>Name</key><string>Thank You</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Paulie Herman</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5288113</integer>
+			<key>Total Time</key><integer>217961</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:27:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251484259</integer>
+			<key>Play Date UTC</key><date>2007-01-13T06:04:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E54</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/06%20Thank%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>678</key>
+		<dict>
+			<key>Track ID</key><integer>678</integer>
+			<key>Name</key><string>Honestly OK</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Matty Benbrook, Rollo Armstrong</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6724245</integer>
+			<key>Total Time</key><integer>277502</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:31:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252564092</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:01:32Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-20T23:09:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E56</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/07%20Honestly%20OK.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>679</key>
+		<dict>
+			<key>Track ID</key><integer>679</integer>
+			<key>Name</key><string>Slide</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Paulie Herman</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7114391</integer>
+			<key>Total Time</key><integer>293758</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:34:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253606144</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:29:04Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-01T23:27:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E58</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/08%20Slide.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>680</key>
+		<dict>
+			<key>Track ID</key><integer>680</integer>
+			<key>Name</key><string>Isobel</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Rollo Armstrong</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5673194</integer>
+			<key>Total Time</key><integer>234110</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:37:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252527400</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:50:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E5A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/09%20Isobel.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>681</key>
+		<dict>
+			<key>Track ID</key><integer>681</integer>
+			<key>Name</key><string>I'm No Angel</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Paul Statham, Pascal Gabriel</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5714491</integer>
+			<key>Total Time</key><integer>235710</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:40:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251860807</integer>
+			<key>Play Date UTC</key><date>2007-01-17T14:40:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E5C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/10%20I'm%20No%20Angel.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>682</key>
+		<dict>
+			<key>Track ID</key><integer>682</integer>
+			<key>Name</key><string>My Life</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Rollo Armstrong, Mark Bates</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4373758</integer>
+			<key>Total Time</key><integer>189545</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:43:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253456001</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:46:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E5E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/11%20My%20Life.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>683</key>
+		<dict>
+			<key>Track ID</key><integer>683</integer>
+			<key>Name</key><string>Take My Hand</string>
+			<key>Artist</key><string>Dido</string>
+			<key>Composer</key><string>Armstrong, Dido, Richard Dekkard</string>
+			<key>Album</key><string>No Angel</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9751045</integer>
+			<key>Total Time</key><integer>402836</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-05-04T13:48:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250707131</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:12:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E60</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dido/No%20Angel/12%20Take%20My%20Hand.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>684</key>
+		<dict>
+			<key>Track ID</key><integer>684</integer>
+			<key>Name</key><string>One Hundred Percent Free</string>
+			<key>Artist</key><string>Digby</string>
+			<key>Album</key><string>Falling Up</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3809784</integer>
+			<key>Total Time</key><integer>237975</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2005-02-23T20:31:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253604322</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:58:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E62</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Digby/Falling%20Up/04%20One%20Hundred%20Percent%20Free.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>685</key>
+		<dict>
+			<key>Track ID</key><integer>685</integer>
+			<key>Name</key><string>Chem trails</string>
+			<key>Artist</key><string>Dj Soul Slinger</string>
+			<key>Genre</key><string>genre</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8639512</integer>
+			<key>Total Time</key><integer>359888</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2005-02-27T02:16:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253282174</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:29:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E65</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dj%20Soul%20Slinger/Unknown%20Album/01%20Chem%20trails.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>686</key>
+		<dict>
+			<key>Track ID</key><integer>686</integer>
+			<key>Name</key><string>Trans-Island Skyway</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9450481</integer>
+			<key>Total Time</key><integer>390078</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T19:54:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252417014</integer>
+			<key>Play Date UTC</key><date>2007-01-24T01:10:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E69</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/01%20Trans-Island%20Skyway.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>687</key>
+		<dict>
+			<key>Track ID</key><integer>687</integer>
+			<key>Name</key><string>Countermoon</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7404822</integer>
+			<key>Total Time</key><integer>305598</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T19:55:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253346988</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:29:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E6C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/02%20Countermoon.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>688</key>
+		<dict>
+			<key>Track ID</key><integer>688</integer>
+			<key>Name</key><string>Springtime</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7427599</integer>
+			<key>Total Time</key><integer>306537</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T19:56:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253599270</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:34:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E6E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/03%20Springtime.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>689</key>
+		<dict>
+			<key>Track ID</key><integer>689</integer>
+			<key>Name</key><string>Snowbound</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Walter Becker &#38; Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10386783</integer>
+			<key>Total Time</key><integer>428734</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T19:57:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252475299</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:21:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E70</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/04%20Snowbound.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>690</key>
+		<dict>
+			<key>Track ID</key><integer>690</integer>
+			<key>Name</key><string>Tomorrow's Girls</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9147896</integer>
+			<key>Total Time</key><integer>377577</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T19:58:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251481062</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:11:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E72</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/05%20Tomorrow's%20Girls.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>691</key>
+		<dict>
+			<key>Track ID</key><integer>691</integer>
+			<key>Name</key><string>Florida Room</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen &#38; Libby Titus</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8775870</integer>
+			<key>Total Time</key><integer>362217</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T20:00:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3246684047</integer>
+			<key>Play Date UTC</key><date>2006-11-18T16:40:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E74</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/06%20Florida%20Room.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>692</key>
+		<dict>
+			<key>Track ID</key><integer>692</integer>
+			<key>Name</key><string>On The Dunes</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11806322</integer>
+			<key>Total Time</key><integer>487358</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T20:01:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252924586</integer>
+			<key>Play Date UTC</key><date>2007-01-29T22:09:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E76</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/07%20On%20The%20Dunes.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>693</key>
+		<dict>
+			<key>Track ID</key><integer>693</integer>
+			<key>Name</key><string>Teahouse On The Tracks</string>
+			<key>Artist</key><string>Donald Fagen</string>
+			<key>Composer</key><string>Donald Fagen</string>
+			<key>Album</key><string>Kamakiriad</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8958095</integer>
+			<key>Total Time</key><integer>369897</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-06-24T20:02:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B85E78</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Donald%20Fagen/Kamakiriad/08%20Teahouse%20On%20The%20Tracks.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>694</key>
+		<dict>
+			<key>Track ID</key><integer>694</integer>
+			<key>Name</key><string>The Look of Love</string>
+			<key>Artist</key><string>Dusty Springfield</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3389234</integer>
+			<key>Total Time</key><integer>211435</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253608164</integer>
+			<key>Play Date UTC</key><date>2007-02-06T20:02:44Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-04T17:10:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85E7A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Dusty%20Springfield/Late%20Lounge%20(2%20of%202)/15%20The%20Look%20of%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>695</key>
+		<dict>
+			<key>Track ID</key><integer>695</integer>
+			<key>Name</key><string>Curveball</string>
+			<key>Artist</key><string>Elite Force</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Elite Force</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5780780</integer>
+			<key>Total Time</key><integer>240039</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253462655</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:37:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E7D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Elite%20Force/Community%20Service/06%20Curveball.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>696</key>
+		<dict>
+			<key>Track ID</key><integer>696</integer>
+			<key>Name</key><string>Baby Get Lost</string>
+			<key>Artist</key><string>Elysian Fields</string>
+			<key>Album</key><string>Dreams That Breathe Your Name</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8125244</integer>
+			<key>Total Time</key><integer>203075</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T21:01:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>320</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253279360</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:42:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E7F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Elysian%20Fields/Dreams%20That%20Breathe%20Your%20Name/02%20Baby%20Get%20Lost.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>697</key>
+		<dict>
+			<key>Track ID</key><integer>697</integer>
+			<key>Name</key><string>Summer Breeze</string>
+			<key>Artist</key><string>Emiliana Torrini</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3577733</integer>
+			<key>Total Time</key><integer>223216</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251523527</integer>
+			<key>Play Date UTC</key><date>2007-01-13T16:58:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85E82</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Emiliana%20Torrini/Late%20Lounge%20(2%20of%202)/14%20Summer%20Breeze.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>698</key>
+		<dict>
+			<key>Track ID</key><integer>698</integer>
+			<key>Name</key><string>Bag Lady</string>
+			<key>Artist</key><string>Erykah Badu</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5545903</integer>
+			<key>Total Time</key><integer>346226</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253471543</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:05:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85E85</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Erykah%20Badu/Late%20Lounge%20(2%20of%202)/07%20Bag%20Lady.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>699</key>
+		<dict>
+			<key>Track ID</key><integer>699</integer>
+			<key>Name</key><string>Cake Hole</string>
+			<key>Artist</key><string>Evil 9</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Chris Pardy/Tom Beaufoy</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8439000</integer>
+			<key>Total Time</key><integer>350798</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252512875</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:47:55Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E88</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Evil%209/Community%20Service/02%20Cake%20Hole.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>700</key>
+		<dict>
+			<key>Track ID</key><integer>700</integer>
+			<key>Name</key><string>Rock and Roll Rhythm</string>
+			<key>Artist</key><string>Fancey</string>
+			<key>Album</key><string>Fancey</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4624603</integer>
+			<key>Total Time</key><integer>192600</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:32:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252533426</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:30:26Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E8A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fancey/Fancey/05%20Rock%20and%20Roll%20Rhythm.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>701</key>
+		<dict>
+			<key>Track ID</key><integer>701</integer>
+			<key>Name</key><string>Song For Lindy</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4654192</integer>
+			<key>Total Time</key><integer>290220</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:24:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3247721168</integer>
+			<key>Play Date UTC</key><date>2006-11-30T16:46:08Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B85E8D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/01%20Song%20For%20Lindy.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>702</key>
+		<dict>
+			<key>Track ID</key><integer>702</integer>
+			<key>Name</key><string>Santa Cruz</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7206518</integer>
+			<key>Total Time</key><integer>450220</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:24:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253341516</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:58:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E90</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/02%20Santa%20Cruz.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>703</key>
+		<dict>
+			<key>Track ID</key><integer>703</integer>
+			<key>Name</key><string>Going Out Of My Head</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim/Pete Townshend</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5031065</integer>
+			<key>Total Time</key><integer>314253</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253350223</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:23:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/03%20Going%20Out%20Of%20My%20Head.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>704</key>
+		<dict>
+			<key>Track ID</key><integer>704</integer>
+			<key>Name</key><string>The Weekend Starts Here</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim/Mohammed</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5606342</integer>
+			<key>Total Time</key><integer>350223</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252503843</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:17:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E94</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/04%20The%20Weekend%20Starts%20Here.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>705</key>
+		<dict>
+			<key>Track ID</key><integer>705</integer>
+			<key>Name</key><string>Everybody Needs A 303</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Edwin Starr/Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5595308</integer>
+			<key>Total Time</key><integer>349518</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253522455</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:14:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E96</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/05%20Everybody%20Needs%20A%20303.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>706</key>
+		<dict>
+			<key>Track ID</key><integer>706</integer>
+			<key>Name</key><string>Give The Po'Man A Break</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5608255</integer>
+			<key>Total Time</key><integer>350328</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252474870</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:14:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E98</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/06%20Give%20The%20Po'Man%20A%20Break.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>707</key>
+		<dict>
+			<key>Track ID</key><integer>707</integer>
+			<key>Name</key><string>10th And Crenshaw</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4176321</integer>
+			<key>Total Time</key><integer>260832</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253594668</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:17:48Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-02T02:25:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E9A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/07%2010th%20And%20Crenshaw.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>708</key>
+		<dict>
+			<key>Track ID</key><integer>708</integer>
+			<key>Name</key><string>First Down</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6058384</integer>
+			<key>Total Time</key><integer>378462</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:25:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253682759</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:45:59Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85E9C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/08%20First%20Down.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>709</key>
+		<dict>
+			<key>Track ID</key><integer>709</integer>
+			<key>Name</key><string>Punk To Funk</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim/Mansfield</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4770246</integer>
+			<key>Total Time</key><integer>297952</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:26:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:42Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253615182</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:59:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B85E9E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/09%20Punk%20To%20Funk.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>710</key>
+		<dict>
+			<key>Track ID</key><integer>710</integer>
+			<key>Name</key><string>The Sound Of Milwaukee</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6054636</integer>
+			<key>Total Time</key><integer>378226</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:26:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253465453</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:24:13Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85EA0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/10%20The%20Sound%20Of%20Milwaukee.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>711</key>
+		<dict>
+			<key>Track ID</key><integer>711</integer>
+			<key>Name</key><string>Michael Jackson</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim/Negativland</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5592378</integer>
+			<key>Total Time</key><integer>349335</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:26:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253334521</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:02:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EA2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/11%20Michael%20Jackson.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>712</key>
+		<dict>
+			<key>Track ID</key><integer>712</integer>
+			<key>Name</key><string>Next To Nothing</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Composer</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Better Living Through Chemistry</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6989185</integer>
+			<key>Total Time</key><integer>436636</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2005-03-21T23:26:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Encoded By Goldsteve</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252552378</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:46:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EA4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Better%20Living%20Through%20Chemistry/12%20Next%20To%20Nothing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>713</key>
+		<dict>
+			<key>Track ID</key><integer>713</integer>
+			<key>Name</key><string>Talking Bout My Baby</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3952896</integer>
+			<key>Total Time</key><integer>224117</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:02:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251892435</integer>
+			<key>Play Date UTC</key><date>2007-01-17T23:27:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EA6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/01%20Talking%20Bout%20My%20Baby.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>714</key>
+		<dict>
+			<key>Track ID</key><integer>714</integer>
+			<key>Name</key><string>Sunset (Bird of Prey)</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6963473</integer>
+			<key>Total Time</key><integer>410155</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:02:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253034789</integer>
+			<key>Play Date UTC</key><date>2007-01-31T04:46:29Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EA9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/02%20Sunset%20(Bird%20of%20Prey).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>715</key>
+		<dict>
+			<key>Track ID</key><integer>715</integer>
+			<key>Name</key><string>Love Life</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7106597</integer>
+			<key>Total Time</key><integer>419025</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:02:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252578765</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:06:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EAB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/03%20Love%20Life.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>716</key>
+		<dict>
+			<key>Track ID</key><integer>716</integer>
+			<key>Name</key><string>Ya Mama</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5799603</integer>
+			<key>Total Time</key><integer>338243</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253450208</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:10:08Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EAD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/04%20Ya%20Mama.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>717</key>
+		<dict>
+			<key>Track ID</key><integer>717</integer>
+			<key>Name</key><string>Mad Flava</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4752485</integer>
+			<key>Total Time</key><integer>273506</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250709884</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:58:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EAF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/05%20Mad%20Flava.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>718</key>
+		<dict>
+			<key>Track ID</key><integer>718</integer>
+			<key>Name</key><string>Retox</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5467137</integer>
+			<key>Total Time</key><integer>317670</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250595477</integer>
+			<key>Play Date UTC</key><date>2007-01-02T23:11:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EB1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/06%20Retox.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>719</key>
+		<dict>
+			<key>Track ID</key><integer>719</integer>
+			<key>Name</key><string>Weapon of Choice</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5924028</integer>
+			<key>Total Time</key><integer>345929</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253772375</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:39:35Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EB3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/07%20Weapon%20of%20Choice.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>720</key>
+		<dict>
+			<key>Track ID</key><integer>720</integer>
+			<key>Name</key><string>Drop the Hate</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5672729</integer>
+			<key>Total Time</key><integer>330395</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249470464</integer>
+			<key>Play Date UTC</key><date>2006-12-20T22:41:04Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:17:59Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EB5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/08%20Drop%20the%20Hate.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>721</key>
+		<dict>
+			<key>Track ID</key><integer>721</integer>
+			<key>Name</key><string>Demons</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6997250</integer>
+			<key>Total Time</key><integer>412268</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:03:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>34</integer>
+			<key>Play Date</key><integer>3253708796</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:59:56Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T21:25:52Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EB7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/09%20Demons.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>722</key>
+		<dict>
+			<key>Track ID</key><integer>722</integer>
+			<key>Name</key><string>Song for Shelter</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9069820</integer>
+			<key>Total Time</key><integer>540326</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:04:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252385843</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:30:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EB9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/10%20Song%20for%20Shelter.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>723</key>
+		<dict>
+			<key>Track ID</key><integer>723</integer>
+			<key>Name</key><string>Talking Bout My Baby (Reprise)</string>
+			<key>Artist</key><string>Fatboy Slim</string>
+			<key>Album Artist</key><string>Fatboy Slim</string>
+			<key>Album</key><string>Halfway Between the Gutter and the Stars</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2767162</integer>
+			<key>Total Time</key><integer>150835</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-07-27T17:04:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252550242</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:10:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EBB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fatboy%20Slim/Halfway%20Between%20the%20Gutter%20and%20the%20Stars/11%20Talking%20Bout%20My%20Baby%20(Reprise).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>724</key>
+		<dict>
+			<key>Track ID</key><integer>724</integer>
+			<key>Name</key><string>Take a Picture [Hybrid Mix]</string>
+			<key>Artist</key><string>Filter</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7790009</integer>
+			<key>Total Time</key><integer>486739</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253556435</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:40:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EBD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Filter/Plastic%20Compilation,%20Vol.%203/04%20Take%20a%20Picture%20%5BHybrid%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>725</key>
+		<dict>
+			<key>Track ID</key><integer>725</integer>
+			<key>Name</key><string>Sleep to Dream</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4027457</integer>
+			<key>Total Time</key><integer>250044</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253523219</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:26:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EC0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/01%20Sleep%20to%20Dream.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>726</key>
+		<dict>
+			<key>Track ID</key><integer>726</integer>
+			<key>Name</key><string>Sullen Girl</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3780485</integer>
+			<key>Total Time</key><integer>234736</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252553335</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:02:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EC3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/02%20Sullen%20Girl.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>727</key>
+		<dict>
+			<key>Track ID</key><integer>727</integer>
+			<key>Name</key><string>Shadowboxer</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5221859</integer>
+			<key>Total Time</key><integer>324310</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252938848</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:07:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EC5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/03%20Shadowboxer.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>728</key>
+		<dict>
+			<key>Track ID</key><integer>728</integer>
+			<key>Name</key><string>Criminal</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5530689</integer>
+			<key>Total Time</key><integer>343484</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253768493</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:34:53Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85EC7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/04%20Criminal.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>729</key>
+		<dict>
+			<key>Track ID</key><integer>729</integer>
+			<key>Name</key><string>Slow Like Honey</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5758853</integer>
+			<key>Total Time</key><integer>357616</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B85EC9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/05%20Slow%20Like%20Honey.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>730</key>
+		<dict>
+			<key>Track ID</key><integer>730</integer>
+			<key>Name</key><string>The First Taste</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4622966</integer>
+			<key>Total Time</key><integer>287007</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252508241</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:30:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ECB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/06%20The%20First%20Taste.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>731</key>
+		<dict>
+			<key>Track ID</key><integer>731</integer>
+			<key>Name</key><string>Never Is a Promise</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5709952</integer>
+			<key>Total Time</key><integer>354560</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252562575</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:36:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ECD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/07%20Never%20Is%20a%20Promise.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>732</key>
+		<dict>
+			<key>Track ID</key><integer>732</integer>
+			<key>Name</key><string>The Child Is Gone</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4105198</integer>
+			<key>Total Time</key><integer>254902</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252579020</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:10:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ECF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/08%20The%20Child%20Is%20Gone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>733</key>
+		<dict>
+			<key>Track ID</key><integer>733</integer>
+			<key>Name</key><string>Pale September</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5652692</integer>
+			<key>Total Time</key><integer>350981</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252418928</integer>
+			<key>Play Date UTC</key><date>2007-01-24T01:42:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ED1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/09%20Pale%20September.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>734</key>
+		<dict>
+			<key>Track ID</key><integer>734</integer>
+			<key>Name</key><string>Carrion</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album</key><string>Tidal</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5566216</integer>
+			<key>Total Time</key><integer>345704</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251479563</integer>
+			<key>Play Date UTC</key><date>2007-01-13T04:46:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B85ED3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/Tidal/10%20Carrion.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>735</key>
+		<dict>
+			<key>Track ID</key><integer>735</integer>
+			<key>Name</key><string>On the Bound</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5418912</integer>
+			<key>Total Time</key><integer>323963</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-19T02:29:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253529195</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:06:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ED5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/01%20On%20the%20Bound.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>736</key>
+		<dict>
+			<key>Track ID</key><integer>736</integer>
+			<key>Name</key><string>To Your Love</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3788112</integer>
+			<key>Total Time</key><integer>221261</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-30T20:12:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252468035</integer>
+			<key>Play Date UTC</key><date>2007-01-24T15:20:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85ED8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/02%20To%20Your%20Love.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>737</key>
+		<dict>
+			<key>Track ID</key><integer>737</integer>
+			<key>Name</key><string>Limp</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3619968</integer>
+			<key>Total Time</key><integer>210673</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-20T23:17:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253111304</integer>
+			<key>Play Date UTC</key><date>2007-02-01T02:01:44Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EDA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/03%20Limp.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>738</key>
+		<dict>
+			<key>Track ID</key><integer>738</integer>
+			<key>Name</key><string>Love Ridden</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3505312</integer>
+			<key>Total Time</key><integer>203451</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-21T03:46:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253355349</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:49:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EDC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/04%20Love%20Ridden.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>739</key>
+		<dict>
+			<key>Track ID</key><integer>739</integer>
+			<key>Name</key><string>Paper Bag</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3765968</integer>
+			<key>Total Time</key><integer>219868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-10T02:24:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252414235</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:23:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EDE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/05%20Paper%20Bag.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>740</key>
+		<dict>
+			<key>Track ID</key><integer>740</integer>
+			<key>Name</key><string>A Mistake</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5001456</integer>
+			<key>Total Time</key><integer>297655</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-19T02:18:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253678784</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:39:44Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EE0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/06%20A%20Mistake.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>741</key>
+		<dict>
+			<key>Track ID</key><integer>741</integer>
+			<key>Name</key><string>Fast As You Can</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4719104</integer>
+			<key>Total Time</key><integer>279891</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-09T10:23:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252473284</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:48:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EE2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/07%20Fast%20As%20You%20Can.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>742</key>
+		<dict>
+			<key>Track ID</key><integer>742</integer>
+			<key>Name</key><string>The Way Things Are</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4371472</integer>
+			<key>Total Time</key><integer>257995</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-23T13:00:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253264194</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:29:54Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T16:27:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EE4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/08%20The%20Way%20Things%20Are.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>743</key>
+		<dict>
+			<key>Track ID</key><integer>743</integer>
+			<key>Name</key><string>Get Gone</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4246416</integer>
+			<key>Total Time</key><integer>250123</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-20T19:59:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253036433</integer>
+			<key>Play Date UTC</key><date>2007-01-31T05:13:53Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EE6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/09%20Get%20Gone.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>744</key>
+		<dict>
+			<key>Track ID</key><integer>744</integer>
+			<key>Name</key><string>I Know</string>
+			<key>Artist</key><string>Fiona Apple</string>
+			<key>Album Artist</key><string>Fiona Apple</string>
+			<key>Composer</key><string>Fiona Apple</string>
+			<key>Album</key><string>When the Pawn Hits the Conflicts He Thinks Like a King...</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5009280</integer>
+			<key>Total Time</key><integer>298165</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-27T02:02:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249477345</integer>
+			<key>Play Date UTC</key><date>2006-12-21T00:35:45Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T18:01:35Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85EE8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fiona%20Apple/When%20the%20Pawn%20Hits%20the%20Conflicts%20He%20Thinks%20Like%20a%20King.._/10%20I%20Know.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>745</key>
+		<dict>
+			<key>Track ID</key><integer>745</integer>
+			<key>Name</key><string>Thumper! (Original Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8556544</integer>
+			<key>Total Time</key><integer>356466</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:13:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>16</integer>
+			<key>Play Date</key><integer>3253687527</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:05:27Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-18T23:12:37Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85EEA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/01%20Thumper!%20(Original%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>746</key>
+		<dict>
+			<key>Track ID</key><integer>746</integer>
+			<key>Name</key><string>Philly (Jamateur Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8103936</integer>
+			<key>Total Time</key><integer>337580</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:13:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3249291517</integer>
+			<key>Play Date UTC</key><date>2006-12-18T20:58:37Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85EED</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/02%20Philly%20(Jamateur%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>747</key>
+		<dict>
+			<key>Track ID</key><integer>747</integer>
+			<key>Name</key><string>Glorious</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8527872</integer>
+			<key>Total Time</key><integer>355213</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:23:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249452598</integer>
+			<key>Play Date UTC</key><date>2006-12-20T17:43:18Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85EEF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/03%20Glorious.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>748</key>
+		<dict>
+			<key>Track ID</key><integer>748</integer>
+			<key>Name</key><string>Easy Peasy</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6023168</integer>
+			<key>Total Time</key><integer>250880</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:23:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253507240</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:00:40Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85EF1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/04%20Easy%20Peasy.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>749</key>
+		<dict>
+			<key>Track ID</key><integer>749</integer>
+			<key>Name</key><string>Pan Am into Philly</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8032256</integer>
+			<key>Total Time</key><integer>334628</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:22:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253716510</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:08:30Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85EF3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/05%20Pan%20Am%20into%20Philly.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>750</key>
+		<dict>
+			<key>Track ID</key><integer>750</integer>
+			<key>Name</key><string>Garden of Blighty</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14129152</integer>
+			<key>Total Time</key><integer>588617</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:22:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251895631</integer>
+			<key>Play Date UTC</key><date>2007-01-18T00:20:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EF5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/06%20Garden%20of%20Blighty.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>751</key>
+		<dict>
+			<key>Track ID</key><integer>751</integer>
+			<key>Name</key><string>Jig</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7313408</integer>
+			<key>Total Time</key><integer>304640</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:22:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252582021</integer>
+			<key>Play Date UTC</key><date>2007-01-25T23:00:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EF7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/07%20Jig.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>752</key>
+		<dict>
+			<key>Track ID</key><integer>752</integer>
+			<key>Name</key><string>Phin</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9357312</integer>
+			<key>Total Time</key><integer>389773</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:22:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253714740</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:39:00Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-25T02:00:53Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85EF9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/08%20Phin.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>753</key>
+		<dict>
+			<key>Track ID</key><integer>753</integer>
+			<key>Name</key><string>Tax (iOriginal White Label B-Side_</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6100992</integer>
+			<key>Total Time</key><integer>254093</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:22:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246960747</integer>
+			<key>Play Date UTC</key><date>2006-11-21T21:32:27Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-14T17:39:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EFB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/09%20Tax%20(iOriginal%20White%20Label%20B-Side_.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>754</key>
+		<dict>
+			<key>Track ID</key><integer>754</integer>
+			<key>Name</key><string>Coolest (Original White Label B2)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4171776</integer>
+			<key>Total Time</key><integer>173714</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:25:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252468700</integer>
+			<key>Play Date UTC</key><date>2007-01-24T15:31:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T23:35:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B85EFD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/10%20Coolest%20(Original%20White%20Label%20B2).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>755</key>
+		<dict>
+			<key>Track ID</key><integer>755</integer>
+			<key>Name</key><string>The Bells (Mix One / 12'' A-Side)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 1]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8196096</integer>
+			<key>Total Time</key><integer>341394</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:23:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253455363</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:36:03Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85EFF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%201%5D/11%20The%20Bells%20(Mix%20One%20_%2012''%20A-Side).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>756</key>
+		<dict>
+			<key>Track ID</key><integer>756</integer>
+			<key>Name</key><string>Spacey (Catch 22 Dub)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8876689</integer>
+			<key>Total Time</key><integer>369737</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:59:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253277638</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:13:58Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85F01</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/01%20Spacey%20(Catch%2022%20Dub).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>757</key>
+		<dict>
+			<key>Track ID</key><integer>757</integer>
+			<key>Name</key><string>Astrosapiens</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9855330</integer>
+			<key>Total Time</key><integer>410514</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:58:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252994044</integer>
+			<key>Play Date UTC</key><date>2007-01-30T17:27:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F04</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/02%20Astrosapiens.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>758</key>
+		<dict>
+			<key>Track ID</key><integer>758</integer>
+			<key>Name</key><string>Life Support</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9376349</integer>
+			<key>Total Time</key><integer>390556</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:00:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249565299</integer>
+			<key>Play Date UTC</key><date>2006-12-22T01:01:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F06</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/03%20Life%20Support.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>759</key>
+		<dict>
+			<key>Track ID</key><integer>759</integer>
+			<key>Name</key><string>Cut</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9617085</integer>
+			<key>Total Time</key><integer>400587</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:00:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253340107</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:35:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T23:07:38Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85F08</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/04%20Cut.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>760</key>
+		<dict>
+			<key>Track ID</key><integer>760</integer>
+			<key>Name</key><string>Wobbler</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12648965</integer>
+			<key>Total Time</key><integer>526915</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:04:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246904639</integer>
+			<key>Play Date UTC</key><date>2006-11-21T05:57:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F0A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/05%20Wobbler.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>761</key>
+		<dict>
+			<key>Track ID</key><integer>761</integer>
+			<key>Name</key><string>O.K.</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11249007</integer>
+			<key>Total Time</key><integer>468584</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:03:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253357556</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:25:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F0C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/06%20O.K..mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>762</key>
+		<dict>
+			<key>Track ID</key><integer>762</integer>
+			<key>Name</key><string>Kitten Moon</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14783695</integer>
+			<key>Total Time</key><integer>615862</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:07:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253679749</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:55:49Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F0E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/07%20Kitten%20Moon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>763</key>
+		<dict>
+			<key>Track ID</key><integer>763</integer>
+			<key>Name</key><string>Bermuda</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11497278</integer>
+			<key>Total Time</key><integer>478928</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:06:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246469987</integer>
+			<key>Play Date UTC</key><date>2006-11-16T05:13:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F10</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/08%20Bermuda.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>764</key>
+		<dict>
+			<key>Track ID</key><integer>764</integer>
+			<key>Name</key><string>Setback</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12559312</integer>
+			<key>Total Time</key><integer>523180</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:10:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253356134</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:02:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F12</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/09%20Setback.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>765</key>
+		<dict>
+			<key>Track ID</key><integer>765</integer>
+			<key>Name</key><string>Goodnight Lover</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 2]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10497320</integer>
+			<key>Total Time</key><integer>437263</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T17:10:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>28</integer>
+			<key>Play Date</key><integer>3253716947</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:15:47Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F14</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%202%5D/10%20Goodnight%20Lover.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>766</key>
+		<dict>
+			<key>Track ID</key><integer>766</integer>
+			<key>Name</key><string>Slid (Justin Robertson's Scat And Sax Frenzy)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9751293</integer>
+			<key>Total Time</key><integer>406177</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:42:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252520731</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:58:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F16</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/01%20Slid%20(Justin%20Robertson's%20Scat%20And%20Sax%20Frenzy).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>767</key>
+		<dict>
+			<key>Track ID</key><integer>767</integer>
+			<key>Name</key><string>Electric Guitar (Headstock)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8040986</integer>
+			<key>Total Time</key><integer>334915</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:43:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252500758</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:25:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F19</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/02%20Electric%20Guitar%20(Headstock).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>768</key>
+		<dict>
+			<key>Track ID</key><integer>768</integer>
+			<key>Name</key><string>Groovy Feeling (Screwball)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10329311</integer>
+			<key>Total Time</key><integer>430262</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:44:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253681674</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:27:54Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85F1B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/03%20Groovy%20Feeling%20(Screwball).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>769</key>
+		<dict>
+			<key>Track ID</key><integer>769</integer>
+			<key>Name</key><string>Bubble (Braillebubble)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9686695</integer>
+			<key>Total Time</key><integer>403487</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:44:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252416116</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:55:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F1D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/04%20Bubble%20(Braillebubble).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>770</key>
+		<dict>
+			<key>Track ID</key><integer>770</integer>
+			<key>Name</key><string>Bullet (Atlas Space Bass)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>13571837</integer>
+			<key>Total Time</key><integer>565368</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:49:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246865086</integer>
+			<key>Play Date UTC</key><date>2006-11-20T18:58:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F1F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/05%20Bullet%20(Atlas%20Space%20Bass).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>771</key>
+		<dict>
+			<key>Track ID</key><integer>771</integer>
+			<key>Name</key><string>Bullet (Dust Brothers Jazz Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2886299</integer>
+			<key>Total Time</key><integer>120137</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:46:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253613407</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:30:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T01:09:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F21</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/06%20Bullet%20(Dust%20Brothers%20Jazz%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>772</key>
+		<dict>
+			<key>Track ID</key><integer>772</integer>
+			<key>Name</key><string>Tosh - Nosh (Fila Brazilia Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9267909</integer>
+			<key>Total Time</key><integer>386037</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:48:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253683760</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:02:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T06:15:40Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F23</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/07%20Tosh%20-%20Nosh%20(Fila%20Brazilia%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>773</key>
+		<dict>
+			<key>Track ID</key><integer>773</integer>
+			<key>Name</key><string>Atom Bomb (Atomix 4)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14710353</integer>
+			<key>Total Time</key><integer>612806</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:52:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B85F25</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/08%20Atom%20Bomb%20(Atomix%204).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>774</key>
+		<dict>
+			<key>Track ID</key><integer>774</integer>
+			<key>Name</key><string>Absurd (Marine Parade Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9549399</integer>
+			<key>Total Time</key><integer>397766</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:52:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249535643</integer>
+			<key>Play Date UTC</key><date>2006-12-21T16:47:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F27</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/09%20Absurd%20(Marine%20Parade%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>775</key>
+		<dict>
+			<key>Track ID</key><integer>775</integer>
+			<key>Name</key><string>Absurd (Soul Of Man Mix)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10949980</integer>
+			<key>Total Time</key><integer>456124</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:55:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252555038</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:30:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F29</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/10%20Absurd%20(Soul%20Of%20Man%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>776</key>
+		<dict>
+			<key>Track ID</key><integer>776</integer>
+			<key>Name</key><string>Squirt (Europicola)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Progrsssive History XXX [CD 3]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10399522</integer>
+			<key>Total Time</key><integer>433188</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2006-09-15T16:50:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250682994</integer>
+			<key>Play Date UTC</key><date>2007-01-03T23:29:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F2B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Progrsssive%20History%20XXX%20%5BCD%203%5D/11%20Squirt%20(Europicola).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>777</key>
+		<dict>
+			<key>Track ID</key><integer>777</integer>
+			<key>Name</key><string>Snapshot</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4409810</integer>
+			<key>Total Time</key><integer>248986</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:27:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253689349</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:35:49Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-16T05:05:52Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F2D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/01%20Snapshot.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>778</key>
+		<dict>
+			<key>Track ID</key><integer>778</integer>
+			<key>Name</key><string>My Spine</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7060322</integer>
+			<key>Total Time</key><integer>442152</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:27:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:43Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>28</integer>
+			<key>Play Date</key><integer>3253039637</integer>
+			<key>Play Date UTC</key><date>2007-01-31T06:07:17Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F30</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/02%20My%20Spine.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>779</key>
+		<dict>
+			<key>Track ID</key><integer>779</integer>
+			<key>Name</key><string>Another Kind of Blues</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4708786</integer>
+			<key>Total Time</key><integer>277569</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:27:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253676748</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:05:48Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T19:41:57Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F32</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/03%20Another%20Kind%20of%20Blues.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>780</key>
+		<dict>
+			<key>Track ID</key><integer>780</integer>
+			<key>Name</key><string>Hang Tough</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5573474</integer>
+			<key>Total Time</key><integer>328003</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:28:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246635389</integer>
+			<key>Play Date UTC</key><date>2006-11-18T03:09:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F34</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/04%20Hang%20Tough.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>781</key>
+		<dict>
+			<key>Track ID</key><integer>781</integer>
+			<key>Name</key><string>Switch / Twitch</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9705282</integer>
+			<key>Total Time</key><integer>573276</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:28:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252934774</integer>
+			<key>Play Date UTC</key><date>2007-01-30T00:59:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F36</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/05%20Switch%20_%20Twitch.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>782</key>
+		<dict>
+			<key>Track ID</key><integer>782</integer>
+			<key>Name</key><string>YKK</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6973042</integer>
+			<key>Total Time</key><integer>404977</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:28:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252039206</integer>
+			<key>Play Date UTC</key><date>2007-01-19T16:13:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F38</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/06%20YKK.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>783</key>
+		<dict>
+			<key>Track ID</key><integer>783</integer>
+			<key>Name</key><string>Expo</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5580866</integer>
+			<key>Total Time</key><integer>318506</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:29:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253295496</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:11:36Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F3A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/07%20Expo.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>784</key>
+		<dict>
+			<key>Track ID</key><integer>784</integer>
+			<key>Name</key><string>Electric Blue</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6558050</integer>
+			<key>Total Time</key><integer>394737</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:29:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253374311</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:05:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F3C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/08%20Electric%20Blue.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>785</key>
+		<dict>
+			<key>Track ID</key><integer>785</integer>
+			<key>Name</key><string>Baby Pain</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5718930</integer>
+			<key>Total Time</key><integer>344373</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:29:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247628773</integer>
+			<key>Play Date UTC</key><date>2006-11-29T15:06:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F3E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/09%20Baby%20Pain.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>786</key>
+		<dict>
+			<key>Track ID</key><integer>786</integer>
+			<key>Name</key><string>Nebulus</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6038098</integer>
+			<key>Total Time</key><integer>357725</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:30:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251354842</integer>
+			<key>Play Date UTC</key><date>2007-01-11T18:07:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F40</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/10%20Nebulus.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>787</key>
+		<dict>
+			<key>Track ID</key><integer>787</integer>
+			<key>Name</key><string>Blue Sky</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album Artist</key><string>Fluke</string>
+			<key>Album</key><string>Puppy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6040114</integer>
+			<key>Total Time</key><integer>348901</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-09-28T20:30:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253377335</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:55:35Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:18Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F42</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Puppy/11%20Blue%20Sky.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>788</key>
+		<dict>
+			<key>Track ID</key><integer>788</integer>
+			<key>Name</key><string>Absurd</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8353920</integer>
+			<key>Total Time</key><integer>348055</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253715391</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:49:51Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85F44</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/01%20Absurd.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>789</key>
+		<dict>
+			<key>Track ID</key><integer>789</integer>
+			<key>Name</key><string>Atom Bomb</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8292480</integer>
+			<key>Total Time</key><integer>345469</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>34</integer>
+			<key>Play Date</key><integer>3253473935</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:45:35Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85F47</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/02%20Atom%20Bomb.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>790</key>
+		<dict>
+			<key>Track ID</key><integer>790</integer>
+			<key>Name</key><string>Kitten Moon</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>13398144</integer>
+			<key>Total Time</key><integer>558236</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253040863</integer>
+			<key>Play Date UTC</key><date>2007-01-31T06:27:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T04:00:11Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F49</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/03%20Kitten%20Moon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>791</key>
+		<dict>
+			<key>Track ID</key><integer>791</integer>
+			<key>Name</key><string>Mosh</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9150592</integer>
+			<key>Total Time</key><integer>381257</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253373917</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:58:37Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F4B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/04%20Mosh.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>792</key>
+		<dict>
+			<key>Track ID</key><integer>792</integer>
+			<key>Name</key><string>Setback</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12841088</integer>
+			<key>Total Time</key><integer>535013</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3253687171</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:59:31Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85F4D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/05%20Setback.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>793</key>
+		<dict>
+			<key>Track ID</key><integer>793</integer>
+			<key>Name</key><string>Bermuda</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11456640</integer>
+			<key>Total Time</key><integer>477283</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253360051</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:07:31Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T21:21:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F4F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/06%20Bermuda.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>794</key>
+		<dict>
+			<key>Track ID</key><integer>794</integer>
+			<key>Name</key><string>Amp</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11751552</integer>
+			<key>Total Time</key><integer>489613</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253765002</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:36:42Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85F51</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/07%20Amp.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>795</key>
+		<dict>
+			<key>Track ID</key><integer>795</integer>
+			<key>Name</key><string>Reeferendrum</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10608768</integer>
+			<key>Total Time</key><integer>441939</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253364121</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:15:21Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F53</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/08%20Reeferendrum.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>796</key>
+		<dict>
+			<key>Track ID</key><integer>796</integer>
+			<key>Name</key><string>Squirt</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9021568</integer>
+			<key>Total Time</key><integer>375849</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251624549</integer>
+			<key>Play Date UTC</key><date>2007-01-14T21:02:29Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85F55</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/09%20Squirt.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>797</key>
+		<dict>
+			<key>Track ID</key><integer>797</integer>
+			<key>Name</key><string>Goodnight Lover</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Risotto</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10899584</integer>
+			<key>Total Time</key><integer>454138</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-09-15T18:17:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253686636</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:50:36Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85F57</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Risotto/10%20Goodnight%20Lover.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>798</key>
+		<dict>
+			<key>Track ID</key><integer>798</integer>
+			<key>Name</key><string>Groovy Feeling (Make Mine A 99)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12243614</integer>
+			<key>Total Time</key><integer>432927</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>226</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253466766</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:46:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F59</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/01%20Groovy%20Feeling%20(Make%20Mine%20A%2099).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>799</key>
+		<dict>
+			<key>Track ID</key><integer>799</integer>
+			<key>Name</key><string>Love Letters</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10732819</integer>
+			<key>Total Time</key><integer>402050</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>213</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253618512</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:55:12Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F5C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/02%20Love%20Letters.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>800</key>
+		<dict>
+			<key>Track ID</key><integer>800</integer>
+			<key>Name</key><string>Glidub</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10207647</integer>
+			<key>Total Time</key><integer>376502</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>216</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252497316</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:28:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T22:30:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F5E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/03%20Glidub.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>801</key>
+		<dict>
+			<key>Track ID</key><integer>801</integer>
+			<key>Name</key><string>Electric Guitar (Humbucker)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11807052</integer>
+			<key>Total Time</key><integer>444995</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>212</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253554452</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:07:32Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T23:07:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F60</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/04%20Electric%20Guitar%20(Humbucker).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>802</key>
+		<dict>
+			<key>Track ID</key><integer>802</integer>
+			<key>Name</key><string>Top Of The World</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9716759</integer>
+			<key>Total Time</key><integer>340192</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>228</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252037842</integer>
+			<key>Play Date UTC</key><date>2007-01-19T15:50:42Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85F62</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/05%20Top%20Of%20The%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>803</key>
+		<dict>
+			<key>Track ID</key><integer>803</integer>
+			<key>Name</key><string>Slid (Pdfmone)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12984812</integer>
+			<key>Total Time</key><integer>461479</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>225</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249529275</integer>
+			<key>Play Date UTC</key><date>2006-12-21T15:01:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F64</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/06%20Slid%20(Pdfmone).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>804</key>
+		<dict>
+			<key>Track ID</key><integer>804</integer>
+			<key>Name</key><string>Slowmotion</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7673889</integer>
+			<key>Total Time</key><integer>311170</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>197</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250576098</integer>
+			<key>Play Date UTC</key><date>2007-01-02T17:48:18Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-13T22:33:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F66</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/07%20Slowmotion.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>805</key>
+		<dict>
+			<key>Track ID</key><integer>805</integer>
+			<key>Name</key><string>Spacey (Catch 22 Dub)</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9498531</integer>
+			<key>Total Time</key><integer>369110</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>205</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253689100</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:31:40Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85F68</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/08%20Spacey%20(Catch%2022%20Dub).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>806</key>
+		<dict>
+			<key>Track ID</key><integer>806</integer>
+			<key>Name</key><string>Astrosapiens</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10605978</integer>
+			<key>Total Time</key><integer>408241</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>207</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253286428</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:40:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F6A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/09%20Astrosapiens.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>807</key>
+		<dict>
+			<key>Track ID</key><integer>807</integer>
+			<key>Name</key><string>Oh Yeah</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8873154</integer>
+			<key>Total Time</key><integer>346749</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>204</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252504825</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:33:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F6C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/10%20Oh%20Yeah.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>808</key>
+		<dict>
+			<key>Track ID</key><integer>808</integer>
+			<key>Name</key><string>Eko</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8058189</integer>
+			<key>Total Time</key><integer>322429</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-09-15T17:45:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>199</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253519000</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:16:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F6E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/11%20Eko.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>809</key>
+		<dict>
+			<key>Track ID</key><integer>809</integer>
+			<key>Name</key><string>Life Support</string>
+			<key>Artist</key><string>Fluke</string>
+			<key>Album</key><string>Six Wheels On My Wagon</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10290831</integer>
+			<key>Total Time</key><integer>388780</integer>
+			<key>Start Time</key><integer>30000</integer>
+			<key>Stop Time</key><integer>330000</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2006-11-16T15:44:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>211</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253043452</integer>
+			<key>Play Date UTC</key><date>2007-01-31T07:10:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:44:19Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85F70</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fluke/Six%20Wheels%20On%20My%20Wagon/12%20Life%20Support.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>810</key>
+		<dict>
+			<key>Track ID</key><integer>810</integer>
+			<key>Name</key><string>Hold Back</string>
+			<key>Artist</key><string>Force Mass Motion &#38; Dylan Rhymes</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Beaver/Wells</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6692349</integer>
+			<key>Total Time</key><integer>278021</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3249303078</integer>
+			<key>Play Date UTC</key><date>2006-12-19T00:11:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F72</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Force%20Mass%20Motion%20&#38;%20Dylan%20Rhymes/Community%20Service/14%20Hold%20Back.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>811</key>
+		<dict>
+			<key>Track ID</key><integer>811</integer>
+			<key>Name</key><string>The Trial Of The Century</string>
+			<key>Artist</key><string>French Kicks</string>
+			<key>Album</key><string>SXSW 2005 Showcasing Artist</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4068541</integer>
+			<key>Total Time</key><integer>254275</integer>
+			<key>Date Modified</key><date>2005-04-13T22:05:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>SXSW 2005 Showcasing Artist</string>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250613811</integer>
+			<key>Play Date UTC</key><date>2007-01-03T04:16:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F74</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/French%20Kicks/SXSW%202005%20Showcasing%20Artist/The%20Trial%20Of%20The%20Century.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>812</key>
+		<dict>
+			<key>Track ID</key><integer>812</integer>
+			<key>Name</key><string>Up on the Hill</string>
+			<key>Artist</key><string>Fun Lovin' Criminals</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3406370</integer>
+			<key>Total Time</key><integer>212506</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252473497</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:51:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F77</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Fun%20Lovin'%20Criminals/Late%20Lounge%20(1%20of%202)/10%20Up%20on%20the%20Hill.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>813</key>
+		<dict>
+			<key>Track ID</key><integer>813</integer>
+			<key>Name</key><string>Paranoid (The Crystal Method Remix)</string>
+			<key>Artist</key><string>Garbage</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Garbage</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7789492</integer>
+			<key>Total Time</key><integer>323735</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253043776</integer>
+			<key>Play Date UTC</key><date>2007-01-31T07:16:16Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B85F7A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Garbage/Community%20Service/12%20Paranoid%20(The%20Crystal%20Method%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>814</key>
+		<dict>
+			<key>Track ID</key><integer>814</integer>
+			<key>Name</key><string>Milk [the Classic Mix Massive Attack]</string>
+			<key>Artist</key><string>Garbage</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4567043</integer>
+			<key>Total Time</key><integer>285048</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-20T22:52:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85F7C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Garbage/Late%20Lounge%20(2%20of%202)/11%20Milk%20%5Bthe%20Classic%20Mix%20Massive%20Attack%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>815</key>
+		<dict>
+			<key>Track ID</key><integer>815</integer>
+			<key>Name</key><string>Frankenstein</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2668360</integer>
+			<key>Total Time</key><integer>163536</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:04:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252518218</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:16:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F7F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/01%20Frankenstein.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>816</key>
+		<dict>
+			<key>Track ID</key><integer>816</integer>
+			<key>Name</key><string>It Don't Mean Nothin'</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3261677</integer>
+			<key>Total Time</key><integer>200618</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:05:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247720499</integer>
+			<key>Play Date UTC</key><date>2006-11-30T16:34:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F82</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/02%20It%20Don't%20Mean%20Nothin'.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>817</key>
+		<dict>
+			<key>Track ID</key><integer>817</integer>
+			<key>Name</key><string>Electric Karma</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2713686</integer>
+			<key>Total Time</key><integer>166369</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:06:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246080541</integer>
+			<key>Play Date UTC</key><date>2006-11-11T17:02:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F84</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/03%20Electric%20Karma.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>818</key>
+		<dict>
+			<key>Track ID</key><integer>818</integer>
+			<key>Name</key><string>Wake Up Call</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3597530</integer>
+			<key>Total Time</key><integer>221609</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:06:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250579337</integer>
+			<key>Play Date UTC</key><date>2007-01-02T18:42:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F86</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/04%20Wake%20Up%20Call.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>819</key>
+		<dict>
+			<key>Track ID</key><integer>819</integer>
+			<key>Name</key><string>Surf Alert</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3134617</integer>
+			<key>Total Time</key><integer>192677</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:07:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253279831</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:50:31Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-26T19:38:05Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85F88</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/05%20Surf%20Alert.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>820</key>
+		<dict>
+			<key>Track ID</key><integer>820</integer>
+			<key>Name</key><string>Last Good Nerve</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4231713</integer>
+			<key>Total Time</key><integer>261246</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:08:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252491225</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:47:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F8A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/06%20Last%20Good%20Nerve.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>821</key>
+		<dict>
+			<key>Track ID</key><integer>821</integer>
+			<key>Name</key><string>Magic Ride</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2859321</integer>
+			<key>Total Time</key><integer>175471</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:08:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247631886</integer>
+			<key>Play Date UTC</key><date>2006-11-29T15:58:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F8C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/07%20Magic%20Ride.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>822</key>
+		<dict>
+			<key>Track ID</key><integer>822</integer>
+			<key>Name</key><string>Big Step Back</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3544774</integer>
+			<key>Total Time</key><integer>218312</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:09:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253044187</integer>
+			<key>Play Date UTC</key><date>2007-01-31T07:23:07Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-02-08T01:39:09Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85F8E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/08%20Big%20Step%20Back.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>823</key>
+		<dict>
+			<key>Track ID</key><integer>823</integer>
+			<key>Name</key><string>Train Wreck</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3243472</integer>
+			<key>Total Time</key><integer>199481</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:10:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251483525</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:52:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F90</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/09%20Train%20Wreck.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>824</key>
+		<dict>
+			<key>Track ID</key><integer>824</integer>
+			<key>Name</key><string>Devil's On The Phone</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2724088</integer>
+			<key>Total Time</key><integer>167019</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:10:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253545944</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:45:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F92</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/10%20Devil's%20On%20The%20Phone.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>825</key>
+		<dict>
+			<key>Track ID</key><integer>825</integer>
+			<key>Name</key><string>Fillmore Blues</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6435715</integer>
+			<key>Total Time</key><integer>397524</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:11:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252574452</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:54:12Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F94</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/11%20Fillmore%20Blues.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>826</key>
+		<dict>
+			<key>Track ID</key><integer>826</integer>
+			<key>Name</key><string>Low Rider</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4243974</integer>
+			<key>Total Time</key><integer>262012</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:12:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250572892</integer>
+			<key>Play Date UTC</key><date>2007-01-02T16:54:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F96</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/12%20Low%20Rider.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>827</key>
+		<dict>
+			<key>Track ID</key><integer>827</integer>
+			<key>Name</key><string>Linus &#38; Lucy</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3509480</integer>
+			<key>Total Time</key><integer>216106</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:13:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250667637</integer>
+			<key>Play Date UTC</key><date>2007-01-03T19:13:57Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F98</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/13%20Linus%20&#38;%20Lucy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>828</key>
+		<dict>
+			<key>Track ID</key><integer>828</integer>
+			<key>Name</key><string>Drive</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3937470</integer>
+			<key>Total Time</key><integer>242856</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:13:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252472256</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:30:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F9A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/14%20Drive.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>829</key>
+		<dict>
+			<key>Track ID</key><integer>829</integer>
+			<key>Name</key><string>Hocus Pocus</string>
+			<key>Artist</key><string>Gary Hoey</string>
+			<key>Composer</key><string>Gary Hoey</string>
+			<key>Album</key><string>Wake Up Call</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3983538</integer>
+			<key>Total Time</key><integer>245735</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-04-16T03:14:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B85F9C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gary%20Hoey/Wake%20Up%20Call/15%20Hocus%20Pocus.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>830</key>
+		<dict>
+			<key>Track ID</key><integer>830</integer>
+			<key>Name</key><string>Viola</string>
+			<key>Artist</key><string>Girlyman</string>
+			<key>Composer</key><string>Nate Borofsky</string>
+			<key>Album</key><string>Remember Who I Am</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3686097</integer>
+			<key>Total Time</key><integer>230243</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-02-23T20:32:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250401994</integer>
+			<key>Play Date UTC</key><date>2006-12-31T17:26:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B85F9E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Girlyman/Remember%20Who%20I%20Am/01%20Viola.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>831</key>
+		<dict>
+			<key>Track ID</key><integer>831</integer>
+			<key>Name</key><string>California</string>
+			<key>Artist</key><string>Glorious</string>
+			<key>Album</key><string>Glorious</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3978640</integer>
+			<key>Total Time</key><integer>248528</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2005-02-23T20:35:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249301841</integer>
+			<key>Play Date UTC</key><date>2006-12-18T23:50:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FA1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Glorious/Glorious/02%20California.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>832</key>
+		<dict>
+			<key>Track ID</key><integer>832</integer>
+			<key>Name</key><string>Intro</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1473241</integer>
+			<key>Total Time</key><integer>59156</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:49:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252290088</integer>
+			<key>Play Date UTC</key><date>2007-01-22T13:54:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FA4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/01%20Intro.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>833</key>
+		<dict>
+			<key>Track ID</key><integer>833</integer>
+			<key>Name</key><string>Rearrange</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5174196</integer>
+			<key>Total Time</key><integer>213225</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:50:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253371544</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:19:04Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T01:40:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FA7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/02%20Rearrange.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>834</key>
+		<dict>
+			<key>Track ID</key><integer>834</integer>
+			<key>Name</key><string>From Your Mouth</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6858265</integer>
+			<key>Total Time</key><integer>283006</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:51:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253112647</integer>
+			<key>Play Date UTC</key><date>2007-02-01T02:24:07Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B85FA9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/03%20From%20Your%20Mouth.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>835</key>
+		<dict>
+			<key>Track ID</key><integer>835</integer>
+			<key>Name</key><string>Can't Come Down</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7402646</integer>
+			<key>Total Time</key><integer>305492</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:52:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253288173</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:09:33Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FAB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/04%20Can't%20Come%20Down.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>836</key>
+		<dict>
+			<key>Track ID</key><integer>836</integer>
+			<key>Name</key><string>Alone Again</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4826276</integer>
+			<key>Total Time</key><integer>198740</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:52:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253596407</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:46:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FAD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/05%20Alone%20Again.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>837</key>
+		<dict>
+			<key>Track ID</key><integer>837</integer>
+			<key>Name</key><string>Behavior Modification</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5706382</integer>
+			<key>Total Time</key><integer>235369</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:53:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253544318</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:18:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FAF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/06%20Behavior%20Modification.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>838</key>
+		<dict>
+			<key>Track ID</key><integer>838</integer>
+			<key>Name</key><string>The Rush Is Loud</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6012751</integer>
+			<key>Total Time</key><integer>248084</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:54:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B85FB1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/07%20The%20Rush%20Is%20Loud.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>839</key>
+		<dict>
+			<key>Track ID</key><integer>839</integer>
+			<key>Name</key><string>Dress Rehearsal For Reproduction</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6445901</integer>
+			<key>Total Time</key><integer>265961</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:55:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246690127</integer>
+			<key>Play Date UTC</key><date>2006-11-18T18:22:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FB3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/08%20Dress%20Rehearsal%20For%20Reproduction.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>840</key>
+		<dict>
+			<key>Track ID</key><integer>840</integer>
+			<key>Name</key><string>Happy</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7588305</integer>
+			<key>Total Time</key><integer>313150</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:56:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252398044</integer>
+			<key>Play Date UTC</key><date>2007-01-23T19:54:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FB5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/09%20Happy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>841</key>
+		<dict>
+			<key>Track ID</key><integer>841</integer>
+			<key>Name</key><string>Vapors</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7032456</integer>
+			<key>Total Time</key><integer>290196</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T15:57:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3250578843</integer>
+			<key>Play Date UTC</key><date>2007-01-02T18:34:03Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-21T18:36:24Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85FB7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/10%20Vapors.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>842</key>
+		<dict>
+			<key>Track ID</key><integer>842</integer>
+			<key>Name</key><string>Medicated To The One I Love</string>
+			<key>Artist</key><string>God Lives Underwater</string>
+			<key>Album</key><string>Life In The So-Called Space Age</string>
+			<key>Genre</key><string>Industrial</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>47094196</integer>
+			<key>Total Time</key><integer>1944532</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-06-14T16:03:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T18:35:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FB9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/God%20Lives%20Underwater/Life%20In%20The%20So-Called%20Space%20Age/11%20Medicated%20To%20The%20One%20I%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>843</key>
+		<dict>
+			<key>Track ID</key><integer>843</integer>
+			<key>Name</key><string>Pilots</string>
+			<key>Artist</key><string>Goldfrapp</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4258171</integer>
+			<key>Total Time</key><integer>265743</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FBB</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Goldfrapp/Late%20Lounge%20(1%20of%202)/03%20Pilots.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>844</key>
+		<dict>
+			<key>Track ID</key><integer>844</integer>
+			<key>Name</key><string>At the River</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6311604</integer>
+			<key>Total Time</key><integer>394083</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253602143</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:22:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FBE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Late%20Lounge%20(2%20of%202)/01%20At%20the%20River.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>845</key>
+		<dict>
+			<key>Track ID</key><integer>845</integer>
+			<key>Name</key><string>Remember</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato, Sandy Denny &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5404981</integer>
+			<key>Total Time</key><integer>330511</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T16:57:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:44Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253514549</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:02:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FC1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/03%20Remember.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>846</key>
+		<dict>
+			<key>Track ID</key><integer>846</integer>
+			<key>Name</key><string>Think Twice</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato, Cameron McVey, Neneh Cherry &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5870886</integer>
+			<key>Total Time</key><integer>359304</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T16:58:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>32</integer>
+			<key>Play Date</key><integer>3253075072</integer>
+			<key>Play Date UTC</key><date>2007-01-31T15:57:52Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FC4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/05%20Think%20Twice.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>847</key>
+		<dict>
+			<key>Track ID</key><integer>847</integer>
+			<key>Name</key><string>Hands of Time</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato, Richie Havens &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4301141</integer>
+			<key>Total Time</key><integer>262291</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T16:58:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253606977</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:42:57Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FC6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/07%20Hands%20of%20Time.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>848</key>
+		<dict>
+			<key>Track ID</key><integer>848</integer>
+			<key>Name</key><string>Easy</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato, Cerrone, Don Ray, Sunshine Anderson &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5753495</integer>
+			<key>Total Time</key><integer>352036</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T16:59:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252928922</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:22:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FC8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/09%20Easy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>849</key>
+		<dict>
+			<key>Track ID</key><integer>849</integer>
+			<key>Name</key><string>Lovebox</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5576292</integer>
+			<key>Total Time</key><integer>341099</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T17:00:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253364462</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:21:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FCA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/10%20Lovebox.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>850</key>
+		<dict>
+			<key>Track ID</key><integer>850</integer>
+			<key>Name</key><string>But I Feel Good</string>
+			<key>Artist</key><string>Groove Armada</string>
+			<key>Album Artist</key><string>Groove Armada</string>
+			<key>Composer</key><string>Andy Cato, Mike Daniels &#38; Tom Findlay</string>
+			<key>Album</key><string>Lovebox</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5213381</integer>
+			<key>Total Time</key><integer>318669</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2006-07-27T17:00:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253463244</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:47:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FCC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Groove%20Armada/Lovebox/11%20But%20I%20Feel%20Good.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>851</key>
+		<dict>
+			<key>Track ID</key><integer>851</integer>
+			<key>Name</key><string>Warning Shots</string>
+			<key>Artist</key><string>Gunjan, Sleeping Wonder &#38; Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5019218</integer>
+			<key>Total Time</key><integer>302159</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:32:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252515295</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:28:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FCE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Gunjan,%20Sleeping%20Wonder%20&#38;%20Thievery%20Corporation/The%20Cosmic%20Game/02%20Warning%20Shots.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>852</key>
+		<dict>
+			<key>Track ID</key><integer>852</integer>
+			<key>Name</key><string>Simply Depression, My Dear</string>
+			<key>Artist</key><string>Harrison, Stan</string>
+			<key>Album</key><string>The Ties That Blind</string>
+			<key>Genre</key><string>Noir</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12473043</integer>
+			<key>Total Time</key><integer>311771</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Date Modified</key><date>2005-02-23T21:05:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>320</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250590277</integer>
+			<key>Play Date UTC</key><date>2007-01-02T21:44:37Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-05T20:28:15Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85FD1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Harrison,%20Stan/The%20Ties%20That%20Blind/05%20Simply%20Depression,%20My%20Dear.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>853</key>
+		<dict>
+			<key>Track ID</key><integer>853</integer>
+			<key>Name</key><string>Battersea</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Alex Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4384742</integer>
+			<key>Total Time</key><integer>231501</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-17T18:05:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>34</integer>
+			<key>Play Date</key><integer>3253680825</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:13:45Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FD4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/01%20Battersea.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>854</key>
+		<dict>
+			<key>Track ID</key><integer>854</integer>
+			<key>Name</key><string>One Way Ride</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3922454</integer>
+			<key>Total Time</key><integer>202383</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-08-10T06:29:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253689551</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:39:11Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-04T22:32:35Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FD7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/02%20One%20Way%20Ride.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>855</key>
+		<dict>
+			<key>Track ID</key><integer>855</integer>
+			<key>Name</key><string>Dictionary</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4096166</integer>
+			<key>Total Time</key><integer>213297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-26T02:20:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253623937</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:25:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FD9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/03%20Dictionary.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>856</key>
+		<dict>
+			<key>Track ID</key><integer>856</integer>
+			<key>Name</key><string>Club Montepulciano</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4213654</integer>
+			<key>Total Time</key><integer>220727</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-08-09T10:52:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252471446</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:17:26Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T22:56:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FDB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/04%20Club%20Montepulciano.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>857</key>
+		<dict>
+			<key>Track ID</key><integer>857</integer>
+			<key>Name</key><string>Eden</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4109734</integer>
+			<key>Total Time</key><integer>214156</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-20T04:27:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253347202</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:33:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FDD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/05%20Eden.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>858</key>
+		<dict>
+			<key>Track ID</key><integer>858</integer>
+			<key>Name</key><string>Lung</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3319558</integer>
+			<key>Total Time</key><integer>164395</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-26T02:51:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253188770</integer>
+			<key>Play Date UTC</key><date>2007-02-01T23:32:50Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FDF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/06%20Lung.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>859</key>
+		<dict>
+			<key>Track ID</key><integer>859</integer>
+			<key>Name</key><string>Electro Shock Faders</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3663910</integer>
+			<key>Total Time</key><integer>186106</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-18T17:28:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253559076</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:24:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FE1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/07%20Electro%20Shock%20Faders.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>860</key>
+		<dict>
+			<key>Track ID</key><integer>860</integer>
+			<key>Name</key><string>Out of Tune</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Duchene</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3995366</integer>
+			<key>Total Time</key><integer>206958</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-08-10T08:08:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253513510</integer>
+			<key>Play Date UTC</key><date>2007-02-05T17:45:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FE3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/08%20Out%20of%20Tune.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>861</key>
+		<dict>
+			<key>Track ID</key><integer>861</integer>
+			<key>Name</key><string>This Strange Effect</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Davies</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4446166</integer>
+			<key>Total Time</key><integer>235332</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-08-11T17:55:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253180244</integer>
+			<key>Play Date UTC</key><date>2007-02-01T21:10:44Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FE5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/09%20This%20Strange%20Effect.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>862</key>
+		<dict>
+			<key>Track ID</key><integer>862</integer>
+			<key>Name</key><string>Renaissance Affair</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Alex Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3952502</integer>
+			<key>Total Time</key><integer>204264</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-20T10:16:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246022275</integer>
+			<key>Play Date UTC</key><date>2006-11-11T00:51:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FE7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/10%20Renaissance%20Affair.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>863</key>
+		<dict>
+			<key>Track ID</key><integer>863</integer>
+			<key>Name</key><string>Tuna</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Bartsoen &#38; Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4333862</integer>
+			<key>Total Time</key><integer>228297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-19T01:45:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253370604</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:03:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FE9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/11%20Tuna.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>864</key>
+		<dict>
+			<key>Track ID</key><integer>864</integer>
+			<key>Name</key><string>Magenta</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5315798</integer>
+			<key>Total Time</key><integer>290131</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-21T11:49:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3253716175</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:02:55Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FEB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/12%20Magenta.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>865</key>
+		<dict>
+			<key>Track ID</key><integer>865</integer>
+			<key>Name</key><string>Blue Wonder Power Milk</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album Artist</key><string>Hooverphonic</string>
+			<key>Composer</key><string>Callier</string>
+			<key>Album</key><string>Blue Wonder Power Milk</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3718118</integer>
+			<key>Total Time</key><integer>189519</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-07-21T06:11:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252403067</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:17:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B85FED</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/Blue%20Wonder%20Power%20Milk/13%20Blue%20Wonder%20Power%20Milk.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>866</key>
+		<dict>
+			<key>Track ID</key><integer>866</integer>
+			<key>Name</key><string>Autoharp</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6348141</integer>
+			<key>Total Time</key><integer>261972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:25:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253613669</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:34:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FEF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/01%20Autoharp.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>867</key>
+		<dict>
+			<key>Track ID</key><integer>867</integer>
+			<key>Name</key><string>Mad About You</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5421586</integer>
+			<key>Total Time</key><integer>223529</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:26:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>32</integer>
+			<key>Play Date</key><integer>3253681048</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:17:28Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B85FF2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/02%20Mad%20About%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>868</key>
+		<dict>
+			<key>Track ID</key><integer>868</integer>
+			<key>Name</key><string>Waves</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5859543</integer>
+			<key>Total Time</key><integer>241748</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:27:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253257898</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:44:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FF4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/03%20Waves.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>869</key>
+		<dict>
+			<key>Track ID</key><integer>869</integer>
+			<key>Name</key><string>Jacky Cane</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6298807</integer>
+			<key>Total Time</key><integer>260030</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:27:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253345619</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:06:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FF6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/04%20Jacky%20Cane.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>870</key>
+		<dict>
+			<key>Track ID</key><integer>870</integer>
+			<key>Name</key><string>The Magnificent Tree</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5692349</integer>
+			<key>Total Time</key><integer>234921</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:28:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249465366</integer>
+			<key>Play Date UTC</key><date>2006-12-20T21:16:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T20:55:13Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FF8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/05%20The%20Magnificent%20Tree.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>871</key>
+		<dict>
+			<key>Track ID</key><integer>871</integer>
+			<key>Name</key><string>Vinegar And Salt</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4861144</integer>
+			<key>Total Time</key><integer>200212</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:29:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246089601</integer>
+			<key>Play Date UTC</key><date>2006-11-11T19:33:21Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-26T19:38:13Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B85FFA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/06%20Vinegar%20And%20Salt.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>872</key>
+		<dict>
+			<key>Track ID</key><integer>872</integer>
+			<key>Name</key><string>Frosted Flake Wood</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4792255</integer>
+			<key>Total Time</key><integer>197438</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:29:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250708014</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:26:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FFC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/07%20Frosted%20Flake%20Wood.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>873</key>
+		<dict>
+			<key>Track ID</key><integer>873</integer>
+			<key>Name</key><string>Everytime We Live Together We Die A Bit...</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5226884</integer>
+			<key>Total Time</key><integer>215572</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:30:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252118871</integer>
+			<key>Play Date UTC</key><date>2007-01-20T14:21:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B85FFE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/08%20Everytime%20We%20Live%20Together%20We%20Die%20A%20Bit....m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>874</key>
+		<dict>
+			<key>Track ID</key><integer>874</integer>
+			<key>Name</key><string>Out Of Sight</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5713900</integer>
+			<key>Total Time</key><integer>235710</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:31:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252939843</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:24:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B86000</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/09%20Out%20Of%20Sight.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>875</key>
+		<dict>
+			<key>Track ID</key><integer>875</integer>
+			<key>Name</key><string>Pink Fluffy Dinosaurs</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5597335</integer>
+			<key>Total Time</key><integer>230868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:31:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253623249</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:14:09Z</date>
+			<key>Persistent ID</key><string>87139F8602B86002</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/10%20Pink%20Fluffy%20Dinosaurs.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>876</key>
+		<dict>
+			<key>Track ID</key><integer>876</integer>
+			<key>Name</key><string>L'Odeur Animale</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5535579</integer>
+			<key>Total Time</key><integer>271977</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:32:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253295177</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:06:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B86004</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/11%20L'Odeur%20Animale.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>877</key>
+		<dict>
+			<key>Track ID</key><integer>877</integer>
+			<key>Name</key><string>Renaissance Affair</string>
+			<key>Artist</key><string>Hooverphonic</string>
+			<key>Album</key><string>The Magnificent Tree</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4974584</integer>
+			<key>Total Time</key><integer>205310</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T17:33:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>28</integer>
+			<key>Play Date</key><integer>3253709001</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:03:21Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86006</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hooverphonic/The%20Magnificent%20Tree/12%20Renaissance%20Affair.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>878</key>
+		<dict>
+			<key>Track ID</key><integer>878</integer>
+			<key>Name</key><string>Adore</string>
+			<key>Artist</key><string>I: Cube</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6563634</integer>
+			<key>Total Time</key><integer>409835</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252567723</integer>
+			<key>Play Date UTC</key><date>2007-01-25T19:02:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86008</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/I_%20Cube/Late%20Lounge%20(1%20of%202)/13%20Adore.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>879</key>
+		<dict>
+			<key>Track ID</key><integer>879</integer>
+			<key>Name</key><string>No Soul (PMT Remix)</string>
+			<key>Artist</key><string>ILS</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>D. Broadberry/I. Walker</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6210860</integer>
+			<key>Total Time</key><integer>257959</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249206722</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:25:22Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-30T03:06:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B8600B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/ILS/Community%20Service/01%20No%20Soul%20(PMT%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>880</key>
+		<dict>
+			<key>Track ID</key><integer>880</integer>
+			<key>Name</key><string>Prayer Wheel</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5086440</integer>
+			<key>Total Time</key><integer>419422</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253615843</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:10:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8600D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/01%20Prayer%20Wheel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>881</key>
+		<dict>
+			<key>Track ID</key><integer>881</integer>
+			<key>Name</key><string>Temple Gates</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4815436</integer>
+			<key>Total Time</key><integer>397008</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253537125</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:18:45Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:01:33Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86010</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/02%20Temple%20Gates.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>882</key>
+		<dict>
+			<key>Track ID</key><integer>882</integer>
+			<key>Name</key><string>Liquid Sky</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4578286</integer>
+			<key>Total Time</key><integer>377417</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252555415</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:36:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86012</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/03%20Liquid%20Sky.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>883</key>
+		<dict>
+			<key>Track ID</key><integer>883</integer>
+			<key>Name</key><string>Assam</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5105562</integer>
+			<key>Total Time</key><integer>421015</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253545370</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:36:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86014</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/04%20Assam.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>884</key>
+		<dict>
+			<key>Track ID</key><integer>884</integer>
+			<key>Name</key><string>Duskfure</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5588639</integer>
+			<key>Total Time</key><integer>460930</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251308688</integer>
+			<key>Play Date UTC</key><date>2007-01-11T05:18:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86016</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/05%20Duskfure.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>885</key>
+		<dict>
+			<key>Track ID</key><integer>885</integer>
+			<key>Name</key><string>Red Desert</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4015274</integer>
+			<key>Total Time</key><integer>330840</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247820555</integer>
+			<key>Play Date UTC</key><date>2006-12-01T20:22:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86018</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/06%20Red%20Desert.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>886</key>
+		<dict>
+			<key>Track ID</key><integer>886</integer>
+			<key>Name</key><string>Nataraj Express</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4141288</integer>
+			<key>Total Time</key><integer>341342</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253556815</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:46:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8601A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/07%20Nataraj%20Express.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>887</key>
+		<dict>
+			<key>Track ID</key><integer>887</integer>
+			<key>Name</key><string>Temple Gates</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5902589</integer>
+			<key>Total Time</key><integer>486922</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253295983</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:19:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8601C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/08%20Temple%20Gates.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>888</key>
+		<dict>
+			<key>Track ID</key><integer>888</integer>
+			<key>Name</key><string>The Astrologer's Seat</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7931760</integer>
+			<key>Total Time</key><integer>654654</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247553995</integer>
+			<key>Play Date UTC</key><date>2006-11-28T18:19:55Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T18:51:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8601E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/09%20The%20Astrologer's%20Seat.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>889</key>
+		<dict>
+			<key>Track ID</key><integer>889</integer>
+			<key>Name</key><string>Temple Gates</string>
+			<key>Artist</key><string>James Asher</string>
+			<key>Album</key><string>Tigers of the Remix</string>
+			<key>Genre</key><string>New Age</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4024051</integer>
+			<key>Total Time</key><integer>331572</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246515633</integer>
+			<key>Play Date UTC</key><date>2006-11-16T17:53:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86020</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/James%20Asher/Tigers%20of%20the%20Remix/10%20Temple%20Gates.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>890</key>
+		<dict>
+			<key>Track ID</key><integer>890</integer>
+			<key>Name</key><string>It Can't Rain All the Time</string>
+			<key>Artist</key><string>Jane Siberry</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4064008</integer>
+			<key>Total Time</key><integer>335072</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253113231</integer>
+			<key>Play Date UTC</key><date>2007-02-01T02:33:51Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86022</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Jane%20Siberry/The%20Crow/14%20It%20Can't%20Rain%20All%20the%20Time.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>891</key>
+		<dict>
+			<key>Track ID</key><integer>891</integer>
+			<key>Name</key><string>Fly Away</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2813955</integer>
+			<key>Total Time</key><integer>232437</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:25:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Persistent ID</key><string>87139F8602B86025</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/01%20Fly%20Away.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>892</key>
+		<dict>
+			<key>Track ID</key><integer>892</integer>
+			<key>Name</key><string>Dreamin' About the Day</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2887620</integer>
+			<key>Total Time</key><integer>238576</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252546417</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:06:57Z</date>
+			<key>Persistent ID</key><string>87139F8602B86028</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/02%20Dreamin'%20About%20the%20Day.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>893</key>
+		<dict>
+			<key>Track ID</key><integer>893</integer>
+			<key>Name</key><string>His Eyes Are a Blue Million Miles</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2863483</integer>
+			<key>Total Time</key><integer>236564</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Persistent ID</key><string>87139F8602B8602A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/03%20His%20Eyes%20Are%20a%20Blue%20Million%20Miles.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>894</key>
+		<dict>
+			<key>Track ID</key><integer>894</integer>
+			<key>Name</key><string>Fingerprints</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3366622</integer>
+			<key>Total Time</key><integer>278151</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253296347</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:25:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B8602C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/04%20Fingerprints.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>895</key>
+		<dict>
+			<key>Track ID</key><integer>895</integer>
+			<key>Name</key><string>4 Camels</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2775084</integer>
+			<key>Total Time</key><integer>229198</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249530574</integer>
+			<key>Play Date UTC</key><date>2006-12-21T15:22:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B8602E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/05%204%20Camels.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>896</key>
+		<dict>
+			<key>Track ID</key><integer>896</integer>
+			<key>Name</key><string>What You Gonna Do</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3598443</integer>
+			<key>Total Time</key><integer>297299</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253601748</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:15:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B86030</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/06%20What%20You%20Gonna%20Do.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>897</key>
+		<dict>
+			<key>Track ID</key><integer>897</integer>
+			<key>Name</key><string>Match Burn Twice</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2822105</integer>
+			<key>Total Time</key><integer>233116</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Persistent ID</key><string>87139F8602B86032</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/07%20Match%20Burn%20Twice.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>898</key>
+		<dict>
+			<key>Track ID</key><integer>898</integer>
+			<key>Name</key><string>Billie Listens (To Your Heartbeat)</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3387311</integer>
+			<key>Total Time</key><integer>279875</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252580711</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:38:31Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T19:10:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B86034</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/08%20Billie%20Listens%20(To%20Your%20Heartbeat).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>899</key>
+		<dict>
+			<key>Track ID</key><integer>899</integer>
+			<key>Name</key><string>Wild World</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3542332</integer>
+			<key>Total Time</key><integer>292623</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246772656</integer>
+			<key>Play Date UTC</key><date>2006-11-19T17:17:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B86036</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/09%20Wild%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>900</key>
+		<dict>
+			<key>Track ID</key><integer>900</integer>
+			<key>Name</key><string>Son of a Preacher Man</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4374154</integer>
+			<key>Total Time</key><integer>361430</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253076983</integer>
+			<key>Play Date UTC</key><date>2007-01-31T16:29:43Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86038</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/10%20Son%20of%20a%20Preacher%20Man.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>901</key>
+		<dict>
+			<key>Track ID</key><integer>901</integer>
+			<key>Name</key><string>Get up Jack</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Early Recordings</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3167088</integer>
+			<key>Total Time</key><integer>261694</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253548071</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:21:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B8603A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Early%20Recordings/11%20Get%20up%20Jack.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>902</key>
+		<dict>
+			<key>Track ID</key><integer>902</integer>
+			<key>Name</key><string>St. Teresa</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3876240</integer>
+			<key>Total Time</key><integer>321985</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:45Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251730427</integer>
+			<key>Play Date UTC</key><date>2007-01-16T02:27:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8603C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/01%20St.%20Teresa.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>903</key>
+		<dict>
+			<key>Track ID</key><integer>903</integer>
+			<key>Name</key><string>Man in the Long Black Coat</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3500703</integer>
+			<key>Total Time</key><integer>290690</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252290863</integer>
+			<key>Play Date UTC</key><date>2007-01-22T14:07:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8603F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/02%20Man%20in%20the%20Long%20Black%20Coat.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>904</key>
+		<dict>
+			<key>Track ID</key><integer>904</integer>
+			<key>Name</key><string>Right Hand Man</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3621076</integer>
+			<key>Total Time</key><integer>300721</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252942380</integer>
+			<key>Play Date UTC</key><date>2007-01-30T03:06:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86041</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/03%20Right%20Hand%20Man.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>905</key>
+		<dict>
+			<key>Track ID</key><integer>905</integer>
+			<key>Name</key><string>Pensacola</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3274378</integer>
+			<key>Total Time</key><integer>271830</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253607249</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:47:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86043</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/04%20Pensacola.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>906</key>
+		<dict>
+			<key>Track ID</key><integer>906</integer>
+			<key>Name</key><string>Dracula Moon</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4560230</integer>
+			<key>Total Time</key><integer>378984</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246640216</integer>
+			<key>Play Date UTC</key><date>2006-11-18T04:30:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86045</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/05%20Dracula%20Moon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>907</key>
+		<dict>
+			<key>Track ID</key><integer>907</integer>
+			<key>Name</key><string>Ladder</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3048367</integer>
+			<key>Total Time</key><integer>252995</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252533915</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:38:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86047</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/07%20Ladder.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>908</key>
+		<dict>
+			<key>Track ID</key><integer>908</integer>
+			<key>Name</key><string>Spider Web</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4003822</integer>
+			<key>Total Time</key><integer>332617</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253263493</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:18:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86049</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/08%20Spider%20Web.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>909</key>
+		<dict>
+			<key>Track ID</key><integer>909</integer>
+			<key>Name</key><string>Let's Just Get Naked</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3730790</integer>
+			<key>Total Time</key><integer>309864</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249471758</integer>
+			<key>Play Date UTC</key><date>2006-12-20T23:02:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8604B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/09%20Let's%20Just%20Get%20Naked.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>910</key>
+		<dict>
+			<key>Track ID</key><integer>910</integer>
+			<key>Name</key><string>Help Me</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3801947</integer>
+			<key>Total Time</key><integer>315794</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253077299</integer>
+			<key>Play Date UTC</key><date>2007-01-31T16:34:59Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:17:11Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8604D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/10%20Help%20Me.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>911</key>
+		<dict>
+			<key>Track ID</key><integer>911</integer>
+			<key>Name</key><string>Crazy Baby</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4730757</integer>
+			<key>Total Time</key><integer>393195</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253077692</integer>
+			<key>Play Date UTC</key><date>2007-01-31T16:41:32Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8604F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/11%20Crazy%20Baby.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>912</key>
+		<dict>
+			<key>Track ID</key><integer>912</integer>
+			<key>Name</key><string>Lumina</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Relish</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2271590</integer>
+			<key>Total Time</key><integer>188264</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249288991</integer>
+			<key>Play Date UTC</key><date>2006-12-18T20:16:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86051</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Relish/12%20Lumina.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>913</key>
+		<dict>
+			<key>Track ID</key><integer>913</integer>
+			<key>Name</key><string>Running Out of Time</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3437842</integer>
+			<key>Total Time</key><integer>285622</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86053</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/01%20Running%20Out%20of%20Time.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>914</key>
+		<dict>
+			<key>Track ID</key><integer>914</integer>
+			<key>Name</key><string>Righteous Love</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3074218</integer>
+			<key>Total Time</key><integer>255320</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:46Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252412111</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:48:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86056</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/02%20Righteous%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>915</key>
+		<dict>
+			<key>Track ID</key><integer>915</integer>
+			<key>Name</key><string>Safety in Numbers</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3224683</integer>
+			<key>Total Time</key><integer>267859</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253715885</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:58:05Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86058</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/03%20Safety%20in%20Numbers.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>916</key>
+		<dict>
+			<key>Track ID</key><integer>916</integer>
+			<key>Name</key><string>Love Is Alive</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2529408</integer>
+			<key>Total Time</key><integer>209920</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8605A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/04%20Love%20Is%20Alive.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>917</key>
+		<dict>
+			<key>Track ID</key><integer>917</integer>
+			<key>Name</key><string>Angel Face</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2591475</integer>
+			<key>Total Time</key><integer>215092</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252581323</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:48:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8605C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/05%20Angel%20Face.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>918</key>
+		<dict>
+			<key>Track ID</key><integer>918</integer>
+			<key>Name</key><string>Grand Illusion</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2922499</integer>
+			<key>Total Time</key><integer>242677</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249300993</integer>
+			<key>Play Date UTC</key><date>2006-12-18T23:36:33Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:28Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8605E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/06%20Grand%20Illusion.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>919</key>
+		<dict>
+			<key>Track ID</key><integer>919</integer>
+			<key>Name</key><string>If I Was Your Man</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3584232</integer>
+			<key>Total Time</key><integer>297822</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252528289</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:04:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86060</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/07%20If%20I%20Was%20Your%20Man.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>920</key>
+		<dict>
+			<key>Track ID</key><integer>920</integer>
+			<key>Name</key><string>Baby Love</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3093026</integer>
+			<key>Total Time</key><integer>256888</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250571541</integer>
+			<key>Play Date UTC</key><date>2007-01-02T16:32:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86062</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/08%20Baby%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>921</key>
+		<dict>
+			<key>Track ID</key><integer>921</integer>
+			<key>Name</key><string>Hurricane</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3096474</integer>
+			<key>Total Time</key><integer>257175</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86064</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/09%20Hurricane.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>922</key>
+		<dict>
+			<key>Track ID</key><integer>922</integer>
+			<key>Name</key><string>Poison Apples (Hallelujah)</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3130329</integer>
+			<key>Total Time</key><integer>259996</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252524452</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:00:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86066</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/10%20Poison%20Apples%20(Hallelujah).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>923</key>
+		<dict>
+			<key>Track ID</key><integer>923</integer>
+			<key>Name</key><string>Make You Feel My Love</string>
+			<key>Artist</key><string>Joan Osborne</string>
+			<key>Album</key><string>Righteous Love</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2914348</integer>
+			<key>Total Time</key><integer>241998</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253078202</integer>
+			<key>Play Date UTC</key><date>2007-01-31T16:50:02Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86068</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Joan%20Osborne/Righteous%20Love/11%20Make%20You%20Feel%20My%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>924</key>
+		<dict>
+			<key>Track ID</key><integer>924</integer>
+			<key>Name</key><string>Youthful</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>10605973</integer>
+			<key>Total Time</key><integer>630954</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:07:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252570061</integer>
+			<key>Play Date UTC</key><date>2007-01-25T19:41:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8606A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/01%20Youthful.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>925</key>
+		<dict>
+			<key>Track ID</key><integer>925</integer>
+			<key>Name</key><string>Mushroom</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6894869</integer>
+			<key>Total Time</key><integer>403096</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:07:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253517434</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:50:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8606D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/02%20Mushroom.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>926</key>
+		<dict>
+			<key>Track ID</key><integer>926</integer>
+			<key>Name</key><string>Such a Tease</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6071465</integer>
+			<key>Total Time</key><integer>352059</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:08:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249314356</integer>
+			<key>Play Date UTC</key><date>2006-12-19T03:19:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8606F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/03%20Such%20a%20Tease.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>927</key>
+		<dict>
+			<key>Track ID</key><integer>927</integer>
+			<key>Name</key><string>Today</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6797650</integer>
+			<key>Total Time</key><integer>397338</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:08:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253710735</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:32:15Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86071</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/04%20Today.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>928</key>
+		<dict>
+			<key>Track ID</key><integer>928</integer>
+			<key>Name</key><string>Drift Away</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5136551</integer>
+			<key>Total Time</key><integer>294590</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:08:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250706728</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:05:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86073</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/05%20Drift%20Away.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>929</key>
+		<dict>
+			<key>Track ID</key><integer>929</integer>
+			<key>Name</key><string>I've Got a Xerox to Copy</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6104693</integer>
+			<key>Total Time</key><integer>354149</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:09:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253275488</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:38:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86075</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/06%20I've%20Got%20a%20Xerox%20to%20Copy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>930</key>
+		<dict>
+			<key>Track ID</key><integer>930</integer>
+			<key>Name</key><string>Even In This Moment</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2185264</integer>
+			<key>Total Time</key><integer>113033</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:09:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252937305</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:41:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86077</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/07%20Even%20In%20This%20Moment.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>931</key>
+		<dict>
+			<key>Track ID</key><integer>931</integer>
+			<key>Name</key><string>Yesterdays</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4156135</integer>
+			<key>Total Time</key><integer>234218</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:09:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250619664</integer>
+			<key>Play Date UTC</key><date>2007-01-03T05:54:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86079</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/08%20Yesterdays.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>932</key>
+		<dict>
+			<key>Track ID</key><integer>932</integer>
+			<key>Name</key><string>Honey</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4116098</integer>
+			<key>Total Time</key><integer>231826</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:09:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253680593</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:09:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-23T04:58:57Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8607B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/09%20Honey.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>933</key>
+		<dict>
+			<key>Track ID</key><integer>933</integer>
+			<key>Name</key><string>We Become One</string>
+			<key>Artist</key><string>Junkie XL</string>
+			<key>Album Artist</key><string>Junkie XL</string>
+			<key>Album</key><string>Today</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4972250</integer>
+			<key>Total Time</key><integer>286370</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-09-05T04:10:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253514931</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:08:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8607D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Junkie%20XL/Today/10%20We%20Become%20One.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>934</key>
+		<dict>
+			<key>Track ID</key><integer>934</integer>
+			<key>Name</key><string>Jardin De Cecile</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6863075</integer>
+			<key>Total Time</key><integer>423460</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:21:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253594097</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:08:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B8607F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/01%20Jardin%20De%20Cecile.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>935</key>
+		<dict>
+			<key>Track ID</key><integer>935</integer>
+			<key>Name</key><string>Conga Fury</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7891435</integer>
+			<key>Total Time</key><integer>486944</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:21:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3251479217</integer>
+			<key>Play Date UTC</key><date>2007-01-13T04:40:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B86082</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/02%20Conga%20Fury.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>936</key>
+		<dict>
+			<key>Track ID</key><integer>936</integer>
+			<key>Name</key><string>God Is God</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6596704</integer>
+			<key>Total Time</key><integer>406974</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:22:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253620084</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:21:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86084</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/03%20God%20Is%20God.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>937</key>
+		<dict>
+			<key>Track ID</key><integer>937</integer>
+			<key>Name</key><string>Komit</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7986618</integer>
+			<key>Total Time</key><integer>492818</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:23:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3252466667</integer>
+			<key>Play Date UTC</key><date>2007-01-24T14:57:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B86086</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/04%20Komit.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>938</key>
+		<dict>
+			<key>Track ID</key><integer>938</integer>
+			<key>Name</key><string>Swamp Thing</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5065037</integer>
+			<key>Total Time</key><integer>312469</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:23:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252386156</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:35:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B86088</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/05%20Swamp%20Thing.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>939</key>
+		<dict>
+			<key>Track ID</key><integer>939</integer>
+			<key>Name</key><string>Kaguya Hime</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6513949</integer>
+			<key>Total Time</key><integer>401843</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:24:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253508071</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:14:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B8608A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/06%20Kaguya%20Hime.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>940</key>
+		<dict>
+			<key>Track ID</key><integer>940</integer>
+			<key>Name</key><string>Children Of The Night</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7738117</integer>
+			<key>Total Time</key><integer>477470</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:25:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253360767</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:19:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B8608C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/07%20Children%20Of%20The%20Night.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>941</key>
+		<dict>
+			<key>Track ID</key><integer>941</integer>
+			<key>Name</key><string>Shark</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9326906</integer>
+			<key>Total Time</key><integer>577478</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:25:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249495458</integer>
+			<key>Play Date UTC</key><date>2006-12-21T05:37:38Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B8608E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/08%20Shark.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>942</key>
+		<dict>
+			<key>Track ID</key><integer>942</integer>
+			<key>Name</key><string>High Energy Protons (Orion Mix)</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Composer</key><string>Juno Reactor</string>
+			<key>Album</key><string>Bible Of Dreams</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6295532</integer>
+			<key>Total Time</key><integer>388677</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2006-07-08T19:26:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252501147</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:32:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B86090</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Bible%20Of%20Dreams/09%20High%20Energy%20Protons%20(Orion%20Mix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>943</key>
+		<dict>
+			<key>Track ID</key><integer>943</integer>
+			<key>Name</key><string>Conquistador I</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6085586</integer>
+			<key>Total Time</key><integer>362972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:16:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253514040</integer>
+			<key>Play Date UTC</key><date>2007-02-05T17:54:00Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86092</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/01%20Conquistador%20I.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>944</key>
+		<dict>
+			<key>Track ID</key><integer>944</integer>
+			<key>Name</key><string>Conquistador II</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5177811</integer>
+			<key>Total Time</key><integer>305991</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-09T20:53:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86095</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/02%20Conquistador%20II.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>945</key>
+		<dict>
+			<key>Track ID</key><integer>945</integer>
+			<key>Name</key><string>Giant</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4135049</integer>
+			<key>Total Time</key><integer>240557</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253364703</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:25:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86097</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/03%20Giant.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>946</key>
+		<dict>
+			<key>Track ID</key><integer>946</integer>
+			<key>Name</key><string>Wardogs</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5086347</integer>
+			<key>Total Time</key><integer>300255</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251301977</integer>
+			<key>Play Date UTC</key><date>2007-01-11T03:26:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86099</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/04%20Wardogs.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>947</key>
+		<dict>
+			<key>Track ID</key><integer>947</integer>
+			<key>Name</key><string>Mona Lisa Overdrive</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4849671</integer>
+			<key>Total Time</key><integer>285395</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>31</integer>
+			<key>Play Date</key><integer>3253677033</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:10:33Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-13T21:44:43Z</date>
+			<key>Rating</key><integer>100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8609B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/05%20Mona%20Lisa%20Overdrive.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>948</key>
+		<dict>
+			<key>Track ID</key><integer>948</integer>
+			<key>Name</key><string>Zwara</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6596009</integer>
+			<key>Total Time</key><integer>394993</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253449059</integer>
+			<key>Play Date UTC</key><date>2007-02-04T23:50:59Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8609D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/06%20Zwara.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>949</key>
+		<dict>
+			<key>Track ID</key><integer>949</integer>
+			<key>Name</key><string>Mutant Message</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6205298</integer>
+			<key>Total Time</key><integer>370496</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:17:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253342866</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:21:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8609F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/07%20Mutant%20Message.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>950</key>
+		<dict>
+			<key>Track ID</key><integer>950</integer>
+			<key>Name</key><string>Angels and Men</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7115330</integer>
+			<key>Total Time</key><integer>427594</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:18:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251890484</integer>
+			<key>Play Date UTC</key><date>2007-01-17T22:54:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860A1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/08%20Angels%20and%20Men.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>951</key>
+		<dict>
+			<key>Track ID</key><integer>951</integer>
+			<key>Name</key><string>Navras</string>
+			<key>Artist</key><string>Juno Reactor</string>
+			<key>Album Artist</key><string>Juno Reactor</string>
+			<key>Album</key><string>Labyrinth</string>
+			<key>Genre</key><string>Dance</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9003354</integer>
+			<key>Total Time</key><integer>546085</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-02-25T17:18:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252577464</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:44:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860A3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Juno%20Reactor/Labyrinth/09%20Navras.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>952</key>
+		<dict>
+			<key>Track ID</key><integer>952</integer>
+			<key>Name</key><string>Not Just Anybody [At Jazz Remix]</string>
+			<key>Artist</key><string>Kate Rogers / Rae &#38; Christian</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5857701</integer>
+			<key>Total Time</key><integer>365714</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252543043</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:10:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860A5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Kate%20Rogers%20_%20Rae%20&#38;%20Christian/Late%20Lounge%20(1%20of%202)/05%20Not%20Just%20Anybody%20%5BAt%20Jazz%20Remix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>953</key>
+		<dict>
+			<key>Track ID</key><integer>953</integer>
+			<key>Name</key><string>Kalifornia</string>
+			<key>Artist</key><string>Kevin Beber &#38; The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>CSII Exclusives - EP</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5877997</integer>
+			<key>Total Time</key><integer>339404</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-10-12T22:55:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3252553767</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:09:27Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-20T22:19:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Kevin%20Beber%20&#38;%20The%20Crystal%20Method/CSII%20Exclusives%20-%20EP/03%20Kalifornia.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>954</key>
+		<dict>
+			<key>Track ID</key><integer>954</integer>
+			<key>Name</key><string>Skyscraper</string>
+			<key>Artist</key><string>Kinobe</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4902246</integer>
+			<key>Total Time</key><integer>305998</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249538130</integer>
+			<key>Play Date UTC</key><date>2006-12-21T17:28:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860AB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Kinobe/Late%20Lounge%20(1%20of%202)/08%20Skyscraper.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>955</key>
+		<dict>
+			<key>Track ID</key><integer>955</integer>
+			<key>Name</key><string>Morpheus (Meat Katie &#38; Dylan Rhymes Mix)</string>
+			<key>Artist</key><string>Koma &#38; Bones</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Andy Duckmanton/Chris Kirkbride/Sebastian Jude 'Proteus"</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5345058</integer>
+			<key>Total Time</key><integer>221884</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253266119</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:01:59Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T03:00:12Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B860AE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Koma%20&#38;%20Bones/Community%20Service/04%20Morpheus%20(Meat%20Katie%20&#38;%20Dylan%20Rhymes%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>956</key>
+		<dict>
+			<key>Track ID</key><integer>956</integer>
+			<key>Name</key><string>Darkness</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5325426</integer>
+			<key>Total Time</key><integer>300325</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-26T19:38:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252496627</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:17:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860B0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/01%20Darkness.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>957</key>
+		<dict>
+			<key>Track ID</key><integer>957</integer>
+			<key>Name</key><string>Stronger</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3629474</integer>
+			<key>Total Time</key><integer>195510</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-27T07:15:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253681244</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:20:44Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860B3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/02%20Stronger.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>958</key>
+		<dict>
+			<key>Track ID</key><integer>958</integer>
+			<key>Name</key><string>Sugar 5</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4295602</integer>
+			<key>Total Time</key><integer>236679</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-23T16:53:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253592568</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:42:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860B5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/03%20Sugar%205.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>959</key>
+		<dict>
+			<key>Track ID</key><integer>959</integer>
+			<key>Name</key><string>Angelica</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4039090</integer>
+			<key>Total Time</key><integer>220797</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-10T20:43:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247113974</integer>
+			<key>Play Date UTC</key><date>2006-11-23T16:06:14Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860B7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/04%20Angelica.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>960</key>
+		<dict>
+			<key>Track ID</key><integer>960</integer>
+			<key>Name</key><string>Till the Clouds Clear</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4866706</integer>
+			<key>Total Time</key><integer>271973</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-30T15:12:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253079583</integer>
+			<key>Play Date UTC</key><date>2007-01-31T17:13:03Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860B9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/05%20Till%20the%20Clouds%20Clear.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>961</key>
+		<dict>
+			<key>Track ID</key><integer>961</integer>
+			<key>Name</key><string>Wonder</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5657186</integer>
+			<key>Total Time</key><integer>320828</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-28T19:14:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:47Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253510648</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:57:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860BB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/06%20Wonder.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>962</key>
+		<dict>
+			<key>Track ID</key><integer>962</integer>
+			<key>Name</key><string>Sun</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3420194</integer>
+			<key>Total Time</key><integer>182577</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-28T17:18:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253341066</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:51:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860BD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/07%20Sun.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>963</key>
+		<dict>
+			<key>Track ID</key><integer>963</integer>
+			<key>Name</key><string>Learn</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2622194</integer>
+			<key>Total Time</key><integer>133257</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-27T00:47:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252939607</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:20:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860BF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/08%20Learn.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>964</key>
+		<dict>
+			<key>Track ID</key><integer>964</integer>
+			<key>Name</key><string>Please</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4897490</integer>
+			<key>Total Time</key><integer>273877</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-19T03:10:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252116651</integer>
+			<key>Play Date UTC</key><date>2007-01-20T13:44:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860C1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/09%20Please.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>965</key>
+		<dict>
+			<key>Track ID</key><integer>965</integer>
+			<key>Name</key><string>Open Up</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5178146</integer>
+			<key>Total Time</key><integer>291223</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-29T19:36:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253348027</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:47:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860C3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/10%20Open%20Up.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>966</key>
+		<dict>
+			<key>Track ID</key><integer>966</integer>
+			<key>Name</key><string>Hearts and Flowers</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Between Darkness and Wonder</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5694002</integer>
+			<key>Total Time</key><integer>323104</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T14:38:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252553100</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:58:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Between%20Darkness%20and%20Wonder/11%20Hearts%20and%20Flowers.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>967</key>
+		<dict>
+			<key>Track ID</key><integer>967</integer>
+			<key>Name</key><string>Gabriel (Radio Edit)</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Original Television Soundtrack</string>
+			<key>Composer</key><string>A. Barlow/L. Rhodes</string>
+			<key>Album</key><string>CSI: Miami</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5881312</integer>
+			<key>Total Time</key><integer>252917</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>185</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253113484</integer>
+			<key>Play Date UTC</key><date>2007-02-01T02:38:04Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B860C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/CSI_%20Miami/03%20Gabriel%20(Radio%20Edit).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>968</key>
+		<dict>
+			<key>Track ID</key><integer>968</integer>
+			<key>Name</key><string>Soft Mistake</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6296649</integer>
+			<key>Total Time</key><integer>196284</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253259472</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:11:12Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860CA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/01%20Soft%20Mistake.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>969</key>
+		<dict>
+			<key>Track ID</key><integer>969</integer>
+			<key>Name</key><string>Little Things</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6380984</integer>
+			<key>Total Time</key><integer>198896</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253526209</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:16:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/02%20Little%20Things.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>970</key>
+		<dict>
+			<key>Track ID</key><integer>970</integer>
+			<key>Name</key><string>B Line</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5348093</integer>
+			<key>Total Time</key><integer>166635</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253516255</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:30:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/03%20B%20Line.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>971</key>
+		<dict>
+			<key>Track ID</key><integer>971</integer>
+			<key>Name</key><string>(untitled hidden track)</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>237905</integer>
+			<key>Total Time</key><integer>6948</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250575787</integer>
+			<key>Play Date UTC</key><date>2007-01-02T17:43:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/04%20(untitled%20hidden%20track).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>972</key>
+		<dict>
+			<key>Track ID</key><integer>972</integer>
+			<key>Name</key><string>All In Your Hands</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8938604</integer>
+			<key>Total Time</key><integer>278831</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:51:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250621978</integer>
+			<key>Play Date UTC</key><date>2007-01-03T06:32:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/05%20All%20In%20Your%20Hands.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>973</key>
+		<dict>
+			<key>Track ID</key><integer>973</integer>
+			<key>Name</key><string>Less Than Two</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2582583</integer>
+			<key>Total Time</key><integer>80195</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:51:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252529974</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:32:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/06%20Less%20Than%20Two.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>974</key>
+		<dict>
+			<key>Track ID</key><integer>974</integer>
+			<key>Name</key><string>Bonfire</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8434257</integer>
+			<key>Total Time</key><integer>263079</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:51:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253682380</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:39:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-18T23:17:38Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/07%20Bonfire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>975</key>
+		<dict>
+			<key>Track ID</key><integer>975</integer>
+			<key>Name</key><string>Ear Parcel</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear Of Fours</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7604361</integer>
+			<key>Total Time</key><integer>474279</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860D9</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20Of%20Fours/08%20Ear%20Parcel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>976</key>
+		<dict>
+			<key>Track ID</key><integer>976</integer>
+			<key>Name</key><string>Softly</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4381500</integer>
+			<key>Total Time</key><integer>237051</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-18T22:51:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251353507</integer>
+			<key>Play Date UTC</key><date>2007-01-11T17:45:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860DB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/09%20Softly.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>977</key>
+		<dict>
+			<key>Track ID</key><integer>977</integer>
+			<key>Name</key><string>Here</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3838220</integer>
+			<key>Total Time</key><integer>203475</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-15T19:08:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250701711</integer>
+			<key>Play Date UTC</key><date>2007-01-04T04:41:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860DD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/10%20Here.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>978</key>
+		<dict>
+			<key>Track ID</key><integer>978</integer>
+			<key>Name</key><string>Fly</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5619452</integer>
+			<key>Total Time</key><integer>313560</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-17T18:54:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250740325</integer>
+			<key>Play Date UTC</key><date>2007-01-04T15:25:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860DF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/11%20Fly.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>979</key>
+		<dict>
+			<key>Track ID</key><integer>979</integer>
+			<key>Name</key><string>Alien</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4539020</integer>
+			<key>Total Time</key><integer>246733</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-08-15T17:00:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253428713</integer>
+			<key>Play Date UTC</key><date>2007-02-04T18:11:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T21:21:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860E1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/12%20Alien.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>980</key>
+		<dict>
+			<key>Track ID</key><integer>980</integer>
+			<key>Name</key><string>Five</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6192044</integer>
+			<key>Total Time</key><integer>348948</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-21T12:44:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246877775</integer>
+			<key>Play Date UTC</key><date>2006-11-20T22:29:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860E3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/13%20Five.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>981</key>
+		<dict>
+			<key>Track ID</key><integer>981</integer>
+			<key>Name</key><string>Lullaby</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album Artist</key><string>Lamb</string>
+			<key>Album</key><string>Fear of Fours</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3444476</integer>
+			<key>Total Time</key><integer>179140</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-07-27T10:14:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249321496</integer>
+			<key>Play Date UTC</key><date>2006-12-19T05:18:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860E5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/Fear%20of%20Fours/14%20Lullaby.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>982</key>
+		<dict>
+			<key>Track ID</key><integer>982</integer>
+			<key>Name</key><string>What Sound</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5403756</integer>
+			<key>Total Time</key><integer>224940</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253266961</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:16:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860E7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/01%20What%20Sound.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>983</key>
+		<dict>
+			<key>Track ID</key><integer>983</integer>
+			<key>Name</key><string>This Could Be</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7329715</integer>
+			<key>Total Time</key><integer>305188</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253685377</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:29:37Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860EA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/02%20This%20Could%20Be.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>984</key>
+		<dict>
+			<key>Track ID</key><integer>984</integer>
+			<key>Name</key><string>Gabriel</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6315322</integer>
+			<key>Total Time</key><integer>262922</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253458386</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:26:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860EC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/03%20Gabriel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>985</key>
+		<dict>
+			<key>Track ID</key><integer>985</integer>
+			<key>Name</key><string>Written</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5331655</integer>
+			<key>Total Time</key><integer>221936</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253532978</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:09:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/04%20Written.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>986</key>
+		<dict>
+			<key>Track ID</key><integer>986</integer>
+			<key>Name</key><string>Sweet</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5728506</integer>
+			<key>Total Time</key><integer>238471</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253454820</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:27:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/05%20Sweet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>987</key>
+		<dict>
+			<key>Track ID</key><integer>987</integer>
+			<key>Name</key><string>One</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6207485</integer>
+			<key>Total Time</key><integer>258429</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252394741</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:59:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860F2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/06%20One.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>988</key>
+		<dict>
+			<key>Track ID</key><integer>988</integer>
+			<key>Name</key><string>Random</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5981163</integer>
+			<key>Total Time</key><integer>248999</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247037717</integer>
+			<key>Play Date UTC</key><date>2006-11-22T18:55:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860F4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/07%20Random.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>989</key>
+		<dict>
+			<key>Track ID</key><integer>989</integer>
+			<key>Name</key><string>Just Is</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6087115</integer>
+			<key>Total Time</key><integer>253413</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252523726</integer>
+			<key>Play Date UTC</key><date>2007-01-25T06:48:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B860F6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/08%20Just%20Is.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>990</key>
+		<dict>
+			<key>Track ID</key><integer>990</integer>
+			<key>Name</key><string>Scratch Bass</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6993340</integer>
+			<key>Total Time</key><integer>290977</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251861578</integer>
+			<key>Play Date UTC</key><date>2007-01-17T14:52:58Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B860F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/09%20Scratch%20Bass.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>991</key>
+		<dict>
+			<key>Track ID</key><integer>991</integer>
+			<key>Name</key><string>Sweetheart</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6059202</integer>
+			<key>Total Time</key><integer>252055</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252570313</integer>
+			<key>Play Date UTC</key><date>2007-01-25T19:45:13Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B860FA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/10%20Sweetheart.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>992</key>
+		<dict>
+			<key>Track ID</key><integer>992</integer>
+			<key>Name</key><string>Small</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7743154</integer>
+			<key>Total Time</key><integer>322220</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252407181</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:26:21Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B860FC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/11%20Small.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>993</key>
+		<dict>
+			<key>Track ID</key><integer>993</integer>
+			<key>Name</key><string>I Cry</string>
+			<key>Artist</key><string>Lamb</string>
+			<key>Album</key><string>What Sound</string>
+			<key>Genre</key><string>Downtempo</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7777009</integer>
+			<key>Total Time</key><integer>323631</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246379338</integer>
+			<key>Play Date UTC</key><date>2006-11-15T04:02:18Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B860FE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lamb/What%20Sound/12%20I%20Cry.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>994</key>
+		<dict>
+			<key>Track ID</key><integer>994</integer>
+			<key>Name</key><string>Up With People [Zero 7 Remix]</string>
+			<key>Artist</key><string>Lambchop</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5288858</integer>
+			<key>Total Time</key><integer>330161</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253525513</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:05:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86100</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lambchop/Late%20Lounge%20(1%20of%202)/01%20Up%20With%20People%20%5BZero%207%20Remix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>995</key>
+		<dict>
+			<key>Track ID</key><integer>995</integer>
+			<key>Name</key><string>Release the Pressure</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>E. Daley, N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7869320</integer>
+			<key>Total Time</key><integer>461379</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:07:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253772836</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:47:16Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86103</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/01%20Release%20the%20Pressure.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>996</key>
+		<dict>
+			<key>Track ID</key><integer>996</integer>
+			<key>Name</key><string>Afro-Left</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes, N. Cole &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7743128</integer>
+			<key>Total Time</key><integer>453437</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:07:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253505623</integer>
+			<key>Play Date UTC</key><date>2007-02-05T15:33:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86106</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/02%20Afro-Left.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>997</key>
+		<dict>
+			<key>Track ID</key><integer>997</integer>
+			<key>Name</key><string>Melt</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5526935</integer>
+			<key>Total Time</key><integer>313839</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:07:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253528030</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:47:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86108</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/03%20Melt.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>998</key>
+		<dict>
+			<key>Track ID</key><integer>998</integer>
+			<key>Name</key><string>Song of Life</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes, P. Daley &#38; Y. Rupkina</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7238072</integer>
+			<key>Total Time</key><integer>421626</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:08:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3251639811</integer>
+			<key>Play Date UTC</key><date>2007-01-15T01:16:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8610A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/04%20Song%20of%20Life.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>999</key>
+		<dict>
+			<key>Track ID</key><integer>999</integer>
+			<key>Name</key><string>Original</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes, P. Daley &#38; T. Halliday</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6619304</integer>
+			<key>Total Time</key><integer>382663</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:08:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253521728</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:02:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8610C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/05%20Original.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1000</key>
+		<dict>
+			<key>Track ID</key><integer>1000</integer>
+			<key>Name</key><string>Black Flute</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4135751</integer>
+			<key>Total Time</key><integer>226230</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:08:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252543751</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:22:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8610E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/06%20Black%20Flute.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1001</key>
+		<dict>
+			<key>Track ID</key><integer>1001</integer>
+			<key>Name</key><string>Space Shanty</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7436071</integer>
+			<key>Total Time</key><integer>434095</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:08:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253553473</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:51:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86110</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/07%20Space%20Shanty.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1002</key>
+		<dict>
+			<key>Track ID</key><integer>1002</integer>
+			<key>Name</key><string>Inspection (Check One)</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>D. Clarke, N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6750968</integer>
+			<key>Total Time</key><integer>390929</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:09:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252417405</integer>
+			<key>Play Date UTC</key><date>2007-01-24T01:16:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86112</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/08%20Inspection%20(Check%20One).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1003</key>
+		<dict>
+			<key>Track ID</key><integer>1003</integer>
+			<key>Name</key><string>Storm 3000</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6002407</integer>
+			<key>Total Time</key><integer>343793</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:09:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252504186</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:23:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86114</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/09%20Storm%203000.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1004</key>
+		<dict>
+			<key>Track ID</key><integer>1004</integer>
+			<key>Name</key><string>Open Up</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>J. Lydon, N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7088472</integer>
+			<key>Total Time</key><integer>412199</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:09:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253461677</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:21:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86116</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/10%20Open%20Up.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1005</key>
+		<dict>
+			<key>Track ID</key><integer>1005</integer>
+			<key>Name</key><string>21st Century Poem</string>
+			<key>Artist</key><string>Leftfield</string>
+			<key>Album Artist</key><string>Leftfield</string>
+			<key>Composer</key><string>N. Barnes &#38; P. Daley</string>
+			<key>Album</key><string>Leftism</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6003271</integer>
+			<key>Total Time</key><integer>343862</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2006-02-25T17:09:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250613557</integer>
+			<key>Play Date UTC</key><date>2007-01-03T04:12:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86118</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Leftfield/Leftism/11%2021st%20Century%20Poem.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1006</key>
+		<dict>
+			<key>Track ID</key><integer>1006</integer>
+			<key>Name</key><string>Live</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz &#38; Craig Ross</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>41485037</integer>
+			<key>Total Time</key><integer>310466</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-10-05T14:40:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>1068</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252523472</integer>
+			<key>Play Date UTC</key><date>2007-01-25T06:44:32Z</date>
+			<key>Persistent ID</key><string>87139F8602B8611A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/01%20Live.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1007</key>
+		<dict>
+			<key>Track ID</key><integer>1007</integer>
+			<key>Name</key><string>Supersoulfighter</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>35639294</integer>
+			<key>Total Time</key><integer>298733</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-26T12:16:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>953</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253458123</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:22:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B8611D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/02%20Supersoulfighter.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1008</key>
+		<dict>
+			<key>Track ID</key><integer>1008</integer>
+			<key>Name</key><string>I Belong To You</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29428495</integer>
+			<key>Total Time</key><integer>257693</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-22T05:01:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>912</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252548784</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:46:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B8611F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/03%20I%20Belong%20To%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1009</key>
+		<dict>
+			<key>Track ID</key><integer>1009</integer>
+			<key>Name</key><string>Black Velveteen</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34936318</integer>
+			<key>Total Time</key><integer>288733</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-10-02T17:57:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>967</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252492259</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:04:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B86121</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/04%20Black%20Velveteen.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1010</key>
+		<dict>
+			<key>Track ID</key><integer>1010</integer>
+			<key>Name</key><string>If You Can't Say No</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34689770</integer>
+			<key>Total Time</key><integer>317040</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-10-18T20:04:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>874</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247638977</integer>
+			<key>Play Date UTC</key><date>2006-11-29T17:56:17Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T19:04:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B86123</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/05%20If%20You%20Can't%20Say%20No.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1011</key>
+		<dict>
+			<key>Track ID</key><integer>1011</integer>
+			<key>Name</key><string>Thinking Of You</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz/Lysa Trenier</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>45316261</integer>
+			<key>Total Time</key><integer>384160</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-28T17:10:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>943</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252575528</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:12:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B86125</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/06%20Thinking%20Of%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1012</key>
+		<dict>
+			<key>Track ID</key><integer>1012</integer>
+			<key>Name</key><string>Take Time</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29904505</integer>
+			<key>Total Time</key><integer>271866</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-10-01T13:21:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:48Z</date>
+			<key>Bit Rate</key><integer>879</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250579115</integer>
+			<key>Play Date UTC</key><date>2007-01-02T18:38:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B86127</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/07%20Take%20Time.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1013</key>
+		<dict>
+			<key>Track ID</key><integer>1013</integer>
+			<key>Name</key><string>Fly Away</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26903600</integer>
+			<key>Total Time</key><integer>221373</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-26T23:52:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>971</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246382027</integer>
+			<key>Play Date UTC</key><date>2006-11-15T04:47:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B86129</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/08%20Fly%20Away.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1014</key>
+		<dict>
+			<key>Track ID</key><integer>1014</integer>
+			<key>Name</key><string>It's Your Life</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>36575064</integer>
+			<key>Total Time</key><integer>302733</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-28T23:53:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>965</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252501846</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:44:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-23T03:56:09Z</date>
+			<key>Persistent ID</key><string>87139F8602B8612B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/09%20It's%20Your%20Life.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1015</key>
+		<dict>
+			<key>Track ID</key><integer>1015</integer>
+			<key>Name</key><string>Straight Cold Player</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29535319</integer>
+			<key>Total Time</key><integer>259666</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-29T16:23:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>909</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252568700</integer>
+			<key>Play Date UTC</key><date>2007-01-25T19:18:20Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T19:45:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B8612D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/10%20Straight%20Cold%20Player.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1016</key>
+		<dict>
+			<key>Track ID</key><integer>1016</integer>
+			<key>Name</key><string>Little Girl's Eyes</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>51190893</integer>
+			<key>Total Time</key><integer>464760</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-10-11T18:13:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>880</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247242736</integer>
+			<key>Play Date UTC</key><date>2006-11-25T03:52:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B8612F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/11%20Little%20Girl's%20Eyes.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1017</key>
+		<dict>
+			<key>Track ID</key><integer>1017</integer>
+			<key>Name</key><string>You're My Flavor</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>5</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26572989</integer>
+			<key>Total Time</key><integer>228506</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2005-09-28T23:55:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>929</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252530865</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:47:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B86131</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/5/12%20You're%20My%20Flavor.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1018</key>
+		<dict>
+			<key>Track ID</key><integer>1018</integer>
+			<key>Name</key><string>Are You Gonna Go My Way</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5164397</integer>
+			<key>Total Time</key><integer>211902</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253519511</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:25:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86133</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/01%20Are%20You%20Gonna%20Go%20My%20Way.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1019</key>
+		<dict>
+			<key>Track ID</key><integer>1019</integer>
+			<key>Name</key><string>Believe</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7162144</integer>
+			<key>Total Time</key><integer>294654</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253519294</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:21:34Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T18:30:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86136</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/02%20Believe.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1020</key>
+		<dict>
+			<key>Track ID</key><integer>1020</integer>
+			<key>Name</key><string>Come On And Love Me</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5695736</integer>
+			<key>Total Time</key><integer>234004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247492678</integer>
+			<key>Play Date UTC</key><date>2006-11-28T01:17:58Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T21:52:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86138</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/03%20Come%20On%20And%20Love%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1021</key>
+		<dict>
+			<key>Track ID</key><integer>1021</integer>
+			<key>Name</key><string>Heaven Help</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4666957</integer>
+			<key>Total Time</key><integer>191166</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253456359</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:52:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8613A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/04%20Heaven%20Help.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1022</key>
+		<dict>
+			<key>Track ID</key><integer>1022</integer>
+			<key>Name</key><string>Just Be A Woman</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5560483</integer>
+			<key>Total Time</key><integer>228393</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252566821</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:47:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8613C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/05%20Just%20Be%20A%20Woman.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1023</key>
+		<dict>
+			<key>Track ID</key><integer>1023</integer>
+			<key>Name</key><string>Is There Any Love In Your Heart</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5378768</integer>
+			<key>Total Time</key><integer>220798</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251466264</integer>
+			<key>Play Date UTC</key><date>2007-01-13T01:04:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8613E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/06%20Is%20There%20Any%20Love%20In%20Your%20Heart.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1024</key>
+		<dict>
+			<key>Track ID</key><integer>1024</integer>
+			<key>Name</key><string>Black Girl</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5477871</integer>
+			<key>Total Time</key><integer>224937</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252550467</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:14:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86140</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/07%20Black%20Girl.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1025</key>
+		<dict>
+			<key>Track ID</key><integer>1025</integer>
+			<key>Name</key><string>My Love</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5675353</integer>
+			<key>Total Time</key><integer>233150</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250596196</integer>
+			<key>Play Date UTC</key><date>2007-01-02T23:23:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86142</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/08%20My%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1026</key>
+		<dict>
+			<key>Track ID</key><integer>1026</integer>
+			<key>Name</key><string>Sugar</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5795729</integer>
+			<key>Total Time</key><integer>238185</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253080851</integer>
+			<key>Play Date UTC</key><date>2007-01-31T17:34:11Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86144</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/09%20Sugar.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1027</key>
+		<dict>
+			<key>Track ID</key><integer>1027</integer>
+			<key>Name</key><string>Sister</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10315633</integer>
+			<key>Total Time</key><integer>424894</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253555732</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:28:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86146</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/10%20Sister.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1028</key>
+		<dict>
+			<key>Track ID</key><integer>1028</integer>
+			<key>Name</key><string>Eleutheria</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Composer</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Are You Gonna Go My Way</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7074565</integer>
+			<key>Total Time</key><integer>291433</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1993</integer>
+			<key>Date Modified</key><date>2004-07-25T23:56:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252504478</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:27:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86148</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Are%20You%20Gonna%20Go%20My%20Way/11%20Eleutheria.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1029</key>
+		<dict>
+			<key>Track ID</key><integer>1029</integer>
+			<key>Name</key><string>Sittin' on Top of the World</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2377145</integer>
+			<key>Total Time</key><integer>195866</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253545566</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:39:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8614A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/01%20Sittin'%20on%20Top%20of%20the%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1030</key>
+		<dict>
+			<key>Track ID</key><integer>1030</integer>
+			<key>Name</key><string>Let Love Rule</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4148164</integer>
+			<key>Total Time</key><integer>342256</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253281814</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:23:34Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T19:09:33Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8614D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/02%20Let%20Love%20Rule.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1031</key>
+		<dict>
+			<key>Track ID</key><integer>1031</integer>
+			<key>Name</key><string>Freedom Train</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2074480</integer>
+			<key>Total Time</key><integer>170814</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252416287</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:58:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8614F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/03%20Freedom%20Train.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1032</key>
+		<dict>
+			<key>Track ID</key><integer>1032</integer>
+			<key>Name</key><string>My Precious Love</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3829825</integer>
+			<key>Total Time</key><integer>315898</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253451347</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:29:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:43:39Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86151</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/04%20My%20Precious%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1033</key>
+		<dict>
+			<key>Track ID</key><integer>1033</integer>
+			<key>Name</key><string>I Build This Garden for Us</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4571995</integer>
+			<key>Total Time</key><integer>377234</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253289181</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:26:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86153</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/05%20I%20Build%20This%20Garden%20for%20Us.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1034</key>
+		<dict>
+			<key>Track ID</key><integer>1034</integer>
+			<key>Name</key><string>Fear</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3884996</integer>
+			<key>Total Time</key><integer>320496</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86155</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/06%20Fear.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1035</key>
+		<dict>
+			<key>Track ID</key><integer>1035</integer>
+			<key>Name</key><string>Does Anybody Out There Even Care</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2701127</integer>
+			<key>Total Time</key><integer>222693</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252494813</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:46:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86157</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/07%20Does%20Anybody%20Out%20There%20Even%20Care.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1036</key>
+		<dict>
+			<key>Track ID</key><integer>1036</integer>
+			<key>Name</key><string>Mr. Cab Driver</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2801604</integer>
+			<key>Total Time</key><integer>230896</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246374489</integer>
+			<key>Play Date UTC</key><date>2006-11-15T02:41:29Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T00:12:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86159</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/08%20Mr.%20Cab%20Driver.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1037</key>
+		<dict>
+			<key>Track ID</key><integer>1037</integer>
+			<key>Name</key><string>Rosemary</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3982339</integer>
+			<key>Total Time</key><integer>328437</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250692796</integer>
+			<key>Play Date UTC</key><date>2007-01-04T02:13:16Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T17:19:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8615B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/09%20Rosemary.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1038</key>
+		<dict>
+			<key>Track ID</key><integer>1038</integer>
+			<key>Name</key><string>Be</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2417583</integer>
+			<key>Total Time</key><integer>199235</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251641075</integer>
+			<key>Play Date UTC</key><date>2007-01-15T01:37:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8615D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/10%20Be.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1039</key>
+		<dict>
+			<key>Track ID</key><integer>1039</integer>
+			<key>Name</key><string>Blues for Sister Someone</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2186702</integer>
+			<key>Total Time</key><integer>180166</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8615F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/11%20Blues%20for%20Sister%20Someone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1040</key>
+		<dict>
+			<key>Track ID</key><integer>1040</integer>
+			<key>Name</key><string>Empty Hands</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3432012</integer>
+			<key>Total Time</key><integer>283088</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86161</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/12%20Empty%20Hands.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1041</key>
+		<dict>
+			<key>Track ID</key><integer>1041</integer>
+			<key>Name</key><string>Flower Child</string>
+			<key>Artist</key><string>Lenny Kravitz</string>
+			<key>Album</key><string>Let Love Rule</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2134666</integer>
+			<key>Total Time</key><integer>175830</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251465402</integer>
+			<key>Play Date UTC</key><date>2007-01-13T00:50:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86163</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lenny%20Kravitz/Let%20Love%20Rule/13%20Flower%20Child.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1042</key>
+		<dict>
+			<key>Track ID</key><integer>1042</integer>
+			<key>Name</key><string>Time's Up</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Calhoun/Glover/Reid/Skillings</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24685498</integer>
+			<key>Total Time</key><integer>185693</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-26T16:00:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>1062</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253356856</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:14:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B86165</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/01%20Time's%20Up.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1043</key>
+		<dict>
+			<key>Track ID</key><integer>1043</integer>
+			<key>Name</key><string>History Lesson</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>5005841</integer>
+			<key>Total Time</key><integer>52706</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-26T19:04:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>755</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:44:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B86168</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/02%20History%20Lesson.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1044</key>
+		<dict>
+			<key>Track ID</key><integer>1044</integer>
+			<key>Name</key><string>Pride</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Calhoun</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>37473162</integer>
+			<key>Total Time</key><integer>294693</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-20T14:28:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>1016</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249208755</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:59:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B8616A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/03%20Pride.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1045</key>
+		<dict>
+			<key>Track ID</key><integer>1045</integer>
+			<key>Name</key><string>Love Rears It's Ugly Head</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31652861</integer>
+			<key>Total Time</key><integer>259466</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-29T14:00:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>975</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253596190</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:43:10Z</date>
+			<key>Persistent ID</key><string>87139F8602B8616C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/04%20Love%20Rears%20It's%20Ugly%20Head.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1046</key>
+		<dict>
+			<key>Track ID</key><integer>1046</integer>
+			<key>Name</key><string>New Jack Theme</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26281819</integer>
+			<key>Total Time</key><integer>210400</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-10T22:55:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>998</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253337384</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:49:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B8616E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/05%20New%20Jack%20Theme.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1047</key>
+		<dict>
+			<key>Track ID</key><integer>1047</integer>
+			<key>Name</key><string>Someone Like You</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Skillings</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28113251</integer>
+			<key>Total Time</key><integer>228906</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-01T14:18:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>981</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252410373</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:19:33Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-25T19:20:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B86170</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/06%20Someone%20Like%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1048</key>
+		<dict>
+			<key>Track ID</key><integer>1048</integer>
+			<key>Name</key><string>Elvis Is Dead</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29604947</integer>
+			<key>Total Time</key><integer>229893</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-17T14:44:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>1029</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252411477</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:37:57Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-16T19:04:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B86172</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/07%20Elvis%20Is%20Dead.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1049</key>
+		<dict>
+			<key>Track ID</key><integer>1049</integer>
+			<key>Name</key><string>Type</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>48766584</integer>
+			<key>Total Time</key><integer>386466</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-08T19:07:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>1008</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251638224</integer>
+			<key>Play Date UTC</key><date>2007-01-15T00:50:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86174</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/08%20Type.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1050</key>
+		<dict>
+			<key>Track ID</key><integer>1050</integer>
+			<key>Name</key><string>Information Overload</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>45823545</integer>
+			<key>Total Time</key><integer>371440</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2004-08-22T05:42:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>986</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86176</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/09%20Information%20Overload.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1051</key>
+		<dict>
+			<key>Track ID</key><integer>1051</integer>
+			<key>Name</key><string>Ology</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Skillings</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>5857994</integer>
+			<key>Total Time</key><integer>67960</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-10-20T00:11:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>686</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252503390</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:09:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B86178</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/11%20Ology.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1052</key>
+		<dict>
+			<key>Track ID</key><integer>1052</integer>
+			<key>Name</key><string>Fight The Fight</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Calhoun/Glover/Reid/Skillings</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>32504161</integer>
+			<key>Total Time</key><integer>272733</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-25T15:28:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>952</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253287867</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:04:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B8617A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/12%20Fight%20The%20Fight.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1053</key>
+		<dict>
+			<key>Track ID</key><integer>1053</integer>
+			<key>Name</key><string>Tag Team Partners</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Glover</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>4247023</integer>
+			<key>Total Time</key><integer>47933</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2004-08-22T05:44:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>704</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252517716</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:08:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B8617C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/13%20Tag%20Team%20Partners.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1054</key>
+		<dict>
+			<key>Track ID</key><integer>1054</integer>
+			<key>Name</key><string>Solace Of You</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Glover/Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>22680179</integer>
+			<key>Total Time</key><integer>217666</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-29T12:27:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>832</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252940508</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:35:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B8617E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/14%20Solace%20Of%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1055</key>
+		<dict>
+			<key>Track ID</key><integer>1055</integer>
+			<key>Name</key><string>This Is The Life</string>
+			<key>Artist</key><string>Living Colour</string>
+			<key>Composer</key><string>Reid</string>
+			<key>Album</key><string>Time's Up</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>45200879</integer>
+			<key>Total Time</key><integer>383306</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2005-09-27T23:59:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>942</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247826863</integer>
+			<key>Play Date UTC</key><date>2006-12-01T22:07:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T19:38:10Z</date>
+			<key>Persistent ID</key><string>87139F8602B86180</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Living%20Colour/Time's%20Up/15%20This%20Is%20The%20Life.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1056</key>
+		<dict>
+			<key>Track ID</key><integer>1056</integer>
+			<key>Name</key><string>Supernova</string>
+			<key>Artist</key><string>Liz Phair</string>
+			<key>Album</key><string>Whip-Smart</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4107049</integer>
+			<key>Total Time</key><integer>168809</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-06-16T12:16:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252545672</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:54:32Z</date>
+			<key>Persistent ID</key><string>87139F8602B86182</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Liz%20Phair/Whip-Smart/02%20Supernova.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1057</key>
+		<dict>
+			<key>Track ID</key><integer>1057</integer>
+			<key>Name</key><string>X-Ray Man</string>
+			<key>Artist</key><string>Liz Phair</string>
+			<key>Album</key><string>Whip-Smart</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3260276</integer>
+			<key>Total Time</key><integer>133545</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-06-16T12:17:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:22:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B86185</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Liz%20Phair/Whip-Smart/04%20X-Ray%20Man.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1058</key>
+		<dict>
+			<key>Track ID</key><integer>1058</integer>
+			<key>Name</key><string>Home</string>
+			<key>Artist</key><string>Lou Barlow</string>
+			<key>Composer</key><string>Lou Barlow</string>
+			<key>Album</key><string>Emoh</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4064738</integer>
+			<key>Total Time</key><integer>203128</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Date Modified</key><date>2005-02-23T20:26:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252517310</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:01:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B86187</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lou%20Barlow/Emoh/02%20Home.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1059</key>
+		<dict>
+			<key>Track ID</key><integer>1059</integer>
+			<key>Name</key><string>Leave You Far Behind</string>
+			<key>Artist</key><string>Lunatic Calm</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3093402</integer>
+			<key>Total Time</key><integer>193201</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252520325</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:52:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B8618A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Lunatic%20Calm/Matrix/06%20Leave%20You%20Far%20Behind.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1060</key>
+		<dict>
+			<key>Track ID</key><integer>1060</integer>
+			<key>Name</key><string>Golotha Tenement Blues</string>
+			<key>Artist</key><string>Machines of Loving Grace</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2927159</integer>
+			<key>Total Time</key><integer>241188</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253619624</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:13:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8618D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Machines%20of%20Loving%20Grace/The%20Crow/02%20Golotha%20Tenement%20Blues.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1061</key>
+		<dict>
+			<key>Track ID</key><integer>1061</integer>
+			<key>Name</key><string>Out Of Zone</string>
+			<key>Artist</key><string>Marbles</string>
+			<key>Composer</key><string>Robert Schneider</string>
+			<key>Album</key><string>Expo</string>
+			<key>Genre</key><string>Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3628397</integer>
+			<key>Total Time</key><integer>226638</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-02-23T20:34:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253683986</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:06:26Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-13T19:39:26Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86190</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Marbles/Expo/02%20Out%20Of%20Zone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1062</key>
+		<dict>
+			<key>Track ID</key><integer>1062</integer>
+			<key>Name</key><string>Poor Paul</string>
+			<key>Artist</key><string>Mardo</string>
+			<key>Album</key><string>Mardo</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3437550</integer>
+			<key>Total Time</key><integer>213942</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2005-02-23T20:35:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253455579</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:39:39Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T02:40:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86193</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Mardo/Mardo/02%20Poor%20Paul.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1063</key>
+		<dict>
+			<key>Track ID</key><integer>1063</integer>
+			<key>Name</key><string>Safe from Harm</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5277930</integer>
+			<key>Total Time</key><integer>318901</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2006-03-28T17:42:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249195729</integer>
+			<key>Play Date UTC</key><date>2006-12-17T18:22:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86196</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/01%20Safe%20from%20Harm.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1064</key>
+		<dict>
+			<key>Track ID</key><integer>1064</integer>
+			<key>Name</key><string>One Love</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4787946</integer>
+			<key>Total Time</key><integer>288645</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253368379</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:26:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86199</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/02%20One%20Love.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1065</key>
+		<dict>
+			<key>Track ID</key><integer>1065</integer>
+			<key>Name</key><string>Blue Lines</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4349866</integer>
+			<key>Total Time</key><integer>261571</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253355611</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:53:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8619B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/03%20Blue%20Lines.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1066</key>
+		<dict>
+			<key>Track ID</key><integer>1066</integer>
+			<key>Name</key><string>Be Thankful for What You've Got</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4158298</integer>
+			<key>Total Time</key><integer>249729</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249451556</integer>
+			<key>Play Date UTC</key><date>2006-12-20T17:25:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8619D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/04%20Be%20Thankful%20for%20What%20You've%20Got.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1067</key>
+		<dict>
+			<key>Track ID</key><integer>1067</integer>
+			<key>Name</key><string>Five Man Army</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6012762</integer>
+			<key>Total Time</key><integer>364342</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246866907</integer>
+			<key>Play Date UTC</key><date>2006-11-20T19:28:27Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T19:09:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8619F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/05%20Five%20Man%20Army.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1068</key>
+		<dict>
+			<key>Track ID</key><integer>1068</integer>
+			<key>Name</key><string>Unfinished Sympathy</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5106666</integer>
+			<key>Total Time</key><integer>308336</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252550091</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:08:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861A1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/06%20Unfinished%20Sympathy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1069</key>
+		<dict>
+			<key>Track ID</key><integer>1069</integer>
+			<key>Name</key><string>Daydreaming</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4239418</integer>
+			<key>Total Time</key><integer>254744</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:43:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246716683</integer>
+			<key>Play Date UTC</key><date>2006-11-19T01:44:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861A3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/07%20Daydreaming.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1070</key>
+		<dict>
+			<key>Track ID</key><integer>1070</integer>
+			<key>Name</key><string>Lately</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4428506</integer>
+			<key>Total Time</key><integer>266401</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:44:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253600400</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:53:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861A5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/08%20Lately.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1071</key>
+		<dict>
+			<key>Track ID</key><integer>1071</integer>
+			<key>Name</key><string>Hymn of the Big Wheel</string>
+			<key>Artist</key><string>Massive Attack</string>
+			<key>Album Artist</key><string>Massive Attack</string>
+			<key>Album</key><string>Blue Lines</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6545594</integer>
+			<key>Total Time</key><integer>397268</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>1991</integer>
+			<key>Date Modified</key><date>2006-03-28T17:44:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252581108</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:45:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861A7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Massive%20Attack/Blue%20Lines/09%20Hymn%20of%20the%20Big%20Wheel.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1072</key>
+		<dict>
+			<key>Track ID</key><integer>1072</integer>
+			<key>Name</key><string>Prime Audio Soup</string>
+			<key>Artist</key><string>Meat Beat Manifesto</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6038343</integer>
+			<key>Total Time</key><integer>377260</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253553039</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:43:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B861A9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Meat%20Beat%20Manifesto/Matrix/05%20Prime%20Audio%20Soup.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1073</key>
+		<dict>
+			<key>Track ID</key><integer>1073</integer>
+			<key>Name</key><string>Time Baby III</string>
+			<key>Artist</key><string>Medicine</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2819012</integer>
+			<key>Total Time</key><integer>232176</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249320221</integer>
+			<key>Play Date UTC</key><date>2006-12-19T04:57:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Medicine/The%20Crow/13%20Time%20Baby%20III.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1074</key>
+		<dict>
+			<key>Track ID</key><integer>1074</integer>
+			<key>Name</key><string>Inside My Love</string>
+			<key>Artist</key><string>Minnie Riperton</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4499751</integer>
+			<key>Total Time</key><integer>280842</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252506464</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:01:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861AF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Minnie%20Riperton/Late%20Lounge%20(1%20of%202)/09%20Inside%20My%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1075</key>
+		<dict>
+			<key>Track ID</key><integer>1075</integer>
+			<key>Name</key><string>We Are All Made of Stars</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4968783</integer>
+			<key>Total Time</key><integer>272740</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-21T20:42:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3249574947</integer>
+			<key>Play Date UTC</key><date>2006-12-22T03:42:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861B2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/01%20We%20Are%20All%20Made%20of%20Stars.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1076</key>
+		<dict>
+			<key>Track ID</key><integer>1076</integer>
+			<key>Name</key><string>In This World</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4480351</integer>
+			<key>Total Time</key><integer>242554</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-08-08T15:24:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246860278</integer>
+			<key>Play Date UTC</key><date>2006-11-20T17:37:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861B5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/02%20In%20This%20World.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1077</key>
+		<dict>
+			<key>Track ID</key><integer>1077</integer>
+			<key>Name</key><string>In My Heart</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5030751</integer>
+			<key>Total Time</key><integer>276571</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-26T21:03:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:49Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252393561</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:39:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861B7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/03%20In%20My%20Heart.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1078</key>
+		<dict>
+			<key>Track ID</key><integer>1078</integer>
+			<key>Name</key><string>Great Escape</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2642751</integer>
+			<key>Total Time</key><integer>128985</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-17T23:10:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250668314</integer>
+			<key>Play Date UTC</key><date>2007-01-03T19:25:14Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:44:33Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861B9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/04%20Great%20Escape.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1079</key>
+		<dict>
+			<key>Track ID</key><integer>1079</integer>
+			<key>Name</key><string>Signs of Love</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4859807</integer>
+			<key>Total Time</key><integer>266006</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-21T21:23:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246910428</integer>
+			<key>Play Date UTC</key><date>2006-11-21T07:33:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861BB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/05%20Signs%20of%20Love.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1080</key>
+		<dict>
+			<key>Track ID</key><integer>1080</integer>
+			<key>Name</key><string>One of These Mornings</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3678207</integer>
+			<key>Total Time</key><integer>192979</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-18T02:59:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249208254</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:50:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861BD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/06%20One%20of%20These%20Mornings.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1081</key>
+		<dict>
+			<key>Track ID</key><integer>1081</integer>
+			<key>Name</key><string>Another Woman</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4375151</integer>
+			<key>Total Time</key><integer>236052</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-20T19:52:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251356603</integer>
+			<key>Play Date UTC</key><date>2007-01-11T18:36:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861BF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/07%20Another%20Woman.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1082</key>
+		<dict>
+			<key>Track ID</key><integer>1082</integer>
+			<key>Name</key><string>Fireworks</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2709999</integer>
+			<key>Total Time</key><integer>133141</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-30T02:55:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252566593</integer>
+			<key>Play Date UTC</key><date>2007-01-25T18:43:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861C1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/08%20Fireworks.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1083</key>
+		<dict>
+			<key>Track ID</key><integer>1083</integer>
+			<key>Name</key><string>Extreme Ways</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4400687</integer>
+			<key>Total Time</key><integer>237631</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-26T20:08:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253551637</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:20:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861C3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/09%20Extreme%20Ways.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1084</key>
+		<dict>
+			<key>Track ID</key><integer>1084</integer>
+			<key>Name</key><string>Jam for the Ladies</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3826991</integer>
+			<key>Total Time</key><integer>202174</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-30T00:13:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/10%20Jam%20for%20the%20Ladies.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1085</key>
+		<dict>
+			<key>Track ID</key><integer>1085</integer>
+			<key>Name</key><string>Sunday (The Day Before My Birthday)</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5564287</integer>
+			<key>Total Time</key><integer>309543</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-26T18:04:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253180008</integer>
+			<key>Play Date UTC</key><date>2007-02-01T21:06:48Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-20T23:09:00Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/11%20Sunday%20(The%20Day%20Before%20My%20Birthday).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1086</key>
+		<dict>
+			<key>Track ID</key><integer>1086</integer>
+			<key>Name</key><string>18</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4899247</integer>
+			<key>Total Time</key><integer>268444</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-08-08T17:10:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252391286</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:01:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861C9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/12%2018.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1087</key>
+		<dict>
+			<key>Track ID</key><integer>1087</integer>
+			<key>Name</key><string>Sleep Alone</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5173519</integer>
+			<key>Total Time</key><integer>285395</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-20T16:08:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247025125</integer>
+			<key>Play Date UTC</key><date>2006-11-22T15:25:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861CB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/13%20Sleep%20Alone.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1088</key>
+		<dict>
+			<key>Track ID</key><integer>1088</integer>
+			<key>Name</key><string>At Least We Tried</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4581407</integer>
+			<key>Total Time</key><integer>248800</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-19T01:54:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253370375</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:59:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/14%20At%20Least%20We%20Tried.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1089</key>
+		<dict>
+			<key>Track ID</key><integer>1089</integer>
+			<key>Name</key><string>Harbour</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6823263</integer>
+			<key>Total Time</key><integer>387353</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-20T17:28:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252413072</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:04:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/15%20Harbour.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1090</key>
+		<dict>
+			<key>Track ID</key><integer>1090</integer>
+			<key>Name</key><string>Look Back In</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2832479</integer>
+			<key>Total Time</key><integer>140711</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-04T10:33:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/16%20Look%20Back%20In.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1091</key>
+		<dict>
+			<key>Track ID</key><integer>1091</integer>
+			<key>Name</key><string>Rafters</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3828479</integer>
+			<key>Total Time</key><integer>202267</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-28T19:43:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252550914</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:21:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/17%20Rafters.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1092</key>
+		<dict>
+			<key>Track ID</key><integer>1092</integer>
+			<key>Name</key><string>I'm Not Worried at All</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album Artist</key><string>Moby</string>
+			<key>Album</key><string>18</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4631759</integer>
+			<key>Total Time</key><integer>251911</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>18</integer>
+			<key>Track Count</key><integer>18</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-07-21T13:59:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253376723</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:45:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/18/18%20I'm%20Not%20Worried%20at%20All.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1093</key>
+		<dict>
+			<key>Track ID</key><integer>1093</integer>
+			<key>Name</key><string>Hymn</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>17330228</integer>
+			<key>Total Time</key><integer>197933</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-26T17:15:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>699</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253081276</integer>
+			<key>Play Date UTC</key><date>2007-01-31T17:41:16Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:56:03Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B861D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/01%20Hymn.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1094</key>
+		<dict>
+			<key>Track ID</key><integer>1094</integer>
+			<key>Name</key><string>Feeling So Real</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26493137</integer>
+			<key>Total Time</key><integer>201600</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-07T15:29:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>1050</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250679872</integer>
+			<key>Play Date UTC</key><date>2007-01-03T22:37:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B861DA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/02%20Feeling%20So%20Real.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1095</key>
+		<dict>
+			<key>Track ID</key><integer>1095</integer>
+			<key>Name</key><string>All That I Need To Be Is Loved</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>22931103</integer>
+			<key>Total Time</key><integer>163333</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-08-22T04:49:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>1121</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T17:28:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B861DC</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/03%20All%20That%20I%20Need%20To%20Be%20Is%20Loved.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1096</key>
+		<dict>
+			<key>Track ID</key><integer>1096</integer>
+			<key>Name</key><string>Let's Go Free</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>4018268</integer>
+			<key>Total Time</key><integer>38440</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-26T20:54:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>831</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253621959</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:52:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B861DE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/04%20Let's%20Go%20Free.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1097</key>
+		<dict>
+			<key>Track ID</key><integer>1097</integer>
+			<key>Name</key><string>Everytime You Touch Me</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28980982</integer>
+			<key>Total Time</key><integer>221760</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-07T21:12:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>1044</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251622954</integer>
+			<key>Play Date UTC</key><date>2007-01-14T20:35:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B861E0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/05%20Everytime%20You%20Touch%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1098</key>
+		<dict>
+			<key>Track ID</key><integer>1098</integer>
+			<key>Name</key><string>Bring Back My Happiness</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26608989</integer>
+			<key>Total Time</key><integer>192640</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-09T00:08:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>1103</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249489126</integer>
+			<key>Play Date UTC</key><date>2006-12-21T03:52:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B861E2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/06%20Bring%20Back%20My%20Happiness.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1099</key>
+		<dict>
+			<key>Track ID</key><integer>1099</integer>
+			<key>Name</key><string>What Love</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>22604245</integer>
+			<key>Total Time</key><integer>168333</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-07T15:42:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>1072</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B861E4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/07%20What%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1100</key>
+		<dict>
+			<key>Track ID</key><integer>1100</integer>
+			<key>Name</key><string>First Cool Hive</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34041165</integer>
+			<key>Total Time</key><integer>317226</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-26T21:05:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>857</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253707790</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:43:10Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B861E6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/08%20First%20Cool%20Hive.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1101</key>
+		<dict>
+			<key>Track ID</key><integer>1101</integer>
+			<key>Name</key><string>Into The Blue</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby and Mimi Goese</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>35305191</integer>
+			<key>Total Time</key><integer>333600</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-28T23:58:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>846</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253278722</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:32:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B861E8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/09%20Into%20The%20Blue.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1102</key>
+		<dict>
+			<key>Track ID</key><integer>1102</integer>
+			<key>Name</key><string>Anthem</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24694085</integer>
+			<key>Total Time</key><integer>207533</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-26T20:17:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>950</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253608371</integer>
+			<key>Play Date UTC</key><date>2007-02-06T20:06:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B861EA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/10%20Anthem.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1103</key>
+		<dict>
+			<key>Track ID</key><integer>1103</integer>
+			<key>Name</key><string>Everything Is Wrong</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>4597821</integer>
+			<key>Total Time</key><integer>74640</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-02T00:25:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>490</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250659644</integer>
+			<key>Play Date UTC</key><date>2007-01-03T17:00:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B861EC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/11%20Everything%20Is%20Wrong.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1104</key>
+		<dict>
+			<key>Track ID</key><integer>1104</integer>
+			<key>Name</key><string>God Moving Over The Face Of The World</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>41265717</integer>
+			<key>Total Time</key><integer>441800</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-10-02T14:38:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>746</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253601451</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:10:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B861EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/12%20God%20Moving%20Over%20The%20Face%20Of%20The%20World.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1105</key>
+		<dict>
+			<key>Track ID</key><integer>1105</integer>
+			<key>Name</key><string>When It's Cold I'd Like To Die</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Composer</key><string>Moby and Mimi Goese</string>
+			<key>Album</key><string>Everything Is Wrong</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24125035</integer>
+			<key>Total Time</key><integer>253293</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2005-09-29T14:56:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>761</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252399280</integer>
+			<key>Play Date UTC</key><date>2007-01-23T20:14:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B861F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Everything%20Is%20Wrong/13%20When%20It's%20Cold%20I'd%20Like%20To%20Die.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1106</key>
+		<dict>
+			<key>Track ID</key><integer>1106</integer>
+			<key>Name</key><string>Into the Blue</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5317279</integer>
+			<key>Total Time</key><integer>331937</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252937660</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:47:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861F2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Late%20Lounge%20(1%20of%202)/07%20Into%20the%20Blue.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1107</key>
+		<dict>
+			<key>Track ID</key><integer>1107</integer>
+			<key>Name</key><string>Bodyrock [Hybrid's Bodyshock Mix]</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7400472</integer>
+			<key>Total Time</key><integer>462393</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247037015</integer>
+			<key>Play Date UTC</key><date>2006-11-22T18:43:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B861F5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Plastic%20Compilation,%20Vol.%203/06%20Bodyrock%20%5BHybrid's%20Bodyshock%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1108</key>
+		<dict>
+			<key>Track ID</key><integer>1108</integer>
+			<key>Name</key><string>Honey</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2513567</integer>
+			<key>Total Time</key><integer>208770</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247727049</integer>
+			<key>Play Date UTC</key><date>2006-11-30T18:24:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/01%20Honey.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1109</key>
+		<dict>
+			<key>Track ID</key><integer>1109</integer>
+			<key>Name</key><string>Find My Baby</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2882207</integer>
+			<key>Total Time</key><integer>239490</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252937067</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:37:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B861FB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/02%20Find%20My%20Baby.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1110</key>
+		<dict>
+			<key>Track ID</key><integer>1110</integer>
+			<key>Name</key><string>Porcelain</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2897066</integer>
+			<key>Total Time</key><integer>241240</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250601296</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:48:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B861FD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/03%20Porcelain.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1111</key>
+		<dict>
+			<key>Track ID</key><integer>1111</integer>
+			<key>Name</key><string>Why Does My Heart Feel So Bad?</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3181383</integer>
+			<key>Total Time</key><integer>264933</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253689816</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:43:36Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-11T05:17:58Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B861FF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/04%20Why%20Does%20My%20Heart%20Feel%20So%20Bad_.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1112</key>
+		<dict>
+			<key>Track ID</key><integer>1112</integer>
+			<key>Name</key><string>South Side</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2760080</integer>
+			<key>Total Time</key><integer>229825</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252386887</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:48:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B86201</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/05%20South%20Side.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1113</key>
+		<dict>
+			<key>Track ID</key><integer>1113</integer>
+			<key>Name</key><string>Rushing</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2166369</integer>
+			<key>Total Time</key><integer>180349</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249317005</integer>
+			<key>Play Date UTC</key><date>2006-12-19T04:03:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B86203</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/06%20Rushing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1114</key>
+		<dict>
+			<key>Track ID</key><integer>1114</integer>
+			<key>Name</key><string>Bodyrock</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2600524</integer>
+			<key>Total Time</key><integer>216528</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246856968</integer>
+			<key>Play Date UTC</key><date>2006-11-20T16:42:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B86205</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/07%20Bodyrock.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1115</key>
+		<dict>
+			<key>Track ID</key><integer>1115</integer>
+			<key>Name</key><string>Natural Blues</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3048472</integer>
+			<key>Total Time</key><integer>253857</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253379634</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:33:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B86207</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/08%20Natural%20Blues.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1116</key>
+		<dict>
+			<key>Track ID</key><integer>1116</integer>
+			<key>Name</key><string>Machete</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2616197</integer>
+			<key>Total Time</key><integer>217835</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249271026</integer>
+			<key>Play Date UTC</key><date>2006-12-18T15:17:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T03:15:14Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86209</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/09%20Machete.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1117</key>
+		<dict>
+			<key>Track ID</key><integer>1117</integer>
+			<key>Name</key><string>7</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>747606</integer>
+			<key>Total Time</key><integer>62119</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250622040</integer>
+			<key>Play Date UTC</key><date>2007-01-03T06:34:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B8620B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/10%207.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1118</key>
+		<dict>
+			<key>Track ID</key><integer>1118</integer>
+			<key>Name</key><string>Run On</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2704909</integer>
+			<key>Total Time</key><integer>225227</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253342227</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:10:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B8620D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/11%20Run%20On.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1119</key>
+		<dict>
+			<key>Track ID</key><integer>1119</integer>
+			<key>Name</key><string>Down Slow</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1141637</integer>
+			<key>Total Time</key><integer>94955</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253557525</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:58:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B8620F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/12%20Down%20Slow.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1120</key>
+		<dict>
+			<key>Track ID</key><integer>1120</integer>
+			<key>Name</key><string>If Things Were Perfect</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3107090</integer>
+			<key>Total Time</key><integer>258742</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249293124</integer>
+			<key>Play Date UTC</key><date>2006-12-18T21:25:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86211</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/13%20If%20Things%20Were%20Perfect.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1121</key>
+		<dict>
+			<key>Track ID</key><integer>1121</integer>
+			<key>Name</key><string>Everloving</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2470120</integer>
+			<key>Total Time</key><integer>205662</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250600309</integer>
+			<key>Play Date UTC</key><date>2007-01-03T00:31:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B86213</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/14%20Everloving.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1122</key>
+		<dict>
+			<key>Track ID</key><integer>1122</integer>
+			<key>Name</key><string>Inside</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3466640</integer>
+			<key>Total Time</key><integer>288705</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252034405</integer>
+			<key>Play Date UTC</key><date>2007-01-19T14:53:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B86215</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/15%20Inside.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1123</key>
+		<dict>
+			<key>Track ID</key><integer>1123</integer>
+			<key>Name</key><string>Guitar Flute and String</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1553536</integer>
+			<key>Total Time</key><integer>129280</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253623018</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:10:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B86217</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/16%20Guitar%20Flute%20and%20String.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1124</key>
+		<dict>
+			<key>Track ID</key><integer>1124</integer>
+			<key>Name</key><string>The Sky Is Broken</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3106150</integer>
+			<key>Total Time</key><integer>258664</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253335646</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:20:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B86219</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/17%20The%20Sky%20Is%20Broken.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1125</key>
+		<dict>
+			<key>Track ID</key><integer>1125</integer>
+			<key>Name</key><string>My Weakness</string>
+			<key>Artist</key><string>Moby</string>
+			<key>Album</key><string>Play</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2614003</integer>
+			<key>Total Time</key><integer>217652</integer>
+			<key>Track Number</key><integer>18</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253472790</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:26:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B8621B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby/Play/18%20My%20Weakness.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1126</key>
+		<dict>
+			<key>Track ID</key><integer>1126</integer>
+			<key>Name</key><string>Patient Love</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7165140</integer>
+			<key>Total Time</key><integer>591281</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253381464</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:04:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8621D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/01%20Patient%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1127</key>
+		<dict>
+			<key>Track ID</key><integer>1127</integer>
+			<key>Name</key><string>Great Lake</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6537386</integer>
+			<key>Total Time</key><integer>539480</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251632059</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:07:39Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86220</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/02%20Great%20Lake.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1128</key>
+		<dict>
+			<key>Track ID</key><integer>1128</integer>
+			<key>Name</key><string>Gentle Love</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6041456</integer>
+			<key>Total Time</key><integer>498494</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253255051</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:57:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86222</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/03%20Gentle%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1129</key>
+		<dict>
+			<key>Track ID</key><integer>1129</integer>
+			<key>Name</key><string>Honest Love</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5439261</integer>
+			<key>Total Time</key><integer>448653</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253345115</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:58:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86224</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/04%20Honest%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1130</key>
+		<dict>
+			<key>Track ID</key><integer>1130</integer>
+			<key>Name</key><string>Slow Motion Suicide</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5204932</integer>
+			<key>Total Time</key><integer>429296</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252034834</integer>
+			<key>Play Date UTC</key><date>2007-01-19T15:00:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86226</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/05%20Slow%20Motion%20Suicide.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1131</key>
+		<dict>
+			<key>Track ID</key><integer>1131</integer>
+			<key>Name</key><string>Dog Heaven</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4435490</integer>
+			<key>Total Time</key><integer>365688</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249550891</integer>
+			<key>Play Date UTC</key><date>2006-12-21T21:01:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86228</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/06%20Dog%20Heaven.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1132</key>
+		<dict>
+			<key>Track ID</key><integer>1132</integer>
+			<key>Name</key><string>Reject</string>
+			<key>Artist</key><string>Moby / Voodoo Child</string>
+			<key>Album</key><string>The End of Everything [US]</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>13406420</integer>
+			<key>Total Time</key><integer>1107121</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253617667</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:41:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8622A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moby%20_%20Voodoo%20Child/The%20End%20of%20Everything%20%5BUS%5D/07%20Reject.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1133</key>
+		<dict>
+			<key>Track ID</key><integer>1133</integer>
+			<key>Name</key><string>Sing It Back [Tee's Radio Mix]</string>
+			<key>Artist</key><string>Moloko</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3314920</integer>
+			<key>Total Time</key><integer>207046</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250610344</integer>
+			<key>Play Date UTC</key><date>2007-01-03T03:19:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B8622C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Moloko/Plastic%20Compilation,%20Vol.%203/08%20Sing%20It%20Back%20%5BTee's%20Radio%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1134</key>
+		<dict>
+			<key>Track ID</key><integer>1134</integer>
+			<key>Name</key><string>Look to Your Orb for the Warning</string>
+			<key>Artist</key><string>Monster Magnet</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4532436</integer>
+			<key>Total Time</key><integer>283141</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B8622F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Monster%20Magnet/Matrix/11%20Look%20to%20Your%20Orb%20for%20the%20Warning.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1135</key>
+		<dict>
+			<key>Track ID</key><integer>1135</integer>
+			<key>Name</key><string>The Sea</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6002085</integer>
+			<key>Total Time</key><integer>347740</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:42:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252925483</integer>
+			<key>Play Date UTC</key><date>2007-01-29T22:24:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86232</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/01%20The%20Sea.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1136</key>
+		<dict>
+			<key>Track ID</key><integer>1136</integer>
+			<key>Name</key><string>Shoulder Holster</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4374974</integer>
+			<key>Total Time</key><integer>245270</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:42:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:50Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252923387</integer>
+			<key>Play Date UTC</key><date>2007-01-29T21:49:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86235</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/02%20Shoulder%20Holster.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1137</key>
+		<dict>
+			<key>Track ID</key><integer>1137</integer>
+			<key>Name</key><string>Part of the Process</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4676193</integer>
+			<key>Total Time</key><integer>264241</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:42:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253511986</integer>
+			<key>Play Date UTC</key><date>2007-02-05T17:19:46Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86237</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/03%20Part%20of%20the%20Process.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1138</key>
+		<dict>
+			<key>Track ID</key><integer>1138</integer>
+			<key>Name</key><string>Blindfold</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4887095</integer>
+			<key>Total Time</key><integer>277523</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253174892</integer>
+			<key>Play Date UTC</key><date>2007-02-01T19:41:32Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86239</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/04%20Blindfold.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1139</key>
+		<dict>
+			<key>Track ID</key><integer>1139</integer>
+			<key>Name</key><string>Let Me See</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4608728</integer>
+			<key>Total Time</key><integer>259992</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253082118</integer>
+			<key>Play Date UTC</key><date>2007-01-31T17:55:18Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8623B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/05%20Let%20Me%20See.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1140</key>
+		<dict>
+			<key>Track ID</key><integer>1140</integer>
+			<key>Name</key><string>Bullet Proof</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4499226</integer>
+			<key>Total Time</key><integer>253096</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251633891</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:38:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8623D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/06%20Bullet%20Proof.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1141</key>
+		<dict>
+			<key>Track ID</key><integer>1141</integer>
+			<key>Name</key><string>Over and Over</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2707291</integer>
+			<key>Total Time</key><integer>140247</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253457564</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:12:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8623F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/07%20Over%20and%20Over.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1142</key>
+		<dict>
+			<key>Track ID</key><integer>1142</integer>
+			<key>Name</key><string>Friction</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4516918</integer>
+			<key>Total Time</key><integer>254210</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249470134</integer>
+			<key>Play Date UTC</key><date>2006-12-20T22:35:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86241</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/08%20Friction.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1143</key>
+		<dict>
+			<key>Track ID</key><integer>1143</integer>
+			<key>Name</key><string>Diggin' in a Watery Grave</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2004167</integer>
+			<key>Total Time</key><integer>95966</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252582677</integer>
+			<key>Play Date UTC</key><date>2007-01-25T23:11:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86243</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/09%20Diggin'%20in%20a%20Watery%20Grave.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1144</key>
+		<dict>
+			<key>Track ID</key><integer>1144</integer>
+			<key>Name</key><string>Fear and Love</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5316651</integer>
+			<key>Total Time</key><integer>304574</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:43:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251486048</integer>
+			<key>Play Date UTC</key><date>2007-01-13T06:34:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86245</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/10%20Fear%20and%20Love.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1145</key>
+		<dict>
+			<key>Track ID</key><integer>1145</integer>
+			<key>Name</key><string>Big Calm</string>
+			<key>Artist</key><string>Morcheeba</string>
+			<key>Album Artist</key><string>Morcheeba</string>
+			<key>Album</key><string>Big Calm</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6205238</integer>
+			<key>Total Time</key><integer>360534</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-05-03T14:44:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252418046</integer>
+			<key>Play Date UTC</key><date>2007-01-24T01:27:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86247</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Morcheeba/Big%20Calm/11%20Big%20Calm.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1146</key>
+		<dict>
+			<key>Track ID</key><integer>1146</integer>
+			<key>Name</key><string>After the Flesh</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2183108</integer>
+			<key>Total Time</key><integer>179696</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253383046</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:30:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86249</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/The%20Crow/11%20After%20the%20Flesh.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1147</key>
+		<dict>
+			<key>Track ID</key><integer>1147</integer>
+			<key>Name</key><string>Astonsilicon</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4381848</integer>
+			<key>Total Time</key><integer>262941</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:22:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253379075</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:24:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8624C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/01%20Astonsilicon.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1148</key>
+		<dict>
+			<key>Track ID</key><integer>1148</integer>
+			<key>Name</key><string>Fade Out</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3991112</integer>
+			<key>Total Time</key><integer>238792</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:22:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249493289</integer>
+			<key>Play Date UTC</key><date>2006-12-21T05:01:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8624F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/02%20Fade%20Out.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1149</key>
+		<dict>
+			<key>Track ID</key><integer>1149</integer>
+			<key>Name</key><string>Option</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4479160</integer>
+			<key>Total Time</key><integer>268955</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:23:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3252116377</integer>
+			<key>Play Date UTC</key><date>2007-01-20T13:39:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86251</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/03%20Option.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1150</key>
+		<dict>
+			<key>Track ID</key><integer>1150</integer>
+			<key>Name</key><string>The Book</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4955944</integer>
+			<key>Total Time</key><integer>298421</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:23:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253362120</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:42:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86253</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/04%20The%20Book.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1151</key>
+		<dict>
+			<key>Track ID</key><integer>1151</integer>
+			<key>Name</key><string>Three Stars No Match</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4385240</integer>
+			<key>Total Time</key><integer>263150</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:23:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253522718</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:18:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86255</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/05%20Three%20Stars%20No%20Match.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1152</key>
+		<dict>
+			<key>Track ID</key><integer>1152</integer>
+			<key>Name</key><string>Paravent</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4485544</integer>
+			<key>Total Time</key><integer>269350</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:24:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251619916</integer>
+			<key>Play Date UTC</key><date>2007-01-14T19:45:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86257</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/06%20Paravent.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1153</key>
+		<dict>
+			<key>Track ID</key><integer>1153</integer>
+			<key>Name</key><string>October</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4627560</integer>
+			<key>Total Time</key><integer>278127</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:24:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253428464</integer>
+			<key>Play Date UTC</key><date>2007-02-04T18:07:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86259</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/07%20October.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1154</key>
+		<dict>
+			<key>Track ID</key><integer>1154</integer>
+			<key>Name</key><string>Rainfall</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4650856</integer>
+			<key>Total Time</key><integer>279566</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:25:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253547036</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:03:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8625B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/08%20Rainfall.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1155</key>
+		<dict>
+			<key>Track ID</key><integer>1155</integer>
+			<key>Name</key><string>King Kong Is Not Dead</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3796536</integer>
+			<key>Total Time</key><integer>226741</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:25:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252574916</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:01:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8625D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/09%20King%20Kong%20Is%20Not%20Dead.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1156</key>
+		<dict>
+			<key>Track ID</key><integer>1156</integer>
+			<key>Name</key><string>The Great Event</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5087064</integer>
+			<key>Total Time</key><integer>306525</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:26:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253380515</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:48:35Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8625F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/10%20The%20Great%20Event.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1157</key>
+		<dict>
+			<key>Track ID</key><integer>1157</integer>
+			<key>Name</key><string>Exit Song</string>
+			<key>Artist</key><string>Naomi</string>
+			<key>Album Artist</key><string>Naomi</string>
+			<key>Album</key><string>Pappelallee</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6331096</integer>
+			<key>Total Time</key><integer>383383</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-06-07T14:26:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253176529</integer>
+			<key>Play Date UTC</key><date>2007-02-01T20:08:49Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86261</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Naomi/Pappelallee/11%20Exit%20Song.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1158</key>
+		<dict>
+			<key>Track ID</key><integer>1158</integer>
+			<key>Name</key><string>Ophelia</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7542272</integer>
+			<key>Total Time</key><integer>310441</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253595931</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:38:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86263</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/01%20Ophelia.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1159</key>
+		<dict>
+			<key>Track ID</key><integer>1159</integer>
+			<key>Name</key><string>Life Is Sweet</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7589804</integer>
+			<key>Total Time</key><integer>312404</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253428186</integer>
+			<key>Play Date UTC</key><date>2007-02-04T18:03:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T01:08:53Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86266</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/02%20Life%20Is%20Sweet.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1160</key>
+		<dict>
+			<key>Track ID</key><integer>1160</integer>
+			<key>Name</key><string>Kind &#38; Generous</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6017968</integer>
+			<key>Total Time</key><integer>247508</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252472503</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:35:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86268</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/03%20Kind%20&#38;%20Generous.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1161</key>
+		<dict>
+			<key>Track ID</key><integer>1161</integer>
+			<key>Name</key><string>Frozen Charlotte</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7844202</integer>
+			<key>Total Time</key><integer>322921</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246430365</integer>
+			<key>Play Date UTC</key><date>2006-11-15T18:12:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8626A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/04%20Frozen%20Charlotte.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1162</key>
+		<dict>
+			<key>Track ID</key><integer>1162</integer>
+			<key>Name</key><string>My Skin</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8081093</integer>
+			<key>Total Time</key><integer>332692</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251482218</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:30:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8626C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/05%20My%20Skin.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1163</key>
+		<dict>
+			<key>Track ID</key><integer>1163</integer>
+			<key>Name</key><string>Break Your Heart</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7005935</integer>
+			<key>Total Time</key><integer>288297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252513316</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:55:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8626E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/06%20Break%20Your%20Heart.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1164</key>
+		<dict>
+			<key>Track ID</key><integer>1164</integer>
+			<key>Name</key><string>King Of May</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6060966</integer>
+			<key>Total Time</key><integer>249278</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253350472</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:27:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:55:49Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86270</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/07%20King%20Of%20May.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1165</key>
+		<dict>
+			<key>Track ID</key><integer>1165</integer>
+			<key>Name</key><string>Thick As Thieves</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10135563</integer>
+			<key>Total Time</key><integer>417534</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3249553956</integer>
+			<key>Play Date UTC</key><date>2006-12-21T21:52:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86272</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/08%20Thick%20As%20Thieves.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1166</key>
+		<dict>
+			<key>Track ID</key><integer>1166</integer>
+			<key>Name</key><string>Effigy</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3679051</integer>
+			<key>Total Time</key><integer>150142</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252481773</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:09:33Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-17T22:21:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86274</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/09%20Effigy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1167</key>
+		<dict>
+			<key>Track ID</key><integer>1167</integer>
+			<key>Name</key><string>The Living</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4829383</integer>
+			<key>Total Time</key><integer>198036</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252503322</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:08:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86276</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/10%20The%20Living.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1168</key>
+		<dict>
+			<key>Track ID</key><integer>1168</integer>
+			<key>Name</key><string>When They Ring The Golden Bells</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Composer</key><string>Dion de Marbelle</string>
+			<key>Album</key><string>Ophelia</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13899608</integer>
+			<key>Total Time</key><integer>573118</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-08-01T17:01:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250664143</integer>
+			<key>Play Date UTC</key><date>2007-01-03T18:15:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86278</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Ophelia/11%20When%20They%20Ring%20The%20Golden%20Bells.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1169</key>
+		<dict>
+			<key>Track ID</key><integer>1169</integer>
+			<key>Name</key><string>San Andreas Fault</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3831769</integer>
+			<key>Total Time</key><integer>238837</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253360290</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:11:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T02:26:24Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8627A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/01%20San%20Andreas%20Fault.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1170</key>
+		<dict>
+			<key>Track ID</key><integer>1170</integer>
+			<key>Name</key><string>Wonder</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4286926</integer>
+			<key>Total Time</key><integer>267284</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8627D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/02%20Wonder.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1171</key>
+		<dict>
+			<key>Track ID</key><integer>1171</integer>
+			<key>Name</key><string>Beloved Wife</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4854097</integer>
+			<key>Total Time</key><integer>302733</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8627F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/03%20Beloved%20Wife.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1172</key>
+		<dict>
+			<key>Track ID</key><integer>1172</integer>
+			<key>Name</key><string>River</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5325973</integer>
+			<key>Total Time</key><integer>332225</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252922585</integer>
+			<key>Play Date UTC</key><date>2007-01-29T21:36:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86281</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/04%20River.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1173</key>
+		<dict>
+			<key>Track ID</key><integer>1173</integer>
+			<key>Name</key><string>Carnival</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5759397</integer>
+			<key>Total Time</key><integer>359314</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86283</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/05%20Carnival.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1174</key>
+		<dict>
+			<key>Track ID</key><integer>1174</integer>
+			<key>Name</key><string>I May Know the Word</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7828712</integer>
+			<key>Total Time</key><integer>488646</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247576537</integer>
+			<key>Play Date UTC</key><date>2006-11-29T00:35:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86285</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/06%20I%20May%20Know%20the%20Word.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1175</key>
+		<dict>
+			<key>Track ID</key><integer>1175</integer>
+			<key>Name</key><string>The Letter</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2123988</integer>
+			<key>Total Time</key><integer>132101</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253593235</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:53:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86287</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/07%20The%20Letter.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1176</key>
+		<dict>
+			<key>Track ID</key><integer>1176</integer>
+			<key>Name</key><string>Cowboy Romance</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4476262</integer>
+			<key>Total Time</key><integer>279118</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:26:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249491040</integer>
+			<key>Play Date UTC</key><date>2006-12-21T04:24:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86289</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/08%20Cowboy%20Romance.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1177</key>
+		<dict>
+			<key>Track ID</key><integer>1177</integer>
+			<key>Name</key><string>Jealousy</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2595446</integer>
+			<key>Total Time</key><integer>161567</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252507571</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:19:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8628B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/09%20Jealousy.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1178</key>
+		<dict>
+			<key>Track ID</key><integer>1178</integer>
+			<key>Name</key><string>Where I Go</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3857682</integer>
+			<key>Total Time</key><integer>240457</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252573777</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:42:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8628D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/10%20Where%20I%20Go.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1179</key>
+		<dict>
+			<key>Track ID</key><integer>1179</integer>
+			<key>Name</key><string>Seven Years</string>
+			<key>Artist</key><string>Natalie Merchant</string>
+			<key>Album</key><string>Tigerlily</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5302567</integer>
+			<key>Total Time</key><integer>330762</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252546747</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:12:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8628F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Natalie%20Merchant/Tigerlily/11%20Seven%20Years.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1180</key>
+		<dict>
+			<key>Track ID</key><integer>1180</integer>
+			<key>Name</key><string>Stormy Weather</string>
+			<key>Artist</key><string>Nina Nastasia</string>
+			<key>Album</key><string>Dogs</string>
+			<key>Genre</key><string>Folk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2880246</integer>
+			<key>Total Time</key><integer>179879</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-02-23T21:00:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86291</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nina%20Nastasia/Dogs/07%20Stormy%20Weather.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1181</key>
+		<dict>
+			<key>Track ID</key><integer>1181</integer>
+			<key>Name</key><string>Head Like A Hole</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7278240</integer>
+			<key>Total Time</key><integer>299604</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>21</integer>
+			<key>Play Date</key><integer>3253613968</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:39:28Z</date>
+			<key>Skip Count</key><integer>3</integer>
+			<key>Skip Date</key><date>2007-01-04T23:40:36Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86294</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/01%20Head%20Like%20A%20Hole.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1182</key>
+		<dict>
+			<key>Track ID</key><integer>1182</integer>
+			<key>Name</key><string>Terrible Lie</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6728629</integer>
+			<key>Total Time</key><integer>278932</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253366882</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:01:22Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T18:35:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86297</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/02%20Terrible%20Lie.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1183</key>
+		<dict>
+			<key>Track ID</key><integer>1183</integer>
+			<key>Name</key><string>Down In It</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5504111</integer>
+			<key>Total Time</key><integer>226366</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86299</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/03%20Down%20In%20It.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1184</key>
+		<dict>
+			<key>Track ID</key><integer>1184</integer>
+			<key>Name</key><string>Sanctified</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8459328</integer>
+			<key>Total Time</key><integer>348372</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252410721</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:25:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8629B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/04%20Sanctified.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1185</key>
+		<dict>
+			<key>Track ID</key><integer>1185</integer>
+			<key>Name</key><string>Something I Can Never Have</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8566488</integer>
+			<key>Total Time</key><integer>354900</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252480383</integer>
+			<key>Play Date UTC</key><date>2007-01-24T18:46:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8629D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/05%20Something%20I%20Can%20Never%20Have.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1186</key>
+		<dict>
+			<key>Track ID</key><integer>1186</integer>
+			<key>Name</key><string>Kinda I Want To</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6635820</integer>
+			<key>Total Time</key><integer>273065</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>23</integer>
+			<key>Play Date</key><integer>3252916245</integer>
+			<key>Play Date UTC</key><date>2007-01-29T19:50:45Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-27T03:11:02Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8629F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/06%20Kinda%20I%20Want%20To.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1187</key>
+		<dict>
+			<key>Track ID</key><integer>1187</integer>
+			<key>Name</key><string>Sin</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5920395</integer>
+			<key>Total Time</key><integer>246292</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253622205</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:56:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862A1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/07%20Sin.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1188</key>
+		<dict>
+			<key>Track ID</key><integer>1188</integer>
+			<key>Name</key><string>That's What I Get</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6515483</integer>
+			<key>Total Time</key><integer>270761</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253260051</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:20:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862A3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/08%20That's%20What%20I%20Get.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1189</key>
+		<dict>
+			<key>Track ID</key><integer>1189</integer>
+			<key>Name</key><string>The Only Time</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6990774</integer>
+			<key>Total Time</key><integer>287721</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252475944</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:32:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862A5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/09%20The%20Only%20Time.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1190</key>
+		<dict>
+			<key>Track ID</key><integer>1190</integer>
+			<key>Name</key><string>Ringfinger</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Composer</key><string>NIN</string>
+			<key>Album</key><string>Pretty Hate Machine</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8277201</integer>
+			<key>Total Time</key><integer>340841</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1989</integer>
+			<key>Date Modified</key><date>2004-07-26T00:56:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251521222</integer>
+			<key>Play Date UTC</key><date>2007-01-13T16:20:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862A7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/Pretty%20Hate%20Machine/10%20Ringfinger.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1191</key>
+		<dict>
+			<key>Track ID</key><integer>1191</integer>
+			<key>Name</key><string>Dead Souls</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3569019</integer>
+			<key>Total Time</key><integer>294164</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>24</integer>
+			<key>Play Date</key><integer>3252842106</integer>
+			<key>Play Date UTC</key><date>2007-01-28T23:15:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-22T18:53:46Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862A9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/The%20Crow/04%20Dead%20Souls.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1192</key>
+		<dict>
+			<key>Track ID</key><integer>1192</integer>
+			<key>Name</key><string>Closer</string>
+			<key>Artist</key><string>Nine Inch Nails</string>
+			<key>Album Artist</key><string>Nine Inch Nails</string>
+			<key>Album</key><string>The Downward Spiral</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6679110</integer>
+			<key>Total Time</key><integer>373027</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2005-10-31T23:44:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>28</integer>
+			<key>Play Date</key><integer>3253685750</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:35:50Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-05T22:48:53Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862AC</string>
+			<key>Explicit</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nine%20Inch%20Nails/The%20Downward%20Spiral/05%20Closer.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1193</key>
+		<dict>
+			<key>Track ID</key><integer>1193</integer>
+			<key>Name</key><string>Cold and Intimate [Nasha Experience Mix]</string>
+			<key>Artist</key><string>Nitin Sawhney</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4457537</integer>
+			<key>Total Time</key><integer>278204</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253599548</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:39:08Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T17:30:01Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862AF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Nitin%20Sawhney/Late%20Lounge%20(1%20of%202)/06%20Cold%20and%20Intimate%20%5BNasha%20Experience%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1194</key>
+		<dict>
+			<key>Track ID</key><integer>1194</integer>
+			<key>Name</key><string>Transient</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10551437</integer>
+			<key>Total Time</key><integer>348551</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:03:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>231</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246971023</integer>
+			<key>Play Date UTC</key><date>2006-11-22T00:23:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T22:59:22Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B862B2</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/01%20Transient.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1195</key>
+		<dict>
+			<key>Track ID</key><integer>1195</integer>
+			<key>Name</key><string>Pants</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9963445</integer>
+			<key>Total Time</key><integer>345129</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:03:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>220</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253082980</integer>
+			<key>Play Date UTC</key><date>2007-01-31T18:09:40Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-18T23:35:58Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B862B5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/02%20Pants.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1196</key>
+		<dict>
+			<key>Track ID</key><integer>1196</integer>
+			<key>Name</key><string>Tunnel Vision</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7472857</integer>
+			<key>Total Time</key><integer>267493</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:04:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:51Z</date>
+			<key>Bit Rate</key><integer>209</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B862B7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/03%20Tunnel%20Vision.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1197</key>
+		<dict>
+			<key>Track ID</key><integer>1197</integer>
+			<key>Name</key><string>Lost</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9189023</integer>
+			<key>Total Time</key><integer>308218</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:04:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>229</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250656556</integer>
+			<key>Play Date UTC</key><date>2007-01-03T16:09:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862B9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/04%20Lost.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1198</key>
+		<dict>
+			<key>Track ID</key><integer>1198</integer>
+			<key>Name</key><string>You Lot</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12098232</integer>
+			<key>Total Time</key><integer>428538</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:04:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>219</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253507669</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:07:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862BB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/05%20You%20Lot.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1199</key>
+		<dict>
+			<key>Track ID</key><integer>1199</integer>
+			<key>Name</key><string>Bath Time</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7562593</integer>
+			<key>Total Time</key><integer>258742</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:04:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>222</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862BD</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/06%20Bath%20Time.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1200</key>
+		<dict>
+			<key>Track ID</key><integer>1200</integer>
+			<key>Name</key><string>Acid Pants</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10485402</integer>
+			<key>Total Time</key><integer>391000</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:05:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>207</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247288179</integer>
+			<key>Play Date UTC</key><date>2006-11-25T16:29:39Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T23:20:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862BF</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/07%20Acid%20Pants.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1201</key>
+		<dict>
+			<key>Track ID</key><integer>1201</integer>
+			<key>Name</key><string>Easy Serv</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6656845</integer>
+			<key>Total Time</key><integer>249129</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:05:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>202</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862C1</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/08%20Easy%20Serv.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1202</key>
+		<dict>
+			<key>Track ID</key><integer>1202</integer>
+			<key>Name</key><string>One Perfect Sunrise</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>Blue Album [UK]</string>
+			<key>Genre</key><string>General Techno</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14779311</integer>
+			<key>Total Time</key><integer>525191</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-03-22T00:05:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>219</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Ripped by Winamp</string>
+			<key>Play Count</key><integer>31</integer>
+			<key>Play Date</key><integer>3253772029</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:33:49Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862C3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Blue%20Album%20%5BUK%5D/09%20One%20Perfect%20Sunrise.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1203</key>
+		<dict>
+			<key>Track ID</key><integer>1203</integer>
+			<key>Name</key><string>Funny Break [One is Enough] (Plump DJ's Mix)</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Bedford/Bramley/Paul Hartnoll</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7701093</integer>
+			<key>Total Time</key><integer>320052</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253289863</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:37:43Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B862C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/Community%20Service/05%20Funny%20Break%20%5BOne%20is%20Enough%5D%20(Plump%20DJ's%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1204</key>
+		<dict>
+			<key>Track ID</key><integer>1204</integer>
+			<key>Name</key><string>Satan [Industry Standard] [Industry Standard]</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>In Sides [2-CD] [U.S. Release #2] (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3563314</integer>
+			<key>Total Time</key><integer>221675</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>27</integer>
+			<key>Play Date</key><integer>3253115538</integer>
+			<key>Play Date UTC</key><date>2007-02-01T03:12:18Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/In%20Sides%20%5B2-CD%5D%20%5BU.S.%20Release%20%232%5D%20(2%20of%202)/01%20Satan%20%5BIndustry%20Standard%5D%20%5BIndustry%20Standard%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1205</key>
+		<dict>
+			<key>Track ID</key><integer>1205</integer>
+			<key>Name</key><string>Satan [Live in New York City] [Live in New York City]</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>In Sides [2-CD] [U.S. Release #2] (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6822977</integer>
+			<key>Total Time</key><integer>425404</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253159368</integer>
+			<key>Play Date UTC</key><date>2007-02-01T15:22:48Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-08T21:30:32Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862CA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/In%20Sides%20%5B2-CD%5D%20%5BU.S.%20Release%20%232%5D%20(2%20of%202)/02%20Satan%20%5BLive%20in%20New%20York%20City%5D%20%5BLive%20in%20New%20York%20City%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1206</key>
+		<dict>
+			<key>Track ID</key><integer>1206</integer>
+			<key>Name</key><string>Halcyon and On and On [Live]</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Album</key><string>In Sides [2-CD] [U.S. Release #2] (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8390742</integer>
+			<key>Total Time</key><integer>523389</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253771504</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:25:04Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862CC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/In%20Sides%20%5B2-CD%5D%20%5BU.S.%20Release%20%232%5D%20(2%20of%202)/05%20Halcyon%20and%20On%20and%20On%20%5BLive%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1207</key>
+		<dict>
+			<key>Track ID</key><integer>1207</integer>
+			<key>Name</key><string>Way Out</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>62033268</integer>
+			<key>Total Time</key><integer>480973</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-10-19T20:28:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>1031</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249295818</integer>
+			<key>Play Date UTC</key><date>2006-12-18T22:10:18Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T18:32:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B862CE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/01%20Way%20Out.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1208</key>
+		<dict>
+			<key>Track ID</key><integer>1208</integer>
+			<key>Name</key><string>Spare Parts Express</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>78709871</integer>
+			<key>Total Time</key><integer>607560</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-10-01T15:39:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>1035</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252571359</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:02:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B862D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/02%20Spare%20Parts%20Express.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1209</key>
+		<dict>
+			<key>Track ID</key><integer>1209</integer>
+			<key>Name</key><string>Know Where To Run</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>65364100</integer>
+			<key>Total Time</key><integer>582373</integer>
+			<key>Start Time</key><integer>120000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2006-11-12T16:23:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>897</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253535289</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:48:09Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B862D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/03%20Know%20Where%20To%20Run.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1210</key>
+		<dict>
+			<key>Track ID</key><integer>1210</integer>
+			<key>Name</key><string>I Don't Know You People</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>55342465</integer>
+			<key>Total Time</key><integer>467533</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-09-27T12:54:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>946</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250622508</integer>
+			<key>Play Date UTC</key><date>2007-01-03T06:41:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B862D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/04%20I%20Don't%20Know%20You%20People.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1211</key>
+		<dict>
+			<key>Track ID</key><integer>1211</integer>
+			<key>Name</key><string>Otono</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>43645318</integer>
+			<key>Total Time</key><integer>348000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-09-28T00:22:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>1002</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250603819</integer>
+			<key>Play Date UTC</key><date>2007-01-03T01:30:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B862D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/05%20Otono.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1212</key>
+		<dict>
+			<key>Track ID</key><integer>1212</integer>
+			<key>Name</key><string>Nothing Left 2</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>60938295</integer>
+			<key>Total Time</key><integer>501426</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-10-06T00:22:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>971</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252479584</integer>
+			<key>Play Date UTC</key><date>2007-01-24T18:33:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B862D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/07%20Nothing%20Left%202.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1213</key>
+		<dict>
+			<key>Track ID</key><integer>1213</integer>
+			<key>Name</key><string>Style</string>
+			<key>Artist</key><string>Orbital</string>
+			<key>Composer</key><string>Hartnoll</string>
+			<key>Album</key><string>The Middle Of Nowhere</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>44306667</integer>
+			<key>Total Time</key><integer>384466</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1999</integer>
+			<key>Date Modified</key><date>2005-09-27T12:39:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>921</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B862DB</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Orbital/The%20Middle%20Of%20Nowhere/08%20Style.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1214</key>
+		<dict>
+			<key>Track ID</key><integer>1214</integer>
+			<key>Name</key><string>Overture/Going Through the Motions</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2131783</integer>
+			<key>Total Time</key><integer>176613</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862DD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/01%20Overture_Going%20Through%20the%20Motions.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1215</key>
+		<dict>
+			<key>Track ID</key><integer>1215</integer>
+			<key>Name</key><string>I've Got a Theory/Bunnies/If We're Together</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1712674</integer>
+			<key>Total Time</key><integer>141688</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253604694</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:04:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862E0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/02%20I've%20Got%20a%20Theory_Bunnies_If%20We're%20Together.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1216</key>
+		<dict>
+			<key>Track ID</key><integer>1216</integer>
+			<key>Name</key><string>The Mustard</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>244070</integer>
+			<key>Total Time</key><integer>19304</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250581081</integer>
+			<key>Play Date UTC</key><date>2007-01-02T19:11:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862E2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/03%20The%20Mustard.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1217</key>
+		<dict>
+			<key>Track ID</key><integer>1217</integer>
+			<key>Name</key><string>Under Your Spell</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2109526</integer>
+			<key>Total Time</key><integer>174759</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247036552</integer>
+			<key>Play Date UTC</key><date>2006-11-22T18:35:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T21:39:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862E4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/04%20Under%20Your%20Spell.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1218</key>
+		<dict>
+			<key>Track ID</key><integer>1218</integer>
+			<key>Name</key><string>I'll Never Tell</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2903231</integer>
+			<key>Total Time</key><integer>240901</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253334762</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:06:02Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:51:05Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862E6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/05%20I'll%20Never%20Tell.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1219</key>
+		<dict>
+			<key>Track ID</key><integer>1219</integer>
+			<key>Name</key><string>The Parking Ticket</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>551270</integer>
+			<key>Total Time</key><integer>44904</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252519873</integer>
+			<key>Play Date UTC</key><date>2007-01-25T05:44:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862E8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/06%20The%20Parking%20Ticket.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1220</key>
+		<dict>
+			<key>Track ID</key><integer>1220</integer>
+			<key>Name</key><string>Rest in Peace</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1997618</integer>
+			<key>Total Time</key><integer>165433</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250589789</integer>
+			<key>Play Date UTC</key><date>2007-01-02T21:36:29Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-09T21:12:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862EA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/07%20Rest%20in%20Peace.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1221</key>
+		<dict>
+			<key>Track ID</key><integer>1221</integer>
+			<key>Name</key><string>Dawn's Lament</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>960974</integer>
+			<key>Total Time</key><integer>79046</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253607952</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:59:12Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862EC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/08%20Dawn's%20Lament.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1222</key>
+		<dict>
+			<key>Track ID</key><integer>1222</integer>
+			<key>Name</key><string>Dawn's Ballet</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>880726</integer>
+			<key>Total Time</key><integer>72359</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250703547</integer>
+			<key>Play Date UTC</key><date>2007-01-04T05:12:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/09%20Dawn's%20Ballet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1223</key>
+		<dict>
+			<key>Track ID</key><integer>1223</integer>
+			<key>Name</key><string>What You Feel</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2183192</integer>
+			<key>Total Time</key><integer>180897</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252509147</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:45:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/10%20What%20You%20Feel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1224</key>
+		<dict>
+			<key>Track ID</key><integer>1224</integer>
+			<key>Name</key><string>Standing</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1579763</integer>
+			<key>Total Time</key><integer>130612</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253461808</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:23:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862F2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/11%20Standing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1225</key>
+		<dict>
+			<key>Track ID</key><integer>1225</integer>
+			<key>Name</key><string>Under Your Spell/Standing (Reprise)</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1146235</integer>
+			<key>Total Time</key><integer>94484</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862F4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/12%20Under%20Your%20Spell_Standing%20(Reprise).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1226</key>
+		<dict>
+			<key>Track ID</key><integer>1226</integer>
+			<key>Name</key><string>Walk Through the Fire</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2698222</integer>
+			<key>Total Time</key><integer>223817</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252440325</integer>
+			<key>Play Date UTC</key><date>2007-01-24T07:38:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862F6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/13%20Walk%20Through%20the%20Fire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1227</key>
+		<dict>
+			<key>Track ID</key><integer>1227</integer>
+			<key>Name</key><string>Something to Sing About</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3373435</integer>
+			<key>Total Time</key><integer>280084</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251522050</integer>
+			<key>Play Date UTC</key><date>2007-01-13T16:34:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/14%20Something%20to%20Sing%20About.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1228</key>
+		<dict>
+			<key>Track ID</key><integer>1228</integer>
+			<key>Name</key><string>What You Feel (Reprise)</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>557539</integer>
+			<key>Total Time</key><integer>45426</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253622889</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:08:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862FA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/15%20What%20You%20Feel%20(Reprise).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1229</key>
+		<dict>
+			<key>Track ID</key><integer>1229</integer>
+			<key>Name</key><string>Where Do We Go From Here?</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1360648</integer>
+			<key>Total Time</key><integer>112352</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252503124</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:05:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862FC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/16%20Where%20Do%20We%20Go%20From%20Here_.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1230</key>
+		<dict>
+			<key>Track ID</key><integer>1230</integer>
+			<key>Name</key><string>Coda</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>506444</integer>
+			<key>Total Time</key><integer>41168</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253376764</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:46:04Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-15T00:35:12Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B862FE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/17%20Coda.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1231</key>
+		<dict>
+			<key>Track ID</key><integer>1231</integer>
+			<key>Name</key><string>End Credits: Broom Dance/Grr Argh</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>418986</integer>
+			<key>Total Time</key><integer>33880</integer>
+			<key>Track Number</key><integer>18</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253346148</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:15:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86300</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/18%20End%20Credits_%20Broom%20Dance_Grr%20Argh.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1232</key>
+		<dict>
+			<key>Track ID</key><integer>1232</integer>
+			<key>Name</key><string>Main Title</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>324005</integer>
+			<key>Total Time</key><integer>25965</integer>
+			<key>Track Number</key><integer>19</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86302</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/19%20Main%20Title.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1233</key>
+		<dict>
+			<key>Track ID</key><integer>1233</integer>
+			<key>Name</key><string>Suite From "Restless": Willow's Nightmare/First Rage/Chain of Ancients</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3665588</integer>
+			<key>Total Time</key><integer>304431</integer>
+			<key>Track Number</key><integer>20</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252488167</integer>
+			<key>Play Date UTC</key><date>2007-01-24T20:56:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86304</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/20%20Suite%20From%20_Restless__%20Willow's%20Nightmare_First%20Rage_Chain%20of%20Ancients.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1234</key>
+		<dict>
+			<key>Track ID</key><integer>1234</integer>
+			<key>Name</key><string>Suite From "Hush": Silent Night/First Kiss/Enter the Gentlemen/Schism</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5002222</integer>
+			<key>Total Time</key><integer>415817</integer>
+			<key>Track Number</key><integer>21</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247247557</integer>
+			<key>Play Date UTC</key><date>2006-11-25T05:12:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86306</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/21%20Suite%20From%20_Hush__%20Silent%20Night_First%20Kiss_Enter%20the%20Gentlemen_Schism.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1235</key>
+		<dict>
+			<key>Track ID</key><integer>1235</integer>
+			<key>Name</key><string>Sacrifice {From "The Gift"}</string>
+			<key>Artist</key><string>Original Television Soundtrack</string>
+			<key>Album</key><string>Buffy the Vampire Slayer: Once More With Feeling [Musical Episode Soundtrack]</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2144635</integer>
+			<key>Total Time</key><integer>177684</integer>
+			<key>Track Number</key><integer>22</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86308</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Original%20Television%20Soundtrack/Buffy%20the%20Vampire%20Slayer_%20Once%20More%20With%20Feeling%20%5BMusical%20Episode%20Soundtrack%5D/22%20Sacrifice%20%7BFrom%20_The%20Gift_%7D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1236</key>
+		<dict>
+			<key>Track ID</key><integer>1236</integer>
+			<key>Name</key><string>Boom (The Crystal Method Remix)</string>
+			<key>Artist</key><string>P.O.D.</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>P.O.D.</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5104940</integer>
+			<key>Total Time</key><integer>211879</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253084178</integer>
+			<key>Play Date UTC</key><date>2007-01-31T18:29:38Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B8630A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/P.O.D_/Community%20Service/09%20Boom%20(The%20Crystal%20Method%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1237</key>
+		<dict>
+			<key>Track ID</key><integer>1237</integer>
+			<key>Name</key><string>Hunkie Tunkie Blues</string>
+			<key>Artist</key><string>Paul Rishell &#38; Annie Raines</string>
+			<key>Album Artist</key><string>Paul Rishell/Annie Raines</string>
+			<key>Composer</key><string>Charlie Jordan/Raines/Rishell</string>
+			<key>Album</key><string>Goin' Home</string>
+			<key>Genre</key><string>Blues</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4219008</integer>
+			<key>Total Time</key><integer>210834</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T20:35:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B8630C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Rishell%20&#38;%20Annie%20Raines/Goin'%20Home/01%20Hunkie%20Tunkie%20Blues.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1238</key>
+		<dict>
+			<key>Track ID</key><integer>1238</integer>
+			<key>Name</key><string>Crush</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11212918</integer>
+			<key>Total Time</key><integer>466520</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252551942</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:39:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8630F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/01%20Crush.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1239</key>
+		<dict>
+			<key>Track ID</key><integer>1239</integer>
+			<key>Name</key><string>Times Of Our Lives</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6349053</integer>
+			<key>Total Time</key><integer>263183</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252410984</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:29:44Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B86312</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/02%20Times%20Of%20Our%20Lives.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1240</key>
+		<dict>
+			<key>Track ID</key><integer>1240</integer>
+			<key>Name</key><string>Like A Friend</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5640069</integer>
+			<key>Total Time</key><integer>234318</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253084412</integer>
+			<key>Play Date UTC</key><date>2007-01-31T18:33:32Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86314</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/03%20Like%20A%20Friend.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1241</key>
+		<dict>
+			<key>Track ID</key><integer>1241</integer>
+			<key>Name</key><string>Reflections</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10752126</integer>
+			<key>Total Time</key><integer>447320</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252940290</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:31:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86316</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/04%20Reflections.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1242</key>
+		<dict>
+			<key>Track ID</key><integer>1242</integer>
+			<key>Name</key><string>Nothing But You</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10032404</integer>
+			<key>Total Time</key><integer>417332</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247722657</integer>
+			<key>Play Date UTC</key><date>2006-11-30T17:10:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86318</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/05%20Nothing%20But%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1243</key>
+		<dict>
+			<key>Track ID</key><integer>1243</integer>
+			<key>Name</key><string>Buenaventura</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12217909</integer>
+			<key>Total Time</key><integer>508395</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250666124</integer>
+			<key>Play Date UTC</key><date>2007-01-03T18:48:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8631A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/06%20Buenaventura.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1244</key>
+		<dict>
+			<key>Track ID</key><integer>1244</integer>
+			<key>Name</key><string>Homage</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5414991</integer>
+			<key>Total Time</key><integer>224940</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253255892</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:11:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8631C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/07%20Homage.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1245</key>
+		<dict>
+			<key>Track ID</key><integer>1245</integer>
+			<key>Name</key><string>Never Forget</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7851908</integer>
+			<key>Total Time</key><integer>326478</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253355146</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:45:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8631E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/08%20Never%20Forget.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1246</key>
+		<dict>
+			<key>Track ID</key><integer>1246</integer>
+			<key>Name</key><string>Knowledge</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5861374</integer>
+			<key>Total Time</key><integer>243539</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246108376</integer>
+			<key>Play Date UTC</key><date>2006-11-12T00:46:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86320</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/09%20Knowledge.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1247</key>
+		<dict>
+			<key>Track ID</key><integer>1247</integer>
+			<key>Name</key><string>That's Life</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5905263</integer>
+			<key>Total Time</key><integer>245368</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253527453</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:37:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86322</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/10%20That's%20Life.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1248</key>
+		<dict>
+			<key>Track ID</key><integer>1248</integer>
+			<key>Name</key><string>Connected</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9513920</integer>
+			<key>Total Time</key><integer>395728</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253550524</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:02:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86324</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/11%20Connected.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1249</key>
+		<dict>
+			<key>Track ID</key><integer>1249</integer>
+			<key>Name</key><string>Spellbound</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6803039</integer>
+			<key>Total Time</key><integer>282775</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253084695</integer>
+			<key>Play Date UTC</key><date>2007-01-31T18:38:15Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:43:05Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86326</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/12%20Spellbound.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1250</key>
+		<dict>
+			<key>Track ID</key><integer>1250</integer>
+			<key>Name</key><string>Kaleidoscope</string>
+			<key>Artist</key><string>Paul Van Dyk</string>
+			<key>Album</key><string>Reflections</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7020588</integer>
+			<key>Total Time</key><integer>291840</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:39:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252487001</integer>
+			<key>Play Date UTC</key><date>2007-01-24T20:36:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86328</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Paul%20Van%20Dyk/Reflections/13%20Kaleidoscope.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1251</key>
+		<dict>
+			<key>Track ID</key><integer>1251</integer>
+			<key>Name</key><string>Come Talk To Me</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5975649</integer>
+			<key>Total Time</key><integer>373342</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249552434</integer>
+			<key>Play Date UTC</key><date>2006-12-21T21:27:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B8632A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/01%20Come%20Talk%20To%20Me.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1252</key>
+		<dict>
+			<key>Track ID</key><integer>1252</integer>
+			<key>Name</key><string>Steam</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7407577</integer>
+			<key>Total Time</key><integer>462837</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253457079</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:04:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8632D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/02%20Steam.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1253</key>
+		<dict>
+			<key>Track ID</key><integer>1253</integer>
+			<key>Name</key><string>Across The River</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5708573</integer>
+			<key>Total Time</key><integer>356649</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253451031</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:23:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B8632F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/03%20Across%20The%20River.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1254</key>
+		<dict>
+			<key>Track ID</key><integer>1254</integer>
+			<key>Name</key><string>Slow Marimbas</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1696165</integer>
+			<key>Total Time</key><integer>105874</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86331</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/04%20Slow%20Marimbas.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1255</key>
+		<dict>
+			<key>Track ID</key><integer>1255</integer>
+			<key>Name</key><string>Shaking The Tree</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8936889</integer>
+			<key>Total Time</key><integer>558419</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253603856</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:50:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B86333</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/05%20Shaking%20The%20Tree.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1256</key>
+		<dict>
+			<key>Track ID</key><integer>1256</integer>
+			<key>Name</key><string>Red Rain</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6000726</integer>
+			<key>Total Time</key><integer>374909</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252490964</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:42:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B86335</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/06%20Red%20Rain.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1257</key>
+		<dict>
+			<key>Track ID</key><integer>1257</integer>
+			<key>Name</key><string>Blood Of Eden</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6682418</integer>
+			<key>Total Time</key><integer>417515</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246375131</integer>
+			<key>Play Date UTC</key><date>2006-11-15T02:52:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B86337</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/07%20Blood%20Of%20Eden.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1258</key>
+		<dict>
+			<key>Track ID</key><integer>1258</integer>
+			<key>Name</key><string>Washing Of The Water</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3953144</integer>
+			<key>Total Time</key><integer>246935</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247741585</integer>
+			<key>Play Date UTC</key><date>2006-11-30T22:26:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B86339</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/09%20Washing%20Of%20The%20Water.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1259</key>
+		<dict>
+			<key>Track ID</key><integer>1259</integer>
+			<key>Name</key><string>Solsbury Hill</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 1)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4541213</integer>
+			<key>Total Time</key><integer>283689</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253684569</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:16:09Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8633B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%201)/10%20Solsbury%20Hill.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1260</key>
+		<dict>
+			<key>Track ID</key><integer>1260</integer>
+			<key>Name</key><string>Digging in the Dirt</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 2)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7301415</integer>
+			<key>Total Time</key><integer>456202</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>33</integer>
+			<key>Play Date</key><integer>3253713354</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:15:54Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B8633D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%202)/01%20Digging%20in%20the%20Dirt.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1261</key>
+		<dict>
+			<key>Track ID</key><integer>1261</integer>
+			<key>Name</key><string>Sledgehammer</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 2)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4789480</integer>
+			<key>Total Time</key><integer>299206</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253684285</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:11:25Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T19:26:26Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86340</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%202)/02%20Sledgehammer.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1262</key>
+		<dict>
+			<key>Track ID</key><integer>1262</integer>
+			<key>Name</key><string>Secret World</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 2)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8821533</integer>
+			<key>Total Time</key><integer>551209</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253506174</integer>
+			<key>Play Date UTC</key><date>2007-02-05T15:42:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B86342</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%202)/03%20Secret%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1263</key>
+		<dict>
+			<key>Track ID</key><integer>1263</integer>
+			<key>Name</key><string>Don't Give Up</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 2)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7283861</integer>
+			<key>Total Time</key><integer>455105</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247638660</integer>
+			<key>Play Date UTC</key><date>2006-11-29T17:51:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B86344</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%202)/04%20Don't%20Give%20Up.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1264</key>
+		<dict>
+			<key>Track ID</key><integer>1264</integer>
+			<key>Name</key><string>In Your Eyes</string>
+			<key>Artist</key><string>Peter Gabriel</string>
+			<key>Album</key><string>Secret World Live (Disc 2)</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11113621</integer>
+			<key>Total Time</key><integer>694465</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246429099</integer>
+			<key>Play Date UTC</key><date>2006-11-15T17:51:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B86346</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Peter%20Gabriel/Secret%20World%20Live%20(Disc%202)/05%20In%20Your%20Eyes.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1265</key>
+		<dict>
+			<key>Track ID</key><integer>1265</integer>
+			<key>Name</key><string>Fat Old Sun</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Atom Heart Mother</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7651375</integer>
+			<key>Total Time</key><integer>318040</integer>
+			<key>Year</key><integer>1970</integer>
+			<key>Date Modified</key><date>2004-11-29T13:44:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253282493</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:34:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86348</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Atom%20Heart%20Mother/Fat%20Old%20Sun.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1266</key>
+		<dict>
+			<key>Track ID</key><integer>1266</integer>
+			<key>Name</key><string>Speak to Me/Breathe in the Air</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3883512</integer>
+			<key>Total Time</key><integer>240535</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246901162</integer>
+			<key>Play Date UTC</key><date>2006-11-21T04:59:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8634B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/01%20Speak%20to%20Me_Breathe%20in%20the%20Air.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1267</key>
+		<dict>
+			<key>Track ID</key><integer>1267</integer>
+			<key>Name</key><string>On the Run</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3439305</integer>
+			<key>Total Time</key><integer>213028</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249535045</integer>
+			<key>Play Date UTC</key><date>2006-12-21T16:37:25Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:46:36Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8634E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/02%20On%20the%20Run.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1268</key>
+		<dict>
+			<key>Track ID</key><integer>1268</integer>
+			<key>Name</key><string>Time</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6877814</integer>
+			<key>Total Time</key><integer>426527</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251637837</integer>
+			<key>Play Date UTC</key><date>2007-01-15T00:43:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86350</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/03%20Time.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1269</key>
+		<dict>
+			<key>Track ID</key><integer>1269</integer>
+			<key>Name</key><string>The Great Gig in the Sky</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4584346</integer>
+			<key>Total Time</key><integer>284081</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251303370</integer>
+			<key>Play Date UTC</key><date>2007-01-11T03:49:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-20T17:46:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86352</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/04%20The%20Great%20Gig%20in%20the%20Sky.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1270</key>
+		<dict>
+			<key>Track ID</key><integer>1270</integer>
+			<key>Name</key><string>Money</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6322011</integer>
+			<key>Total Time</key><integer>392045</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:28:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253277268</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:07:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86354</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/05%20Money.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1271</key>
+		<dict>
+			<key>Track ID</key><integer>1271</integer>
+			<key>Name</key><string>Us and Them</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7429060</integer>
+			<key>Total Time</key><integer>460852</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251888938</integer>
+			<key>Play Date UTC</key><date>2007-01-17T22:28:58Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:06:54Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86356</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/06%20Us%20and%20Them.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1272</key>
+		<dict>
+			<key>Track ID</key><integer>1272</integer>
+			<key>Name</key><string>Any Colour You Like</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3321023</integer>
+			<key>Total Time</key><integer>205635</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:52Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246598715</integer>
+			<key>Play Date UTC</key><date>2006-11-17T16:58:35Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:06:58Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86358</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/07%20Any%20Colour%20You%20Like.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1273</key>
+		<dict>
+			<key>Track ID</key><integer>1273</integer>
+			<key>Name</key><string>Brain Damage</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3721386</integer>
+			<key>Total Time</key><integer>230530</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8635A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/08%20Brain%20Damage.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1274</key>
+		<dict>
+			<key>Track ID</key><integer>1274</integer>
+			<key>Name</key><string>Eclipse</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Dark Side of the Moon</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2012560</integer>
+			<key>Total Time</key><integer>124368</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252990314</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:25:14Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8635C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Dark%20Side%20of%20the%20Moon/09%20Eclipse.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1275</key>
+		<dict>
+			<key>Track ID</key><integer>1275</integer>
+			<key>Name</key><string>Shine On You Crazy Diamond</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>17298577</integer>
+			<key>Total Time</key><integer>713364</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253459099</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:38:19Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8635E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-01%20Shine%20On%20You%20Crazy%20Diamond.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1276</key>
+		<dict>
+			<key>Track ID</key><integer>1276</integer>
+			<key>Name</key><string>Learning To Fly</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7941761</integer>
+			<key>Total Time</key><integer>326974</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253254553</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:49:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86361</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-02%20Learning%20To%20Fly.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1277</key>
+		<dict>
+			<key>Track ID</key><integer>1277</integer>
+			<key>Name</key><string>Yet Another Movie</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9258043</integer>
+			<key>Total Time</key><integer>381332</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253339706</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:28:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86363</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-03%20Yet%20Another%20Movie.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1278</key>
+		<dict>
+			<key>Track ID</key><integer>1278</integer>
+			<key>Name</key><string>Round And Around</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>855365</integer>
+			<key>Total Time</key><integer>33428</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246441280</integer>
+			<key>Play Date UTC</key><date>2006-11-15T21:14:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86365</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-04%20Round%20And%20Around.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1279</key>
+		<dict>
+			<key>Track ID</key><integer>1279</integer>
+			<key>Name</key><string>Sorrow</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13792301</integer>
+			<key>Total Time</key><integer>568574</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246877169</integer>
+			<key>Play Date UTC</key><date>2006-11-20T22:19:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86367</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-05%20Sorrow.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1280</key>
+		<dict>
+			<key>Track ID</key><integer>1280</integer>
+			<key>Name</key><string>The Dogs Of War</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10639552</integer>
+			<key>Total Time</key><integer>438377</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253593673</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:01:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86369</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-06%20The%20Dogs%20Of%20War.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1281</key>
+		<dict>
+			<key>Track ID</key><integer>1281</integer>
+			<key>Name</key><string>On The Turning Away</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Pink Floyd</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11620814</integer>
+			<key>Total Time</key><integer>478910</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>7</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249566629</integer>
+			<key>Play Date UTC</key><date>2006-12-22T01:23:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8636B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%201)/1-07%20On%20The%20Turning%20Away.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1282</key>
+		<dict>
+			<key>Track ID</key><integer>1282</integer>
+			<key>Name</key><string>One Of These Days</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Nick Mason &#38; David Gilmour &#38; Roger Waters &#38; Richard Wright</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9127395</integer>
+			<key>Total Time</key><integer>375934</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247503043</integer>
+			<key>Play Date UTC</key><date>2006-11-28T04:10:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8636D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-01%20One%20Of%20These%20Days.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1283</key>
+		<dict>
+			<key>Track ID</key><integer>1283</integer>
+			<key>Name</key><string>Time</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Nick Mason &#38; Roger Waters &#38; Richard Wright &#38; David Gilmour</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7687856</integer>
+			<key>Total Time</key><integer>316478</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253367199</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:06:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86370</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-02%20Time.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1284</key>
+		<dict>
+			<key>Track ID</key><integer>1284</integer>
+			<key>Name</key><string>Wish You Where Here</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters &#38; David Gilmour</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7025309</integer>
+			<key>Total Time</key><integer>289129</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253555307</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:21:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86372</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-03%20Wish%20You%20Where%20Here.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1285</key>
+		<dict>
+			<key>Track ID</key><integer>1285</integer>
+			<key>Name</key><string>Us And Them</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters &#38; Richard Wright</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10727453</integer>
+			<key>Total Time</key><integer>442004</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253370127</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:55:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86374</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-04%20Us%20And%20Them.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1286</key>
+		<dict>
+			<key>Track ID</key><integer>1286</integer>
+			<key>Name</key><string>Money</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>14361813</integer>
+			<key>Total Time</key><integer>592105</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253552229</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:30:29Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T15:53:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86376</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-05%20Money.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1287</key>
+		<dict>
+			<key>Track ID</key><integer>1287</integer>
+			<key>Name</key><string>Another Brick In The Wall</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7989055</integer>
+			<key>Total Time</key><integer>328937</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253382657</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:24:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86378</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-06%20Another%20Brick%20In%20The%20Wall.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1288</key>
+		<dict>
+			<key>Track ID</key><integer>1288</integer>
+			<key>Name</key><string>Comfortably Numb</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Roger Waters</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13014874</integer>
+			<key>Total Time</key><integer>536468</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253538463</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:41:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8637A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-07%20Comfortably%20Numb.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1289</key>
+		<dict>
+			<key>Track ID</key><integer>1289</integer>
+			<key>Name</key><string>Run Like Hell</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Roger Waters</string>
+			<key>Album</key><string>Delicate Sound Of Thunder (Disc 2) [Live]</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10500557</integer>
+			<key>Total Time</key><integer>432638</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-25T15:12:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253552662</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:37:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8637C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Delicate%20Sound%20Of%20Thunder%20(Disc%202)%20%5BLive%5D/2-08%20Run%20Like%20Hell.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1290</key>
+		<dict>
+			<key>Track ID</key><integer>1290</integer>
+			<key>Name</key><string>Obscured by Clouds</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4503840</integer>
+			<key>Total Time</key><integer>184510</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253596591</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:49:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8637E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/01%20Obscured%20by%20Clouds.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1291</key>
+		<dict>
+			<key>Track ID</key><integer>1291</integer>
+			<key>Name</key><string>When You're In</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3688671</integer>
+			<key>Total Time</key><integer>150569</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253690424</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:53:44Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:37Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86381</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/02%20When%20You're%20In.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1292</key>
+		<dict>
+			<key>Track ID</key><integer>1292</integer>
+			<key>Name</key><string>Burning Bridges</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5100991</integer>
+			<key>Total Time</key><integer>209364</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250595160</integer>
+			<key>Play Date UTC</key><date>2007-01-02T23:06:00Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-13T00:23:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86383</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/03%20Burning%20Bridges.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1293</key>
+		<dict>
+			<key>Track ID</key><integer>1293</integer>
+			<key>Name</key><string>The Gold It's In The . . .</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4563889</integer>
+			<key>Total Time</key><integer>187006</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253474578</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:56:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86385</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/04%20The%20Gold%20It's%20In%20The%20.%20.%20..m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1294</key>
+		<dict>
+			<key>Track ID</key><integer>1294</integer>
+			<key>Name</key><string>Wot's . . . Uh The Deal</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7480007</integer>
+			<key>Total Time</key><integer>307902</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247037468</integer>
+			<key>Play Date UTC</key><date>2006-11-22T18:51:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86387</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/05%20Wot's%20.%20.%20.%20Uh%20The%20Deal.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1295</key>
+		<dict>
+			<key>Track ID</key><integer>1295</integer>
+			<key>Name</key><string>Mudmen</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6323260</integer>
+			<key>Total Time</key><integer>260137</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252034116</integer>
+			<key>Play Date UTC</key><date>2007-01-19T14:48:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86389</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/06%20Mudmen.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1296</key>
+		<dict>
+			<key>Track ID</key><integer>1296</integer>
+			<key>Name</key><string>Childhood's End</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6611526</integer>
+			<key>Total Time</key><integer>272041</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246898241</integer>
+			<key>Play Date UTC</key><date>2006-11-21T04:10:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8638B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/07%20Childhood's%20End.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1297</key>
+		<dict>
+			<key>Track ID</key><integer>1297</integer>
+			<key>Name</key><string>Free Four</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6198220</integer>
+			<key>Total Time</key><integer>254974</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253464511</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:08:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8638D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/08%20Free%20Four.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1298</key>
+		<dict>
+			<key>Track ID</key><integer>1298</integer>
+			<key>Name</key><string>Stay</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5970538</integer>
+			<key>Total Time</key><integer>245566</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253549221</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:40:21Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T22:17:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8638F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/09%20Stay.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1299</key>
+		<dict>
+			<key>Track ID</key><integer>1299</integer>
+			<key>Name</key><string>Absolutely Curtains</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>Obscured by Clouds</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8535663</integer>
+			<key>Total Time</key><integer>351508</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1972</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246629792</integer>
+			<key>Play Date UTC</key><date>2006-11-18T01:36:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86391</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/Obscured%20by%20Clouds/10%20Absolutely%20Curtains.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1300</key>
+		<dict>
+			<key>Track ID</key><integer>1300</integer>
+			<key>Name</key><string>Cluster One</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Richard Wright &#38; David Gilmour</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8720677</integer>
+			<key>Total Time</key><integer>358334</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250586332</integer>
+			<key>Play Date UTC</key><date>2007-01-02T20:38:52Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B86393</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/01%20Cluster%20One.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1301</key>
+		<dict>
+			<key>Track ID</key><integer>1301</integer>
+			<key>Name</key><string>What Do You Want From Me</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Richard Wright &#38; Polly Samson</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6378150</integer>
+			<key>Total Time</key><integer>261609</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251464469</integer>
+			<key>Play Date UTC</key><date>2007-01-13T00:34:29Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B86396</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/02%20What%20Do%20You%20Want%20From%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1302</key>
+		<dict>
+			<key>Track ID</key><integer>1302</integer>
+			<key>Name</key><string>Poles Apart</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Polly Samson &#38; Nick Laird-Clowes</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10311617</integer>
+			<key>Total Time</key><integer>424041</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253475432</integer>
+			<key>Play Date UTC</key><date>2007-02-05T07:10:32Z</date>
+			<key>Artwork Count</key><integer>2</integer>
+			<key>Persistent ID</key><string>87139F8602B86398</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/03%20Poles%20Apart.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1303</key>
+		<dict>
+			<key>Track ID</key><integer>1303</integer>
+			<key>Name</key><string>Marooned</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Richard Wright &#38; David Gilmour</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8004779</integer>
+			<key>Total Time</key><integer>329577</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252544407</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:33:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8639A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/04%20Marooned.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1304</key>
+		<dict>
+			<key>Track ID</key><integer>1304</integer>
+			<key>Name</key><string>A Great Day For Freedom</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Polly Samson</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6261845</integer>
+			<key>Total Time</key><integer>257598</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252505813</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:50:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8639C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/05%20A%20Great%20Day%20For%20Freedom.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1305</key>
+		<dict>
+			<key>Track ID</key><integer>1305</integer>
+			<key>Name</key><string>Wearing The Inside Out</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Richard Wright &#38; Anthony Moore</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9939620</integer>
+			<key>Total Time</key><integer>409470</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252579429</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:17:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8639E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/06%20Wearing%20The%20Inside%20Out.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1306</key>
+		<dict>
+			<key>Track ID</key><integer>1306</integer>
+			<key>Name</key><string>Take It Back</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Bob Ezrin</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9041061</integer>
+			<key>Total Time</key><integer>372372</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252563247</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:47:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863A0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/07%20Take%20It%20Back.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1307</key>
+		<dict>
+			<key>Track ID</key><integer>1307</integer>
+			<key>Name</key><string>Coming Back To Life</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9211025</integer>
+			<key>Total Time</key><integer>379390</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:13:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249458944</integer>
+			<key>Play Date UTC</key><date>2006-12-20T19:29:04Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-20T20:23:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/08%20Coming%20Back%20To%20Life.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1308</key>
+		<dict>
+			<key>Track ID</key><integer>1308</integer>
+			<key>Name</key><string>Keep Talking</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Richard Wright &#38; Polly Samson</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9009707</integer>
+			<key>Total Time</key><integer>371070</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250573664</integer>
+			<key>Play Date UTC</key><date>2007-01-02T17:07:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/09%20Keep%20Talking.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1309</key>
+		<dict>
+			<key>Track ID</key><integer>1309</integer>
+			<key>Name</key><string>Lost For Words</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Polly Samson</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7649511</integer>
+			<key>Total Time</key><integer>314900</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249207817</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:43:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/10%20Lost%20For%20Words.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1310</key>
+		<dict>
+			<key>Track ID</key><integer>1310</integer>
+			<key>Name</key><string>High Hopes</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour &#38; Polly Samson</string>
+			<key>Album</key><string>The Division Bell</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>12424828</integer>
+			<key>Total Time</key><integer>512297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251482960</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:42:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Division%20Bell/11%20High%20Hopes.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1311</key>
+		<dict>
+			<key>Track ID</key><integer>1311</integer>
+			<key>Name</key><string>The hero's return</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>The Final Cut</string>
+			<key>Genre</key><string>Progressive</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5697547</integer>
+			<key>Total Time</key><integer>177554</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1983</integer>
+			<key>Date Modified</key><date>2004-11-29T13:42:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253595621</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:33:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Final%20Cut/04%20The%20hero's%20return.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1312</key>
+		<dict>
+			<key>Track ID</key><integer>1312</integer>
+			<key>Name</key><string>The gunners dream</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>The Final Cut</string>
+			<key>Genre</key><string>Progressive</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9750915</integer>
+			<key>Total Time</key><integer>304222</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1983</integer>
+			<key>Date Modified</key><date>2004-11-29T13:42:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252542677</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:04:37Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-05T19:11:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863AD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Final%20Cut/05%20The%20gunners%20dream.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1313</key>
+		<dict>
+			<key>Track ID</key><integer>1313</integer>
+			<key>Name</key><string>Paranoid eyes</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>The Final Cut</string>
+			<key>Genre</key><string>Progressive</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7356005</integer>
+			<key>Total Time</key><integer>229381</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1983</integer>
+			<key>Date Modified</key><date>2004-11-29T13:43:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252557413</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:10:13Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T16:45:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863AF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Final%20Cut/06%20Paranoid%20eyes.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1314</key>
+		<dict>
+			<key>Track ID</key><integer>1314</integer>
+			<key>Name</key><string>Not Now John</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Album</key><string>The Final Cut</string>
+			<key>Genre</key><string>Progressive</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9702428</integer>
+			<key>Total Time</key><integer>302706</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1983</integer>
+			<key>Date Modified</key><date>2004-11-29T13:44:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247821533</integer>
+			<key>Play Date UTC</key><date>2006-12-01T20:38:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:22:28Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863B1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Final%20Cut/11%20Not%20Now%20John.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1315</key>
+		<dict>
+			<key>Track ID</key><integer>1315</integer>
+			<key>Name</key><string>In The Flesh?</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4857068</integer>
+			<key>Total Time</key><integer>199529</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251465226</integer>
+			<key>Play Date UTC</key><date>2007-01-13T00:47:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863B3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-01%20In%20The%20Flesh_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1316</key>
+		<dict>
+			<key>Track ID</key><integer>1316</integer>
+			<key>Name</key><string>The Thin Ice</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3652212</integer>
+			<key>Total Time</key><integer>149865</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863B6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-02%20The%20Thin%20Ice.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1317</key>
+		<dict>
+			<key>Track ID</key><integer>1317</integer>
+			<key>Name</key><string>Another Brick In The Wall (Part 1)</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4646266</integer>
+			<key>Total Time</key><integer>190761</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252495004</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:50:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863B8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-03%20Another%20Brick%20In%20The%20Wall%20(Part%201).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1318</key>
+		<dict>
+			<key>Track ID</key><integer>1318</integer>
+			<key>Name</key><string>The Happiest Days Of Our Lives</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2720582</integer>
+			<key>Total Time</key><integer>111060</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246470098</integer>
+			<key>Play Date UTC</key><date>2006-11-16T05:14:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863BA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-04%20The%20Happiest%20Days%20Of%20Our%20Lives.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1319</key>
+		<dict>
+			<key>Track ID</key><integer>1319</integer>
+			<key>Name</key><string>Another Brick In The Wall (Part 2)</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5846025</integer>
+			<key>Total Time</key><integer>240702</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252390495</integer>
+			<key>Play Date UTC</key><date>2007-01-23T17:48:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863BC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-05%20Another%20Brick%20In%20The%20Wall%20(Part%202).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1320</key>
+		<dict>
+			<key>Track ID</key><integer>1320</integer>
+			<key>Name</key><string>Mother</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8032893</integer>
+			<key>Total Time</key><integer>333673</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253508629</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:23:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863BE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-06%20Mother.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1321</key>
+		<dict>
+			<key>Track ID</key><integer>1321</integer>
+			<key>Name</key><string>Goodbye Blue Sky</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4133289</integer>
+			<key>Total Time</key><integer>169897</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252290257</integer>
+			<key>Play Date UTC</key><date>2007-01-22T13:57:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863C0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-07%20Goodbye%20Blue%20Sky.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1322</key>
+		<dict>
+			<key>Track ID</key><integer>1322</integer>
+			<key>Name</key><string>Empty Spaces</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3106013</integer>
+			<key>Total Time</key><integer>127124</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252559685</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:48:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863C2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-08%20Empty%20Spaces.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1323</key>
+		<dict>
+			<key>Track ID</key><integer>1323</integer>
+			<key>Name</key><string>Young Lust</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5181209</integer>
+			<key>Total Time</key><integer>213033</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251485155</integer>
+			<key>Play Date UTC</key><date>2007-01-13T06:19:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863C4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-09%20Young%20Lust.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1324</key>
+		<dict>
+			<key>Track ID</key><integer>1324</integer>
+			<key>Name</key><string>One Of My Turns</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5220664</integer>
+			<key>Total Time</key><integer>214676</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252930367</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:46:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863C6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-10%20One%20Of%20My%20Turns.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1325</key>
+		<dict>
+			<key>Track ID</key><integer>1325</integer>
+			<key>Name</key><string>Don't Leave Me Now</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6231939</integer>
+			<key>Total Time</key><integer>256724</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253257378</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:36:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863C8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-11%20Don't%20Leave%20Me%20Now.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1326</key>
+		<dict>
+			<key>Track ID</key><integer>1326</integer>
+			<key>Name</key><string>Another Brick In The Wall (Part 3)</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1914047</integer>
+			<key>Total Time</key><integer>77502</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252501224</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:33:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863CA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-12%20Another%20Brick%20In%20The%20Wall%20(Part%203).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1327</key>
+		<dict>
+			<key>Track ID</key><integer>1327</integer>
+			<key>Name</key><string>Goodbye Cruel World</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 1)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1842679</integer>
+			<key>Total Time</key><integer>74601</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252414016</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:20:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863CC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%201)/1-13%20Goodbye%20Cruel%20World.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1328</key>
+		<dict>
+			<key>Track ID</key><integer>1328</integer>
+			<key>Name</key><string>Hey You</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Bob Ezrin/Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6828584</integer>
+			<key>Total Time</key><integer>281321</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250684523</integer>
+			<key>Play Date UTC</key><date>2007-01-03T23:55:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863CE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-01%20Hey%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1329</key>
+		<dict>
+			<key>Track ID</key><integer>1329</integer>
+			<key>Name</key><string>Is There Anybody Out There?</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4322707</integer>
+			<key>Total Time</key><integer>177769</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252482160</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:16:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-02%20Is%20There%20Anybody%20Out%20There_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1330</key>
+		<dict>
+			<key>Track ID</key><integer>1330</integer>
+			<key>Name</key><string>Nobody Home</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4670299</integer>
+			<key>Total Time</key><integer>191764</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253554644</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:10:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-03%20Nobody%20Home.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1331</key>
+		<dict>
+			<key>Track ID</key><integer>1331</integer>
+			<key>Name</key><string>Vera</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2201762</integer>
+			<key>Total Time</key><integer>89470</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247249904</integer>
+			<key>Play Date UTC</key><date>2006-11-25T05:51:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-04%20Vera.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1332</key>
+		<dict>
+			<key>Track ID</key><integer>1332</integer>
+			<key>Name</key><string>Bring The Boys Back Home</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2122290</integer>
+			<key>Total Time</key><integer>86164</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:14:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252506183</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:56:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-05%20Bring%20The%20Boys%20Back%20Home.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1333</key>
+		<dict>
+			<key>Track ID</key><integer>1333</integer>
+			<key>Name</key><string>Comfortably Numb</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9265135</integer>
+			<key>Total Time</key><integer>383934</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253385406</integer>
+			<key>Play Date UTC</key><date>2007-02-04T06:10:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-06%20Comfortably%20Numb.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1334</key>
+		<dict>
+			<key>Track ID</key><integer>1334</integer>
+			<key>Name</key><string>The Show Must Go On</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2386309</integer>
+			<key>Total Time</key><integer>97150</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252485217</integer>
+			<key>Play Date UTC</key><date>2007-01-24T20:06:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863DB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-07%20The%20Show%20Must%20Go%20On.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1335</key>
+		<dict>
+			<key>Track ID</key><integer>1335</integer>
+			<key>Name</key><string>In The Flesh</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6197108</integer>
+			<key>Total Time</key><integer>255252</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863DD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-08%20In%20The%20Flesh.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1336</key>
+		<dict>
+			<key>Track ID</key><integer>1336</integer>
+			<key>Name</key><string>Run Like Hell</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>David Gilmour</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6331484</integer>
+			<key>Total Time</key><integer>260798</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249531144</integer>
+			<key>Play Date UTC</key><date>2006-12-21T15:32:24Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T19:37:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863DF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-09%20Run%20Like%20Hell.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1337</key>
+		<dict>
+			<key>Track ID</key><integer>1337</integer>
+			<key>Name</key><string>Waiting For The Worms</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5867269</integer>
+			<key>Total Time</key><integer>241598</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253615423</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:03:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863E1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-10%20Waiting%20For%20The%20Worms.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1338</key>
+		<dict>
+			<key>Track ID</key><integer>1338</integer>
+			<key>Name</key><string>Stop</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>805419</integer>
+			<key>Total Time</key><integer>31358</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253453673</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:07:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863E3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-11%20Stop.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1339</key>
+		<dict>
+			<key>Track ID</key><integer>1339</integer>
+			<key>Name</key><string>The Trial</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Bob Ezrin</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7744912</integer>
+			<key>Total Time</key><integer>319166</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247663266</integer>
+			<key>Play Date UTC</key><date>2006-11-30T00:41:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863E5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-12%20The%20Trial.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1340</key>
+		<dict>
+			<key>Track ID</key><integer>1340</integer>
+			<key>Name</key><string>Outside The Wall</string>
+			<key>Artist</key><string>Pink Floyd</string>
+			<key>Composer</key><string>Roger Waters</string>
+			<key>Album</key><string>The Wall (Disc 2)</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2564671</integer>
+			<key>Total Time</key><integer>104617</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-07-25T15:15:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:53Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247498558</integer>
+			<key>Play Date UTC</key><date>2006-11-28T02:55:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B863E7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Pink%20Floyd/The%20Wall%20(Disc%202)/2-13%20Outside%20The%20Wall.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1341</key>
+		<dict>
+			<key>Track ID</key><integer>1341</integer>
+			<key>Name</key><string>Angelika Suspended</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4885314</integer>
+			<key>Total Time</key><integer>201193</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:38:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253346114</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:15:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B86441</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-01%20Angelika%20Suspended.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1342</key>
+		<dict>
+			<key>Track ID</key><integer>1342</integer>
+			<key>Name</key><string>Postcard From A Dream</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6292802</integer>
+			<key>Total Time</key><integer>259646</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:39:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253623724</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:22:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B86444</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-02%20Postcard%20From%20A%20Dream.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1343</key>
+		<dict>
+			<key>Track ID</key><integer>1343</integer>
+			<key>Name</key><string>Living With The Dreaming Body</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5796706</integer>
+			<key>Total Time</key><integer>239145</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:40:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249111203</integer>
+			<key>Play Date UTC</key><date>2006-12-16T18:53:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B86446</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-03%20Living%20With%20The%20Dreaming%20Body.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1344</key>
+		<dict>
+			<key>Track ID</key><integer>1344</integer>
+			<key>Name</key><string>Catacombs</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7121349</integer>
+			<key>Total Time</key><integer>293865</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:40:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253526972</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:29:32Z</date>
+			<key>Persistent ID</key><string>87139F8602B86448</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-04%20Catacombs.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1345</key>
+		<dict>
+			<key>Track ID</key><integer>1345</integer>
+			<key>Name</key><string>Sugarbush Cushman</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3855179</integer>
+			<key>Total Time</key><integer>158313</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:41:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252924099</integer>
+			<key>Play Date UTC</key><date>2007-01-29T22:01:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B8644A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-05%20Sugarbush%20Cushman.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1346</key>
+		<dict>
+			<key>Track ID</key><integer>1346</integer>
+			<key>Name</key><string>Lay My Love</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10150169</integer>
+			<key>Total Time</key><integer>418942</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:42:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253518135</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:02:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B8644C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-06%20Lay%20My%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1347</key>
+		<dict>
+			<key>Track ID</key><integer>1347</integer>
+			<key>Name</key><string>Everybody's Trying</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9131198</integer>
+			<key>Total Time</key><integer>376852</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:43:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246620132</integer>
+			<key>Play Date UTC</key><date>2006-11-17T22:55:32Z</date>
+			<key>Persistent ID</key><string>87139F8602B8644E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-07%20Everybody's%20Trying.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1348</key>
+		<dict>
+			<key>Track ID</key><integer>1348</integer>
+			<key>Name</key><string>Tall</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4785688</integer>
+			<key>Total Time</key><integer>197054</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:44:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252562220</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:30:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B86450</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-08%20Tall.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1349</key>
+		<dict>
+			<key>Track ID</key><integer>1349</integer>
+			<key>Name</key><string>Searching For The Fertile Fields</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5524392</integer>
+			<key>Total Time</key><integer>227796</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:45:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252576918</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:35:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B86452</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-09%20Searching%20For%20The%20Fertile%20Fields.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1350</key>
+		<dict>
+			<key>Track ID</key><integer>1350</integer>
+			<key>Name</key><string>Pulling Touch</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10889611</integer>
+			<key>Total Time</key><integer>449470</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:46:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252541896</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:51:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B86454</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-10%20Pulling%20Touch.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1351</key>
+		<dict>
+			<key>Track ID</key><integer>1351</integer>
+			<key>Name</key><string>Sandra At The Beach</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7273261</integer>
+			<key>Total Time</key><integer>304340</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Date Modified</key><date>2005-06-14T15:47:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253339325</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:22:05Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T22:30:17Z</date>
+			<key>Persistent ID</key><string>87139F8602B86456</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light/1-11%20Sandra%20At%20The%20Beach.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1352</key>
+		<dict>
+			<key>Track ID</key><integer>1352</integer>
+			<key>Name</key><string>Diamonds and Buttermilk</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6457948</integer>
+			<key>Total Time</key><integer>266452</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:19:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B86458</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-01%20Diamonds%20and%20Buttermilk.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1353</key>
+		<dict>
+			<key>Track ID</key><integer>1353</integer>
+			<key>Name</key><string>Ecstasy</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6253241</integer>
+			<key>Total Time</key><integer>258025</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:20:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253605299</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:14:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B8645B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-02%20Ecstasy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1354</key>
+		<dict>
+			<key>Track ID</key><integer>1354</integer>
+			<key>Name</key><string>I've Got Body</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7574941</integer>
+			<key>Total Time</key><integer>312596</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:21:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253549533</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:45:33Z</date>
+			<key>Persistent ID</key><string>87139F8602B8645D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-03%20I've%20Got%20Body.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1355</key>
+		<dict>
+			<key>Track ID</key><integer>1355</integer>
+			<key>Name</key><string>Shu Zulu Za</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8557502</integer>
+			<key>Total Time</key><integer>353172</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:22:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247552280</integer>
+			<key>Play Date UTC</key><date>2006-11-28T17:51:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B8645F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-04%20Shu%20Zulu%20Za.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1356</key>
+		<dict>
+			<key>Track ID</key><integer>1356</integer>
+			<key>Name</key><string>God's Gallipolli</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9314793</integer>
+			<key>Total Time</key><integer>384425</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:23:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253358453</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:40:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-17T15:18:03Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86461</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-05%20God's%20Gallipolli.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1357</key>
+		<dict>
+			<key>Track ID</key><integer>1357</integer>
+			<key>Name</key><string>Ta Bouche Est Tabu</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8176403</integer>
+			<key>Total Time</key><integer>337428</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:24:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253613286</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:28:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B86463</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-06%20Ta%20Bouche%20Est%20Tabu.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1358</key>
+		<dict>
+			<key>Track ID</key><integer>1358</integer>
+			<key>Name</key><string>Collarbone</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6844079</integer>
+			<key>Total Time</key><integer>282409</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:25:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252556206</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:50:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B86465</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-07%20Collarbone.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1359</key>
+		<dict>
+			<key>Track ID</key><integer>1359</integer>
+			<key>Name</key><string>Big Constellation</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8676144</integer>
+			<key>Total Time</key><integer>358057</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:26:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B86467</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-08%20Big%20Constellation.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1360</key>
+		<dict>
+			<key>Track ID</key><integer>1360</integer>
+			<key>Name</key><string>The Chain</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7469025</integer>
+			<key>Total Time</key><integer>308222</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:27:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253259780</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:16:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B86469</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-09%20The%20Chain.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1361</key>
+		<dict>
+			<key>Track ID</key><integer>1361</integer>
+			<key>Name</key><string>Jackass Ginger</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6637078</integer>
+			<key>Total Time</key><integer>273876</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:28:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252488581</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:03:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B8646B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-10%20Jackass%20Ginger.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1362</key>
+		<dict>
+			<key>Track ID</key><integer>1362</integer>
+			<key>Name</key><string>Platetectonic</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7777312</integer>
+			<key>Total Time</key><integer>320958</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:29:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253614289</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:44:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B8646D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-11%20Platetectonic.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1363</key>
+		<dict>
+			<key>Track ID</key><integer>1363</integer>
+			<key>Name</key><string>Complicated</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Composer</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Liquid White Light : 2</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6502999</integer>
+			<key>Total Time</key><integer>268542</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Date Modified</key><date>2005-06-14T15:30:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251466994</integer>
+			<key>Play Date UTC</key><date>2007-01-13T01:16:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B8646F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Liquid%20White%20Light%20_%202/2-12%20Complicated.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1364</key>
+		<dict>
+			<key>Track ID</key><integer>1364</integer>
+			<key>Name</key><string>Octavio - Beautiful To Meet You</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8574519</integer>
+			<key>Total Time</key><integer>535771</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253369684</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:48:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B86471</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/01%20Octavio%20-%20Beautiful%20To%20Meet%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1365</key>
+		<dict>
+			<key>Track ID</key><integer>1365</integer>
+			<key>Name</key><string>Ta Bouche Est Tabou (French Mix)</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5579841</integer>
+			<key>Total Time</key><integer>348604</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T19:09:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B86474</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/02%20Ta%20Bouche%20Est%20Tabou%20(French%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1366</key>
+		<dict>
+			<key>Track ID</key><integer>1366</integer>
+			<key>Name</key><string>Natural Thing</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5693944</integer>
+			<key>Total Time</key><integer>355735</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247060629</integer>
+			<key>Play Date UTC</key><date>2006-11-23T01:17:09Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T01:08:44Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86476</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/03%20Natural%20Thing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1367</key>
+		<dict>
+			<key>Track ID</key><integer>1367</integer>
+			<key>Name</key><string>Come Together</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4816230</integer>
+			<key>Total Time</key><integer>300878</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253255352</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:02:32Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86478</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/04%20Come%20Together.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1368</key>
+		<dict>
+			<key>Track ID</key><integer>1368</integer>
+			<key>Name</key><string>Diva</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7523769</integer>
+			<key>Total Time</key><integer>470099</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251487527</integer>
+			<key>Play Date UTC</key><date>2007-01-13T06:58:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B8647A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/05%20Diva.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1369</key>
+		<dict>
+			<key>Track ID</key><integer>1369</integer>
+			<key>Name</key><string>Berry</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2624452</integer>
+			<key>Total Time</key><integer>163892</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251634275</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:44:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B8647C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/06%20Berry.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1370</key>
+		<dict>
+			<key>Track ID</key><integer>1370</integer>
+			<key>Name</key><string>That's The Way Love Is</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4754790</integer>
+			<key>Total Time</key><integer>297038</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247582283</integer>
+			<key>Play Date UTC</key><date>2006-11-29T02:11:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B8647E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/07%20That's%20The%20Way%20Love%20Is.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1371</key>
+		<dict>
+			<key>Track ID</key><integer>1371</integer>
+			<key>Name</key><string>Spend My Life (Moorea Mix)</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8243913</integer>
+			<key>Total Time</key><integer>515108</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253337174</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:46:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B86480</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/08%20Spend%20My%20Life%20(Moorea%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1372</key>
+		<dict>
+			<key>Track ID</key><integer>1372</integer>
+			<key>Name</key><string>Hard Sometime</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5092919</integer>
+			<key>Total Time</key><integer>318171</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253516573</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:36:13Z</date>
+			<key>Persistent ID</key><string>87139F8602B86482</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/09%20Hard%20Sometime.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1373</key>
+		<dict>
+			<key>Track ID</key><integer>1373</integer>
+			<key>Name</key><string>Jealous</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5320289</integer>
+			<key>Total Time</key><integer>332382</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:29:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253532756</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:05:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B86484</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/10%20Jealous.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1374</key>
+		<dict>
+			<key>Track ID</key><integer>1374</integer>
+			<key>Name</key><string>Tracery - Tana Dery Na (Waterlily Mix)</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Natural Thing</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7869840</integer>
+			<key>Total Time</key><integer>491728</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252516060</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:41:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B86486</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Natural%20Thing/11%20Tracery%20-%20Tana%20Dery%20Na%20(Waterlily%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1375</key>
+		<dict>
+			<key>Track ID</key><integer>1375</integer>
+			<key>Name</key><string>Pomegranate</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3791080</integer>
+			<key>Total Time</key><integer>313182</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252496940</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:22:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B86488</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/01%20Pomegranate.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1376</key>
+		<dict>
+			<key>Track ID</key><integer>1376</integer>
+			<key>Name</key><string>Catacombs</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3575560</integer>
+			<key>Total Time</key><integer>295392</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247721966</integer>
+			<key>Play Date UTC</key><date>2006-11-30T16:59:26Z</date>
+			<key>Persistent ID</key><string>87139F8602B8648B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/02%20Catacombs.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1377</key>
+		<dict>
+			<key>Track ID</key><integer>1377</integer>
+			<key>Name</key><string>Complicated</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3016936</integer>
+			<key>Total Time</key><integer>249182</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251644318</integer>
+			<key>Play Date UTC</key><date>2007-01-15T02:31:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B8648D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/03%20Complicated.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1378</key>
+		<dict>
+			<key>Track ID</key><integer>1378</integer>
+			<key>Name</key><string>The Cham</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3743747</integer>
+			<key>Total Time</key><integer>309237</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249539669</integer>
+			<key>Play Date UTC</key><date>2006-12-21T17:54:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B8648F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/04%20The%20Cham.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1379</key>
+		<dict>
+			<key>Track ID</key><integer>1379</integer>
+			<key>Name</key><string>Big Constellation</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4700497</integer>
+			<key>Total Time</key><integer>388284</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253384664</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:57:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B86491</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/05%20Big%20Constellation.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1380</key>
+		<dict>
+			<key>Track ID</key><integer>1380</integer>
+			<key>Name</key><string>Sandra at the Beach</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3809262</integer>
+			<key>Total Time</key><integer>314697</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252290572</integer>
+			<key>Play Date UTC</key><date>2007-01-22T14:02:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B86493</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/06%20Sandra%20at%20the%20Beach.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1381</key>
+		<dict>
+			<key>Track ID</key><integer>1381</integer>
+			<key>Name</key><string>Diamonds and Buttermilk</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3056434</integer>
+			<key>Total Time</key><integer>252473</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253544083</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:14:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B86495</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/07%20Diamonds%20and%20Buttermilk.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1382</key>
+		<dict>
+			<key>Track ID</key><integer>1382</integer>
+			<key>Name</key><string>Shu Zulu Za</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3444741</integer>
+			<key>Total Time</key><integer>284656</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253614884</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:54:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B86497</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/08%20Shu%20Zulu%20Za.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1383</key>
+		<dict>
+			<key>Track ID</key><integer>1383</integer>
+			<key>Name</key><string>God's Gallipoli</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4047666</integer>
+			<key>Total Time</key><integer>334393</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253087161</integer>
+			<key>Play Date UTC</key><date>2007-01-31T19:19:21Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-28T01:43:02Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86499</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/09%20God's%20Gallipoli.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1384</key>
+		<dict>
+			<key>Track ID</key><integer>1384</integer>
+			<key>Name</key><string>The Shake of Big Hands</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3889510</integer>
+			<key>Total Time</key><integer>321384</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251350222</integer>
+			<key>Play Date UTC</key><date>2007-01-11T16:50:22Z</date>
+			<key>Persistent ID</key><string>87139F8602B8649B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/10%20The%20Shake%20of%20Big%20Hands.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1385</key>
+		<dict>
+			<key>Track ID</key><integer>1385</integer>
+			<key>Name</key><string>Al le Luia</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Pomegranate</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6573393</integer>
+			<key>Total Time</key><integer>543164</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253260593</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:29:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B8649D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Pomegranate/11%20Al%20le%20Luia.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1386</key>
+		<dict>
+			<key>Track ID</key><integer>1386</integer>
+			<key>Name</key><string>Lackluster</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3490045</integer>
+			<key>Total Time</key><integer>217991</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252497534</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:32:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B8649F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/01%20Lackluster.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1387</key>
+		<dict>
+			<key>Track ID</key><integer>1387</integer>
+			<key>Name</key><string>Collarbone</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3869552</integer>
+			<key>Total Time</key><integer>241711</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3252539342</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:09:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B864A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/02%20Collarbone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1388</key>
+		<dict>
+			<key>Track ID</key><integer>1388</integer>
+			<key>Name</key><string>Get Me On</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3785125</integer>
+			<key>Total Time</key><integer>236434</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249488682</integer>
+			<key>Play Date UTC</key><date>2006-12-21T03:44:42Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-03T22:18:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B864A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/03%20Get%20Me%20On.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1389</key>
+		<dict>
+			<key>Track ID</key><integer>1389</integer>
+			<key>Name</key><string>The Hardest Thing</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4263688</integer>
+			<key>Total Time</key><integer>266344</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247288445</integer>
+			<key>Play Date UTC</key><date>2006-11-25T16:34:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B864A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/04%20The%20Hardest%20Thing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1390</key>
+		<dict>
+			<key>Track ID</key><integer>1390</integer>
+			<key>Name</key><string>Ta Bouche Est Tabou</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4378627</integer>
+			<key>Total Time</key><integer>273528</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:30:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:54Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246717708</integer>
+			<key>Play Date UTC</key><date>2006-11-19T02:01:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B864A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/05%20Ta%20Bouche%20Est%20Tabou.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1391</key>
+		<dict>
+			<key>Track ID</key><integer>1391</integer>
+			<key>Name</key><string>I've Got My Body</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4994698</integer>
+			<key>Total Time</key><integer>312032</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251466043</integer>
+			<key>Play Date UTC</key><date>2007-01-13T01:00:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B864AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/06%20I've%20Got%20My%20Body.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1392</key>
+		<dict>
+			<key>Track ID</key><integer>1392</integer>
+			<key>Name</key><string>Jack Ass Ginger</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5323214</integer>
+			<key>Total Time</key><integer>332564</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253361100</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:25:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B864AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/07%20Jack%20Ass%20Ginger.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1393</key>
+		<dict>
+			<key>Track ID</key><integer>1393</integer>
+			<key>Name</key><string>Be The One</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5013507</integer>
+			<key>Total Time</key><integer>313208</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253616378</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:19:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B864AE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/08%20Be%20The%20One.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1394</key>
+		<dict>
+			<key>Track ID</key><integer>1394</integer>
+			<key>Name</key><string>Tall</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2938339</integer>
+			<key>Total Time</key><integer>183510</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253267144</integer>
+			<key>Play Date UTC</key><date>2007-02-02T21:19:04Z</date>
+			<key>Persistent ID</key><string>87139F8602B864B0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/09%20Tall.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1395</key>
+		<dict>
+			<key>Track ID</key><integer>1395</integer>
+			<key>Name</key><string>Building</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>627025</integer>
+			<key>Total Time</key><integer>39053</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253556474</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:41:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B864B2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/10%20Building.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1396</key>
+		<dict>
+			<key>Track ID</key><integer>1396</integer>
+			<key>Name</key><string>Te Manu Pukarua</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2014649</integer>
+			<key>Total Time</key><integer>125779</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252937192</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:39:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B864B4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/11%20Te%20Manu%20Pukarua.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1397</key>
+		<dict>
+			<key>Track ID</key><integer>1397</integer>
+			<key>Name</key><string>Entrance</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3901735</integer>
+			<key>Total Time</key><integer>243722</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B864B6</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/13%20Entrance.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1398</key>
+		<dict>
+			<key>Track ID</key><integer>1398</integer>
+			<key>Name</key><string>Endtrance</string>
+			<key>Artist</key><string>Poi Dog Pondering</string>
+			<key>Album</key><string>Volo Volo</string>
+			<key>Genre</key><string>Jam Bands</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5713170</integer>
+			<key>Total Time</key><integer>356937</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253362826</integer>
+			<key>Play Date UTC</key><date>2007-02-03T23:53:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B864B8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Poi%20Dog%20Pondering/Volo%20Volo/14%20Endtrance.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1399</key>
+		<dict>
+			<key>Track ID</key><integer>1399</integer>
+			<key>Name</key><string>Mysterons</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4936728</integer>
+			<key>Total Time</key><integer>306233</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253383832</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:43:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864BA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/01%20Mysterons.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1400</key>
+		<dict>
+			<key>Track ID</key><integer>1400</integer>
+			<key>Name</key><string>Sour Times</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4095501</integer>
+			<key>Total Time</key><integer>254040</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247489500</integer>
+			<key>Play Date UTC</key><date>2006-11-28T00:25:00Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-26T19:12:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864BD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/02%20Sour%20Times.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1401</key>
+		<dict>
+			<key>Track ID</key><integer>1401</integer>
+			<key>Name</key><string>Strangers</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3837323</integer>
+			<key>Total Time</key><integer>238027</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249577201</integer>
+			<key>Play Date UTC</key><date>2006-12-22T04:20:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864BF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/03%20Strangers.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1402</key>
+		<dict>
+			<key>Track ID</key><integer>1402</integer>
+			<key>Name</key><string>It Could Be Sweet</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4193262</integer>
+			<key>Total Time</key><integer>260022</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251297088</integer>
+			<key>Play Date UTC</key><date>2007-01-11T02:04:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864C1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/04%20It%20Could%20Be%20Sweet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1403</key>
+		<dict>
+			<key>Track ID</key><integer>1403</integer>
+			<key>Name</key><string>Wandering Star</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4739075</integer>
+			<key>Total Time</key><integer>294008</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251354484</integer>
+			<key>Play Date UTC</key><date>2007-01-11T18:01:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864C3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/05%20Wandering%20Star.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1404</key>
+		<dict>
+			<key>Track ID</key><integer>1404</integer>
+			<key>Name</key><string>It's a Fire</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3698482</integer>
+			<key>Total Time</key><integer>229355</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:31:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252549450</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:57:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T06:15:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/06%20It's%20a%20Fire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1405</key>
+		<dict>
+			<key>Track ID</key><integer>1405</integer>
+			<key>Name</key><string>Numb</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3836896</integer>
+			<key>Total Time</key><integer>238001</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253263731</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:22:11Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:12Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/07%20Numb.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1406</key>
+		<dict>
+			<key>Track ID</key><integer>1406</integer>
+			<key>Name</key><string>Roads</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4920427</integer>
+			<key>Total Time</key><integer>305214</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249283085</integer>
+			<key>Play Date UTC</key><date>2006-12-18T18:38:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864C9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/08%20Roads.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1407</key>
+		<dict>
+			<key>Track ID</key><integer>1407</integer>
+			<key>Name</key><string>Pedestal</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3565571</integer>
+			<key>Total Time</key><integer>221048</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252990770</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:32:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864CB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/09%20Pedestal.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1408</key>
+		<dict>
+			<key>Track ID</key><integer>1408</integer>
+			<key>Name</key><string>Biscuit</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4903291</integer>
+			<key>Total Time</key><integer>304143</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252542373</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:59:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/10%20Biscuit.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1409</key>
+		<dict>
+			<key>Track ID</key><integer>1409</integer>
+			<key>Name</key><string>Glory Box</string>
+			<key>Artist</key><string>Portishead</string>
+			<key>Album</key><string>Dummy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4926696</integer>
+			<key>Total Time</key><integer>305606</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3246961868</integer>
+			<key>Play Date UTC</key><date>2006-11-21T21:51:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B864CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Portishead/Dummy/11%20Glory%20Box.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1410</key>
+		<dict>
+			<key>Track ID</key><integer>1410</integer>
+			<key>Name</key><string>Dragonflies [Uberzone Strapped to Your Bed Mix]</string>
+			<key>Artist</key><string>Povi</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4000792</integer>
+			<key>Total Time</key><integer>249913</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246425620</integer>
+			<key>Play Date UTC</key><date>2006-11-15T16:53:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B864D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Povi/Plastic%20Compilation,%20Vol.%203/07%20Dragonflies%20%5BUberzone%20Strapped%20to%20Your%20Bed%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1411</key>
+		<dict>
+			<key>Track ID</key><integer>1411</integer>
+			<key>Name</key><string>Take California</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10691440</integer>
+			<key>Total Time</key><integer>441705</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:41:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249629412</integer>
+			<key>Play Date UTC</key><date>2006-12-22T18:50:12Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B864D4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/01%20Take%20California.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1412</key>
+		<dict>
+			<key>Track ID</key><integer>1412</integer>
+			<key>Name</key><string>Velvet Pants</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8398139</integer>
+			<key>Total Time</key><integer>346921</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:42:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253526010</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:13:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B864D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/02%20Velvet%20Pants.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1413</key>
+		<dict>
+			<key>Track ID</key><integer>1413</integer>
+			<key>Name</key><string>Better?</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3011637</integer>
+			<key>Total Time</key><integer>123305</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:43:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253335157</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:12:37Z</date>
+			<key>Persistent ID</key><string>87139F8602B864D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/03%20Better_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1414</key>
+		<dict>
+			<key>Track ID</key><integer>1414</integer>
+			<key>Name</key><string>History Repeating</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5874840</integer>
+			<key>Total Time</key><integer>242601</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:44:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246379581</integer>
+			<key>Play Date UTC</key><date>2006-11-15T04:06:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B864DB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/05%20History%20Repeating.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1415</key>
+		<dict>
+			<key>Track ID</key><integer>1415</integer>
+			<key>Name</key><string>Winning Style</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8672012</integer>
+			<key>Total Time</key><integer>358249</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:45:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253385022</integer>
+			<key>Play Date UTC</key><date>2007-02-04T06:03:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B864DD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/06%20Winning%20Style.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1416</key>
+		<dict>
+			<key>Track ID</key><integer>1416</integer>
+			<key>Name</key><string>Bang On!</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8348860</integer>
+			<key>Total Time</key><integer>344873</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:46:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253547810</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:16:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B864DF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/07%20Bang%20On!.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1417</key>
+		<dict>
+			<key>Track ID</key><integer>1417</integer>
+			<key>Name</key><string>A Number Of Microphones</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>1147578</integer>
+			<key>Total Time</key><integer>45630</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:46:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251890695</integer>
+			<key>Play Date UTC</key><date>2007-01-17T22:58:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B864E1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/08%20A%20Number%20Of%20Microphones.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1418</key>
+		<dict>
+			<key>Track ID</key><integer>1418</integer>
+			<key>Name</key><string>On Her Majesty's Secret Service</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13575908</integer>
+			<key>Total Time</key><integer>560916</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:48:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252551475</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:31:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B864E3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/09%20On%20Her%20Majesty's%20Secret%20Service.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1419</key>
+		<dict>
+			<key>Track ID</key><integer>1419</integer>
+			<key>Name</key><string>Bigger?</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3422297</integer>
+			<key>Total Time</key><integer>140414</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:48:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253543831</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:10:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B864E5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/10%20Bigger_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1420</key>
+		<dict>
+			<key>Track ID</key><integer>1420</integer>
+			<key>Name</key><string>Cominagetcha</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10229465</integer>
+			<key>Total Time</key><integer>422612</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:49:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B864E7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/11%20Cominagetcha.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1421</key>
+		<dict>
+			<key>Track ID</key><integer>1421</integer>
+			<key>Name</key><string>Spybreak!</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Decksandrumsandrockandroll</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10124825</integer>
+			<key>Total Time</key><integer>418281</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2004-04-20T16:50:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253087844</integer>
+			<key>Play Date UTC</key><date>2007-01-31T19:30:44Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T06:15:53Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B864E9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Decksandrumsandrockandroll/12%20Spybreak!.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1422</key>
+		<dict>
+			<key>Track ID</key><integer>1422</integer>
+			<key>Name</key><string>Spybreak! (Short One)</string>
+			<key>Artist</key><string>Propellerheads</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3851162</integer>
+			<key>Total Time</key><integer>240561</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253706347</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:19:07Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B864EB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Propellerheads/Matrix/02%20Spybreak!%20(Short%20One).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1423</key>
+		<dict>
+			<key>Track ID</key><integer>1423</integer>
+			<key>Name</key><string>Renegades Of Funk (The Crystal Method Remix)</string>
+			<key>Artist</key><string>Rage Against the Machine</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Rage Against the Machine</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5661662</integer>
+			<key>Total Time</key><integer>235075</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253351775</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:49:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B864EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20the%20Machine/Community%20Service/11%20Renegades%20Of%20Funk%20(The%20Crystal%20Method%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1424</key>
+		<dict>
+			<key>Track ID</key><integer>1424</integer>
+			<key>Name</key><string>Wake Up</string>
+			<key>Artist</key><string>Rage Against the Machine</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5821004</integer>
+			<key>Total Time</key><integer>363676</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252489674</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:21:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B864F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20the%20Machine/Matrix/13%20Wake%20Up.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1425</key>
+		<dict>
+			<key>Track ID</key><integer>1425</integer>
+			<key>Name</key><string>Testify</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3369255</integer>
+			<key>Total Time</key><integer>210442</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253275699</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:41:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B864F3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/01%20Testify.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1426</key>
+		<dict>
+			<key>Track ID</key><integer>1426</integer>
+			<key>Name</key><string>Guerilla Radio</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3299874</integer>
+			<key>Total Time</key><integer>206106</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253469038</integer>
+			<key>Play Date UTC</key><date>2007-02-05T05:23:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B864F6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/02%20Guerilla%20Radio.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1427</key>
+		<dict>
+			<key>Track ID</key><integer>1427</integer>
+			<key>Name</key><string>Calm Like A Bomb</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4785301</integer>
+			<key>Total Time</key><integer>298945</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253283626</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:53:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B864F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/03%20Calm%20Like%20A%20Bomb.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1428</key>
+		<dict>
+			<key>Track ID</key><integer>1428</integer>
+			<key>Name</key><string>Mic Check</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3423172</integer>
+			<key>Total Time</key><integer>213812</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251297302</integer>
+			<key>Play Date UTC</key><date>2007-01-11T02:08:22Z</date>
+			<key>Persistent ID</key><string>87139F8602B864FA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/04%20Mic%20Check.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1429</key>
+		<dict>
+			<key>Track ID</key><integer>1429</integer>
+			<key>Name</key><string>Sleep Now in the Fire</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3292351</integer>
+			<key>Total Time</key><integer>205635</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252516808</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:53:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B864FC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/05%20Sleep%20Now%20in%20the%20Fire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1430</key>
+		<dict>
+			<key>Track ID</key><integer>1430</integer>
+			<key>Name</key><string>Born of a Broken Man</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4499417</integer>
+			<key>Total Time</key><integer>281077</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249459225</integer>
+			<key>Play Date UTC</key><date>2006-12-20T19:33:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B864FE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/06%20Born%20of%20a%20Broken%20Man.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1431</key>
+		<dict>
+			<key>Track ID</key><integer>1431</integer>
+			<key>Name</key><string>Born as Ghosts</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3234672</integer>
+			<key>Total Time</key><integer>202031</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86500</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/07%20Born%20as%20Ghosts.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1432</key>
+		<dict>
+			<key>Track ID</key><integer>1432</integer>
+			<key>Name</key><string>Maria</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3651796</integer>
+			<key>Total Time</key><integer>228101</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253372111</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:28:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B86502</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/08%20Maria.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1433</key>
+		<dict>
+			<key>Track ID</key><integer>1433</integer>
+			<key>Name</key><string>Voice of the Voiceless</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2428429</integer>
+			<key>Total Time</key><integer>151640</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253558343</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:12:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B86504</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/09%20Voice%20of%20the%20Voiceless.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1434</key>
+		<dict>
+			<key>Track ID</key><integer>1434</integer>
+			<key>Name</key><string>New Millenium Homes</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3601223</integer>
+			<key>Total Time</key><integer>224940</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253352347</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:59:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B86506</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/10%20New%20Millenium%20Homes.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1435</key>
+		<dict>
+			<key>Track ID</key><integer>1435</integer>
+			<key>Name</key><string>Ashes in the Fall</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4432543</integer>
+			<key>Total Time</key><integer>276897</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252290028</integer>
+			<key>Play Date UTC</key><date>2007-01-22T13:53:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B86508</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/11%20Ashes%20in%20the%20Fall.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1436</key>
+		<dict>
+			<key>Track ID</key><integer>1436</integer>
+			<key>Name</key><string>War Within a Breath</string>
+			<key>Artist</key><string>Rage Against The Machine</string>
+			<key>Album</key><string>The Battle of Los Angeles</string>
+			<key>Genre</key><string>Alternative Metal</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3474163</integer>
+			<key>Total Time</key><integer>216999</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250695187</integer>
+			<key>Play Date UTC</key><date>2007-01-04T02:53:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B8650A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rage%20Against%20The%20Machine/The%20Battle%20of%20Los%20Angeles/12%20War%20Within%20a%20Breath.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1437</key>
+		<dict>
+			<key>Track ID</key><integer>1437</integer>
+			<key>Name</key><string>A Chance Counsel</string>
+			<key>Artist</key><string>Richard Buckner</string>
+			<key>Album</key><string>Dents And Shells</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6967485</integer>
+			<key>Total Time</key><integer>290220</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T21:01:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253261231</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:40:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B8650C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Richard%20Buckner/Dents%20And%20Shells/01%20A%20Chance%20Counsel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1438</key>
+		<dict>
+			<key>Track ID</key><integer>1438</integer>
+			<key>Name</key><string>Catherine Of Aragon</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5459682</integer>
+			<key>Total Time</key><integer>227326</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252582248</integer>
+			<key>Play Date UTC</key><date>2007-01-25T23:04:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8650F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/01%20Catherine%20Of%20Aragon.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1439</key>
+		<dict>
+			<key>Track ID</key><integer>1439</integer>
+			<key>Name</key><string>Anne Of Cleves</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11470329</integer>
+			<key>Total Time</key><integer>474964</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252403970</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:32:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86512</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/02%20Anne%20Of%20Cleves.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1440</key>
+		<dict>
+			<key>Track ID</key><integer>1440</integer>
+			<key>Name</key><string>Catherine Howard</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9585257</integer>
+			<key>Total Time</key><integer>397908</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249576641</integer>
+			<key>Play Date UTC</key><date>2006-12-22T04:10:41Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:05:04Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86514</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/03%20Catherine%20Howard.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1441</key>
+		<dict>
+			<key>Track ID</key><integer>1441</integer>
+			<key>Name</key><string>Jane Seymour</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6977910</integer>
+			<key>Total Time</key><integer>290665</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252529894</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:31:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86516</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/04%20Jane%20Seymour.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1442</key>
+		<dict>
+			<key>Track ID</key><integer>1442</integer>
+			<key>Name</key><string>Anne Boleyn</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9539749</integer>
+			<key>Total Time</key><integer>396692</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252927821</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:03:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86518</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/05%20Anne%20Boleyn.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1443</key>
+		<dict>
+			<key>Track ID</key><integer>1443</integer>
+			<key>Name</key><string>Catherine Parr</string>
+			<key>Artist</key><string>Rick Wakeman</string>
+			<key>Composer</key><string>Rick Wakeman</string>
+			<key>Album</key><string>The Six Wives Of Henry VIII</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10296939</integer>
+			<key>Total Time</key><integer>424766</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>6</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-08-01T17:09:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252535323</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:02:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8651A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rick%20Wakeman/The%20Six%20Wives%20Of%20Henry%20VIII/06%20Catherine%20Parr.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1444</key>
+		<dict>
+			<key>Track ID</key><integer>1444</integer>
+			<key>Name</key><string>Clubbed to Death [Kurayamino Mix]</string>
+			<key>Artist</key><string>Rob D.</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7144263</integer>
+			<key>Total Time</key><integer>446380</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>22</integer>
+			<key>Play Date</key><integer>3253160974</integer>
+			<key>Play Date UTC</key><date>2007-02-01T15:49:34Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-04T23:35:51Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B8651C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20D_/Matrix/04%20Clubbed%20to%20Death%20%5BKurayamino%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1445</key>
+		<dict>
+			<key>Track ID</key><integer>1445</integer>
+			<key>Name</key><string>Prelude</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>2151815</integer>
+			<key>Total Time</key><integer>43013</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-08-22T04:32:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>395</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252923430</integer>
+			<key>Play Date UTC</key><date>2007-01-29T21:50:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B8651F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/01%20Prelude.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1446</key>
+		<dict>
+			<key>Track ID</key><integer>1446</integer>
+			<key>Name</key><string>Furious Angels</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>44897461</integer>
+			<key>Total Time</key><integer>356253</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-11T18:45:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>1007</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250574604</integer>
+			<key>Play Date UTC</key><date>2007-01-02T17:23:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86522</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/02%20Furious%20Angels.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1447</key>
+		<dict>
+			<key>Track ID</key><integer>1447</integer>
+			<key>Name</key><string>Will You Follow Me?</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>21575892</integer>
+			<key>Total Time</key><integer>230480</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-26T22:19:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>748</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253335387</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:16:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B86524</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/03%20Will%20You%20Follow%20Me_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1448</key>
+		<dict>
+			<key>Track ID</key><integer>1448</integer>
+			<key>Name</key><string>Left Me For Dead</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34509778</integer>
+			<key>Total Time</key><integer>279880</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-26T22:38:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>985</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253356670</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:11:10Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86526</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/04%20Left%20Me%20For%20Dead.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1449</key>
+		<dict>
+			<key>Track ID</key><integer>1449</integer>
+			<key>Name</key><string>I'm Not Driving Anymore</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>32686603</integer>
+			<key>Total Time</key><integer>274106</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-27T18:49:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>953</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252534436</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:47:16Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T20:09:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B86528</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/05%20I'm%20Not%20Driving%20Anymore.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1450</key>
+		<dict>
+			<key>Track ID</key><integer>1450</integer>
+			<key>Name</key><string>Clubbed To Death (Kurayamino Variation)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>47092987</integer>
+			<key>Total Time</key><integer>449546</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-17T23:29:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>837</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250740011</integer>
+			<key>Play Date UTC</key><date>2007-01-04T15:20:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B8652A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/06%20Clubbed%20To%20Death%20(Kurayamino%20Variation).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1451</key>
+		<dict>
+			<key>Track ID</key><integer>1451</integer>
+			<key>Name</key><string>There's Only Me</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>37178750</integer>
+			<key>Total Time</key><integer>336933</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-05T13:10:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>882</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246985133</integer>
+			<key>Play Date UTC</key><date>2006-11-22T04:18:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B8652C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/07%20There's%20Only%20Me.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1452</key>
+		<dict>
+			<key>Track ID</key><integer>1452</integer>
+			<key>Name</key><string>Instrumental</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26109449</integer>
+			<key>Total Time</key><integer>268506</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-26T18:01:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>777</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253342495</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:14:55Z</date>
+			<key>Persistent ID</key><string>87139F8602B8652E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/08%20Instrumental.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1453</key>
+		<dict>
+			<key>Track ID</key><integer>1453</integer>
+			<key>Name</key><string>Nothing At All</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>36635462</integer>
+			<key>Total Time</key><integer>392133</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-05T15:29:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>746</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3250682368</integer>
+			<key>Play Date UTC</key><date>2007-01-03T23:19:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B86530</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/09%20Nothing%20At%20All.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1454</key>
+		<dict>
+			<key>Track ID</key><integer>1454</integer>
+			<key>Name</key><string>Born Yesterday</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>33696188</integer>
+			<key>Total Time</key><integer>319946</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-26T15:46:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>841</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249383320</integer>
+			<key>Play Date UTC</key><date>2006-12-19T22:28:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B86532</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/10%20Born%20Yesterday.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1455</key>
+		<dict>
+			<key>Track ID</key><integer>1455</integer>
+			<key>Name</key><string>Speed Me Towards Death</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>29659020</integer>
+			<key>Total Time</key><integer>272893</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-28T13:25:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>868</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253509916</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:45:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B86534</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/11%20Speed%20Me%20Towards%20Death.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1456</key>
+		<dict>
+			<key>Track ID</key><integer>1456</integer>
+			<key>Name</key><string>Drinking Song</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24663590</integer>
+			<key>Total Time</key><integer>238813</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-11T03:53:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>825</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252503012</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:03:32Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T18:36:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B86536</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/12%20Drinking%20Song.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1457</key>
+		<dict>
+			<key>Track ID</key><integer>1457</integer>
+			<key>Name</key><string>Pause</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31564</integer>
+			<key>Total Time</key><integer>31960</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-08T19:01:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>2</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249193612</integer>
+			<key>Play Date UTC</key><date>2006-12-17T17:46:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B86538</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/13%20Pause.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1458</key>
+		<dict>
+			<key>Track ID</key><integer>1458</integer>
+			<key>Name</key><string>One And The Same (Coda)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>39471403</integer>
+			<key>Total Time</key><integer>346066</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-10-17T16:30:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>911</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253338379</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:06:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B8653A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/14%20One%20And%20The%20Same%20(Coda).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1459</key>
+		<dict>
+			<key>Track ID</key><integer>1459</integer>
+			<key>Name</key><string>Clubbed To Death 2</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34279715</integer>
+			<key>Total Time</key><integer>427680</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-09-28T19:29:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>640</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252472013</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:26:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B8653C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels/15%20Clubbed%20To%20Death%202.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1460</key>
+		<dict>
+			<key>Track ID</key><integer>1460</integer>
+			<key>Name</key><string>Will You Follow Me? (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23674994</integer>
+			<key>Total Time</key><integer>272973</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-09-28T23:54:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>693</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252515568</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:32:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B8653E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-01%20Will%20You%20Follow%20Me_%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1461</key>
+		<dict>
+			<key>Track ID</key><integer>1461</integer>
+			<key>Name</key><string>Furious Angels (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>44442503</integer>
+			<key>Total Time</key><integer>363480</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-09-26T23:08:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>977</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253368091</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:21:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B86541</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-02%20Furious%20Angels%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1462</key>
+		<dict>
+			<key>Track ID</key><integer>1462</integer>
+			<key>Name</key><string>Left Me For Dead (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34299133</integer>
+			<key>Total Time</key><integer>282786</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-08-22T04:23:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>969</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253382328</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:18:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B86543</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-03%20Left%20Me%20For%20Dead%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1463</key>
+		<dict>
+			<key>Track ID</key><integer>1463</integer>
+			<key>Name</key><string>I'm Not Driving Anymore (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>32338581</integer>
+			<key>Total Time</key><integer>274106</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-10-07T13:35:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>942</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247488444</integer>
+			<key>Play Date UTC</key><date>2006-11-28T00:07:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86545</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-04%20I'm%20Not%20Driving%20Anymore%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1464</key>
+		<dict>
+			<key>Track ID</key><integer>1464</integer>
+			<key>Name</key><string>There's Only Me (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34724717</integer>
+			<key>Total Time</key><integer>338280</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-08-22T04:25:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>820</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252931606</integer>
+			<key>Play Date UTC</key><date>2007-01-30T00:06:46Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-30T22:30:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B86547</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-05%20There's%20Only%20Me%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1465</key>
+		<dict>
+			<key>Track ID</key><integer>1465</integer>
+			<key>Name</key><string>Clubbed To Death (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>26090179</integer>
+			<key>Total Time</key><integer>270240</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-09-26T15:34:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>771</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86549</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-06%20Clubbed%20To%20Death%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1466</key>
+		<dict>
+			<key>Track ID</key><integer>1466</integer>
+			<key>Name</key><string>Nothing At All (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>32778176</integer>
+			<key>Total Time</key><integer>353400</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2005-09-28T00:54:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>741</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252563815</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:56:55Z</date>
+			<key>Persistent ID</key><string>87139F8602B8654B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-07%20Nothing%20At%20All%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1467</key>
+		<dict>
+			<key>Track ID</key><integer>1467</integer>
+			<key>Name</key><string>Born Yesterday (Instrumental)</string>
+			<key>Artist</key><string>Rob Dougan</string>
+			<key>Album</key><string>Furious Angels Disc2~Instrumental~</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>46622797</integer>
+			<key>Total Time</key><integer>452866</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-08-22T04:28:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>823</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3249273799</integer>
+			<key>Play Date UTC</key><date>2006-12-18T16:03:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B8654D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Rob%20Dougan/Furious%20Angels%20Disc2%EF%BD%9EInstrumental%EF%BD%9E/2-08%20Born%20Yesterday%20(Instrumental).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1468</key>
+		<dict>
+			<key>Track ID</key><integer>1468</integer>
+			<key>Name</key><string>Possession</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3379474</integer>
+			<key>Total Time</key><integer>279222</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253712591</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:03:11Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:01:28Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8654F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/01%20Possession.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1469</key>
+		<dict>
+			<key>Track ID</key><integer>1469</integer>
+			<key>Name</key><string>Wait</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3023206</integer>
+			<key>Total Time</key><integer>249704</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253285552</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:25:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T01:21:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B86552</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/02%20Wait.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1470</key>
+		<dict>
+			<key>Track ID</key><integer>1470</integer>
+			<key>Name</key><string>Plenty</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2970856</integer>
+			<key>Total Time</key><integer>245342</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250617224</integer>
+			<key>Play Date UTC</key><date>2007-01-03T05:13:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B86554</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/03%20Plenty.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1471</key>
+		<dict>
+			<key>Track ID</key><integer>1471</integer>
+			<key>Name</key><string>Good Enough</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3679632</integer>
+			<key>Total Time</key><integer>304065</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:55Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250704694</integer>
+			<key>Play Date UTC</key><date>2007-01-04T05:31:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B86556</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/04%20Good%20Enough.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1472</key>
+		<dict>
+			<key>Track ID</key><integer>1472</integer>
+			<key>Name</key><string>Mary</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2855019</integer>
+			<key>Total Time</key><integer>235859</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249385802</integer>
+			<key>Play Date UTC</key><date>2006-12-19T23:10:02Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T02:35:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B86558</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/05%20Mary.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1473</key>
+		<dict>
+			<key>Track ID</key><integer>1473</integer>
+			<key>Name</key><string>Elsewhere</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3441589</integer>
+			<key>Total Time</key><integer>284395</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250710169</integer>
+			<key>Play Date UTC</key><date>2007-01-04T07:02:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B8655A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/06%20Elsewhere.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1474</key>
+		<dict>
+			<key>Track ID</key><integer>1474</integer>
+			<key>Name</key><string>Circle</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2712704</integer>
+			<key>Total Time</key><integer>224000</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253764001</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:20:01Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8655C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/07%20Circle.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1475</key>
+		<dict>
+			<key>Track ID</key><integer>1475</integer>
+			<key>Name</key><string>Ice</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2841226</integer>
+			<key>Total Time</key><integer>234710</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253717181</integer>
+			<key>Play Date UTC</key><date>2007-02-08T02:19:41Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:30Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8655E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/08%20Ice.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1476</key>
+		<dict>
+			<key>Track ID</key><integer>1476</integer>
+			<key>Name</key><string>Hold On</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3027594</integer>
+			<key>Total Time</key><integer>250070</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253706106</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:15:06Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T20:17:30Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86560</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/09%20Hold%20On.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1477</key>
+		<dict>
+			<key>Track ID</key><integer>1477</integer>
+			<key>Name</key><string>Ice Cream</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1994984</integer>
+			<key>Total Time</key><integer>164702</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Persistent ID</key><string>87139F8602B86562</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/10%20Ice%20Cream.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1478</key>
+		<dict>
+			<key>Track ID</key><integer>1478</integer>
+			<key>Name</key><string>Fear</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Fumbling Towards Ecstasy</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2898278</integer>
+			<key>Total Time</key><integer>239464</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246373105</integer>
+			<key>Play Date UTC</key><date>2006-11-15T02:18:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B86564</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Fumbling%20Towards%20Ecstasy/11%20Fear.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1479</key>
+		<dict>
+			<key>Track ID</key><integer>1479</integer>
+			<key>Name</key><string>Sweet Surrender [Roni Size Mix V2]</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2925299</integer>
+			<key>Total Time</key><integer>240692</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253512227</integer>
+			<key>Play Date UTC</key><date>2007-02-05T17:23:47Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86566</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Plastic%20Compilation,%20Vol.%202/05%20Sweet%20Surrender%20%5BRoni%20Size%20Mix%20V2%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1480</key>
+		<dict>
+			<key>Track ID</key><integer>1480</integer>
+			<key>Name</key><string>I Love You [BT Mix]</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8678591</integer>
+			<key>Total Time</key><integer>542275</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252405456</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:57:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B86569</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Plastic%20Compilation,%20Vol.%203/01%20I%20Love%20You%20%5BBT%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1481</key>
+		<dict>
+			<key>Track ID</key><integer>1481</integer>
+			<key>Name</key><string>Building a Mystery</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2998149</integer>
+			<key>Total Time</key><integer>247275</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252511143</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:19:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8656C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/01%20Building%20a%20Mystery.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1482</key>
+		<dict>
+			<key>Track ID</key><integer>1482</integer>
+			<key>Name</key><string>I Love You</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3442043</integer>
+			<key>Total Time</key><integer>283924</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252039772</integer>
+			<key>Play Date UTC</key><date>2007-01-19T16:22:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-20T23:09:13Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8656F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/02%20I%20Love%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1483</key>
+		<dict>
+			<key>Track ID</key><integer>1483</integer>
+			<key>Name</key><string>Sweet Surrender</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2921663</integer>
+			<key>Total Time</key><integer>240901</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252486709</integer>
+			<key>Play Date UTC</key><date>2007-01-24T20:31:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86571</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/03%20Sweet%20Surrender.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1484</key>
+		<dict>
+			<key>Track ID</key><integer>1484</integer>
+			<key>Name</key><string>Adia</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2971818</integer>
+			<key>Total Time</key><integer>245080</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249451087</integer>
+			<key>Play Date UTC</key><date>2006-12-20T17:18:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86573</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/04%20Adia.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1485</key>
+		<dict>
+			<key>Track ID</key><integer>1485</integer>
+			<key>Name</key><string>Do What You Have to Do</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2751909</integer>
+			<key>Total Time</key><integer>226925</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250670001</integer>
+			<key>Play Date UTC</key><date>2007-01-03T19:53:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86575</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/05%20Do%20What%20You%20Have%20to%20Do.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1486</key>
+		<dict>
+			<key>Track ID</key><integer>1486</integer>
+			<key>Name</key><string>Witness</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3484361</integer>
+			<key>Total Time</key><integer>287451</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251630401</integer>
+			<key>Play Date UTC</key><date>2007-01-14T22:40:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86577</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/06%20Witness.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1487</key>
+		<dict>
+			<key>Track ID</key><integer>1487</integer>
+			<key>Name</key><string>Angel</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3279185</integer>
+			<key>Total Time</key><integer>270524</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:32:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253530258</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:24:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86579</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/07%20Angel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1488</key>
+		<dict>
+			<key>Track ID</key><integer>1488</integer>
+			<key>Name</key><string>Black and White</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3671356</integer>
+			<key>Total Time</key><integer>302863</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253538766</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:46:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8657B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/08%20Black%20and%20White.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1489</key>
+		<dict>
+			<key>Track ID</key><integer>1489</integer>
+			<key>Name</key><string>Full of Grace</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2677616</integer>
+			<key>Total Time</key><integer>220734</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250397476</integer>
+			<key>Play Date UTC</key><date>2006-12-31T16:11:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8657D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/09%20Full%20of%20Grace.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1490</key>
+		<dict>
+			<key>Track ID</key><integer>1490</integer>
+			<key>Name</key><string>Last Dance</string>
+			<key>Artist</key><string>Sarah McLachlan</string>
+			<key>Album</key><string>Surfacing</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1854571</integer>
+			<key>Total Time</key><integer>152659</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253543327</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:02:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8657F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sarah%20McLachlan/Surfacing/10%20Last%20Dance.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1491</key>
+		<dict>
+			<key>Track ID</key><integer>1491</integer>
+			<key>Name</key><string>Xpander</string>
+			<key>Artist</key><string>Sasha</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3705712</integer>
+			<key>Total Time</key><integer>231471</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253357087</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:18:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B86581</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sasha/Plastic%20Compilation,%20Vol.%203/02%20Xpander.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1492</key>
+		<dict>
+			<key>Track ID</key><integer>1492</integer>
+			<key>Name</key><string>The Red Pill</string>
+			<key>Artist</key><string>Scratch-D &#38; H-Bomb</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>David B. Noller/Scott Christina/Sean Herman</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4931278</integer>
+			<key>Total Time</key><integer>204643</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3252918917</integer>
+			<key>Play Date UTC</key><date>2007-01-29T20:35:17Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-22T19:11:55Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86584</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Scratch-D%20&#38;%20H-Bomb/Community%20Service/16%20The%20Red%20Pill.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1493</key>
+		<dict>
+			<key>Track ID</key><integer>1493</integer>
+			<key>Name</key><string>Halo of Ashes</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner, Barrett Martin &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5932200</integer>
+			<key>Total Time</key><integer>244798</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:29:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253348507</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:55:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B86586</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/01%20Halo%20of%20Ashes.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1494</key>
+		<dict>
+			<key>Track ID</key><integer>1494</integer>
+			<key>Name</key><string>All I Know</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5701851</integer>
+			<key>Total Time</key><integer>235497</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:30:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247385122</integer>
+			<key>Play Date UTC</key><date>2006-11-26T19:25:22Z</date>
+			<key>Persistent ID</key><string>87139F8602B86589</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/02%20All%20I%20Know.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1495</key>
+		<dict>
+			<key>Track ID</key><integer>1495</integer>
+			<key>Name</key><string>Look At You</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6833790</integer>
+			<key>Total Time</key><integer>282025</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:30:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246778019</integer>
+			<key>Play Date UTC</key><date>2006-11-19T18:46:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B8658B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/03%20Look%20At%20You.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1496</key>
+		<dict>
+			<key>Track ID</key><integer>1496</integer>
+			<key>Name</key><string>Dying Days</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7033202</integer>
+			<key>Total Time</key><integer>291476</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:31:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253767727</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:22:07Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8658D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/04%20Dying%20Days.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1497</key>
+		<dict>
+			<key>Track ID</key><integer>1497</integer>
+			<key>Name</key><string>Make My Mind</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6069578</integer>
+			<key>Total Time</key><integer>251796</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:32:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252537087</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:31:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B8658F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/05%20Make%20My%20Mind.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1498</key>
+		<dict>
+			<key>Track ID</key><integer>1498</integer>
+			<key>Name</key><string>Sworn and Broken</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5172062</integer>
+			<key>Total Time</key><integer>214398</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:33:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253339020</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:17:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B86591</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/06%20Sworn%20and%20Broken.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1499</key>
+		<dict>
+			<key>Track ID</key><integer>1499</integer>
+			<key>Name</key><string>Witness</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5299869</integer>
+			<key>Total Time</key><integer>219326</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:33:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249450842</integer>
+			<key>Play Date UTC</key><date>2006-12-20T17:14:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B86593</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/07%20Witness.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1500</key>
+		<dict>
+			<key>Track ID</key><integer>1500</integer>
+			<key>Name</key><string>Traveler</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7811909</integer>
+			<key>Total Time</key><integer>322430</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:34:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253551114</integer>
+			<key>Play Date UTC</key><date>2007-02-06T04:11:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B86595</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/08%20Traveler.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1501</key>
+		<dict>
+			<key>Track ID</key><integer>1501</integer>
+			<key>Name</key><string>Dime Western</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner, Barrett Martin &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5334063</integer>
+			<key>Total Time</key><integer>219881</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:35:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B86597</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/09%20Dime%20Western.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1502</key>
+		<dict>
+			<key>Track ID</key><integer>1502</integer>
+			<key>Name</key><string>Gospel Plow</string>
+			<key>Artist</key><string>Screaming Trees</string>
+			<key>Composer</key><string>Gary Lee Conner, Van Conner, Barrett Martin &#38; Mark Lanegan</string>
+			<key>Album</key><string>Dust</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9149285</integer>
+			<key>Total Time</key><integer>377662</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1996</integer>
+			<key>Date Modified</key><date>2004-06-21T13:36:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253522105</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:08:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B86599</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Screaming%20Trees/Dust/10%20Gospel%20Plow.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1503</key>
+		<dict>
+			<key>Track ID</key><integer>1503</integer>
+			<key>Name</key><string>The Beginning</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5447766</integer>
+			<key>Total Time</key><integer>340349</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252941879</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:57:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B8659B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/01%20The%20Beginning.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1504</key>
+		<dict>
+			<key>Track ID</key><integer>1504</integer>
+			<key>Name</key><string>Deep Water</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5719440</integer>
+			<key>Total Time</key><integer>357328</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253603298</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:41:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B8659E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/02%20Deep%20Water.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1505</key>
+		<dict>
+			<key>Track ID</key><integer>1505</integer>
+			<key>Name</key><string>Crazy</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5714424</integer>
+			<key>Total Time</key><integer>357015</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246632648</integer>
+			<key>Play Date UTC</key><date>2006-11-18T02:24:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B865A0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/03%20Crazy.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1506</key>
+		<dict>
+			<key>Track ID</key><integer>1506</integer>
+			<key>Name</key><string>Killer</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6124442</integer>
+			<key>Total Time</key><integer>382641</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253338033</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:00:33Z</date>
+			<key>Persistent ID</key><string>87139F8602B865A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/04%20Killer.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1507</key>
+		<dict>
+			<key>Track ID</key><integer>1507</integer>
+			<key>Name</key><string>Whirlpool</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3815636</integer>
+			<key>Total Time</key><integer>238341</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252525007</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:10:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B865A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/05%20Whirlpool.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1508</key>
+		<dict>
+			<key>Track ID</key><integer>1508</integer>
+			<key>Name</key><string>Future Love Paradise</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4169229</integer>
+			<key>Total Time</key><integer>260440</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253352942</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:09:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B865A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/06%20Future%20Love%20Paradise.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1509</key>
+		<dict>
+			<key>Track ID</key><integer>1509</integer>
+			<key>Name</key><string>Wild</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5255505</integer>
+			<key>Total Time</key><integer>328333</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252928570</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:16:10Z</date>
+			<key>Persistent ID</key><string>87139F8602B865A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/07%20Wild.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1510</key>
+		<dict>
+			<key>Track ID</key><integer>1510</integer>
+			<key>Name</key><string>Violet</string>
+			<key>Artist</key><string>Seal</string>
+			<key>Album</key><string>Seal</string>
+			<key>Genre</key><string>General R&#38;B</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8172860</integer>
+			<key>Total Time</key><integer>510667</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252923941</integer>
+			<key>Play Date UTC</key><date>2007-01-29T21:59:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B865AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Seal/Seal/09%20Violet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1511</key>
+		<dict>
+			<key>Track ID</key><integer>1511</integer>
+			<key>Name</key><string>6 Underground</string>
+			<key>Artist</key><string>Sneaker Pimps</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3954732</integer>
+			<key>Total Time</key><integer>246778</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>23</integer>
+			<key>Play Date</key><integer>3253372777</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:39:37Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-02T23:08:49Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Sneaker%20Pimps/Late%20Lounge%20(2%20of%202)/05%206%20Underground.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1512</key>
+		<dict>
+			<key>Track ID</key><integer>1512</integer>
+			<key>Name</key><string>Cry Baby [Röyksopp's Malselves Memorabilia Mix]</string>
+			<key>Artist</key><string>Spiller</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5718938</integer>
+			<key>Total Time</key><integer>357041</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253534354</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:32:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865AF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Spiller/Late%20Lounge%20(2%20of%202)/09%20Cry%20Baby%20%5BRo%CC%88yksopp's%20Malselves%20Memorabilia%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1513</key>
+		<dict>
+			<key>Track ID</key><integer>1513</integer>
+			<key>Name</key><string>I Think I'm in Love [The Chemical Brothers Remix]</string>
+			<key>Artist</key><string>Spiritualized</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5583791</integer>
+			<key>Total Time</key><integer>460355</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252562023</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:27:03Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865B2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Spiritualized/Plastic%20Compilation,%20Vol.%202/11%20I%20Think%20I'm%20in%20Love%20%5BThe%20Chemical%20Brothers%20Remix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1514</key>
+		<dict>
+			<key>Track ID</key><integer>1514</integer>
+			<key>Name</key><string>Black Cow</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4969579</integer>
+			<key>Total Time</key><integer>310334</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253594407</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:13:27Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865B5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/01%20Black%20Cow.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1515</key>
+		<dict>
+			<key>Track ID</key><integer>1515</integer>
+			<key>Name</key><string>Aja</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7646608</integer>
+			<key>Total Time</key><integer>477648</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253089911</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:05:11Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865B8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/02%20Aja.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1516</key>
+		<dict>
+			<key>Track ID</key><integer>1516</integer>
+			<key>Name</key><string>Deacon Blues</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7318510</integer>
+			<key>Total Time</key><integer>457142</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252512524</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:42:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865BA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/03%20Deacon%20Blues.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1517</key>
+		<dict>
+			<key>Track ID</key><integer>1517</integer>
+			<key>Name</key><string>Peg</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3800547</integer>
+			<key>Total Time</key><integer>237270</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253595212</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:26:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865BC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/04%20Peg.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1518</key>
+		<dict>
+			<key>Track ID</key><integer>1518</integer>
+			<key>Name</key><string>Home at Last</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5362461</integer>
+			<key>Total Time</key><integer>334889</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247845119</integer>
+			<key>Play Date UTC</key><date>2006-12-02T03:11:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865BE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/05%20Home%20at%20Last.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1519</key>
+		<dict>
+			<key>Track ID</key><integer>1519</integer>
+			<key>Name</key><string>I Got the News</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4912737</integer>
+			<key>Total Time</key><integer>306782</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253594974</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:22:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865C0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/06%20I%20Got%20the%20News.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1520</key>
+		<dict>
+			<key>Track ID</key><integer>1520</integer>
+			<key>Name</key><string>Josie</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Album</key><string>Aja</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4377749</integer>
+			<key>Total Time</key><integer>273345</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:33:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252511416</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:23:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865C2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Aja/07%20Josie.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1521</key>
+		<dict>
+			<key>Track ID</key><integer>1521</integer>
+			<key>Name</key><string>Black Friday</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5358737</integer>
+			<key>Total Time</key><integer>220905</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:28:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251634111</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:41:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B865C4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/01%20Black%20Friday.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1522</key>
+		<dict>
+			<key>Track ID</key><integer>1522</integer>
+			<key>Name</key><string>Bad Sneakers</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4862330</integer>
+			<key>Total Time</key><integer>201108</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:29:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252929420</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:30:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B865C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/02%20Bad%20Sneakers.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1523</key>
+		<dict>
+			<key>Track ID</key><integer>1523</integer>
+			<key>Name</key><string>Rose Darling</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4499524</integer>
+			<key>Total Time</key><integer>187369</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:29:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251471243</integer>
+			<key>Play Date UTC</key><date>2007-01-13T02:27:23Z</date>
+			<key>Persistent ID</key><string>87139F8602B865C9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/03%20Rose%20Darling.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1524</key>
+		<dict>
+			<key>Track ID</key><integer>1524</integer>
+			<key>Name</key><string>Daddy Don't Live In That New York City No More</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4765342</integer>
+			<key>Total Time</key><integer>196542</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:30:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252937938</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:52:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B865CB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/04%20Daddy%20Don't%20Live%20In%20That%20New%20York%20City%20No%20More.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1525</key>
+		<dict>
+			<key>Track ID</key><integer>1525</integer>
+			<key>Name</key><string>Doctor Wu</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5728911</integer>
+			<key>Total Time</key><integer>237225</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:30:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253606715</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:38:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B865CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/05%20Doctor%20Wu.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1526</key>
+		<dict>
+			<key>Track ID</key><integer>1526</integer>
+			<key>Name</key><string>Everyone's Gone To The Movies</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5500967</integer>
+			<key>Total Time</key><integer>226836</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:31:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253453900</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:11:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B865CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/06%20Everyone's%20Gone%20To%20The%20Movies.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1527</key>
+		<dict>
+			<key>Track ID</key><integer>1527</integer>
+			<key>Name</key><string>Your Gold Teeth II</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6172528</integer>
+			<key>Total Time</key><integer>254910</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:32:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253292024</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:13:44Z</date>
+			<key>Persistent ID</key><string>87139F8602B865D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/07%20Your%20Gold%20Teeth%20II.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1528</key>
+		<dict>
+			<key>Track ID</key><integer>1528</integer>
+			<key>Name</key><string>Chain Lightning</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4401772</integer>
+			<key>Total Time</key><integer>181694</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:32:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253616560</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:22:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B865D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/08%20Chain%20Lightning.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1529</key>
+		<dict>
+			<key>Track ID</key><integer>1529</integer>
+			<key>Name</key><string>Any World (That I'm Welcome To)</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5704619</integer>
+			<key>Total Time</key><integer>235305</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:33:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253527208</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:33:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B865D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/09%20Any%20World%20(That%20I'm%20Welcome%20To).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1530</key>
+		<dict>
+			<key>Track ID</key><integer>1530</integer>
+			<key>Name</key><string>Throw Back The Little Ones</string>
+			<key>Artist</key><string>Steely Dan</string>
+			<key>Composer</key><string>Steely Dan</string>
+			<key>Album</key><string>Katy Lied</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4729693</integer>
+			<key>Total Time</key><integer>195604</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1975</integer>
+			<key>Date Modified</key><date>2004-07-18T18:34:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251894100</integer>
+			<key>Play Date UTC</key><date>2007-01-17T23:55:00Z</date>
+			<key>Persistent ID</key><string>87139F8602B865D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Steely%20Dan/Katy%20Lied/10%20Throw%20Back%20The%20Little%20Ones.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1531</key>
+		<dict>
+			<key>Track ID</key><integer>1531</integer>
+			<key>Name</key><string>Breakin On The Streets (False Prophet Remix)</string>
+			<key>Artist</key><string>Stir Fry</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>John Ross</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5657900</integer>
+			<key>Total Time</key><integer>234919</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B865D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Stir%20Fry/Community%20Service/03%20Breakin%20On%20The%20Streets%20(False%20Prophet%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1532</key>
+		<dict>
+			<key>Track ID</key><integer>1532</integer>
+			<key>Name</key><string>Big Empty</string>
+			<key>Artist</key><string>Stone Temple Pilots</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3597231</integer>
+			<key>Total Time</key><integer>296515</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253090208</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:10:08Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T20:55:09Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B865DB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Stone%20Temple%20Pilots/The%20Crow/03%20Big%20Empty.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1533</key>
+		<dict>
+			<key>Track ID</key><integer>1533</integer>
+			<key>Name</key><string>Gone Hollywood</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34346695</integer>
+			<key>Total Time</key><integer>319573</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-08-22T18:46:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>859</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252540214</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:23:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B865DE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/01%20Gone%20Hollywood.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1534</key>
+		<dict>
+			<key>Track ID</key><integer>1534</integer>
+			<key>Name</key><string>The Logical Song</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>28151074</integer>
+			<key>Total Time</key><integer>251133</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-09-26T17:25:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>896</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253597891</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:11:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B865E1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/02%20The%20Logical%20Song.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1535</key>
+		<dict>
+			<key>Track ID</key><integer>1535</integer>
+			<key>Name</key><string>Goodbye Stranger</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>39054873</integer>
+			<key>Total Time</key><integer>350600</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2004-08-22T18:48:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>890</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252440676</integer>
+			<key>Play Date UTC</key><date>2007-01-24T07:44:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B865E3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/03%20Goodbye%20Stranger.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1536</key>
+		<dict>
+			<key>Track ID</key><integer>1536</integer>
+			<key>Name</key><string>Breakfast In America</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>18700703</integer>
+			<key>Total Time</key><integer>159333</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-10-03T13:01:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>937</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249540725</integer>
+			<key>Play Date UTC</key><date>2006-12-21T18:12:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B865E5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/04%20Breakfast%20In%20America.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1537</key>
+		<dict>
+			<key>Track ID</key><integer>1537</integer>
+			<key>Name</key><string>Oh Darling</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25713917</integer>
+			<key>Total Time</key><integer>228826</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-10-18T16:17:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>898</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252409849</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:10:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B865E7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/05%20Oh%20Darling.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1538</key>
+		<dict>
+			<key>Track ID</key><integer>1538</integer>
+			<key>Name</key><string>Take The Long Way Home</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>34147064</integer>
+			<key>Total Time</key><integer>308906</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-09-24T17:25:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>883</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249530883</integer>
+			<key>Play Date UTC</key><date>2006-12-21T15:28:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B865E9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/06%20Take%20The%20Long%20Way%20Home.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1539</key>
+		<dict>
+			<key>Track ID</key><integer>1539</integer>
+			<key>Name</key><string>Lord Is It Mine</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25112996</integer>
+			<key>Total Time</key><integer>250000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-09-26T20:31:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>802</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252527166</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:46:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B865EB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/07%20Lord%20Is%20It%20Mine.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1540</key>
+		<dict>
+			<key>Track ID</key><integer>1540</integer>
+			<key>Name</key><string>Just Another Nervous Wreck</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>30781489</integer>
+			<key>Total Time</key><integer>265733</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-09-26T16:26:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>925</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252534899</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:54:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B865ED</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/08%20Just%20Another%20Nervous%20Wreck.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1541</key>
+		<dict>
+			<key>Track ID</key><integer>1541</integer>
+			<key>Name</key><string>Casual Conversations</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>16403308</integer>
+			<key>Total Time</key><integer>178866</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-10-17T18:46:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>732</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250619430</integer>
+			<key>Play Date UTC</key><date>2007-01-03T05:50:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-18T01:58:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B865EF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/09%20Casual%20Conversations.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1542</key>
+		<dict>
+			<key>Track ID</key><integer>1542</integer>
+			<key>Name</key><string>Child Of Vision</string>
+			<key>Artist</key><string>Supertramp</string>
+			<key>Album</key><string>Breakfast In America</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>52448214</integer>
+			<key>Total Time</key><integer>447666</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>1979</integer>
+			<key>Date Modified</key><date>2005-10-06T20:54:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>936</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246529700</integer>
+			<key>Play Date UTC</key><date>2006-11-16T21:48:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B865F1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Supertramp/Breakfast%20In%20America/10%20Child%20Of%20Vision.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1543</key>
+		<dict>
+			<key>Track ID</key><integer>1543</integer>
+			<key>Name</key><string>Psycho Killer</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Chris Frantz/David Byrne/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6538705</integer>
+			<key>Total Time</key><integer>269844</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:17:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253275968</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:46:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B865F3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/01%20Psycho%20Killer.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1544</key>
+		<dict>
+			<key>Track ID</key><integer>1544</integer>
+			<key>Name</key><string>Swamp</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Chris Frantz/David Byrne/Jerry Harrison/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6508222</integer>
+			<key>Total Time</key><integer>268564</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:20:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253612949</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:22:29Z</date>
+			<key>Persistent ID</key><string>87139F8602B865F6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/02%20Swamp.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1545</key>
+		<dict>
+			<key>Track ID</key><integer>1545</integer>
+			<key>Name</key><string>Slippery People</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Chris Frantz/David Byrne/Jerry Harrison/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6131719</integer>
+			<key>Total Time</key><integer>253609</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:23:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:56Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253601010</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:03:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B865F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/03%20Slippery%20People.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1546</key>
+		<dict>
+			<key>Track ID</key><integer>1546</integer>
+			<key>Name</key><string>Burning Down The House</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Chris Frantz/David Byrne/Jerry Harrison/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6139033</integer>
+			<key>Total Time</key><integer>254292</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:26:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249547368</integer>
+			<key>Play Date UTC</key><date>2006-12-21T20:02:48Z</date>
+			<key>Persistent ID</key><string>87139F8602B865FA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/04%20Burning%20Down%20The%20House.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1547</key>
+		<dict>
+			<key>Track ID</key><integer>1547</integer>
+			<key>Name</key><string>Girlfriend Is Better</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Chris Frantz/David Byrne/Jerry Harrison/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7423140</integer>
+			<key>Total Time</key><integer>307241</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:30:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249543534</integer>
+			<key>Play Date UTC</key><date>2006-12-21T18:58:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B865FC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/05%20Girlfriend%20Is%20Better.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1548</key>
+		<dict>
+			<key>Track ID</key><integer>1548</integer>
+			<key>Name</key><string>Once In A Lifetime</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Brian Eno/Chris Frantz/David Byrne/Jerry Harrison/Tina Weymouth</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8058339</integer>
+			<key>Total Time</key><integer>333972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:34:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246906645</integer>
+			<key>Play Date UTC</key><date>2006-11-21T06:30:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B865FE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/06%20Once%20In%20A%20Lifetime.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1549</key>
+		<dict>
+			<key>Track ID</key><integer>1549</integer>
+			<key>Name</key><string>What A Day That Was</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>David Byrne</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9377218</integer>
+			<key>Total Time</key><integer>390825</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:38:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252505555</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:45:55Z</date>
+			<key>Persistent ID</key><string>87139F8602B86600</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/07%20What%20A%20Day%20That%20Was.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1550</key>
+		<dict>
+			<key>Track ID</key><integer>1550</integer>
+			<key>Name</key><string>Life During Wartime</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>David Byrne</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8521998</integer>
+			<key>Total Time</key><integer>352596</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:43:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253090560</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:16:00Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-04T22:26:37Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86602</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/08%20Life%20During%20Wartime.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1551</key>
+		<dict>
+			<key>Track ID</key><integer>1551</integer>
+			<key>Name</key><string>Take Me To The River</string>
+			<key>Artist</key><string>Talking Heads</string>
+			<key>Composer</key><string>Al Green/M. Hodges</string>
+			<key>Album</key><string>Stop Making Sense</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8717934</integer>
+			<key>Total Time</key><integer>360937</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1984</integer>
+			<key>Date Modified</key><date>2004-05-04T16:47:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253544949</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:29:09Z</date>
+			<key>Persistent ID</key><string>87139F8602B86604</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Talking%20Heads/Stop%20Making%20Sense/09%20Take%20Me%20To%20The%20River.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1552</key>
+		<dict>
+			<key>Track ID</key><integer>1552</integer>
+			<key>Name</key><string>Me And Mia</string>
+			<key>Artist</key><string>Ted Leo/Pharmacists</string>
+			<key>Album</key><string>Shake The Sheets</string>
+			<key>Genre</key><string>genre</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3381376</integer>
+			<key>Total Time</key><integer>211200</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2005-02-23T21:05:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252509976</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:59:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B86606</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Ted%20Leo_Pharmacists/Shake%20The%20Sheets/01%20Me%20And%20Mia.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1553</key>
+		<dict>
+			<key>Track ID</key><integer>1553</integer>
+			<key>Name</key><string>If u want me</string>
+			<key>Artist</key><string>The Aphrodisiacs</string>
+			<key>Album</key><string>The is a Campaign (Master)</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2623198</integer>
+			<key>Total Time</key><integer>163813</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2005-02-27T02:14:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253454064</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:14:24Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T21:43:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B86609</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Aphrodisiacs/The%20is%20a%20Campaign%20(Master)/04%20If%20u%20want%20me.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1554</key>
+		<dict>
+			<key>Track ID</key><integer>1554</integer>
+			<key>Name</key><string>Rebellion (Lies)</string>
+			<key>Artist</key><string>The Arcade Fire</string>
+			<key>Album</key><string>Funeral</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4977573</integer>
+			<key>Total Time</key><integer>310961</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T21:03:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253353581</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:19:41Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T02:29:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B8660C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Arcade%20Fire/Funeral/09%20Rebellion%20(Lies).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1555</key>
+		<dict>
+			<key>Track ID</key><integer>1555</integer>
+			<key>Name</key><string>Slumberdoll</string>
+			<key>Artist</key><string>The Autumns</string>
+			<key>Album</key><string>The Autumns</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3254748</integer>
+			<key>Total Time</key><integer>203284</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-02-23T21:03:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252549221</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:53:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B8660F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Autumns/The%20Autumns/07%20Slumberdoll.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1556</key>
+		<dict>
+			<key>Track ID</key><integer>1556</integer>
+			<key>Name</key><string>Come With Us</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4771056</integer>
+			<key>Total Time</key><integer>297665</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253557823</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:03:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86612</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/01%20Come%20With%20Us.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1557</key>
+		<dict>
+			<key>Track ID</key><integer>1557</integer>
+			<key>Name</key><string>It Began in Afrika</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6027865</integer>
+			<key>Total Time</key><integer>376215</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253090937</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:22:17Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T17:29:05Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86615</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/02%20It%20Began%20in%20Afrika.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1558</key>
+		<dict>
+			<key>Track ID</key><integer>1558</integer>
+			<key>Name</key><string>Galaxy Bounce</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3335367</integer>
+			<key>Total Time</key><integer>207934</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>33</integer>
+			<key>Play Date</key><integer>3253688213</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:16:53Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-12T21:32:30Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86617</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/03%20Galaxy%20Bounce.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1559</key>
+		<dict>
+			<key>Track ID</key><integer>1559</integer>
+			<key>Name</key><string>Star Guitar</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6203819</integer>
+			<key>Total Time</key><integer>387213</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253766468</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:01:08Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86619</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/04%20Star%20Guitar.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1560</key>
+		<dict>
+			<key>Track ID</key><integer>1560</integer>
+			<key>Name</key><string>Hoops</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6278210</integer>
+			<key>Total Time</key><integer>391862</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252496327</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:12:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8661B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/05%20Hoops.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1561</key>
+		<dict>
+			<key>Track ID</key><integer>1561</integer>
+			<key>Name</key><string>My Elastic Eye</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3557722</integer>
+			<key>Total Time</key><integer>221831</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>34</integer>
+			<key>Play Date</key><integer>3253677255</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:14:15Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-19T02:40:58Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8661D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/06%20My%20Elastic%20Eye.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1562</key>
+		<dict>
+			<key>Track ID</key><integer>1562</integer>
+			<key>Name</key><string>The State We're In</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6198393</integer>
+			<key>Total Time</key><integer>386873</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251455612</integer>
+			<key>Play Date UTC</key><date>2007-01-12T22:06:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T21:16:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8661F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/07%20The%20State%20We're%20In.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1563</key>
+		<dict>
+			<key>Track ID</key><integer>1563</integer>
+			<key>Name</key><string>Denmark</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4921934</integer>
+			<key>Total Time</key><integer>307095</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253707472</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:37:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-27T23:10:12Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86621</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/08%20Denmark.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1564</key>
+		<dict>
+			<key>Track ID</key><integer>1564</integer>
+			<key>Name</key><string>Pioneer Skies</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3921764</integer>
+			<key>Total Time</key><integer>244584</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252510220</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:03:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-14T16:50:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86623</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/09%20Pioneer%20Skies.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1565</key>
+		<dict>
+			<key>Track ID</key><integer>1565</integer>
+			<key>Name</key><string>The Test</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Come with Us</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7469397</integer>
+			<key>Total Time</key><integer>466311</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253110290</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:44:50Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86625</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Come%20with%20Us/10%20The%20Test.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1566</key>
+		<dict>
+			<key>Track ID</key><integer>1566</integer>
+			<key>Name</key><string>Block Rockin' Beats</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7638027</integer>
+			<key>Total Time</key><integer>314814</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253600756</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:59:16Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86627</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/01%20Block%20Rockin'%20Beats.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1567</key>
+		<dict>
+			<key>Track ID</key><integer>1567</integer>
+			<key>Name</key><string>Dig Your Own Hole</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7942894</integer>
+			<key>Total Time</key><integer>327401</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253558890</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:21:30Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8662A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/02%20Dig%20Your%20Own%20Hole.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1568</key>
+		<dict>
+			<key>Track ID</key><integer>1568</integer>
+			<key>Name</key><string>Elektrobank</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>12089813</integer>
+			<key>Total Time</key><integer>498644</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253274615</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:23:35Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T00:35:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8662C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/03%20Elektrobank.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1569</key>
+		<dict>
+			<key>Track ID</key><integer>1569</integer>
+			<key>Name</key><string>Piku</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7145844</integer>
+			<key>Total Time</key><integer>294484</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253773130</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:52:10Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-02T14:03:53Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8662E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/04%20Piku.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1570</key>
+		<dict>
+			<key>Track ID</key><integer>1570</integer>
+			<key>Name</key><string>Setting Sun</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7960502</integer>
+			<key>Total Time</key><integer>328958</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253344205</integer>
+			<key>Play Date UTC</key><date>2007-02-03T18:43:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86630</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/05%20Setting%20Sun.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1571</key>
+		<dict>
+			<key>Track ID</key><integer>1571</integer>
+			<key>Name</key><string>It Doesn't Matter</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9080315</integer>
+			<key>Total Time</key><integer>374377</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86632</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/06%20It%20Doesn't%20Matter.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1572</key>
+		<dict>
+			<key>Track ID</key><integer>1572</integer>
+			<key>Name</key><string>Don't Stop The Rock</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6998536</integer>
+			<key>Total Time</key><integer>288404</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253548360</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:26:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86634</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/07%20Don't%20Stop%20The%20Rock.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1573</key>
+		<dict>
+			<key>Track ID</key><integer>1573</integer>
+			<key>Name</key><string>Get Up On It Like This</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4062141</integer>
+			<key>Total Time</key><integer>168041</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253092315</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:45:15Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-08T00:07:27Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86636</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/08%20Get%20Up%20On%20It%20Like%20This.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1574</key>
+		<dict>
+			<key>Track ID</key><integer>1574</integer>
+			<key>Name</key><string>Lost In The K-Hole</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5633994</integer>
+			<key>Total Time</key><integer>231934</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251457204</integer>
+			<key>Play Date UTC</key><date>2007-01-12T22:33:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86638</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/09%20Lost%20In%20The%20K-Hole.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1575</key>
+		<dict>
+			<key>Track ID</key><integer>1575</integer>
+			<key>Name</key><string>Where Do I Begin</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9970013</integer>
+			<key>Total Time</key><integer>411092</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253092726</integer>
+			<key>Play Date UTC</key><date>2007-01-31T20:52:06Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8663A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/10%20Where%20Do%20I%20Begin.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1576</key>
+		<dict>
+			<key>Track ID</key><integer>1576</integer>
+			<key>Name</key><string>The Private Psychedelic Reel</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Composer</key><string>chemical brothers</string>
+			<key>Album</key><string>Dig Your Own Hole</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13769752</integer>
+			<key>Total Time</key><integer>568297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-08-01T15:45:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253602941</integer>
+			<key>Play Date UTC</key><date>2007-02-06T18:35:41Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8663C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Dig%20Your%20Own%20Hole/11%20The%20Private%20Psychedelic%20Reel.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1577</key>
+		<dict>
+			<key>Track ID</key><integer>1577</integer>
+			<key>Name</key><string>Leave Home</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10663231</integer>
+			<key>Total Time</key><integer>332617</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:44:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253531057</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:37:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8663E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/01%20Leave%20Home.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1578</key>
+		<dict>
+			<key>Track ID</key><integer>1578</integer>
+			<key>Name</key><string>In Dust We Trust</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10186758</integer>
+			<key>Total Time</key><integer>317727</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:46:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251346809</integer>
+			<key>Play Date UTC</key><date>2007-01-11T15:53:29Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86641</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/02%20In%20Dust%20We%20Trust.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1579</key>
+		<dict>
+			<key>Track ID</key><integer>1579</integer>
+			<key>Name</key><string>Song To The Siren</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6318963</integer>
+			<key>Total Time</key><integer>196858</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:44:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253621405</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:43:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86643</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/03%20Song%20To%20The%20Siren.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1580</key>
+		<dict>
+			<key>Track ID</key><integer>1580</integer>
+			<key>Name</key><string>Three Little Birdies Down Beat</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10859672</integer>
+			<key>Total Time</key><integer>338755</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:47:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253542489</integer>
+			<key>Play Date UTC</key><date>2007-02-06T01:48:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86645</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/04%20Three%20Little%20Birdies%20Down%20Beat.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1582</key>
+		<dict>
+			<key>Track ID</key><integer>1582</integer>
+			<key>Name</key><string>Chemical Beats</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9311551</integer>
+			<key>Total Time</key><integer>290377</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:44:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253093585</integer>
+			<key>Play Date UTC</key><date>2007-01-31T21:06:25Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-23T04:58:55Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86649</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/06%20Chemical%20Beats.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1583</key>
+		<dict>
+			<key>Track ID</key><integer>1583</integer>
+			<key>Name</key><string>Chico's Groove</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9260560</integer>
+			<key>Total Time</key><integer>288783</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:45:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253256181</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:16:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8664B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/07%20Chico's%20Groove.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1584</key>
+		<dict>
+			<key>Track ID</key><integer>1584</integer>
+			<key>Name</key><string>One Too Many Mornings</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8122875</integer>
+			<key>Total Time</key><integer>253231</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:45:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3251619040</integer>
+			<key>Play Date UTC</key><date>2007-01-14T19:30:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8664D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/08%20One%20Too%20Many%20Mornings.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1585</key>
+		<dict>
+			<key>Track ID</key><integer>1585</integer>
+			<key>Name</key><string>Life Is Sweet</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12615101</integer>
+			<key>Total Time</key><integer>393613</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:46:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3251459093</integer>
+			<key>Play Date UTC</key><date>2007-01-12T23:04:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8664F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/09%20Life%20Is%20Sweet.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1586</key>
+		<dict>
+			<key>Track ID</key><integer>1586</integer>
+			<key>Name</key><string>Playground For A Wedgeless Firm</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4878679</integer>
+			<key>Total Time</key><integer>151849</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:46:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251459245</integer>
+			<key>Play Date UTC</key><date>2007-01-12T23:07:25Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-22T21:55:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86651</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/10%20Playground%20For%20A%20Wedgeless%20Firm.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1587</key>
+		<dict>
+			<key>Track ID</key><integer>1587</integer>
+			<key>Name</key><string>Alive Alone</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Exit Planet Dust</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10149978</integer>
+			<key>Total Time</key><integer>316577</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1995</integer>
+			<key>Date Modified</key><date>2004-11-29T13:46:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>http://mp3xchange.da.ru</string>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251459562</integer>
+			<key>Play Date UTC</key><date>2007-01-12T23:12:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86653</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Exit%20Planet%20Dust/11%20Alive%20Alone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1588</key>
+		<dict>
+			<key>Track ID</key><integer>1588</integer>
+			<key>Name</key><string>Under the Influence</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 3</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4103609</integer>
+			<key>Total Time</key><integer>256339</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253463500</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:51:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T02:45:37Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86655</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Plastic%20Compilation,%20Vol.%203/09%20Under%20the%20Influence.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1589</key>
+		<dict>
+			<key>Track ID</key><integer>1589</integer>
+			<key>Name</key><string>Music: Response</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5132416</integer>
+			<key>Total Time</key><integer>320000</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253622769</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:06:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86658</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/01%20Music_%20Response.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1590</key>
+		<dict>
+			<key>Track ID</key><integer>1590</integer>
+			<key>Name</key><string>under the influence</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4109670</integer>
+			<key>Total Time</key><integer>256078</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253347458</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:37:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8665B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/02%20under%20the%20influence.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1591</key>
+		<dict>
+			<key>Track ID</key><integer>1591</integer>
+			<key>Name</key><string>Out of Control</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7049177</integer>
+			<key>Total Time</key><integer>439797</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251460833</integer>
+			<key>Play Date UTC</key><date>2007-01-12T23:33:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8665D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/03%20Out%20of%20Control.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1592</key>
+		<dict>
+			<key>Track ID</key><integer>1592</integer>
+			<key>Name</key><string>Orange Wedge</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2999152</integer>
+			<key>Total Time</key><integer>186671</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252579616</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:20:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8665F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/04%20Orange%20Wedge.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1593</key>
+		<dict>
+			<key>Track ID</key><integer>1593</integer>
+			<key>Name</key><string>Let Forever Be</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3794947</integer>
+			<key>Total Time</key><integer>236408</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251730105</integer>
+			<key>Play Date UTC</key><date>2007-01-16T02:21:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86661</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/05%20Let%20Forever%20Be.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1594</key>
+		<dict>
+			<key>Track ID</key><integer>1594</integer>
+			<key>Name</key><string>The Sunshine Underground</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8315593</integer>
+			<key>Total Time</key><integer>518948</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250581062</integer>
+			<key>Play Date UTC</key><date>2007-01-02T19:11:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86663</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/06%20The%20Sunshine%20Underground.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1595</key>
+		<dict>
+			<key>Track ID</key><integer>1595</integer>
+			<key>Name</key><string>Asleep from Day</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4608713</integer>
+			<key>Total Time</key><integer>287268</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252521635</integer>
+			<key>Play Date UTC</key><date>2007-01-25T06:13:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86665</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/07%20Asleep%20from%20Day.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1596</key>
+		<dict>
+			<key>Track ID</key><integer>1596</integer>
+			<key>Name</key><string>Got Glint?</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5236070</integer>
+			<key>Total Time</key><integer>326478</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253378573</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:16:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86667</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/08%20Got%20Glint_.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1597</key>
+		<dict>
+			<key>Track ID</key><integer>1597</integer>
+			<key>Name</key><string>Hey Boy Hey Girl</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4660958</integer>
+			<key>Total Time</key><integer>290533</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253358743</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:45:43Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86669</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/09%20Hey%20Boy%20Hey%20Girl.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1598</key>
+		<dict>
+			<key>Track ID</key><integer>1598</integer>
+			<key>Name</key><string>surrender</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4333696</integer>
+			<key>Total Time</key><integer>270080</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3247552550</integer>
+			<key>Play Date UTC</key><date>2006-11-28T17:55:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8666B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/10%20surrender.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1599</key>
+		<dict>
+			<key>Track ID</key><integer>1599</integer>
+			<key>Name</key><string>Dream On</string>
+			<key>Artist</key><string>The Chemical Brothers</string>
+			<key>Album</key><string>Surrender</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6517533</integer>
+			<key>Total Time</key><integer>406569</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249204015</integer>
+			<key>Play Date UTC</key><date>2006-12-17T20:40:15Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-24T22:55:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8666D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Chemical%20Brothers/Surrender/11%20Dream%20On.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1600</key>
+		<dict>
+			<key>Track ID</key><integer>1600</integer>
+			<key>Name</key><string>Name Of The Game (Hybrid's LA Blackout Remix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Ken Jordan/Scott Kirkland/Tom Morello</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8417193</integer>
+			<key>Total Time</key><integer>349100</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253679133</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:45:33Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-18T23:36:03Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B8666F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Community%20Service/08%20Name%20Of%20The%20Game%20(Hybrid's%20LA%20Blackout%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1601</key>
+		<dict>
+			<key>Track ID</key><integer>1601</integer>
+			<key>Name</key><string>Wild, Sweet &#38; Cool (Static Revenger Mix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Ken Jordan/Scott Kirkland/Tom Morello</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6398450</integer>
+			<key>Total Time</key><integer>264986</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:57Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253473590</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:39:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B86671</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Community%20Service/13%20Wild,%20Sweet%20&#38;%20Cool%20(Static%20Revenger%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1602</key>
+		<dict>
+			<key>Track ID</key><integer>1602</integer>
+			<key>Name</key><string>You Know Its Hard (Koma + Bones Remix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Composer</key><string>Ken Jordan/Scott Kirkland</string>
+			<key>Album</key><string>Community Service</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9656024</integer>
+			<key>Total Time</key><integer>400718</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253506575</integer>
+			<key>Play Date UTC</key><date>2007-02-05T15:49:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B86673</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Community%20Service/15%20You%20Know%20Its%20Hard%20(Koma%20+%20Bones%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1603</key>
+		<dict>
+			<key>Track ID</key><integer>1603</integer>
+			<key>Name</key><string>Badass</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>CSII Exclusives - EP</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5597981</integer>
+			<key>Total Time</key><integer>323150</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-10-12T22:53:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3250614849</integer>
+			<key>Play Date UTC</key><date>2007-01-03T04:34:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86675</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/CSII%20Exclusives%20-%20EP/01%20Badass.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1604</key>
+		<dict>
+			<key>Track ID</key><integer>1604</integer>
+			<key>Name</key><string>Bound Too Long (Hyper Mix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>CSII Exclusives - EP</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7298461</integer>
+			<key>Total Time</key><integer>427152</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-10-12T22:54:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253338806</integer>
+			<key>Play Date UTC</key><date>2007-02-03T17:13:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86677</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/CSII%20Exclusives%20-%20EP/02%20Bound%20Too%20Long%20(Hyper%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1605</key>
+		<dict>
+			<key>Track ID</key><integer>1605</integer>
+			<key>Name</key><string>Keep Hope Alive (JDS Mix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>CSII Exclusives - EP</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7912717</integer>
+			<key>Total Time</key><integer>466487</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-10-12T22:57:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253530724</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:32:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86679</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/CSII%20Exclusives%20-%20EP/04%20Keep%20Hope%20Alive%20(JDS%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1606</key>
+		<dict>
+			<key>Track ID</key><integer>1606</integer>
+			<key>Name</key><string>Starting Over (Elite Force Mix)</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>CSII Exclusives - EP</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8229277</integer>
+			<key>Total Time</key><integer>485458</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2005-10-12T22:58:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253094966</integer>
+			<key>Play Date UTC</key><date>2007-01-31T21:29:26Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8667B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/CSII%20Exclusives%20-%20EP/05%20Starting%20Over%20(Elite%20Force%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1607</key>
+		<dict>
+			<key>Track ID</key><integer>1607</integer>
+			<key>Name</key><string>Starting Over</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4372220</integer>
+			<key>Total Time</key><integer>242925</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-27T05:34:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3250620476</integer>
+			<key>Play Date UTC</key><date>2007-01-03T06:07:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8667D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/01%20Starting%20Over.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1608</key>
+		<dict>
+			<key>Track ID</key><integer>1608</integer>
+			<key>Name</key><string>Born Too Slow</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3350796</integer>
+			<key>Total Time</key><integer>179790</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T04:12:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>24</integer>
+			<key>Play Date</key><integer>3253110470</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:47:50Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86680</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/02%20Born%20Too%20Slow.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1609</key>
+		<dict>
+			<key>Track ID</key><integer>1609</integer>
+			<key>Name</key><string>True Grit</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5405548</integer>
+			<key>Total Time</key><integer>306803</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T01:50:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253712076</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:54:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T23:27:49Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86682</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/03%20True%20Grit.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1610</key>
+		<dict>
+			<key>Track ID</key><integer>1610</integer>
+			<key>Name</key><string>The American Way</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4762268</integer>
+			<key>Total Time</key><integer>267028</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-25T15:02:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253354819</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:40:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86684</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/04%20The%20American%20Way.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1611</key>
+		<dict>
+			<key>Track ID</key><integer>1611</integer>
+			<key>Name</key><string>I Know It's You</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6084844</integer>
+			<key>Total Time</key><integer>348785</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-22T01:37:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253531665</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:47:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86686</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/05%20I%20Know%20It's%20You.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1612</key>
+		<dict>
+			<key>Track ID</key><integer>1612</integer>
+			<key>Name</key><string>Realizer</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4146044</integer>
+			<key>Total Time</key><integer>228947</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-21T22:19:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247048094</integer>
+			<key>Play Date UTC</key><date>2006-11-22T21:48:14Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86688</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/06%20Realizer.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1613</key>
+		<dict>
+			<key>Track ID</key><integer>1613</integer>
+			<key>Name</key><string>Broken Glass</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4252316</integer>
+			<key>Total Time</key><integer>235518</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-18T17:37:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253452848</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:54:08Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8668A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/07%20Broken%20Glass.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1614</key>
+		<dict>
+			<key>Track ID</key><integer>1614</integer>
+			<key>Name</key><string>Weapons of Mass Distortion</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5154060</integer>
+			<key>Total Time</key><integer>291246</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-08T20:21:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>33</integer>
+			<key>Play Date</key><integer>3253537927</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:32:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-17T06:15:45Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8668C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/08%20Weapons%20of%20Mass%20Distortion.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1615</key>
+		<dict>
+			<key>Track ID</key><integer>1615</integer>
+			<key>Name</key><string>Bound Too Long</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6648092</integer>
+			<key>Total Time</key><integer>383592</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-30T01:32:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253770980</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:16:20Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-04T22:26:44Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8668E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/09%20Bound%20Too%20Long.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1616</key>
+		<dict>
+			<key>Track ID</key><integer>1616</integer>
+			<key>Name</key><string>Acetone</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5547580</integer>
+			<key>Total Time</key><integer>315580</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-25T13:52:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253767141</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:12:21Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86690</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/10%20Acetone.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1617</key>
+		<dict>
+			<key>Track ID</key><integer>1617</integer>
+			<key>Name</key><string>High and Low</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5688540</integer>
+			<key>Total Time</key><integer>324288</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-07-18T17:43:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249191751</integer>
+			<key>Play Date UTC</key><date>2006-12-17T17:15:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86692</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/11%20High%20and%20Low.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1618</key>
+		<dict>
+			<key>Track ID</key><integer>1618</integer>
+			<key>Name</key><string>Wide Open</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Legion of Boom</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7610252</integer>
+			<key>Total Time</key><integer>443058</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2004</integer>
+			<key>Date Modified</key><date>2005-08-09T03:44:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253384275</integer>
+			<key>Play Date UTC</key><date>2007-02-04T05:51:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86694</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Legion%20of%20Boom/12%20Wide%20Open.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1619</key>
+		<dict>
+			<key>Track ID</key><integer>1619</integer>
+			<key>Name</key><string>Comin' Back [The Light's Southern Grit Mix]</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6416554</integer>
+			<key>Total Time</key><integer>529240</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253619041</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:04:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86696</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Plastic%20Compilation,%20Vol.%202/01%20Comin'%20Back%20%5BThe%20Light's%20Southern%20Grit%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1620</key>
+		<dict>
+			<key>Track ID</key><integer>1620</integer>
+			<key>Name</key><string>Roll It Up</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8753284</integer>
+			<key>Total Time</key><integer>362132</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:37:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253710338</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:25:38Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-20T22:40:43Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86699</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/03%20Roll%20It%20Up.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1621</key>
+		<dict>
+			<key>Track ID</key><integer>1621</integer>
+			<key>Name</key><string>Murder</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4485624</integer>
+			<key>Total Time</key><integer>280215</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>21</integer>
+			<key>Play Date</key><integer>3253110750</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:52:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-08T21:42:07Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B8669C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/04%20Murder.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1622</key>
+		<dict>
+			<key>Track ID</key><integer>1622</integer>
+			<key>Name</key><string>Name Of The Game</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6176539</integer>
+			<key>Total Time</key><integer>255060</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:38:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3245669805</integer>
+			<key>Play Date UTC</key><date>2006-11-06T22:56:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B8669E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/05%20Name%20Of%20The%20Game.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1623</key>
+		<dict>
+			<key>Track ID</key><integer>1623</integer>
+			<key>Name</key><string>The Winner</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7551593</integer>
+			<key>Total Time</key><integer>311678</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:39:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250574248</integer>
+			<key>Play Date UTC</key><date>2007-01-02T17:17:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B866A0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/06%20The%20Winner.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1624</key>
+		<dict>
+			<key>Track ID</key><integer>1624</integer>
+			<key>Name</key><string>Ready For Action</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7297018</integer>
+			<key>Total Time</key><integer>301396</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:40:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247050022</integer>
+			<key>Play Date UTC</key><date>2006-11-22T22:20:22Z</date>
+			<key>Persistent ID</key><string>87139F8602B866A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/07%20Ready%20For%20Action.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1625</key>
+		<dict>
+			<key>Track ID</key><integer>1625</integer>
+			<key>Name</key><string>Ten Miles Back</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10174141</integer>
+			<key>Total Time</key><integer>420414</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:41:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253261651</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:47:31Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B866A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/08%20Ten%20Miles%20Back.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1626</key>
+		<dict>
+			<key>Track ID</key><integer>1626</integer>
+			<key>Name</key><string>Over The Line</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>10020703</integer>
+			<key>Total Time</key><integer>414334</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:43:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249463647</integer>
+			<key>Play Date UTC</key><date>2006-12-20T20:47:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B866A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/09%20Over%20The%20Line.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1627</key>
+		<dict>
+			<key>Track ID</key><integer>1627</integer>
+			<key>Name</key><string>Blowout</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11550363</integer>
+			<key>Total Time</key><integer>477609</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:44:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253097666</integer>
+			<key>Play Date UTC</key><date>2007-01-31T22:14:26Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T19:09:35Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B866A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/10%20Blowout.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1628</key>
+		<dict>
+			<key>Track ID</key><integer>1628</integer>
+			<key>Name</key><string>Tough Guy</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Tweekend</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>15730428</integer>
+			<key>Total Time</key><integer>692436</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-17T16:57:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253709976</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:19:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T19:11:07Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B866AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Tweekend/11%20Tough%20Guy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1629</key>
+		<dict>
+			<key>Track ID</key><integer>1629</integer>
+			<key>Name</key><string>Trip Like I Do</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7282774</integer>
+			<key>Total Time</key><integer>454269</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253528484</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:54:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/01%20Trip%20Like%20I%20Do.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1630</key>
+		<dict>
+			<key>Track ID</key><integer>1630</integer>
+			<key>Name</key><string>Busy Child</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7135235</integer>
+			<key>Total Time</key><integer>445048</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253690869</integer>
+			<key>Play Date UTC</key><date>2007-02-07T19:01:09Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-11T02:45:32Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866AF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/02%20Busy%20Child.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1631</key>
+		<dict>
+			<key>Track ID</key><integer>1631</integer>
+			<key>Name</key><string>Cherry Twist</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4264691</integer>
+			<key>Total Time</key><integer>265639</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247031484</integer>
+			<key>Play Date UTC</key><date>2006-11-22T17:11:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866B1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/03%20Cherry%20Twist.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1632</key>
+		<dict>
+			<key>Track ID</key><integer>1632</integer>
+			<key>Name</key><string>High Roller</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5290781</integer>
+			<key>Total Time</key><integer>329769</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247558079</integer>
+			<key>Play Date UTC</key><date>2006-11-28T19:27:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866B3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/04%20High%20Roller.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1633</key>
+		<dict>
+			<key>Track ID</key><integer>1633</integer>
+			<key>Name</key><string>Comin' Back</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5439992</integer>
+			<key>Total Time</key><integer>339095</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253371883</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:24:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866B5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/05%20Comin'%20Back.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1634</key>
+		<dict>
+			<key>Track ID</key><integer>1634</integer>
+			<key>Name</key><string>Keep Hope Alive</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5977906</integer>
+			<key>Total Time</key><integer>372715</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253284396</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:06:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866B7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/06%20Keep%20Hope%20Alive.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1635</key>
+		<dict>
+			<key>Track ID</key><integer>1635</integer>
+			<key>Name</key><string>Vapor Trail</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6279254</integer>
+			<key>Total Time</key><integer>391549</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866B9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/07%20Vapor%20Trail.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1636</key>
+		<dict>
+			<key>Track ID</key><integer>1636</integer>
+			<key>Name</key><string>She's My Pusher</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5478862</integer>
+			<key>Total Time</key><integer>341524</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3252536502</integer>
+			<key>Play Date UTC</key><date>2007-01-25T10:21:42Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T20:45:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866BB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/08%20She's%20My%20Pusher.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1637</key>
+		<dict>
+			<key>Track ID</key><integer>1637</integer>
+			<key>Name</key><string>Jaded</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6826781</integer>
+			<key>Total Time</key><integer>425769</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251634856</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:54:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866BD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/09%20Jaded.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1638</key>
+		<dict>
+			<key>Track ID</key><integer>1638</integer>
+			<key>Name</key><string>Bad Stone</string>
+			<key>Artist</key><string>The Crystal Method</string>
+			<key>Album</key><string>Vegas</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4971878</integer>
+			<key>Total Time</key><integer>309838</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250616979</integer>
+			<key>Play Date UTC</key><date>2007-01-03T05:09:39Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T02:35:44Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866BF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Crystal%20Method/Vegas/10%20Bad%20Stone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1639</key>
+		<dict>
+			<key>Track ID</key><integer>1639</integer>
+			<key>Name</key><string>The Kiss</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>39261735</integer>
+			<key>Total Time</key><integer>374840</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-26T18:50:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>837</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252930152</integer>
+			<key>Play Date UTC</key><date>2007-01-29T23:42:32Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:44:53Z</date>
+			<key>Persistent ID</key><string>87139F8602B866C1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/01%20The%20Kiss.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1640</key>
+		<dict>
+			<key>Track ID</key><integer>1640</integer>
+			<key>Name</key><string>Catch</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>16872238</integer>
+			<key>Total Time</key><integer>164200</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-28T23:49:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>820</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253713518</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:18:38Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-05T01:01:36Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B866C4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/02%20Catch.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1641</key>
+		<dict>
+			<key>Track ID</key><integer>1641</integer>
+			<key>Name</key><string>Torture</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31268016</integer>
+			<key>Total Time</key><integer>258266</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-10-08T18:37:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>967</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249323329</integer>
+			<key>Play Date UTC</key><date>2006-12-19T05:48:49Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:44:24Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B866C6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/03%20Torture.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1642</key>
+		<dict>
+			<key>Track ID</key><integer>1642</integer>
+			<key>Name</key><string>If Only Tonight We Could Sleep</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>31353713</integer>
+			<key>Total Time</key><integer>293266</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-08-22T05:18:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>854</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249286632</integer>
+			<key>Play Date UTC</key><date>2006-12-18T19:37:12Z</date>
+			<key>Persistent ID</key><string>87139F8602B866C8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/04%20If%20Only%20Tonight%20We%20Could%20Sleep.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1643</key>
+		<dict>
+			<key>Track ID</key><integer>1643</integer>
+			<key>Name</key><string>Why Can't I Be You?</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24263144</integer>
+			<key>Total Time</key><integer>194533</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-08-22T05:19:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>996</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253474130</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:48:50Z</date>
+			<key>Persistent ID</key><string>87139F8602B866CA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/05%20Why%20Can't%20I%20Be%20You_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1644</key>
+		<dict>
+			<key>Track ID</key><integer>1644</integer>
+			<key>Name</key><string>How Beautiful You Are</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>36459222</integer>
+			<key>Total Time</key><integer>314200</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-28T23:52:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>927</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252580431</integer>
+			<key>Play Date UTC</key><date>2007-01-25T22:33:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B866CC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/06%20How%20Beautiful%20You%20Are.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1645</key>
+		<dict>
+			<key>Track ID</key><integer>1645</integer>
+			<key>Name</key><string>The Snakepit</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>43051025</integer>
+			<key>Total Time</key><integer>419226</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-29T13:15:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>820</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253449870</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:04:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B866CE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/07%20The%20Snakepit.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1646</key>
+		<dict>
+			<key>Track ID</key><integer>1646</integer>
+			<key>Name</key><string>Just Like Heaven</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>25363983</integer>
+			<key>Total Time</key><integer>212866</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-10-17T23:20:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>952</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253359259</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:54:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B866D0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/08%20Just%20Like%20Heaven.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1647</key>
+		<dict>
+			<key>Track ID</key><integer>1647</integer>
+			<key>Name</key><string>All I Want</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>38101575</integer>
+			<key>Total Time</key><integer>322533</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-28T13:32:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>944</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249471128</integer>
+			<key>Play Date UTC</key><date>2006-12-20T22:52:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B866D2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/09%20All%20I%20Want.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1648</key>
+		<dict>
+			<key>Track ID</key><integer>1648</integer>
+			<key>Name</key><string>Hot Hot Hot!!!</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23118828</integer>
+			<key>Total Time</key><integer>215306</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-28T13:29:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>857</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251621975</integer>
+			<key>Play Date UTC</key><date>2007-01-14T20:19:35Z</date>
+			<key>Persistent ID</key><string>87139F8602B866D4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/10%20Hot%20Hot%20Hot!!!.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1649</key>
+		<dict>
+			<key>Track ID</key><integer>1649</integer>
+			<key>Name</key><string>One More Time</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>27816114</integer>
+			<key>Total Time</key><integer>272400</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-29T01:17:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>816</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252415712</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:48:32Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-21T22:42:54Z</date>
+			<key>Persistent ID</key><string>87139F8602B866D6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/11%20One%20More%20Time.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1650</key>
+		<dict>
+			<key>Track ID</key><integer>1650</integer>
+			<key>Name</key><string>Like Cockatoos</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>22710806</integer>
+			<key>Total Time</key><integer>220000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-10-07T15:45:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>824</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253377555</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:59:15Z</date>
+			<key>Persistent ID</key><string>87139F8602B866D8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/12%20Like%20Cockatoos.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1651</key>
+		<dict>
+			<key>Track ID</key><integer>1651</integer>
+			<key>Name</key><string>Icing Sugar</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>23007461</integer>
+			<key>Total Time</key><integer>229360</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-08-22T05:25:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>801</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250675909</integer>
+			<key>Play Date UTC</key><date>2007-01-03T21:31:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B866DA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/13%20Icing%20Sugar.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1652</key>
+		<dict>
+			<key>Track ID</key><integer>1652</integer>
+			<key>Name</key><string>The Perfect Girl</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>17005170</integer>
+			<key>Total Time</key><integer>155106</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-09-28T16:36:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>876</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249283240</integer>
+			<key>Play Date UTC</key><date>2006-12-18T18:40:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B866DC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/14%20The%20Perfect%20Girl.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1653</key>
+		<dict>
+			<key>Track ID</key><integer>1653</integer>
+			<key>Name</key><string>A Thousand Hours</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>20347139</integer>
+			<key>Total Time</key><integer>204026</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-08-22T05:26:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>796</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253618110</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:48:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B866DE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/15%20A%20Thousand%20Hours.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1654</key>
+		<dict>
+			<key>Track ID</key><integer>1654</integer>
+			<key>Name</key><string>Shiver And Shake</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>24301474</integer>
+			<key>Total Time</key><integer>209733</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2005-10-05T21:01:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>925</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253592331</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:38:51Z</date>
+			<key>Persistent ID</key><string>87139F8602B866E0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/16%20Shiver%20And%20Shake.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1655</key>
+		<dict>
+			<key>Track ID</key><integer>1655</integer>
+			<key>Name</key><string>Fight</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Composer</key><string>The Cure</string>
+			<key>Album</key><string>Kiss Me, Kiss Me, Kiss Me</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Apple Lossless audio file</string>
+			<key>Size</key><integer>30975390</integer>
+			<key>Total Time</key><integer>267666</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Track Count</key><integer>17</integer>
+			<key>Year</key><integer>1987</integer>
+			<key>Date Modified</key><date>2004-08-22T05:27:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>925</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253526678</integer>
+			<key>Play Date UTC</key><date>2007-02-05T21:24:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B866E2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Kiss%20Me,%20Kiss%20Me,%20Kiss%20Me/17%20Fight.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1656</key>
+		<dict>
+			<key>Track ID</key><integer>1656</integer>
+			<key>Name</key><string>Lullaby</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7420544</integer>
+			<key>Total Time</key><integer>465094</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:36:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3246896030</integer>
+			<key>Play Date UTC</key><date>2006-11-21T03:33:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866E4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/01%20Lullaby.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1657</key>
+		<dict>
+			<key>Track ID</key><integer>1657</integer>
+			<key>Name</key><string>Close to Me (Closer Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4189184</integer>
+			<key>Total Time</key><integer>261594</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:36:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249547890</integer>
+			<key>Play Date UTC</key><date>2006-12-21T20:11:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866E7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/02%20Close%20to%20Me%20(Closer%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1658</key>
+		<dict>
+			<key>Track ID</key><integer>1658</integer>
+			<key>Name</key><string>Fascination Street ( Extended Mix )</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8428752</integer>
+			<key>Total Time</key><integer>528577</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:37:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866E9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/03%20Fascination%20Street%20(%20Extended%20Mix%20).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1659</key>
+		<dict>
+			<key>Track ID</key><integer>1659</integer>
+			<key>Name</key><string>The Walk (Everything Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5241472</integer>
+			<key>Total Time</key><integer>327864</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:38:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252938524</integer>
+			<key>Play Date UTC</key><date>2007-01-30T02:02:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866EB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/04%20The%20Walk%20(Everything%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1660</key>
+		<dict>
+			<key>Track ID</key><integer>1660</integer>
+			<key>Name</key><string>Love Song</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6079552</integer>
+			<key>Total Time</key><integer>380643</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:39:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253099057</integer>
+			<key>Play Date UTC</key><date>2007-01-31T22:37:37Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-02T14:03:46Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866ED</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/05%20Love%20Song.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1661</key>
+		<dict>
+			<key>Track ID</key><integer>1661</integer>
+			<key>Name</key><string>A Forest (Tree Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6644784</integer>
+			<key>Total Time</key><integer>416239</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:40:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:58Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251480435</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:00:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866EF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/06%20A%20Forest%20(Tree%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1662</key>
+		<dict>
+			<key>Track ID</key><integer>1662</integer>
+			<key>Name</key><string>Pictures of You (Extended Dub Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6434656</integer>
+			<key>Total Time</key><integer>403004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:40:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253468330</integer>
+			<key>Play Date UTC</key><date>2007-02-05T05:12:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866F1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/07%20Pictures%20of%20You%20(Extended%20Dub%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1663</key>
+		<dict>
+			<key>Track ID</key><integer>1663</integer>
+			<key>Name</key><string>Hot Hot Hot!!!</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6734016</integer>
+			<key>Total Time</key><integer>421858</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:41:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253768149</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:29:09Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866F3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/08%20Hot%20Hot%20Hot!!!.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1664</key>
+		<dict>
+			<key>Track ID</key><integer>1664</integer>
+			<key>Name</key><string>The Caterpilar (Flicker Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5459088</integer>
+			<key>Total Time</key><integer>341564</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:42:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251353270</integer>
+			<key>Play Date UTC</key><date>2007-01-11T17:41:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866F5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/09%20The%20Caterpilar%20(Flicker%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1665</key>
+		<dict>
+			<key>Track ID</key><integer>1665</integer>
+			<key>Name</key><string>In Between Days (Shiver Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6139296</integer>
+			<key>Total Time</key><integer>384404</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:43:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253536348</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:05:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866F7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/10%20In%20Between%20Days%20(Shiver%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1666</key>
+		<dict>
+			<key>Track ID</key><integer>1666</integer>
+			<key>Name</key><string>Never Enough (Big Mix)</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album Artist</key><string>The Cure</string>
+			<key>Album</key><string>Mixed Up</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4294688</integer>
+			<key>Total Time</key><integer>268235</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>1990</integer>
+			<key>Date Modified</key><date>2006-01-12T22:43:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>37</integer>
+			<key>Play Date</key><integer>3253288804</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:20:04Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866F9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/Mixed%20Up/11%20Never%20Enough%20(Big%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1667</key>
+		<dict>
+			<key>Track ID</key><integer>1667</integer>
+			<key>Name</key><string>Burn</string>
+			<key>Artist</key><string>The Cure</string>
+			<key>Album</key><string>The Crow</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4842540</integer>
+			<key>Total Time</key><integer>399438</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253548975</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:36:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B866FB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Cure/The%20Crow/01%20Burn.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1668</key>
+		<dict>
+			<key>Track ID</key><integer>1668</integer>
+			<key>Name</key><string>Do You Wanna Hit It</string>
+			<key>Artist</key><string>The Donnas</string>
+			<key>Album Artist</key><string>The Donnas</string>
+			<key>Composer</key><string>Allison Robertson/Brett Anderson/Maya Ford/Torry Castellano</string>
+			<key>Album</key><string>Turn 21</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2845717</integer>
+			<key>Total Time</key><integer>177711</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-02-23T20:35:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string> 000071AA 00000FA7 00019185 000092BA 00029E4E 00017F92 00008D68 00008D10 00008C1A 00007E05</string>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252487625</integer>
+			<key>Play Date UTC</key><date>2007-01-24T20:47:05Z</date>
+			<key>Persistent ID</key><string>87139F8602B866FE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Donnas/Turn%2021/02%20Do%20You%20Wanna%20Hit%20It.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1669</key>
+		<dict>
+			<key>Track ID</key><integer>1669</integer>
+			<key>Name</key><string>Cosmonaut</string>
+			<key>Artist</key><string>The Fatáles</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3495259</integer>
+			<key>Total Time</key><integer>249652</integer>
+			<key>Date Modified</key><date>2005-04-13T22:05:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>112</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251480685</integer>
+			<key>Play Date UTC</key><date>2007-01-13T05:04:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B86701</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Fata%CC%81les/Unknown%20Album/Cosmonaut.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1670</key>
+		<dict>
+			<key>Track ID</key><integer>1670</integer>
+			<key>Name</key><string>Ministry of Defense</string>
+			<key>Artist</key><string>The Fatáles</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3027145</integer>
+			<key>Total Time</key><integer>216215</integer>
+			<key>Date Modified</key><date>2005-04-13T22:05:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>112</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253555948</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:32:28Z</date>
+			<key>Persistent ID</key><string>87139F8602B86705</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Fata%CC%81les/Unknown%20Album/Ministry%20of%20Defense.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1671</key>
+		<dict>
+			<key>Track ID</key><integer>1671</integer>
+			<key>Name</key><string>You're Not the Lunar Type</string>
+			<key>Artist</key><string>The Fatáles</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4465865</integer>
+			<key>Total Time</key><integer>318981</integer>
+			<key>Date Modified</key><date>2005-04-13T22:05:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>112</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252510896</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:14:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B86709</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Fata%CC%81les/Unknown%20Album/You're%20Not%20the%20Lunar%20Type.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1672</key>
+		<dict>
+			<key>Track ID</key><integer>1672</integer>
+			<key>Name</key><string>A Beaten Dog Beneath the Hail</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3721678</integer>
+			<key>Total Time</key><integer>306886</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249540290</integer>
+			<key>Play Date UTC</key><date>2006-12-21T18:04:50Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8670D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/01%20A%20Beaten%20Dog%20Beneath%20the%20Hail.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1673</key>
+		<dict>
+			<key>Track ID</key><integer>1673</integer>
+			<key>Name</key><string>Down in the Happy Zone</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2387971</integer>
+			<key>Total Time</key><integer>196597</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252499608</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:06:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86710</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/02%20Down%20in%20the%20Happy%20Zone.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1674</key>
+		<dict>
+			<key>Track ID</key><integer>1674</integer>
+			<key>Name</key><string>Every Third Thought</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3654909</integer>
+			<key>Total Time</key><integer>301322</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253765303</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:41:43Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86712</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/03%20Every%20Third%20Thought.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1675</key>
+		<dict>
+			<key>Track ID</key><integer>1675</integer>
+			<key>Name</key><string>Blue Wires</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3555999</integer>
+			<key>Total Time</key><integer>293250</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253452613</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:50:13Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-21T22:12:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86714</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/04%20Blue%20Wires.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1676</key>
+		<dict>
+			<key>Track ID</key><integer>1676</integer>
+			<key>Name</key><string>Paul Has an Emotional Uncle</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4228579</integer>
+			<key>Total Time</key><integer>348786</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251635426</integer>
+			<key>Play Date UTC</key><date>2007-01-15T00:03:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86716</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/05%20Paul%20Has%20an%20Emotional%20Uncle.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1677</key>
+		<dict>
+			<key>Track ID</key><integer>1677</integer>
+			<key>Name</key><string>Six to Four to Three</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2200976</integer>
+			<key>Total Time</key><integer>181185</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86718</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/06%20Six%20to%20Four%20to%20Three.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1678</key>
+		<dict>
+			<key>Track ID</key><integer>1678</integer>
+			<key>Name</key><string>Of All Possible Worlds...Pt. II</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3650207</integer>
+			<key>Total Time</key><integer>300930</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253280132</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:55:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8671A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/07%20Of%20All%20Possible%20Worlds...Pt.%20II.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1679</key>
+		<dict>
+			<key>Track ID</key><integer>1679</integer>
+			<key>Name</key><string>The Violent Misery of Everything Lost</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3890179</integer>
+			<key>Total Time</key><integer>320757</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253557430</integer>
+			<key>Play Date UTC</key><date>2007-02-06T05:57:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8671C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/08%20The%20Violent%20Misery%20of%20Everything%20Lost.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1680</key>
+		<dict>
+			<key>Track ID</key><integer>1680</integer>
+			<key>Name</key><string>A World Reduced to Zero</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3818540</integer>
+			<key>Total Time</key><integer>314958</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246641070</integer>
+			<key>Play Date UTC</key><date>2006-11-18T04:44:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:22Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8671E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/09%20A%20World%20Reduced%20to%20Zero.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1681</key>
+		<dict>
+			<key>Track ID</key><integer>1681</integer>
+			<key>Name</key><string>Safe</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3290637</integer>
+			<key>Total Time</key><integer>271307</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253335033</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:10:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86720</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/10%20Safe.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1682</key>
+		<dict>
+			<key>Track ID</key><integer>1682</integer>
+			<key>Name</key><string>III</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4124194</integer>
+			<key>Total Time</key><integer>340088</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253368719</integer>
+			<key>Play Date UTC</key><date>2007-02-04T01:31:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86722</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/11%20III.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1683</key>
+		<dict>
+			<key>Track ID</key><integer>1683</integer>
+			<key>Name</key><string>112 Greene Street</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3903031</integer>
+			<key>Total Time</key><integer>321828</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251468567</integer>
+			<key>Play Date UTC</key><date>2007-01-13T01:42:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86724</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/12%20112%20Greene%20Street.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1684</key>
+		<dict>
+			<key>Track ID</key><integer>1684</integer>
+			<key>Name</key><string>Thunder Ain't Rain</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>III</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3750518</integer>
+			<key>Total Time</key><integer>309289</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251889786</integer>
+			<key>Play Date UTC</key><date>2007-01-17T22:43:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86726</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/III/13%20Thunder%20Ain't%20Rain.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1685</key>
+		<dict>
+			<key>Track ID</key><integer>1685</integer>
+			<key>Name</key><string>Black Helicopters</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3829428</integer>
+			<key>Total Time</key><integer>239203</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253617906</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:45:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B86728</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/01%20Black%20Helicopters.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1686</key>
+		<dict>
+			<key>Track ID</key><integer>1686</integer>
+			<key>Name</key><string>Driving Nowhere</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5025627</integer>
+			<key>Total Time</key><integer>313965</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251892211</integer>
+			<key>Play Date UTC</key><date>2007-01-17T23:23:31Z</date>
+			<key>Persistent ID</key><string>87139F8602B8672B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/02%20Driving%20Nowhere.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1687</key>
+		<dict>
+			<key>Track ID</key><integer>1687</integer>
+			<key>Name</key><string>Slow Steady Starvation</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3908005</integer>
+			<key>Total Time</key><integer>244114</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252392607</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:23:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B8672D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/03%20Slow%20Steady%20Starvation.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1688</key>
+		<dict>
+			<key>Track ID</key><integer>1688</integer>
+			<key>Name</key><string>1961</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6074705</integer>
+			<key>Total Time</key><integer>379533</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249487894</integer>
+			<key>Play Date UTC</key><date>2006-12-21T03:31:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B8672F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/04%201961.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1689</key>
+		<dict>
+			<key>Track ID</key><integer>1689</integer>
+			<key>Name</key><string>The Americans</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3543962</integer>
+			<key>Total Time</key><integer>221361</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249553098</integer>
+			<key>Play Date UTC</key><date>2006-12-21T21:38:18Z</date>
+			<key>Persistent ID</key><string>87139F8602B86731</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/05%20The%20Americans.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1690</key>
+		<dict>
+			<key>Track ID</key><integer>1690</integer>
+			<key>Name</key><string>Roswell Crash</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3770078</integer>
+			<key>Total Time</key><integer>235493</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253348262</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:51:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B86733</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/06%20Roswell%20Crash.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1691</key>
+		<dict>
+			<key>Track ID</key><integer>1691</integer>
+			<key>Name</key><string>The Common Ground</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3258078</integer>
+			<key>Total Time</key><integer>203493</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252544849</integer>
+			<key>Play Date UTC</key><date>2007-01-25T12:40:49Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T15:55:16Z</date>
+			<key>Persistent ID</key><string>87139F8602B86735</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/07%20The%20Common%20Ground.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1692</key>
+		<dict>
+			<key>Track ID</key><integer>1692</integer>
+			<key>Name</key><string>Another Theory</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1406101</integer>
+			<key>Total Time</key><integer>87745</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249307206</integer>
+			<key>Play Date UTC</key><date>2006-12-19T01:20:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B86737</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/08%20Another%20Theory.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1693</key>
+		<dict>
+			<key>Track ID</key><integer>1693</integer>
+			<key>Name</key><string>Wailing And Gnashing Of Teeth</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2264589</integer>
+			<key>Total Time</key><integer>141400</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249281458</integer>
+			<key>Play Date UTC</key><date>2006-12-18T18:10:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B86739</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/09%20Wailing%20And%20Gnashing%20Of%20Teeth.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1694</key>
+		<dict>
+			<key>Track ID</key><integer>1694</integer>
+			<key>Name</key><string>Fall Of The American Empire</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4322620</integer>
+			<key>Total Time</key><integer>270027</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250572630</integer>
+			<key>Play Date UTC</key><date>2007-01-02T16:50:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B8673B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/10%20Fall%20Of%20The%20American%20Empire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1695</key>
+		<dict>
+			<key>Track ID</key><integer>1695</integer>
+			<key>Name</key><string>All Things Considered</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4337249</integer>
+			<key>Total Time</key><integer>270942</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252561085</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:11:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B8673D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/11%20All%20Things%20Considered.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1696</key>
+		<dict>
+			<key>Track ID</key><integer>1696</integer>
+			<key>Name</key><string>Corrosion Of The Masses</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3900899</integer>
+			<key>Total Time</key><integer>243670</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253611551</integer>
+			<key>Play Date UTC</key><date>2007-02-06T20:59:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B8673F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/12%20Corrosion%20Of%20The%20Masses.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1697</key>
+		<dict>
+			<key>Track ID</key><integer>1697</integer>
+			<key>Name</key><string>End Of It All</string>
+			<key>Artist</key><string>The Grassy Knoll</string>
+			<key>Album</key><string>Positive</string>
+			<key>Genre</key><string>Acid Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1656458</integer>
+			<key>Total Time</key><integer>103392</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249577557</integer>
+			<key>Play Date UTC</key><date>2006-12-22T04:25:57Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-28T20:45:30Z</date>
+			<key>Persistent ID</key><string>87139F8602B86741</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Grassy%20Knoll/Positive/13%20End%20Of%20It%20All.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1698</key>
+		<dict>
+			<key>Track ID</key><integer>1698</integer>
+			<key>Name</key><string>Little Fluffy Clouds</string>
+			<key>Artist</key><string>The Orb</string>
+			<key>Album Artist</key><string>The Orb</string>
+			<key>Composer</key><string>Alex Paterson, Ennio Morricone, Martin Glover, Rickie Lee Jones &#38; Steve Reich</string>
+			<key>Album</key><string>The Orb's Adventures Beyond the Ultraworld</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4838955</integer>
+			<key>Total Time</key><integer>267074</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2005-07-25T15:40:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>24</integer>
+			<key>Play Date</key><integer>3253099894</integer>
+			<key>Play Date UTC</key><date>2007-01-31T22:51:34Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86743</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Orb/The%20Orb's%20Adventures%20Beyond%20the%20Ultraworld/1-01%20Little%20Fluffy%20Clouds.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1699</key>
+		<dict>
+			<key>Track ID</key><integer>1699</integer>
+			<key>Name</key><string>Jericho</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5416919</integer>
+			<key>Total Time</key><integer>222868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:27:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249191974</integer>
+			<key>Play Date UTC</key><date>2006-12-17T17:19:34Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86746</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-01%20Jericho.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1700</key>
+		<dict>
+			<key>Track ID</key><integer>1700</integer>
+			<key>Name</key><string>Music Reach 1/2/3/4</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6119776</integer>
+			<key>Total Time</key><integer>252094</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:27:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250679670</integer>
+			<key>Play Date UTC</key><date>2007-01-03T22:34:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-16T15:42:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86749</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-02%20Music%20Reach%201_2_3_4.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1701</key>
+		<dict>
+			<key>Track ID</key><integer>1701</integer>
+			<key>Name</key><string>Wind It Up</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6628653</integer>
+			<key>Total Time</key><integer>273108</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252478169</integer>
+			<key>Play Date UTC</key><date>2007-01-24T18:09:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8674B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-03%20Wind%20It%20Up.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1702</key>
+		<dict>
+			<key>Track ID</key><integer>1702</integer>
+			<key>Name</key><string>Your Love</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8034697</integer>
+			<key>Total Time</key><integer>331177</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252526519</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:35:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8674D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-04%20Your%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1703</key>
+		<dict>
+			<key>Track ID</key><integer>1703</integer>
+			<key>Name</key><string>Hyperspeed (G-Force Part 2)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7644915</integer>
+			<key>Total Time</key><integer>315070</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252035488</integer>
+			<key>Play Date UTC</key><date>2007-01-19T15:11:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8674F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-05%20Hyperspeed%20(G-Force%20Part%202).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1704</key>
+		<dict>
+			<key>Track ID</key><integer>1704</integer>
+			<key>Name</key><string>Charly (Trip Into Drum &#38; Bass Version)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7587486</integer>
+			<key>Total Time</key><integer>312702</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246636107</integer>
+			<key>Play Date UTC</key><date>2006-11-18T03:21:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86751</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-06%20Charly%20(Trip%20Into%20Drum%20&#38;%20Bass%20Version).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1705</key>
+		<dict>
+			<key>Track ID</key><integer>1705</integer>
+			<key>Name</key><string>Out Of Space</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7237417</integer>
+			<key>Total Time</key><integer>298238</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253546756</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:59:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86753</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-07%20Out%20Of%20Space.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1706</key>
+		<dict>
+			<key>Track ID</key><integer>1706</integer>
+			<key>Name</key><string>Everybody In The Place (135 &#38; Rising)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6090141</integer>
+			<key>Total Time</key><integer>250878</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249114444</integer>
+			<key>Play Date UTC</key><date>2006-12-16T19:47:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86755</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-08%20Everybody%20In%20The%20Place%20(135%20&#38;%20Rising).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1707</key>
+		<dict>
+			<key>Track ID</key><integer>1707</integer>
+			<key>Name</key><string>Weather Experience</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11755028</integer>
+			<key>Total Time</key><integer>484798</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249454219</integer>
+			<key>Play Date UTC</key><date>2006-12-20T18:10:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86757</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-09%20Weather%20Experience.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1708</key>
+		<dict>
+			<key>Track ID</key><integer>1708</integer>
+			<key>Name</key><string>Fire (Sunrise Version)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7258550</integer>
+			<key>Total Time</key><integer>299134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247384887</integer>
+			<key>Play Date UTC</key><date>2006-11-26T19:21:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86759</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-10%20Fire%20(Sunrise%20Version).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1709</key>
+		<dict>
+			<key>Track ID</key><integer>1709</integer>
+			<key>Name</key><string>Ruff In The Jungle Bizness</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7495926</integer>
+			<key>Total Time</key><integer>308926</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253259058</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:04:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8675B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-11%20Ruff%20In%20The%20Jungle%20Bizness.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1710</key>
+		<dict>
+			<key>Track ID</key><integer>1710</integer>
+			<key>Name</key><string>Death Of The Prodigy Dancers (Live)</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Experience</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5422284</integer>
+			<key>Total Time</key><integer>223273</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>1992</integer>
+			<key>Date Modified</key><date>2004-08-01T16:28:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8675D</string>
+			<key>Disabled</key><true/>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Experience/1-12%20Death%20Of%20The%20Prodigy%20Dancers%20(Live).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1711</key>
+		<dict>
+			<key>Track ID</key><integer>1711</integer>
+			<key>Name</key><string>Mindfields</string>
+			<key>Artist</key><string>The Prodigy</string>
+			<key>Album</key><string>Matrix</string>
+			<key>Genre</key><string>Soundtrack</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5456543</integer>
+			<key>Total Time</key><integer>340897</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:27:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253448664</integer>
+			<key>Play Date UTC</key><date>2007-02-04T23:44:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B8675F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/The%20Prodigy/Matrix/07%20Mindfields.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1712</key>
+		<dict>
+			<key>Track ID</key><integer>1712</integer>
+			<key>Name</key><string>The Cosmic Game</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2372090</integer>
+			<key>Total Time</key><integer>139225</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:32:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252471585</integer>
+			<key>Play Date UTC</key><date>2007-01-24T16:19:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86762</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Cosmic%20Game/04%20The%20Cosmic%20Game.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1713</key>
+		<dict>
+			<key>Track ID</key><integer>1713</integer>
+			<key>Name</key><string>A Gentle Dissolve</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2863596</integer>
+			<key>Total Time</key><integer>169643</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:38:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252476114</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:35:14Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86764</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Cosmic%20Game/16%20A%20Gentle%20Dissolve.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1714</key>
+		<dict>
+			<key>Track ID</key><integer>1714</integer>
+			<key>Name</key><string>Treasures</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2450381</integer>
+			<key>Total Time</key><integer>145007</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-27T09:15:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249491381</integer>
+			<key>Play Date UTC</key><date>2006-12-21T04:29:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86766</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/01%20Treasures.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1715</key>
+		<dict>
+			<key>Track ID</key><integer>1715</integer>
+			<key>Name</key><string>Le Monde</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3195037</integer>
+			<key>Total Time</key><integer>191029</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-20T09:05:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3250703141</integer>
+			<key>Play Date UTC</key><date>2007-01-04T05:05:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86769</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/02%20Le%20Monde.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1716</key>
+		<dict>
+			<key>Track ID</key><integer>1716</integer>
+			<key>Name</key><string>Indra</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5328685</integer>
+			<key>Total Time</key><integer>322895</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-17T18:09:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252511999</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:33:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8676B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/03%20Indra.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1717</key>
+		<dict>
+			<key>Track ID</key><integer>1717</integer>
+			<key>Name</key><string>Lebanese Blonde</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4777901</integer>
+			<key>Total Time</key><integer>288854</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-21T08:28:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8676D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/04%20Lebanese%20Blonde.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1718</key>
+		<dict>
+			<key>Track ID</key><integer>1718</integer>
+			<key>Name</key><string>Focus On Sight</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3782653</integer>
+			<key>Total Time</key><integer>227345</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-20T17:35:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253769472</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:51:12Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8676F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/05%20Focus%20On%20Sight.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1719</key>
+		<dict>
+			<key>Track ID</key><integer>1719</integer>
+			<key>Name</key><string>Air Batucada</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4730941</integer>
+			<key>Total Time</key><integer>285952</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-17T23:57:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252409621</integer>
+			<key>Play Date UTC</key><date>2007-01-23T23:07:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86771</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/06%20Air%20Batucada.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1720</key>
+		<dict>
+			<key>Track ID</key><integer>1720</integer>
+			<key>Name</key><string>So Com Voce</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2811053</integer>
+			<key>Total Time</key><integer>167298</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-21T07:53:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252525430</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:17:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86773</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/07%20So%20Com%20Voce.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1721</key>
+		<dict>
+			<key>Track ID</key><integer>1721</integer>
+			<key>Name</key><string>Samba Tranquille</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3120653</integer>
+			<key>Total Time</key><integer>186431</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-21T06:24:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253253018</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:23:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86775</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/08%20Samba%20Tranquille.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1722</key>
+		<dict>
+			<key>Track ID</key><integer>1722</integer>
+			<key>Name</key><string>Shadows of Ourselves</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3628237</integer>
+			<key>Total Time</key><integer>217801</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-26T01:28:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249286117</integer>
+			<key>Play Date UTC</key><date>2006-12-18T19:28:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86777</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/09%20Shadows%20of%20Ourselves.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1723</key>
+		<dict>
+			<key>Track ID</key><integer>1723</integer>
+			<key>Name</key><string>The Hong Kong Triad</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3045133</integer>
+			<key>Total Time</key><integer>181764</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-28T03:48:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253765485</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:44:45Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86779</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/10%20The%20Hong%20Kong%20Triad.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1724</key>
+		<dict>
+			<key>Track ID</key><integer>1724</integer>
+			<key>Name</key><string>Illumination</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4605821</integer>
+			<key>Total Time</key><integer>278220</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-27T08:59:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253179699</integer>
+			<key>Play Date UTC</key><date>2007-02-01T21:01:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8677B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/11%20Illumination.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1725</key>
+		<dict>
+			<key>Track ID</key><integer>1725</integer>
+			<key>Name</key><string>The Mirror Conspiracy</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3746205</integer>
+			<key>Total Time</key><integer>225092</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-21T19:13:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246374258</integer>
+			<key>Play Date UTC</key><date>2006-11-15T02:37:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8677D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/12%20The%20Mirror%20Conspiracy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1726</key>
+		<dict>
+			<key>Track ID</key><integer>1726</integer>
+			<key>Name</key><string>Tomorrow</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Mirror Conspiracy</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3718397</integer>
+			<key>Total Time</key><integer>223374</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2005-07-30T15:31:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246045077</integer>
+			<key>Play Date UTC</key><date>2006-11-11T07:11:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8677F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Mirror%20Conspiracy/13%20Tomorrow.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1727</key>
+		<dict>
+			<key>Track ID</key><integer>1727</integer>
+			<key>Name</key><string>Heaven's Gonna Burn Your Eyes</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4109874</integer>
+			<key>Total Time</key><integer>250309</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:49:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253515181</integer>
+			<key>Play Date UTC</key><date>2007-02-05T18:13:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86781</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/01%20Heaven's%20Gonna%20Burn%20Your%20Eyes.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1728</key>
+		<dict>
+			<key>Track ID</key><integer>1728</integer>
+			<key>Name</key><string>Facing East</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3682690</integer>
+			<key>Total Time</key><integer>223908</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:50:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252467814</integer>
+			<key>Play Date UTC</key><date>2007-01-24T15:16:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86784</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/02%20Facing%20East.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1729</key>
+		<dict>
+			<key>Track ID</key><integer>1729</integer>
+			<key>Name</key><string>The Outernationalist</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3462418</integer>
+			<key>Total Time</key><integer>210301</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:50:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253597078</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:57:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86786</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/03%20The%20Outernationalist.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1730</key>
+		<dict>
+			<key>Track ID</key><integer>1730</integer>
+			<key>Name</key><string>Interlude</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>1370834</integer>
+			<key>Total Time</key><integer>81036</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:50:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252937741</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:49:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86788</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/04%20Interlude.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1731</key>
+		<dict>
+			<key>Track ID</key><integer>1731</integer>
+			<key>Name</key><string>Omid (Hope)</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3753586</integer>
+			<key>Total Time</key><integer>228297</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:51:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251300289</integer>
+			<key>Play Date UTC</key><date>2007-01-11T02:58:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8678A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/05%20Omid%20(Hope).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1732</key>
+		<dict>
+			<key>Track ID</key><integer>1732</integer>
+			<key>Name</key><string>All That We Perceive</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3719026</integer>
+			<key>Total Time</key><integer>226160</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:51:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:12:59Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252513899</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:04:59Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8678C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/06%20All%20That%20We%20Perceive.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1733</key>
+		<dict>
+			<key>Track ID</key><integer>1733</integer>
+			<key>Name</key><string>Un Simple Histoire (A Simple Story)</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3707778</integer>
+			<key>Total Time</key><integer>225464</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:51:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250709611</integer>
+			<key>Play Date UTC</key><date>2007-01-04T06:53:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8678E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/07%20Un%20Simple%20Histoire%20(A%20Simple%20Story).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1734</key>
+		<dict>
+			<key>Track ID</key><integer>1734</integer>
+			<key>Name</key><string>Meu Destino (My Destiny)</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3457170</integer>
+			<key>Total Time</key><integer>209976</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:52:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252552588</integer>
+			<key>Play Date UTC</key><date>2007-01-25T14:49:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86790</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/08%20Meu%20Destino%20(My%20Destiny).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1735</key>
+		<dict>
+			<key>Track ID</key><integer>1735</integer>
+			<key>Name</key><string>Exilio (Exile)</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3021330</integer>
+			<key>Total Time</key><integer>183041</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:52:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252406084</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:08:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86792</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/09%20Exilio%20(Exile).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1736</key>
+		<dict>
+			<key>Track ID</key><integer>1736</integer>
+			<key>Name</key><string>From Creation</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4270194</integer>
+			<key>Total Time</key><integer>260224</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:53:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3247028940</integer>
+			<key>Play Date UTC</key><date>2006-11-22T16:29:00Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86794</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/10%20From%20Creation.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1737</key>
+		<dict>
+			<key>Track ID</key><integer>1737</integer>
+			<key>Name</key><string>The Richest Man in Babylon</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3785922</integer>
+			<key>Total Time</key><integer>230294</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:53:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253604552</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:02:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86796</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/11%20The%20Richest%20Man%20in%20Babylon.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1738</key>
+		<dict>
+			<key>Track ID</key><integer>1738</integer>
+			<key>Name</key><string>Liberation Front</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4979538</integer>
+			<key>Total Time</key><integer>304063</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:54:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250684911</integer>
+			<key>Play Date UTC</key><date>2007-01-04T00:01:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86798</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/12%20Liberation%20Front.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1739</key>
+		<dict>
+			<key>Track ID</key><integer>1739</integer>
+			<key>Name</key><string>The State of the Union</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4404706</integer>
+			<key>Total Time</key><integer>268537</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:54:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252484192</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:49:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8679A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/13%20The%20State%20of%20the%20Union.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1740</key>
+		<dict>
+			<key>Track ID</key><integer>1740</integer>
+			<key>Name</key><string>Until the Morning</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3894482</integer>
+			<key>Total Time</key><integer>237004</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:54:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253292261</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:17:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8679C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/14%20Until%20the%20Morning.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1741</key>
+		<dict>
+			<key>Track ID</key><integer>1741</integer>
+			<key>Name</key><string>Resolution</string>
+			<key>Artist</key><string>Thievery Corporation</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Richest Man in Babylon</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4698114</integer>
+			<key>Total Time</key><integer>286672</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>15</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2005-05-09T20:55:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252483924</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:45:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8679E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation/The%20Richest%20Man%20in%20Babylon/15%20Resolution.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1742</key>
+		<dict>
+			<key>Track ID</key><integer>1742</integer>
+			<key>Name</key><string>The Heart's a Lonely Hunter</string>
+			<key>Artist</key><string>Thievery Corporation &#38; David Byrne</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4071108</integer>
+			<key>Total Time</key><integer>243854</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:35:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251886099</integer>
+			<key>Play Date UTC</key><date>2007-01-17T21:41:39Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867A0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20David%20Byrne/The%20Cosmic%20Game/10%20The%20Heart's%20a%20Lonely%20Hunter.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1743</key>
+		<dict>
+			<key>Track ID</key><integer>1743</integer>
+			<key>Name</key><string>Doors of Perception</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Doors of Perception featuring Gunjan</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3299253</integer>
+			<key>Total Time</key><integer>196346</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:36:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253100499</integer>
+			<key>Play Date UTC</key><date>2007-01-31T23:01:39Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Doors%20of%20Perception%20featuring%20Gunjan/The%20Cosmic%20Game/12%20Doors%20of%20Perception.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1744</key>
+		<dict>
+			<key>Track ID</key><integer>1744</integer>
+			<key>Name</key><string>Pela Janela (Through the Window)</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Gigi Rezende</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3706922</integer>
+			<key>Total Time</key><integer>221493</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:34:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252392829</integer>
+			<key>Play Date UTC</key><date>2007-01-23T18:27:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Gigi%20Rezende/The%20Cosmic%20Game/08%20Pela%20Janela%20(Through%20the%20Window).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1745</key>
+		<dict>
+			<key>Track ID</key><integer>1745</integer>
+			<key>Name</key><string>Satyam Shivam Sundaram</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Gunjan</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4115210</integer>
+			<key>Total Time</key><integer>247407</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:33:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247664954</integer>
+			<key>Play Date UTC</key><date>2006-11-30T01:09:14Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Gunjan/The%20Cosmic%20Game/05%20Satyam%20Shivam%20Sundaram.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1746</key>
+		<dict>
+			<key>Track ID</key><integer>1746</integer>
+			<key>Name</key><string>Holographic Universe</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Gunjan</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3712360</integer>
+			<key>Total Time</key><integer>222027</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:36:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253616065</integer>
+			<key>Play Date UTC</key><date>2007-02-06T22:14:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Gunjan/The%20Cosmic%20Game/11%20Holographic%20Universe.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1747</key>
+		<dict>
+			<key>Track ID</key><integer>1747</integer>
+			<key>Name</key><string>The Supreme Illusion</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Gunjan</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4175112</integer>
+			<key>Total Time</key><integer>250240</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:37:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251356853</integer>
+			<key>Play Date UTC</key><date>2007-01-11T18:40:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Gunjan/The%20Cosmic%20Game/14%20The%20Supreme%20Illusion.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1748</key>
+		<dict>
+			<key>Track ID</key><integer>1748</integer>
+			<key>Name</key><string>The Time We Lost Our Way</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Loulou</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4191356</integer>
+			<key>Total Time</key><integer>251726</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:38:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251621518</integer>
+			<key>Play Date UTC</key><date>2007-01-14T20:11:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Loulou/The%20Cosmic%20Game/15%20The%20Time%20We%20Lost%20Our%20Way.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1749</key>
+		<dict>
+			<key>Track ID</key><integer>1749</integer>
+			<key>Name</key><string>Amerimacka</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Notch</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5658925</integer>
+			<key>Total Time</key><integer>341517</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:33:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249286973</integer>
+			<key>Play Date UTC</key><date>2006-12-18T19:42:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867AE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Notch/The%20Cosmic%20Game/06%20Amerimacka.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1750</key>
+		<dict>
+			<key>Track ID</key><integer>1750</integer>
+			<key>Name</key><string>Sol Tapado (The Covered Sun)</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Patrick de Santos</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3968587</integer>
+			<key>Total Time</key><integer>237538</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:35:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252574689</integer>
+			<key>Play Date UTC</key><date>2007-01-25T20:58:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867B0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Patrick%20de%20Santos/The%20Cosmic%20Game/09%20Sol%20Tapado%20(The%20Covered%20Sun).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1751</key>
+		<dict>
+			<key>Track ID</key><integer>1751</integer>
+			<key>Name</key><string>Revolution Solution</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Perry Farrell</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3708942</integer>
+			<key>Total Time</key><integer>221516</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:32:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252404642</integer>
+			<key>Play Date UTC</key><date>2007-01-23T21:44:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867B2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Perry%20Farrell/The%20Cosmic%20Game/03%20Revolution%20Solution.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1752</key>
+		<dict>
+			<key>Track ID</key><integer>1752</integer>
+			<key>Name</key><string>Wires and Watchtowers</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Sista Pat</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4321740</integer>
+			<key>Total Time</key><integer>259249</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:37:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249378616</integer>
+			<key>Play Date UTC</key><date>2006-12-19T21:10:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867B4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Sista%20Pat/The%20Cosmic%20Game/13%20Wires%20and%20Watchtowers.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1753</key>
+		<dict>
+			<key>Track ID</key><integer>1753</integer>
+			<key>Name</key><string>Marching the Hate Machines (Into the Sun)</string>
+			<key>Artist</key><string>Thievery Corporation &#38; The Flaming Lips</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4029991</integer>
+			<key>Total Time</key><integer>241207</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:31:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253597640</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:07:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867B6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20The%20Flaming%20Lips/The%20Cosmic%20Game/01%20Marching%20the%20Hate%20Machines%20(Into%20the%20Sun).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1754</key>
+		<dict>
+			<key>Track ID</key><integer>1754</integer>
+			<key>Name</key><string>Ambicion Eterna (Eternal Ambition)</string>
+			<key>Artist</key><string>Thievery Corporation &#38; Verny Varela</string>
+			<key>Album Artist</key><string>Thievery Corporation</string>
+			<key>Album</key><string>The Cosmic Game</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3747948</integer>
+			<key>Total Time</key><integer>223955</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-01-12T21:34:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252987591</integer>
+			<key>Play Date UTC</key><date>2007-01-30T15:39:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867B8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Thievery%20Corporation%20&#38;%20Verny%20Varela/The%20Cosmic%20Game/07%20Ambicion%20Eterna%20(Eternal%20Ambition).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1755</key>
+		<dict>
+			<key>Track ID</key><integer>1755</integer>
+			<key>Name</key><string>Ride</string>
+			<key>Artist</key><string>TPC</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6305428</integer>
+			<key>Total Time</key><integer>520150</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253452320</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:45:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867BA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/TPC/Plastic%20Compilation,%20Vol.%202/09%20Ride.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1756</key>
+		<dict>
+			<key>Track ID</key><integer>1756</integer>
+			<key>Name</key><string>The Door</string>
+			<key>Artist</key><string>Turin Brakes</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3463212</integer>
+			<key>Total Time</key><integer>216058</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252405901</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:05:01Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867BD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Turin%20Brakes/Late%20Lounge%20(2%20of%202)/02%20The%20Door.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1757</key>
+		<dict>
+			<key>Track ID</key><integer>1757</integer>
+			<key>Name</key><string>Zoo Station</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3357815</integer>
+			<key>Total Time</key><integer>276218</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253596867</integer>
+			<key>Play Date UTC</key><date>2007-02-06T16:54:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867C0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/01%20Zoo%20Station.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1758</key>
+		<dict>
+			<key>Track ID</key><integer>1758</integer>
+			<key>Name</key><string>Even Better Than the Real Thing</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2697887</integer>
+			<key>Total Time</key><integer>221570</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251635078</integer>
+			<key>Play Date UTC</key><date>2007-01-14T23:57:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867C3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/02%20Even%20Better%20Than%20the%20Real%20Thing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1759</key>
+		<dict>
+			<key>Track ID</key><integer>1759</integer>
+			<key>Name</key><string>One</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3357807</integer>
+			<key>Total Time</key><integer>276218</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246878278</integer>
+			<key>Play Date UTC</key><date>2006-11-20T22:37:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/03%20One.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1760</key>
+		<dict>
+			<key>Track ID</key><integer>1760</integer>
+			<key>Name</key><string>Until the End of the World</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3388335</integer>
+			<key>Total Time</key><integer>278595</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253605578</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:19:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867C7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/04%20Until%20the%20End%20of%20the%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1761</key>
+		<dict>
+			<key>Track ID</key><integer>1761</integer>
+			<key>Name</key><string>Who's Gonna Ride Your Wild Horses</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3847765</integer>
+			<key>Total Time</key><integer>316708</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:34:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252524769</integer>
+			<key>Play Date UTC</key><date>2007-01-25T07:06:09Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-02-06T16:43:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867C9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/05%20Who's%20Gonna%20Ride%20Your%20Wild%20Horses.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1762</key>
+		<dict>
+			<key>Track ID</key><integer>1762</integer>
+			<key>Name</key><string>So Cruel</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4242727</integer>
+			<key>Total Time</key><integer>349283</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253262913</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:08:33Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867CB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/06%20So%20Cruel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1763</key>
+		<dict>
+			<key>Track ID</key><integer>1763</integer>
+			<key>Name</key><string>The Fly</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3273125</integer>
+			<key>Total Time</key><integer>269165</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:00Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249200882</integer>
+			<key>Play Date UTC</key><date>2006-12-17T19:48:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/07%20The%20Fly.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1764</key>
+		<dict>
+			<key>Track ID</key><integer>1764</integer>
+			<key>Name</key><string>Mysterious Ways</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2965130</integer>
+			<key>Total Time</key><integer>243670</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253622449</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:00:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/08%20Mysterious%20Ways.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1765</key>
+		<dict>
+			<key>Track ID</key><integer>1765</integer>
+			<key>Name</key><string>Tryin' to Throw Your Arms Around the World</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2831739</integer>
+			<key>Total Time</key><integer>232724</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249205223</integer>
+			<key>Play Date UTC</key><date>2006-12-17T21:00:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/09%20Tryin'%20to%20Throw%20Your%20Arms%20Around%20the%20World.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1766</key>
+		<dict>
+			<key>Track ID</key><integer>1766</integer>
+			<key>Name</key><string>Ultraviolet (Light My Way)</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4016549</integer>
+			<key>Total Time</key><integer>330605</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252554582</integer>
+			<key>Play Date UTC</key><date>2007-01-25T15:23:02Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-19T18:01:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/10%20Ultraviolet%20(Light%20My%20Way).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1767</key>
+		<dict>
+			<key>Track ID</key><integer>1767</integer>
+			<key>Name</key><string>Acrobat</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3287544</integer>
+			<key>Total Time</key><integer>270367</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252541447</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:44:07Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-20T18:14:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/11%20Acrobat.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1768</key>
+		<dict>
+			<key>Track ID</key><integer>1768</integer>
+			<key>Name</key><string>Love Is Blindness</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Achtung Baby</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3203848</integer>
+			<key>Total Time</key><integer>263392</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:03Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252992337</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:58:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Achtung%20Baby/12%20Love%20Is%20Blindness.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1769</key>
+		<dict>
+			<key>Track ID</key><integer>1769</integer>
+			<key>Name</key><string>Beautiful Day</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6010685</integer>
+			<key>Total Time</key><integer>248041</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:11:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B867D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/01%20Beautiful%20Day.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1770</key>
+		<dict>
+			<key>Track ID</key><integer>1770</integer>
+			<key>Name</key><string>Stuck In A Moment You Can't Get Out Of</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6596971</integer>
+			<key>Total Time</key><integer>272254</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:14:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251607500</integer>
+			<key>Play Date UTC</key><date>2007-01-14T16:18:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B867DC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/02%20Stuck%20In%20A%20Moment%20You%20Can't%20Get%20Out%20Of.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1771</key>
+		<dict>
+			<key>Track ID</key><integer>1771</integer>
+			<key>Name</key><string>Elevation</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5515391</integer>
+			<key>Total Time</key><integer>227433</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:17:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253451800</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:36:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B867DE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/03%20Elevation.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1772</key>
+		<dict>
+			<key>Track ID</key><integer>1772</integer>
+			<key>Name</key><string>Walk On</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7175751</integer>
+			<key>Total Time</key><integer>296169</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:21:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253363612</integer>
+			<key>Play Date UTC</key><date>2007-02-04T00:06:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B867E0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/04%20Walk%20On.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1773</key>
+		<dict>
+			<key>Track ID</key><integer>1773</integer>
+			<key>Name</key><string>Kite</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6464654</integer>
+			<key>Total Time</key><integer>266772</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:24:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253450474</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:14:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B867E2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/05%20Kite.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1774</key>
+		<dict>
+			<key>Track ID</key><integer>1774</integer>
+			<key>Name</key><string>In A Little While</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5316122</integer>
+			<key>Total Time</key><integer>219134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:27:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253558562</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:16:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B867E4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/06%20In%20A%20Little%20While.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1775</key>
+		<dict>
+			<key>Track ID</key><integer>1775</integer>
+			<key>Name</key><string>Wild Honey</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5496888</integer>
+			<key>Total Time</key><integer>226644</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:29:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252468927</integer>
+			<key>Play Date UTC</key><date>2007-01-24T15:35:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B867E6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/07%20Wild%20Honey.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1776</key>
+		<dict>
+			<key>Track ID</key><integer>1776</integer>
+			<key>Name</key><string>Peace On Earth</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6987346</integer>
+			<key>Total Time</key><integer>288361</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:33:30Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250611339</integer>
+			<key>Play Date UTC</key><date>2007-01-03T03:35:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B867E8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/08%20Peace%20On%20Earth.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1777</key>
+		<dict>
+			<key>Track ID</key><integer>1777</integer>
+			<key>Name</key><string>When I Look At The World</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6244094</integer>
+			<key>Total Time</key><integer>257662</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:36:41Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3250693682</integer>
+			<key>Play Date UTC</key><date>2007-01-04T02:28:02Z</date>
+			<key>Persistent ID</key><string>87139F8602B867EA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/09%20When%20I%20Look%20At%20The%20World.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1778</key>
+		<dict>
+			<key>Track ID</key><integer>1778</integer>
+			<key>Name</key><string>New York</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8001442</integer>
+			<key>Total Time</key><integer>330238</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:40:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253280703</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:05:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B867EC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/10%20New%20York.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1779</key>
+		<dict>
+			<key>Track ID</key><integer>1779</integer>
+			<key>Name</key><string>Grace</string>
+			<key>Artist</key><string>U2</string>
+			<key>Composer</key><string>Adam Clayton/Bono/Larry Mullen/The Edge</string>
+			<key>Album</key><string>All That You Can't Leave Behind</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8008440</integer>
+			<key>Total Time</key><integer>330537</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-05-04T14:44:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252935509</integer>
+			<key>Play Date UTC</key><date>2007-01-30T01:11:49Z</date>
+			<key>Persistent ID</key><string>87139F8602B867EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/All%20That%20You%20Can't%20Leave%20Behind/11%20Grace.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1780</key>
+		<dict>
+			<key>Track ID</key><integer>1780</integer>
+			<key>Name</key><string>A Sort of Homecoming</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3982506</integer>
+			<key>Total Time</key><integer>328280</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252988950</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:02:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/01%20A%20Sort%20of%20Homecoming.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1781</key>
+		<dict>
+			<key>Track ID</key><integer>1781</integer>
+			<key>Name</key><string>Pride (In the Name of Love)</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2791594</integer>
+			<key>Total Time</key><integer>229720</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252390724</integer>
+			<key>Play Date UTC</key><date>2007-01-23T17:52:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867F3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/02%20Pride%20(In%20the%20Name%20of%20Love).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1782</key>
+		<dict>
+			<key>Track ID</key><integer>1782</integer>
+			<key>Name</key><string>Wire</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3148176</integer>
+			<key>Total Time</key><integer>259265</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252531124</integer>
+			<key>Play Date UTC</key><date>2007-01-25T08:52:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867F5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/03%20Wire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1783</key>
+		<dict>
+			<key>Track ID</key><integer>1783</integer>
+			<key>Name</key><string>The Unforgettable Fire</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3585800</integer>
+			<key>Total Time</key><integer>295392</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253467343</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:55:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867F7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/04%20The%20Unforgettable%20Fire.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1784</key>
+		<dict>
+			<key>Track ID</key><integer>1784</integer>
+			<key>Name</key><string>Promenade</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1876535</integer>
+			<key>Total Time</key><integer>154148</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252493448</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:24:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867F9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/05%20Promenade.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1785</key>
+		<dict>
+			<key>Track ID</key><integer>1785</integer>
+			<key>Name</key><string>4th of July</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1637817</integer>
+			<key>Total Time</key><integer>134426</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253354552</integer>
+			<key>Play Date UTC</key><date>2007-02-03T21:35:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867FB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/06%204th%20of%20July.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1786</key>
+		<dict>
+			<key>Track ID</key><integer>1786</integer>
+			<key>Name</key><string>Bad</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4469031</integer>
+			<key>Total Time</key><integer>368483</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251620774</integer>
+			<key>Play Date UTC</key><date>2007-01-14T19:59:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867FD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/07%20Bad.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1787</key>
+		<dict>
+			<key>Track ID</key><integer>1787</integer>
+			<key>Name</key><string>Indian Summer Sky</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3150997</integer>
+			<key>Total Time</key><integer>259500</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253370863</integer>
+			<key>Play Date UTC</key><date>2007-02-04T02:07:43Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B867FF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/08%20Indian%20Summer%20Sky.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1788</key>
+		<dict>
+			<key>Track ID</key><integer>1788</integer>
+			<key>Name</key><string>Elvis Presley and America</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4643174</integer>
+			<key>Total Time</key><integer>382824</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:00Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251886996</integer>
+			<key>Play Date UTC</key><date>2007-01-17T21:56:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86801</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/09%20Elvis%20Presley%20and%20America.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1789</key>
+		<dict>
+			<key>Track ID</key><integer>1789</integer>
+			<key>Name</key><string>MLK</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>The Unforgettable Fire</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1859921</integer>
+			<key>Total Time</key><integer>152764</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252513027</integer>
+			<key>Play Date UTC</key><date>2007-01-25T03:50:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86803</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/The%20Unforgettable%20Fire/10%20MLK.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1790</key>
+		<dict>
+			<key>Track ID</key><integer>1790</integer>
+			<key>Name</key><string>Zooropa</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4757632</integer>
+			<key>Total Time</key><integer>391680</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253612210</integer>
+			<key>Play Date UTC</key><date>2007-02-06T21:10:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86805</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/01%20Zooropa.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1791</key>
+		<dict>
+			<key>Track ID</key><integer>1791</integer>
+			<key>Name</key><string>Babyface</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2945382</integer>
+			<key>Total Time</key><integer>242024</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253265685</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:54:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86808</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/02%20Babyface.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1792</key>
+		<dict>
+			<key>Track ID</key><integer>1792</integer>
+			<key>Name</key><string>Numb</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3166232</integer>
+			<key>Total Time</key><integer>260257</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253457824</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:17:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8680A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/03%20Numb.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1793</key>
+		<dict>
+			<key>Track ID</key><integer>1793</integer>
+			<key>Name</key><string>Lemon</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5079419</integer>
+			<key>Total Time</key><integer>418324</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247632953</integer>
+			<key>Play Date UTC</key><date>2006-11-29T16:15:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8680C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/04%20Lemon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1794</key>
+		<dict>
+			<key>Track ID</key><integer>1794</integer>
+			<key>Name</key><string>Stay (Faraway, So Close!)</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3629247</integer>
+			<key>Total Time</key><integer>298501</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8680E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/05%20Stay%20(Faraway,%20So%20Close!).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1795</key>
+		<dict>
+			<key>Track ID</key><integer>1795</integer>
+			<key>Name</key><string>Daddy's Gonna Pay for Your Crashed Car</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3892415</integer>
+			<key>Total Time</key><integer>320261</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249574373</integer>
+			<key>Play Date UTC</key><date>2006-12-22T03:32:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86810</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/06%20Daddy's%20Gonna%20Pay%20for%20Your%20Crashed%20Car.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1796</key>
+		<dict>
+			<key>Track ID</key><integer>1796</integer>
+			<key>Name</key><string>Some Days Are Better Than Others</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3132690</integer>
+			<key>Total Time</key><integer>257462</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251521770</integer>
+			<key>Play Date UTC</key><date>2007-01-13T16:29:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86812</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/07%20Some%20Days%20Are%20Better%20Than%20Others.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1797</key>
+		<dict>
+			<key>Track ID</key><integer>1797</integer>
+			<key>Name</key><string>The First Time</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2746475</integer>
+			<key>Total Time</key><integer>225619</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253451572</integer>
+			<key>Play Date UTC</key><date>2007-02-05T00:32:52Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-18T18:17:41Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86814</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/08%20The%20First%20Time.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1798</key>
+		<dict>
+			<key>Track ID</key><integer>1798</integer>
+			<key>Name</key><string>Dirty Day</string>
+			<key>Artist</key><string>U2</string>
+			<key>Album</key><string>Zooropa</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3943197</integer>
+			<key>Total Time</key><integer>324493</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253293841</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:44:01Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86816</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/U2/Zooropa/09%20Dirty%20Day.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1799</key>
+		<dict>
+			<key>Track ID</key><integer>1799</integer>
+			<key>Name</key><string>Thin</string>
+			<key>Artist</key><string>Underwolves</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2737635</integer>
+			<key>Total Time</key><integer>170710</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252488752</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:05:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86818</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underwolves/Late%20Lounge%20(1%20of%202)/04%20Thin.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1800</key>
+		<dict>
+			<key>Track ID</key><integer>1800</integer>
+			<key>Name</key><string>Cowgirl</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8182348</integer>
+			<key>Total Time</key><integer>510876</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253764512</integer>
+			<key>Play Date UTC</key><date>2007-02-08T15:28:32Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8681B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/01%20Cowgirl.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1801</key>
+		<dict>
+			<key>Track ID</key><integer>1801</integer>
+			<key>Name</key><string>Born Slippy [Nuxx]</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7272451</integer>
+			<key>Total Time</key><integer>454008</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253100953</integer>
+			<key>Play Date UTC</key><date>2007-01-31T23:09:13Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8681E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/02%20Born%20Slippy%20%5BNuxx%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1802</key>
+		<dict>
+			<key>Track ID</key><integer>1802</integer>
+			<key>Name</key><string>Pearls Girl</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9243546</integer>
+			<key>Total Time</key><integer>577201</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253101530</integer>
+			<key>Play Date UTC</key><date>2007-01-31T23:18:50Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-24T23:07:26Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86820</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/03%20Pearls%20Girl.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1803</key>
+		<dict>
+			<key>Track ID</key><integer>1803</integer>
+			<key>Name</key><string>Jumbo</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6723252</integer>
+			<key>Total Time</key><integer>419683</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252987367</integer>
+			<key>Play Date UTC</key><date>2007-01-30T15:36:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86822</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/04%20Jumbo.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1804</key>
+		<dict>
+			<key>Track ID</key><integer>1804</integer>
+			<key>Name</key><string>Push Upstairs</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5922442</integer>
+			<key>Total Time</key><integer>369632</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>30</integer>
+			<key>Play Date</key><integer>3253162102</integer>
+			<key>Play Date UTC</key><date>2007-02-01T16:08:22Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86824</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/05%20Push%20Upstairs.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1805</key>
+		<dict>
+			<key>Track ID</key><integer>1805</integer>
+			<key>Name</key><string>Moaner</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9975393</integer>
+			<key>Total Time</key><integer>622942</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253678486</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:34:46Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86826</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/06%20Moaner.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1806</key>
+		<dict>
+			<key>Track ID</key><integer>1806</integer>
+			<key>Name</key><string>Shudder/King of Snake</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9136549</integer>
+			<key>Total Time</key><integer>570514</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249322537</integer>
+			<key>Play Date UTC</key><date>2006-12-19T05:35:37Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86828</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/07%20Shudder_King%20of%20Snake.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1807</key>
+		<dict>
+			<key>Track ID</key><integer>1807</integer>
+			<key>Name</key><string>8 Ball</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8563109</integer>
+			<key>Total Time</key><integer>534674</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253593103</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:51:43Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-18T23:17:33Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8682A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/08%208%20Ball.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1808</key>
+		<dict>
+			<key>Track ID</key><integer>1808</integer>
+			<key>Name</key><string>Two Months Off</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8810122</integer>
+			<key>Total Time</key><integer>550112</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253103238</integer>
+			<key>Play Date UTC</key><date>2007-01-31T23:47:18Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8682C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20(2%20of%202)/09%20Two%20Months%20Off.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1809</key>
+		<dict>
+			<key>Track ID</key><integer>1809</integer>
+			<key>Name</key><string>Big Mouth</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9847482</integer>
+			<key>Total Time</key><integer>608384</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-04-14T18:25:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>34</integer>
+			<key>Play Date</key><integer>3253677863</integer>
+			<key>Play Date UTC</key><date>2007-02-07T15:24:23Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-16T03:49:09Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B8682E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/01%20Big%20Mouth.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1810</key>
+		<dict>
+			<key>Track ID</key><integer>1810</integer>
+			<key>Name</key><string>Dirty</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9887747</integer>
+			<key>Total Time</key><integer>617848</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>27</integer>
+			<key>Play Date</key><integer>3253163328</integer>
+			<key>Play Date UTC</key><date>2007-02-01T16:28:48Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86831</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/02%20Dirty.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1811</key>
+		<dict>
+			<key>Track ID</key><integer>1811</integer>
+			<key>Name</key><string>Mmm Skyscraper I Love You</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12720674</integer>
+			<key>Total Time</key><integer>794906</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251895043</integer>
+			<key>Play Date UTC</key><date>2007-01-18T00:10:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B86833</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/03%20Mmm%20Skyscraper%20I%20Love%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1812</key>
+		<dict>
+			<key>Track ID</key><integer>1812</integer>
+			<key>Name</key><string>Rez</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9561320</integer>
+			<key>Total Time</key><integer>597446</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253103835</integer>
+			<key>Play Date UTC</key><date>2007-01-31T23:57:15Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86835</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/04%20Rez.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1813</key>
+		<dict>
+			<key>Track ID</key><integer>1813</integer>
+			<key>Name</key><string>Spikee</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11999694</integer>
+			<key>Total Time</key><integer>749844</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246984796</integer>
+			<key>Play Date UTC</key><date>2006-11-22T04:13:16Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86837</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/05%20Spikee.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1814</key>
+		<dict>
+			<key>Track ID</key><integer>1814</integer>
+			<key>Name</key><string>Dirty Epic</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9588488</integer>
+			<key>Total Time</key><integer>599144</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B86839</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/06%20Dirty%20Epic.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1815</key>
+		<dict>
+			<key>Track ID</key><integer>1815</integer>
+			<key>Name</key><string>Dark &#38; Long (Dark Train)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>1992-2002 Disc 1</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10451574</integer>
+			<key>Total Time</key><integer>653087</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247823290</integer>
+			<key>Play Date UTC</key><date>2006-12-01T21:08:10Z</date>
+			<key>Persistent ID</key><string>87139F8602B8683B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/1992-2002%20Disc%201/07%20Dark%20&#38;%20Long%20(Dark%20Train).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1816</key>
+		<dict>
+			<key>Track ID</key><integer>1816</integer>
+			<key>Name</key><string>No Move</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9905252</integer>
+			<key>Total Time</key><integer>412368</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:48:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252989656</integer>
+			<key>Play Date UTC</key><date>2007-01-30T16:14:16Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8683D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/01%20No%20Move.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1817</key>
+		<dict>
+			<key>Track ID</key><integer>1817</integer>
+			<key>Name</key><string>Two Months Off</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>13126470</integer>
+			<key>Total Time</key><integer>546586</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:48:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86840</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/02%20Two%20Months%20Off.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1818</key>
+		<dict>
+			<key>Track ID</key><integer>1818</integer>
+			<key>Name</key><string>Twist</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9231918</integer>
+			<key>Total Time</key><integer>384313</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:49:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252491970</integer>
+			<key>Play Date UTC</key><date>2007-01-24T21:59:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86842</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/03%20Twist.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1819</key>
+		<dict>
+			<key>Track ID</key><integer>1819</integer>
+			<key>Name</key><string>Sola Sistim</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9297125</integer>
+			<key>Total Time</key><integer>387030</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:49:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252493835</integer>
+			<key>Play Date UTC</key><date>2007-01-24T22:30:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86844</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/04%20Sola%20Sistim.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1820</key>
+		<dict>
+			<key>Track ID</key><integer>1820</integer>
+			<key>Name</key><string>Little Speaker</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12407372</integer>
+			<key>Total Time</key><integer>516623</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252478686</integer>
+			<key>Play Date UTC</key><date>2007-01-24T18:18:06Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86846</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/05%20Little%20Speaker.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1821</key>
+		<dict>
+			<key>Track ID</key><integer>1821</integer>
+			<key>Name</key><string>Trim</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4899770</integer>
+			<key>Total Time</key><integer>203807</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253104039</integer>
+			<key>Play Date UTC</key><date>2007-02-01T00:00:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86848</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/06%20Trim.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1822</key>
+		<dict>
+			<key>Track ID</key><integer>1822</integer>
+			<key>Name</key><string>Ess Gee</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3417690</integer>
+			<key>Total Time</key><integer>142053</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3246599061</integer>
+			<key>Play Date UTC</key><date>2006-11-17T17:04:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8684A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/07%20Ess%20Gee.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1823</key>
+		<dict>
+			<key>Track ID</key><integer>1823</integer>
+			<key>Name</key><string>Dinosaur Adventured 3d</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11436878</integer>
+			<key>Total Time</key><integer>476186</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253472572</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:22:52Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8684C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/08%20Dinosaur%20Adventured%203d.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1824</key>
+		<dict>
+			<key>Track ID</key><integer>1824</integer>
+			<key>Name</key><string>Ballet Lane</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5284717</integer>
+			<key>Total Time</key><integer>219846</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:50:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253358068</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:34:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8684E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/09%20Ballet%20Lane.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1825</key>
+		<dict>
+			<key>Track ID</key><integer>1825</integer>
+			<key>Name</key><string>Luetin</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>A Hundred Days Off</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10108380</integer>
+			<key>Total Time</key><integer>420832</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2004-11-29T13:47:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246791376</integer>
+			<key>Play Date UTC</key><date>2006-11-19T22:29:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-29T23:49:40Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86850</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/A%20Hundred%20Days%20Off/10%20Luetin.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1826</key>
+		<dict>
+			<key>Track ID</key><integer>1826</integer>
+			<key>Name</key><string>Dirty Epic (Dirty Guitar Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dirty Epic - Cowgirl (EP)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12000428</integer>
+			<key>Total Time</key><integer>600006</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:27Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>From club.mp3search.ru April 27 2004</string>
+			<key>Play Count</key><integer>9</integer>
+			<key>Play Date</key><integer>3253104639</integer>
+			<key>Play Date UTC</key><date>2007-02-01T00:10:39Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Persistent ID</key><string>87139F8602B86852</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dirty%20Epic%20-%20Cowgirl%20(EP)/01%20Dirty%20Epic%20(Dirty%20Guitar%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1827</key>
+		<dict>
+			<key>Track ID</key><integer>1827</integer>
+			<key>Name</key><string>Cowgirl (Winjer Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dirty Epic - Cowgirl (EP)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7694392</integer>
+			<key>Total Time</key><integer>384705</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:29Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>club.mp3search.ru on Apri 27 2004</string>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246781333</integer>
+			<key>Play Date UTC</key><date>2006-11-19T19:42:13Z</date>
+			<key>Persistent ID</key><string>87139F8602B86855</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dirty%20Epic%20-%20Cowgirl%20(EP)/05%20Cowgirl%20(Winjer%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1828</key>
+		<dict>
+			<key>Track ID</key><integer>1828</integer>
+			<key>Name</key><string>River Of Bass</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dirty Epic - Cowgirl (EP)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7729387</integer>
+			<key>Total Time</key><integer>386455</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1994</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>club.mp3search.ru April 27 2004</string>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247119459</integer>
+			<key>Play Date UTC</key><date>2006-11-23T17:37:39Z</date>
+			<key>Persistent ID</key><string>87139F8602B86857</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dirty%20Epic%20-%20Cowgirl%20(EP)/08%20River%20Of%20Bass.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1829</key>
+		<dict>
+			<key>Track ID</key><integer>1829</integer>
+			<key>Name</key><string>Surfboy</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dubnobasswithmyheadman</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7731513</integer>
+			<key>Total Time</key><integer>453716</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2006-09-05T15:58:46Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253286882</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:48:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86859</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dubnobasswithmyheadman/03%20Surfboy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1830</key>
+		<dict>
+			<key>Track ID</key><integer>1830</integer>
+			<key>Name</key><string>Spoonman</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dubnobasswithmyheadman</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7634250</integer>
+			<key>Total Time</key><integer>461193</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2006-09-05T15:58:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246988820</integer>
+			<key>Play Date UTC</key><date>2006-11-22T05:20:20Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-19T19:10:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8685C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dubnobasswithmyheadman/04%20Spoonman.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1831</key>
+		<dict>
+			<key>Track ID</key><integer>1831</integer>
+			<key>Name</key><string>Tongue</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album Artist</key><string>Underworld</string>
+			<key>Album</key><string>Dubnobasswithmyheadman</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4960936</integer>
+			<key>Total Time</key><integer>290851</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>9</integer>
+			<key>Year</key><integer>1998</integer>
+			<key>Date Modified</key><date>2006-09-05T15:59:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253529987</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:19:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8685E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Dubnobasswithmyheadman/05%20Tongue.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1832</key>
+		<dict>
+			<key>Track ID</key><integer>1832</integer>
+			<key>Name</key><string>M.E.</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6875849</integer>
+			<key>Total Time</key><integer>429348</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253547465</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:11:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86860</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Late%20Lounge%20(1%20of%202)/12%20M.E..mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1833</key>
+		<dict>
+			<key>Track ID</key><integer>1833</integer>
+			<key>Name</key><string>Banstyle (alex Reece Remix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6850535</integer>
+			<key>Total Time</key><integer>342439</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:22Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3251351495</integer>
+			<key>Play Date UTC</key><date>2007-01-11T17:11:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86863</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/01%20Banstyle%20(alex%20Reece%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1834</key>
+		<dict>
+			<key>Track ID</key><integer>1834</integer>
+			<key>Name</key><string>Born Slippy (nuxx)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6478020</integer>
+			<key>Total Time</key><integer>323813</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253277962</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:19:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86866</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/02%20Born%20Slippy%20(nuxx).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1835</key>
+		<dict>
+			<key>Track ID</key><integer>1835</integer>
+			<key>Name</key><string>Cherry Pie (unrealized Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10051059</integer>
+			<key>Total Time</key><integer>502465</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:28Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253685072</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:24:32Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86868</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/03%20Cherry%20Pie%20(unrealized%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1836</key>
+		<dict>
+			<key>Track ID</key><integer>1836</integer>
+			<key>Name</key><string>Dark &#38; Long (movie Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>12498205</integer>
+			<key>Total Time</key><integer>624822</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253607873</integer>
+			<key>Play Date UTC</key><date>2007-02-06T19:57:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8686A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/04%20Dark%20&#38;%20Long%20(movie%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1837</key>
+		<dict>
+			<key>Track ID</key><integer>1837</integer>
+			<key>Name</key><string>Deep Arch (deep Remix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10131510</integer>
+			<key>Total Time</key><integer>506488</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3252546178</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:02:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8686C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/05%20Deep%20Arch%20(deep%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1838</key>
+		<dict>
+			<key>Track ID</key><integer>1838</integer>
+			<key>Name</key><string>Jumbo (future Remix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7577777</integer>
+			<key>Total Time</key><integer>378801</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:39Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3249573885</integer>
+			<key>Play Date UTC</key><date>2006-12-22T03:24:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8686E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/06%20Jumbo%20(future%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1839</key>
+		<dict>
+			<key>Track ID</key><integer>1839</integer>
+			<key>Name</key><string>Oich Oich (industrial Remix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10288252</integer>
+			<key>Total Time</key><integer>514324</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253598964</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:29:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86870</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/07%20Oich%20Oich%20(industrial%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1840</key>
+		<dict>
+			<key>Track ID</key><integer>1840</integer>
+			<key>Name</key><string>Pearl's Girl (short Remix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5326028</integer>
+			<key>Total Time</key><integer>266213</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253337650</integer>
+			<key>Play Date UTC</key><date>2007-02-03T16:54:10Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86872</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/08%20Pearl's%20Girl%20(short%20Remix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1841</key>
+		<dict>
+			<key>Track ID</key><integer>1841</integer>
+			<key>Name</key><string>Peral's Girl (singled Edit)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3621802</integer>
+			<key>Total Time</key><integer>181002</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252523162</integer>
+			<key>Play Date UTC</key><date>2007-01-25T06:39:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86874</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/09%20Peral's%20Girl%20(singled%20Edit).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1842</key>
+		<dict>
+			<key>Track ID</key><integer>1842</integer>
+			<key>Name</key><string>Puppies (short Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4710056</integer>
+			<key>Total Time</key><integer>235415</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253597313</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:01:53Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86876</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/10%20Puppies%20(short%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1843</key>
+		<dict>
+			<key>Track ID</key><integer>1843</integer>
+			<key>Name</key><string>Second Hand (cafe Dell Mar Mix)</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Remix Album</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10801413</integer>
+			<key>Total Time</key><integer>539977</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>160</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253524191</integer>
+			<key>Play Date UTC</key><date>2007-02-05T20:43:11Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-15T23:25:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86878</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Remix%20Album/11%20Second%20Hand%20(cafe%20Dell%20Mar%20Mix).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1844</key>
+		<dict>
+			<key>Track ID</key><integer>1844</integer>
+			<key>Name</key><string>Juanita/Kiteless/To Dream of Love</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>45059</integer>
+			<key>Total Time</key><integer>2168</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253428467</integer>
+			<key>Play Date UTC</key><date>2007-02-04T18:07:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8687A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/01%20Juanita_Kiteless_To%20Dream%20of%20Love.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1845</key>
+		<dict>
+			<key>Track ID</key><integer>1845</integer>
+			<key>Name</key><string>Banstyle/Sappys Curry</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>14771432</integer>
+			<key>Total Time</key><integer>922566</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252533038</integer>
+			<key>Play Date UTC</key><date>2007-01-25T09:23:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8687D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/02%20Banstyle_Sappys%20Curry.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1846</key>
+		<dict>
+			<key>Track ID</key><integer>1846</integer>
+			<key>Name</key><string>Confusion the Waitress</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6524680</integer>
+			<key>Total Time</key><integer>407144</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252988304</integer>
+			<key>Play Date UTC</key><date>2007-01-30T15:51:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8687F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/03%20Confusion%20the%20Waitress.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1847</key>
+		<dict>
+			<key>Track ID</key><integer>1847</integer>
+			<key>Name</key><string>Rowla</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6275994</integer>
+			<key>Total Time</key><integer>391601</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253449450</integer>
+			<key>Play Date UTC</key><date>2007-02-04T23:57:30Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86881</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/04%20Rowla.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1848</key>
+		<dict>
+			<key>Track ID</key><integer>1848</integer>
+			<key>Name</key><string>Pearl's Girl</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9237235</integer>
+			<key>Total Time</key><integer>576679</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:42Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253276876</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:01:16Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-08T19:43:48Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86883</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/05%20Pearl's%20Girl.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1849</key>
+		<dict>
+			<key>Track ID</key><integer>1849</integer>
+			<key>Name</key><string>Air Towel</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7334267</integer>
+			<key>Total Time</key><integer>457743</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:35Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:01Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253690274</integer>
+			<key>Play Date UTC</key><date>2007-02-07T18:51:14Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-16T05:05:48Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86885</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/06%20Air%20Towel.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1850</key>
+		<dict>
+			<key>Track ID</key><integer>1850</integer>
+			<key>Name</key><string>Blueski</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2822397</integer>
+			<key>Total Time</key><integer>175751</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:38Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253454239</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:17:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86887</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/07%20Blueski.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1851</key>
+		<dict>
+			<key>Track ID</key><integer>1851</integer>
+			<key>Name</key><string>Stagger</string>
+			<key>Artist</key><string>Underworld</string>
+			<key>Album</key><string>Second Toughest in the Infants</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7335103</integer>
+			<key>Total Time</key><integer>457795</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:44Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252522387</integer>
+			<key>Play Date UTC</key><date>2007-01-25T06:26:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86889</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Underworld/Second%20Toughest%20in%20the%20Infants/08%20Stagger.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1852</key>
+		<dict>
+			<key>Track ID</key><integer>1852</integer>
+			<key>Name</key><string>born slippy (nuxx)</string>
+			<key>Artist</key><string>underworld</string>
+			<key>Album</key><string>underworld: second toughest in the infants (disk 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>11208080</integer>
+			<key>Total Time</key><integer>700368</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:45Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B8688B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/underworld/underworld_%20second%20toughest%20in%20the%20infants%20(disk%202)/01%20born%20slippy%20(nuxx).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1853</key>
+		<dict>
+			<key>Track ID</key><integer>1853</integer>
+			<key>Name</key><string>rez</string>
+			<key>Artist</key><string>underworld</string>
+			<key>Album</key><string>underworld: second toughest in the infants (disk 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9526212</integer>
+			<key>Total Time</key><integer>595252</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253106195</integer>
+			<key>Play Date UTC</key><date>2007-02-01T00:36:35Z</date>
+			<key>Rating</key><integer>80</integer>
+			<key>Persistent ID</key><string>87139F8602B8688E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/underworld/underworld_%20second%20toughest%20in%20the%20infants%20(disk%202)/02%20rez.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1854</key>
+		<dict>
+			<key>Track ID</key><integer>1854</integer>
+			<key>Name</key><string>A Timeless Place [Acoustic Version]</string>
+			<key>Artist</key><string>Urban Dwellers</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6348803</integer>
+			<key>Total Time</key><integer>396408</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250582184</integer>
+			<key>Play Date UTC</key><date>2007-01-02T19:29:44Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86890</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Urban%20Dwellers/Late%20Lounge%20(2%20of%202)/13%20A%20Timeless%20Place%20%5BAcoustic%20Version%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1855</key>
+		<dict>
+			<key>Track ID</key><integer>1855</integer>
+			<key>Name</key><string>Buffy T.V. Theme - Nerf Herder</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1037879</integer>
+			<key>Total Time</key><integer>64731</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>25</integer>
+			<key>Play Date</key><integer>3252912356</integer>
+			<key>Play Date UTC</key><date>2007-01-29T18:45:56Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B86893</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/01%20Buffy%20T.V.%20Theme%20-%20Nerf%20Herder.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1856</key>
+		<dict>
+			<key>Track ID</key><integer>1856</integer>
+			<key>Name</key><string>Guided By Voices - Teenage FBI</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3195384</integer>
+			<key>Total Time</key><integer>199575</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253278161</integer>
+			<key>Play Date UTC</key><date>2007-02-03T00:22:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B86896</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/02%20Guided%20By%20Voices%20-%20Teenage%20FBI.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1857</key>
+		<dict>
+			<key>Track ID</key><integer>1857</integer>
+			<key>Name</key><string>Temptation Waits - Garbage</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4465562</integer>
+			<key>Total Time</key><integer>278961</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252466174</integer>
+			<key>Play Date UTC</key><date>2007-01-24T14:49:34Z</date>
+			<key>Persistent ID</key><string>87139F8602B86898</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/03%20Temptation%20Waits%20-%20Garbage.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1858</key>
+		<dict>
+			<key>Track ID</key><integer>1858</integer>
+			<key>Name</key><string>I Quit - Hepburn</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3777183</integer>
+			<key>Total Time</key><integer>235937</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251347045</integer>
+			<key>Play Date UTC</key><date>2007-01-11T15:57:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B8689A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/05%20I%20Quit%20-%20Hepburn.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1859</key>
+		<dict>
+			<key>Track ID</key><integer>1859</integer>
+			<key>Name</key><string>Over My Head - Furslide</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2956729</integer>
+			<key>Total Time</key><integer>184659</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:51Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252499792</integer>
+			<key>Play Date UTC</key><date>2007-01-25T00:09:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B8689C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/06%20Over%20My%20Head%20-%20Furslide.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1860</key>
+		<dict>
+			<key>Track ID</key><integer>1860</integer>
+			<key>Name</key><string>Lucky - Bif Naked</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3844893</integer>
+			<key>Total Time</key><integer>240169</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:52Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249571279</integer>
+			<key>Play Date UTC</key><date>2006-12-22T02:41:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B8689E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/07%20Lucky%20-%20Bif%20Naked.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1861</key>
+		<dict>
+			<key>Track ID</key><integer>1861</integer>
+			<key>Name</key><string>Keep Myself Awake - Black Lab</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4367342</integer>
+			<key>Total Time</key><integer>272822</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252482433</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:20:33Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T18:57:41Z</date>
+			<key>Persistent ID</key><string>87139F8602B868A0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/08%20Keep%20Myself%20Awake%20-%20Black%20Lab.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1862</key>
+		<dict>
+			<key>Track ID</key><integer>1862</integer>
+			<key>Name</key><string>K's Choice - Virgin State Of Mind</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3088805</integer>
+			<key>Total Time</key><integer>192914</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252516253</integer>
+			<key>Play Date UTC</key><date>2007-01-25T04:44:13Z</date>
+			<key>Persistent ID</key><string>87139F8602B868A2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/09%20K's%20Choice%20-%20Virgin%20State%20Of%20Mind.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1863</key>
+		<dict>
+			<key>Track ID</key><integer>1863</integer>
+			<key>Name</key><string>Already Met You - Superfine</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3416485</integer>
+			<key>Total Time</key><integer>213394</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:54Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B868A4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/10%20Already%20Met%20You%20-%20Superfine.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1864</key>
+		<dict>
+			<key>Track ID</key><integer>1864</integer>
+			<key>Name</key><string>The Devil You Know (God Is A Man) - Face To Face</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3457027</integer>
+			<key>Total Time</key><integer>215928</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253623465</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:17:45Z</date>
+			<key>Persistent ID</key><string>87139F8602B868A6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/11%20The%20Devil%20You%20Know%20(God%20Is%20A%20Man)%20-%20Face%20To%20Face.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1865</key>
+		<dict>
+			<key>Track ID</key><integer>1865</integer>
+			<key>Name</key><string>Nothing But You - Kim Ferron</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3769660</integer>
+			<key>Total Time</key><integer>235467</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253712312</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:58:32Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B868A8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/12%20Nothing%20But%20You%20-%20Kim%20Ferron.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1866</key>
+		<dict>
+			<key>Track ID</key><integer>1866</integer>
+			<key>Name</key><string>It Doesn`t Matter - Alison Krauss &#38; Union Station</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3699861</integer>
+			<key>Total Time</key><integer>231105</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253462039</integer>
+			<key>Play Date UTC</key><date>2007-02-05T03:27:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B868AA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/13%20It%20Doesn%60t%20Matter%20-%20Alison%20Krauss%20&#38;%20Union%20Station.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1867</key>
+		<dict>
+			<key>Track ID</key><integer>1867</integer>
+			<key>Name</key><string>Wild Horses - The Sundays</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4547482</integer>
+			<key>Total Time</key><integer>284081</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252506097</integer>
+			<key>Play Date UTC</key><date>2007-01-25T01:54:57Z</date>
+			<key>Persistent ID</key><string>87139F8602B868AC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/14%20Wild%20Horses%20-%20The%20Sundays.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1868</key>
+		<dict>
+			<key>Track ID</key><integer>1868</integer>
+			<key>Name</key><string>Pain (Slayer Mix) - Four Star Mary</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3458698</integer>
+			<key>Total Time</key><integer>216032</integer>
+			<key>Track Number</key><integer>15</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253548576</integer>
+			<key>Play Date UTC</key><date>2007-02-06T03:29:36Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-23T01:18:42Z</date>
+			<key>Persistent ID</key><string>87139F8602B868AE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/15%20Pain%20(Slayer%20Mix)%20-%20Four%20Star%20Mary.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1869</key>
+		<dict>
+			<key>Track ID</key><integer>1869</integer>
+			<key>Name</key><string>Charge - Splendid</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3662663</integer>
+			<key>Total Time</key><integer>228780</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:58Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252405685</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:01:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B868B0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/16%20Charge%20-%20Splendid.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1870</key>
+		<dict>
+			<key>Track ID</key><integer>1870</integer>
+			<key>Name</key><string>Transylvanian Concubine - Rasputina</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2664576</integer>
+			<key>Total Time</key><integer>166400</integer>
+			<key>Track Number</key><integer>17</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253456167</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:49:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B868B2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/17%20Transylvanian%20Concubine%20-%20Rasputina.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1871</key>
+		<dict>
+			<key>Track ID</key><integer>1871</integer>
+			<key>Name</key><string>Close Your Eyes (Buffy-Angel Love Theme) - Christophe Beck</string>
+			<key>Artist</key><string>Various Artists</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2643678</integer>
+			<key>Total Time</key><integer>165093</integer>
+			<key>Track Number</key><integer>18</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253294617</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:56:57Z</date>
+			<key>Persistent ID</key><string>87139F8602B868B4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Various%20Artists/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/18%20Close%20Your%20Eyes%20(Buffy-Angel%20Love%20Theme)%20-%20Christophe%20Beck.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1872</key>
+		<dict>
+			<key>Track ID</key><integer>1872</integer>
+			<key>Name</key><string>Floating Away</string>
+			<key>Artist</key><string>Velvet Chain</string>
+			<key>Album</key><string>Asteroid Belt</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3690882</integer>
+			<key>Total Time</key><integer>230556</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252476812</integer>
+			<key>Play Date UTC</key><date>2007-01-24T17:46:52Z</date>
+			<key>Persistent ID</key><string>87139F8602B868B6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Velvet%20Chain/Asteroid%20Belt/02%20Floating%20Away.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1873</key>
+		<dict>
+			<key>Track ID</key><integer>1873</integer>
+			<key>Name</key><string>You Remind Me</string>
+			<key>Artist</key><string>Velvet Chain</string>
+			<key>Album</key><string>Asteroid Belt</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2590813</integer>
+			<key>Total Time</key><integer>161802</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>2003</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253534827</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:40:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B868B9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Velvet%20Chain/Asteroid%20Belt/12%20You%20Remind%20Me.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1874</key>
+		<dict>
+			<key>Track ID</key><integer>1874</integer>
+			<key>Name</key><string>I Don't Care</string>
+			<key>Artist</key><string>Velvet Chain</string>
+			<key>Album Artist</key><string>Velvet Chain</string>
+			<key>Composer</key><string>Erika Amato/Jeff Stacy</string>
+			<key>Album</key><string>Buffy EP</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6592064</integer>
+			<key>Total Time</key><integer>411872</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>1997</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:13Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252559558</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:45:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B868BB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Velvet%20Chain/Buffy%20EP/06%20I%20Don't%20Care.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1875</key>
+		<dict>
+			<key>Track ID</key><integer>1875</integer>
+			<key>Name</key><string>Strong</string>
+			<key>Artist</key><string>Velvet Chain</string>
+			<key>Album</key><string>Buffy The Vampire Slayer - The Album</string>
+			<key>Genre</key><string>General Rock</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4336831</integer>
+			<key>Total Time</key><integer>270915</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:35:50Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>28</integer>
+			<key>Play Date</key><integer>3253164610</integer>
+			<key>Play Date UTC</key><date>2007-02-01T16:50:10Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B868BE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Velvet%20Chain/Buffy%20The%20Vampire%20Slayer%20-%20The%20Album/04%20Strong.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1876</key>
+		<dict>
+			<key>Track ID</key><integer>1876</integer>
+			<key>Name</key><string>Floating Away - Full Moon Space Cake Dub</string>
+			<key>Artist</key><string>Velvet Chain - Ashfelt</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6416954</integer>
+			<key>Total Time</key><integer>267284</integer>
+			<key>Date Modified</key><date>2004-11-29T13:38:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250582451</integer>
+			<key>Play Date UTC</key><date>2007-01-02T19:34:11Z</date>
+			<key>Persistent ID</key><string>87139F8602B868C1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Velvet%20Chain%20-%20Ashfelt/Unknown%20Album/Floating%20Away%20-%20Full%20Moon%20Space%20Cake%20Dub.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1877</key>
+		<dict>
+			<key>Track ID</key><integer>1877</integer>
+			<key>Name</key><string>Sound of the Samba</string>
+			<key>Artist</key><string>Victor Davies</string>
+			<key>Album</key><string>Late Lounge (2 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4916039</integer>
+			<key>Total Time</key><integer>306860</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252387194</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:53:14Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B868C5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Victor%20Davies/Late%20Lounge%20(2%20of%202)/08%20Sound%20of%20the%20Samba.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1878</key>
+		<dict>
+			<key>Track ID</key><integer>1878</integer>
+			<key>Name</key><string>Somewhere In America There's A Street Named After My Dad</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5376481</integer>
+			<key>Total Time</key><integer>221652</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:36:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253285774</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:29:34Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-25T00:20:20Z</date>
+			<key>Persistent ID</key><string>87139F8602B868C8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/01%20Somewhere%20In%20America%20There's%20A%20Street%20Named%20After%20My%20Dad.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1879</key>
+		<dict>
+			<key>Track ID</key><integer>1879</integer>
+			<key>Name</key><string>Spy In The House Of Love</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6222256</integer>
+			<key>Total Time</key><integer>256766</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:37:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3252905920</integer>
+			<key>Play Date UTC</key><date>2007-01-29T16:58:40Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-27T03:11:05Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B868CB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/02%20Spy%20In%20The%20House%20Of%20Love.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1880</key>
+		<dict>
+			<key>Track ID</key><integer>1880</integer>
+			<key>Name</key><string>Out Come The Freaks</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6686922</integer>
+			<key>Total Time</key><integer>275945</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:37:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252578346</integer>
+			<key>Play Date UTC</key><date>2007-01-25T21:59:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B868CD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/03%20Out%20Come%20The%20Freaks.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1881</key>
+		<dict>
+			<key>Track ID</key><integer>1881</integer>
+			<key>Name</key><string>Earth To Doris</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>3022181</integer>
+			<key>Total Time</key><integer>123625</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:38:18Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253289987</integer>
+			<key>Play Date UTC</key><date>2007-02-03T03:39:47Z</date>
+			<key>Persistent ID</key><string>87139F8602B868CF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/04%20Earth%20To%20Doris.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1882</key>
+		<dict>
+			<key>Track ID</key><integer>1882</integer>
+			<key>Name</key><string>Love Can Be Bad Luck</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was/Marshall Crenshaw</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5495373</integer>
+			<key>Total Time</key><integer>226601</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:38:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253256638</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:23:58Z</date>
+			<key>Persistent ID</key><string>87139F8602B868D1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/05%20Love%20Can%20Be%20Bad%20Luck.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1883</key>
+		<dict>
+			<key>Track ID</key><integer>1883</integer>
+			<key>Name</key><string>Boy's Gone Crazy</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5330869</integer>
+			<key>Total Time</key><integer>219732</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:39:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B868D3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/06%20Boy's%20Gone%20Crazy.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1884</key>
+		<dict>
+			<key>Track ID</key><integer>1884</integer>
+			<key>Name</key><string>11 Miles An Hour</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5933961</integer>
+			<key>Total Time</key><integer>244841</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:40:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252498434</integer>
+			<key>Play Date UTC</key><date>2007-01-24T23:47:14Z</date>
+			<key>Persistent ID</key><string>87139F8602B868D5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/07%2011%20Miles%20An%20Hour.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1885</key>
+		<dict>
+			<key>Track ID</key><integer>1885</integer>
+			<key>Name</key><string>What Up Dog?</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was/Harry Bowens/Sweetpea Atkinson</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2588560</integer>
+			<key>Total Time</key><integer>105577</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:40:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249455287</integer>
+			<key>Play Date UTC</key><date>2006-12-20T18:28:07Z</date>
+			<key>Persistent ID</key><string>87139F8602B868D7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/08%20What%20Up%20Dog_.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1886</key>
+		<dict>
+			<key>Track ID</key><integer>1886</integer>
+			<key>Name</key><string>Anything Can Happen</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Aaron Zigman/David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5726348</integer>
+			<key>Total Time</key><integer>236201</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:41:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247833159</integer>
+			<key>Play Date UTC</key><date>2006-12-01T23:52:39Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B868D9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/09%20Anything%20Can%20Happen.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1887</key>
+		<dict>
+			<key>Track ID</key><integer>1887</integer>
+			<key>Name</key><string>Wedding Vows In Vegas</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5272076</integer>
+			<key>Total Time</key><integer>217300</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:42:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253259276</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:07:56Z</date>
+			<key>Persistent ID</key><string>87139F8602B868DB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/11%20Wedding%20Vows%20In%20Vegas.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1888</key>
+		<dict>
+			<key>Track ID</key><integer>1888</integer>
+			<key>Name</key><string>Anytime Lisa</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6176048</integer>
+			<key>Total Time</key><integer>254868</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:43:15Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246610726</integer>
+			<key>Play Date UTC</key><date>2006-11-17T20:18:46Z</date>
+			<key>Persistent ID</key><string>87139F8602B868DD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/12%20Anytime%20Lisa.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1889</key>
+		<dict>
+			<key>Track ID</key><integer>1889</integer>
+			<key>Name</key><string>Walk The Dinosaur</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was/Randy Jacobs</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6346024</integer>
+			<key>Total Time</key><integer>261865</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:44:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252481623</integer>
+			<key>Play Date UTC</key><date>2007-01-24T19:07:03Z</date>
+			<key>Persistent ID</key><string>87139F8602B868DF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/13%20Walk%20The%20Dinosaur.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1890</key>
+		<dict>
+			<key>Track ID</key><integer>1890</integer>
+			<key>Name</key><string>I Can't Turn You Loose</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>Otis Redding</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>5281640</integer>
+			<key>Total Time</key><integer>217705</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:45:02Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B868E1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/14%20I%20Can't%20Turn%20You%20Loose.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1891</key>
+		<dict>
+			<key>Track ID</key><integer>1891</integer>
+			<key>Name</key><string>Dad I'm In Jail</string>
+			<key>Artist</key><string>Was (Not Was)</string>
+			<key>Composer</key><string>David Was/Don Was</string>
+			<key>Album</key><string>What Up, Dog?</string>
+			<key>Genre</key><string>Alternative &#38; Punk</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>2116909</integer>
+			<key>Total Time</key><integer>85972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>16</integer>
+			<key>Track Count</key><integer>16</integer>
+			<key>Year</key><integer>1988</integer>
+			<key>Date Modified</key><date>2004-07-18T18:50:48Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253597399</integer>
+			<key>Play Date UTC</key><date>2007-02-06T17:03:19Z</date>
+			<key>Persistent ID</key><string>87139F8602B868E3</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Was%20(Not%20Was)/What%20Up,%20Dog_/16%20Dad%20I'm%20In%20Jail.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1892</key>
+		<dict>
+			<key>Track ID</key><integer>1892</integer>
+			<key>Name</key><string>Adagio For Strings</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Samuel Barber</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>13850005</integer>
+			<key>Total Time</key><integer>574121</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:26:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253453642</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:07:22Z</date>
+			<key>Persistent ID</key><string>87139F8602B868E5</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/01%20Adagio%20For%20Strings.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1893</key>
+		<dict>
+			<key>Track ID</key><integer>1893</integer>
+			<key>Name</key><string>In A Landscape</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>John Cage</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4286407</integer>
+			<key>Total Time</key><integer>177065</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:26:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Persistent ID</key><string>87139F8602B868E8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/02%20In%20A%20Landscape.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1894</key>
+		<dict>
+			<key>Track ID</key><integer>1894</integer>
+			<key>Name</key><string>Ogive Number I</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Erik Satie</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9756368</integer>
+			<key>Total Time</key><integer>404564</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:28:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253426780</integer>
+			<key>Play Date UTC</key><date>2007-02-04T17:39:40Z</date>
+			<key>Persistent ID</key><string>87139F8602B868EA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/03%20Ogive%20Number%20I.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1895</key>
+		<dict>
+			<key>Track ID</key><integer>1895</integer>
+			<key>Name</key><string>Cavalleria Rusticana</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Pietro Mascagni</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>4696904</integer>
+			<key>Total Time</key><integer>199828</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:28:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253346348</integer>
+			<key>Play Date UTC</key><date>2007-02-03T19:19:08Z</date>
+			<key>Persistent ID</key><string>87139F8602B868EC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/04%20Cavalleria%20Rusticana.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1896</key>
+		<dict>
+			<key>Track ID</key><integer>1896</integer>
+			<key>Name</key><string>Triple Concerto</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Ludwig Van Beethoven</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7956749</integer>
+			<key>Total Time</key><integer>332670</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:31:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253519843</integer>
+			<key>Play Date UTC</key><date>2007-02-05T19:30:43Z</date>
+			<key>Persistent ID</key><string>87139F8602B868EE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/07%20Triple%20Concerto.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1897</key>
+		<dict>
+			<key>Track ID</key><integer>1897</integer>
+			<key>Name</key><string>Xerxes</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>George Frederic Handel/George Frideric Handel</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>6746001</integer>
+			<key>Total Time</key><integer>282708</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:32:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252395301</integer>
+			<key>Play Date UTC</key><date>2007-01-23T19:08:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B868F0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/08%20Xerxes.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1898</key>
+		<dict>
+			<key>Track ID</key><integer>1898</integer>
+			<key>Name</key><string>Piece In The Old Style I</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Henryk Górecki</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>7268617</integer>
+			<key>Total Time</key><integer>306132</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:33:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253293516</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:38:36Z</date>
+			<key>Persistent ID</key><string>87139F8602B868F2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/09%20Piece%20In%20The%20Old%20Style%20I.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1899</key>
+		<dict>
+			<key>Track ID</key><integer>1899</integer>
+			<key>Name</key><string>Piece In The Old Style 3</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Henryk Górecki</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>8423407</integer>
+			<key>Total Time</key><integer>349652</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:34:32Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253509278</integer>
+			<key>Play Date UTC</key><date>2007-02-05T16:34:38Z</date>
+			<key>Persistent ID</key><string>87139F8602B868F4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/10%20Piece%20In%20The%20Old%20Style%203.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1900</key>
+		<dict>
+			<key>Track ID</key><integer>1900</integer>
+			<key>Name</key><string>Opus I32</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Ludwig Van Beethoven</string>
+			<key>Album</key><string>Pieces In A Modern Style</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9063458</integer>
+			<key>Total Time</key><integer>374569</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T18:35:36Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253532039</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:53:59Z</date>
+			<key>Persistent ID</key><string>87139F8602B868F6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style/11%20Opus%20I32.m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1901</key>
+		<dict>
+			<key>Track ID</key><integer>1901</integer>
+			<key>Name</key><string>Adagio For Strings (Ferry Corsten Remix)</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Samuel Barber</string>
+			<key>Album</key><string>Pieces In A Modern Style [Bonus Disc]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>9520868</integer>
+			<key>Total Time</key><integer>394964</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>2</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T19:12:43Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247839201</integer>
+			<key>Play Date UTC</key><date>2006-12-02T01:33:21Z</date>
+			<key>Persistent ID</key><string>87139F8602B868F8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style%20%5BBonus%20Disc%5D/2-01%20Adagio%20For%20Strings%20(Ferry%20Corsten%20Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1902</key>
+		<dict>
+			<key>Track ID</key><integer>1902</integer>
+			<key>Name</key><string>Adagio For Strings (ATB Remix)</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Composer</key><string>Samuel Barber</string>
+			<key>Album</key><string>Pieces In A Modern Style [Bonus Disc]</string>
+			<key>Genre</key><string>Electronica/Dance</string>
+			<key>Kind</key><string>AAC audio file</string>
+			<key>Size</key><integer>11107544</integer>
+			<key>Total Time</key><integer>458665</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>2</integer>
+			<key>Year</key><integer>2000</integer>
+			<key>Date Modified</key><date>2004-06-01T19:14:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>48000</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250742029</integer>
+			<key>Play Date UTC</key><date>2007-01-04T15:53:49Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Persistent ID</key><string>87139F8602B868FB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Pieces%20In%20A%20Modern%20Style%20%5BBonus%20Disc%5D/2-02%20Adagio%20For%20Strings%20(ATB%20Remix).m4a</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1903</key>
+		<dict>
+			<key>Track ID</key><integer>1903</integer>
+			<key>Name</key><string>Water from a Vine Leaf [Xylem Flow Mix]</string>
+			<key>Artist</key><string>William Orbit</string>
+			<key>Album</key><string>Plastic Compilation, Vol. 2</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4750234</integer>
+			<key>Total Time</key><integer>391575</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>96</integer>
+			<key>Sample Rate</key><integer>22050</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3246890910</integer>
+			<key>Play Date UTC</key><date>2006-11-21T02:08:30Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-07T22:57:19Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B868FD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/William%20Orbit/Plastic%20Compilation,%20Vol.%202/03%20Water%20from%20a%20Vine%20Leaf%20%5BXylem%20Flow%20Mix%5D.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1904</key>
+		<dict>
+			<key>Track ID</key><integer>1904</integer>
+			<key>Name</key><string>Close to the Edge: The Solid Time of Change/Total Mass Retain/I Get Up</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Close to the Edge</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>17996155</integer>
+			<key>Total Time</key><integer>1124623</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:56Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253770597</integer>
+			<key>Play Date UTC</key><date>2007-02-08T17:09:57Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-24T21:56:49Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86900</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Close%20to%20the%20Edge/01%20Close%20to%20the%20Edge_%20The%20Solid%20Time%20of%20Change_Total%20Mass%20Retain_I%20Get%20Up.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1905</key>
+		<dict>
+			<key>Track ID</key><integer>1905</integer>
+			<key>Name</key><string>An And You and I: Cord of Life/Eclipse/The Preacher the Teacher/Apocalypse</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Close to the Edge</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9788690</integer>
+			<key>Total Time</key><integer>611657</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:53Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252548526</integer>
+			<key>Play Date UTC</key><date>2007-01-25T13:42:06Z</date>
+			<key>Persistent ID</key><string>87139F8602B86903</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Close%20to%20the%20Edge/02%20An%20And%20You%20and%20I_%20Cord%20of%20Life_Eclipse_The%20Preacher%20the%20Teacher_Apocalypse.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1906</key>
+		<dict>
+			<key>Track ID</key><integer>1906</integer>
+			<key>Name</key><string>Siberian Khatru</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Close to the Edge</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8535649</integer>
+			<key>Total Time</key><integer>533342</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253165143</integer>
+			<key>Play Date UTC</key><date>2007-02-01T16:59:03Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86905</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Close%20to%20the%20Edge/03%20Siberian%20Khatru.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1907</key>
+		<dict>
+			<key>Track ID</key><integer>1907</integer>
+			<key>Name</key><string>Machine Messiah</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10052351</integer>
+			<key>Total Time</key><integer>627748</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3252943011</integer>
+			<key>Play Date UTC</key><date>2007-01-30T03:16:51Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86907</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/01%20Machine%20Messiah.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1908</key>
+		<dict>
+			<key>Track ID</key><integer>1908</integer>
+			<key>Name</key><string>White Car</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>1309892</integer>
+			<key>Total Time</key><integer>81345</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251299687</integer>
+			<key>Play Date UTC</key><date>2007-01-11T02:48:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8690A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/02%20White%20Car.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1909</key>
+		<dict>
+			<key>Track ID</key><integer>1909</integer>
+			<key>Name</key><string>Does It Really Happen?</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6314549</integer>
+			<key>Total Time</key><integer>394135</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253375855</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:30:55Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-28T20:45:26Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8690C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/03%20Does%20It%20Really%20Happen_.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1910</key>
+		<dict>
+			<key>Track ID</key><integer>1910</integer>
+			<key>Name</key><string>Into the Lens</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8223778</integer>
+			<key>Total Time</key><integer>513462</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247503817</integer>
+			<key>Play Date UTC</key><date>2006-11-28T04:23:37Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8690E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/04%20Into%20the%20Lens.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1911</key>
+		<dict>
+			<key>Track ID</key><integer>1911</integer>
+			<key>Name</key><string>Run Through the Light</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4538640</integer>
+			<key>Total Time</key><integer>283141</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249385161</integer>
+			<key>Play Date UTC</key><date>2006-12-19T22:59:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86910</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/05%20Run%20Through%20the%20Light.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1912</key>
+		<dict>
+			<key>Track ID</key><integer>1912</integer>
+			<key>Name</key><string>Tempus Fugit</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Drama</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5041435</integer>
+			<key>Total Time</key><integer>314566</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:06Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3250624066</integer>
+			<key>Play Date UTC</key><date>2007-01-03T07:07:46Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86912</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Drama/06%20Tempus%20Fugit.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1913</key>
+		<dict>
+			<key>Track ID</key><integer>1913</integer>
+			<key>Name</key><string>Roundabout</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8252105</integer>
+			<key>Total Time</key><integer>515108</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253621920</integer>
+			<key>Play Date UTC</key><date>2007-02-06T23:52:00Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86914</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/01%20Roundabout.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1914</key>
+		<dict>
+			<key>Track ID</key><integer>1914</integer>
+			<key>Name</key><string>South Side of the Sky</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>7639795</integer>
+			<key>Total Time</key><integer>476839</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253106671</integer>
+			<key>Play Date UTC</key><date>2007-02-01T00:44:31Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-12-16T05:05:45Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86917</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/04%20South%20Side%20of%20the%20Sky.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1915</key>
+		<dict>
+			<key>Track ID</key><integer>1915</integer>
+			<key>Name</key><string>Five Per Cent for Nothing</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>618499</integer>
+			<key>Total Time</key><integer>38008</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247722004</integer>
+			<key>Play Date UTC</key><date>2006-11-30T17:00:04Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86919</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/05%20Five%20Per%20Cent%20for%20Nothing.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1916</key>
+		<dict>
+			<key>Track ID</key><integer>1916</integer>
+			<key>Name</key><string>Long Distance Runaround</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3362819</integer>
+			<key>Total Time</key><integer>209528</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249296502</integer>
+			<key>Play Date UTC</key><date>2006-12-18T22:21:42Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8691B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/06%20Long%20Distance%20Runaround.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1917</key>
+		<dict>
+			<key>Track ID</key><integer>1917</integer>
+			<key>Name</key><string>Fish (Schindleria Praematurus)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2613836</integer>
+			<key>Total Time</key><integer>162716</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:08Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253166946</integer>
+			<key>Play Date UTC</key><date>2007-02-01T17:29:06Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8691D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/07%20Fish%20(Schindleria%20Praematurus).mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1918</key>
+		<dict>
+			<key>Track ID</key><integer>1918</integer>
+			<key>Name</key><string>Mood for a Day</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>2928141</integer>
+			<key>Total Time</key><integer>182360</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:11Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8691F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/08%20Mood%20for%20a%20Day.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1919</key>
+		<dict>
+			<key>Track ID</key><integer>1919</integer>
+			<key>Name</key><string>Heart of the Sunrise</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>Fragile</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>10957973</integer>
+			<key>Total Time</key><integer>684225</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:09Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86921</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Fragile/09%20Heart%20of%20the%20Sunrise.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1920</key>
+		<dict>
+			<key>Track ID</key><integer>1920</integer>
+			<key>Name</key><string>Yours Is No Disgrace</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9308455</integer>
+			<key>Total Time</key><integer>581642</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:21Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3247547127</integer>
+			<key>Play Date UTC</key><date>2006-11-28T16:25:27Z</date>
+			<key>Persistent ID</key><string>87139F8602B86923</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/01%20Yours%20Is%20No%20Disgrace.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1921</key>
+		<dict>
+			<key>Track ID</key><integer>1921</integer>
+			<key>Name</key><string>The Clap</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3166545</integer>
+			<key>Total Time</key><integer>197773</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:20Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3249448044</integer>
+			<key>Play Date UTC</key><date>2006-12-20T16:27:24Z</date>
+			<key>Persistent ID</key><string>87139F8602B86926</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/02%20The%20Clap.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1922</key>
+		<dict>
+			<key>Track ID</key><integer>1922</integer>
+			<key>Name</key><string>Starship Trooper: Life Seeker/Disillusion/Würm</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>9197278</integer>
+			<key>Total Time</key><integer>574693</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:19Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253769245</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:47:25Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2006-11-16T00:10:03Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Persistent ID</key><string>87139F8602B86928</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/03%20Starship%20Trooper_%20Life%20Seeker_Disillusion_Wu%CC%88rm.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1923</key>
+		<dict>
+			<key>Track ID</key><integer>1923</integer>
+			<key>Name</key><string>I've Seen All Good People: Your Move/All Good People</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6664027</integer>
+			<key>Total Time</key><integer>416365</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:16Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3250602061</integer>
+			<key>Play Date UTC</key><date>2007-01-03T01:01:01Z</date>
+			<key>Persistent ID</key><string>87139F8602B8692A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/04%20I've%20Seen%20All%20Good%20People_%20Your%20Move_All%20Good%20People.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1924</key>
+		<dict>
+			<key>Track ID</key><integer>1924</integer>
+			<key>Name</key><string>A Venture</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>3182009</integer>
+			<key>Total Time</key><integer>198739</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>87139F8602B8692C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/05%20A%20Venture.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1925</key>
+		<dict>
+			<key>Track ID</key><integer>1925</integer>
+			<key>Name</key><string>Perpetual Change</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album</key><string>The Yes Album</string>
+			<key>Genre</key><string>Rock/Pop</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>8562816</integer>
+			<key>Total Time</key><integer>535040</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Date Modified</key><date>2004-11-29T13:37:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253473325</integer>
+			<key>Play Date UTC</key><date>2007-02-05T06:35:25Z</date>
+			<key>Persistent ID</key><string>87139F8602B8692E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/The%20Yes%20Album/06%20Perpetual%20Change.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1926</key>
+		<dict>
+			<key>Track ID</key><integer>1926</integer>
+			<key>Name</key><string>Opening (Excerpt from the "Firebird Suite") [Live]</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3788958</integer>
+			<key>Total Time</key><integer>227670</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:35:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252389385</integer>
+			<key>Play Date UTC</key><date>2007-01-23T17:29:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86930</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-01%20Opening%20(Excerpt%20from%20the%20_Firebird%20Suite_)%20%5BLive%5D.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1927</key>
+		<dict>
+			<key>Track ID</key><integer>1927</integer>
+			<key>Name</key><string>Siberian Khatru (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8805886</integer>
+			<key>Total Time</key><integer>543624</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:35:33Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:02Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253592121</integer>
+			<key>Play Date UTC</key><date>2007-02-06T15:35:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86933</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-02%20Siberian%20Khatru%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1928</key>
+		<dict>
+			<key>Track ID</key><integer>1928</integer>
+			<key>Name</key><string>Heart of the Sunrise (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>11191038</integer>
+			<key>Total Time</key><integer>693834</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:36:07Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253533671</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:21:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86935</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-03%20Heart%20of%20the%20Sunrise%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1929</key>
+		<dict>
+			<key>Track ID</key><integer>1929</integer>
+			<key>Name</key><string>Perpetual Change (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>13693662</integer>
+			<key>Total Time</key><integer>851427</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:36:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253258749</integer>
+			<key>Play Date UTC</key><date>2007-02-02T18:59:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86937</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-04%20Perpetual%20Change%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1930</key>
+		<dict>
+			<key>Track ID</key><integer>1930</integer>
+			<key>Name</key><string>And You and I: Cord of Life/Eclipse/The Preacher and the Teacher/The Apocalypse (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9282398</integer>
+			<key>Total Time</key><integer>573624</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:37:24Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86939</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-05%20And%20You%20and%20I_%20Cord%20of%20Life_Eclipse_The%20Preacher%20and%20the%20Teacher_The%20Apocalypse%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1931</key>
+		<dict>
+			<key>Track ID</key><integer>1931</integer>
+			<key>Name</key><string>Mood for a Day (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>2924574</integer>
+			<key>Total Time</key><integer>173242</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:37:34Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252542069</integer>
+			<key>Play Date UTC</key><date>2007-01-25T11:54:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8693B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-06%20Mood%20for%20a%20Day%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1932</key>
+		<dict>
+			<key>Track ID</key><integer>1932</integer>
+			<key>Name</key><string>Excerpts from "The Six Wives of Henry VIII" (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6489102</integer>
+			<key>Total Time</key><integer>397709</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:37:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253284023</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:00:23Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-25T19:20:12Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8693D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-07%20Excerpts%20from%20_The%20Six%20Wives%20of%20Henry%20VIII_%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1933</key>
+		<dict>
+			<key>Track ID</key><integer>1933</integer>
+			<key>Name</key><string>Roundabout (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>8323214</integer>
+			<key>Total Time</key><integer>513229</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>8</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:38:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>7</integer>
+			<key>Play Date</key><integer>3253706860</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:27:40Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T16:01:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8693F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/1-08%20Roundabout%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1934</key>
+		<dict>
+			<key>Track ID</key><integer>1934</integer>
+			<key>Name</key><string>I've Seen All Good People: Your Move/All Good People (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6989646</integer>
+			<key>Total Time</key><integer>429242</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:38:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252396855</integer>
+			<key>Play Date UTC</key><date>2007-01-23T19:34:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86941</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/2-01%20I've%20Seen%20All%20Good%20People_%20Your%20Move_All%20Good%20People%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1935</key>
+		<dict>
+			<key>Track ID</key><integer>1935</integer>
+			<key>Name</key><string>Long Distance Runaround/The Fish (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>13147502</integer>
+			<key>Total Time</key><integer>817039</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:39:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-10T17:18:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86943</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/2-02%20Long%20Distance%20Runaround_The%20Fish%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1936</key>
+		<dict>
+			<key>Track ID</key><integer>1936</integer>
+			<key>Name</key><string>Close to the Edge: The Solid Time of Change/Total Mass Retain/I Get Up I Get Down/Seasons of Man (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>17543550</integer>
+			<key>Total Time</key><integer>1093890</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:40:23Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253427874</integer>
+			<key>Play Date UTC</key><date>2007-02-04T17:57:54Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-11-12T17:32:11Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86945</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/2-03%20Close%20to%20the%20Edge_%20The%20Solid%20Time%20of%20Change_Total%20Mass%20Retain_I%20Get%20Up%20I%20Get%20Down_Seasons%20of%20Man%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1937</key>
+		<dict>
+			<key>Track ID</key><integer>1937</integer>
+			<key>Name</key><string>Yours Is No Disgrace (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>13890142</integer>
+			<key>Total Time</key><integer>863804</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:41:12Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3251348370</integer>
+			<key>Play Date UTC</key><date>2007-01-11T16:19:30Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86947</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/2-04%20Yours%20Is%20No%20Disgrace%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1938</key>
+		<dict>
+			<key>Track ID</key><integer>1938</integer>
+			<key>Name</key><string>Starship Trooper: Life Seeker/Disillusion/Würm (Live)</string>
+			<key>Artist</key><string>Yes</string>
+			<key>Album Artist</key><string>Yes</string>
+			<key>Album</key><string>Yessongs</string>
+			<key>Genre</key><string>Rock</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9987582</integer>
+			<key>Total Time</key><integer>618044</integer>
+			<key>Disc Number</key><integer>2</integer>
+			<key>Disc Count</key><integer>2</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>5</integer>
+			<key>Year</key><integer>1973</integer>
+			<key>Date Modified</key><date>2004-05-21T20:41:59Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252509765</integer>
+			<key>Play Date UTC</key><date>2007-01-25T02:56:05Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86949</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Yes/Yessongs/2-05%20Starship%20Trooper_%20Life%20Seeker_Disillusion_Wu%CC%88rm%20(Live).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1939</key>
+		<dict>
+			<key>Track ID</key><integer>1939</integer>
+			<key>Name</key><string>Out of Town</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Late Lounge (1 of 2)</string>
+			<key>Genre</key><string>Electronica</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4612182</integer>
+			<key>Total Time</key><integer>287869</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Date Modified</key><date>2004-11-29T13:36:01Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3249392989</integer>
+			<key>Play Date UTC</key><date>2006-12-20T01:09:49Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8694B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Late%20Lounge%20(1%20of%202)/02%20Out%20of%20Town.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1940</key>
+		<dict>
+			<key>Track ID</key><integer>1940</integer>
+			<key>Name</key><string>I Have Seen</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5014642</integer>
+			<key>Total Time</key><integer>307430</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:56:05Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253378247</integer>
+			<key>Play Date UTC</key><date>2007-02-04T04:10:47Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8694E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/01%20I%20Have%20Seen.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1941</key>
+		<dict>
+			<key>Track ID</key><integer>1941</integer>
+			<key>Name</key><string>Polaris</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4702418</integer>
+			<key>Total Time</key><integer>288134</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:56:31Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253253306</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:28:26Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86951</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/02%20Polaris.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1942</key>
+		<dict>
+			<key>Track ID</key><integer>1942</integer>
+			<key>Name</key><string>Destiny</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5504946</integer>
+			<key>Total Time</key><integer>337709</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:57:04Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253274952</integer>
+			<key>Play Date UTC</key><date>2007-02-02T23:29:12Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86953</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/03%20Destiny.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1943</key>
+		<dict>
+			<key>Track ID</key><integer>1943</integer>
+			<key>Name</key><string>Give It Away</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5175442</integer>
+			<key>Total Time</key><integer>317368</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:57:40Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247465882</integer>
+			<key>Play Date UTC</key><date>2006-11-27T17:51:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86955</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/04%20Give%20It%20Away.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1944</key>
+		<dict>
+			<key>Track ID</key><integer>1944</integer>
+			<key>Name</key><string>Simple Things</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4314322</integer>
+			<key>Total Time</key><integer>264148</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:58:10Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247466147</integer>
+			<key>Play Date UTC</key><date>2006-11-27T17:55:47Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-02T19:45:56Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86957</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/05%20Simple%20Things.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1945</key>
+		<dict>
+			<key>Track ID</key><integer>1945</integer>
+			<key>Name</key><string>Red Dust</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5547394</integer>
+			<key>Total Time</key><integer>340356</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:58:49Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3251350562</integer>
+			<key>Play Date UTC</key><date>2007-01-11T16:56:02Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86959</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/06%20Red%20Dust.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1946</key>
+		<dict>
+			<key>Track ID</key><integer>1946</integer>
+			<key>Name</key><string>Distractions</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5159666</integer>
+			<key>Total Time</key><integer>316393</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:59:26Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253468832</integer>
+			<key>Play Date UTC</key><date>2007-02-05T05:20:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8695B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/07%20Distractions.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1947</key>
+		<dict>
+			<key>Track ID</key><integer>1947</integer>
+			<key>Name</key><string>In the Waiting Line</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4445826</integer>
+			<key>Total Time</key><integer>272275</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T20:59:57Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252413651</integer>
+			<key>Play Date UTC</key><date>2007-01-24T00:14:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8695D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/08%20In%20the%20Waiting%20Line.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1948</key>
+		<dict>
+			<key>Track ID</key><integer>1948</integer>
+			<key>Name</key><string>Out of Town</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4699794</integer>
+			<key>Total Time</key><integer>287972</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:00:37Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253294905</integer>
+			<key>Play Date UTC</key><date>2007-02-03T05:01:45Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B8695F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/09%20Out%20of%20Town.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1949</key>
+		<dict>
+			<key>Track ID</key><integer>1949</integer>
+			<key>Name</key><string>This World</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5474130</integer>
+			<key>Total Time</key><integer>335828</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:01:14Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253287595</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:59:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86961</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/10%20This%20World.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1950</key>
+		<dict>
+			<key>Track ID</key><integer>1950</integer>
+			<key>Name</key><string>Likufanele</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6048594</integer>
+			<key>Total Time</key><integer>371332</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:01:55Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>4</integer>
+			<key>Play Date</key><integer>3253539327</integer>
+			<key>Play Date UTC</key><date>2007-02-06T00:55:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86963</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/11%20Likufanele.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1951</key>
+		<dict>
+			<key>Track ID</key><integer>1951</integer>
+			<key>Name</key><string>End Theme</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3595202</integer>
+			<key>Total Time</key><integer>219705</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:02:17Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3249490761</integer>
+			<key>Play Date UTC</key><date>2006-12-21T04:19:21Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86965</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/12%20End%20Theme.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1952</key>
+		<dict>
+			<key>Track ID</key><integer>1952</integer>
+			<key>Name</key><string>Salt Water Sound</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5394482</integer>
+			<key>Total Time</key><integer>330906</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:02:47Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3247836625</integer>
+			<key>Play Date UTC</key><date>2006-12-02T00:50:25Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86967</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/13%20Salt%20Water%20Sound.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1953</key>
+		<dict>
+			<key>Track ID</key><integer>1953</integer>
+			<key>Name</key><string>Spinning</string>
+			<key>Artist</key><string>Zero 7</string>
+			<key>Album Artist</key><string>Zero 7</string>
+			<key>Album</key><string>Simple Things</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5916338</integer>
+			<key>Total Time</key><integer>363158</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>14</integer>
+			<key>Track Count</key><integer>14</integer>
+			<key>Year</key><integer>2001</integer>
+			<key>Date Modified</key><date>2005-05-09T21:03:25Z</date>
+			<key>Date Added</key><date>2006-11-09T20:13:03Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>6</integer>
+			<key>Play Date</key><integer>3253108411</integer>
+			<key>Play Date UTC</key><date>2007-02-01T01:13:31Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>87139F8602B86969</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Zero%207/Simple%20Things/14%20Spinning.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1954</key>
+		<dict>
+			<key>Track ID</key><integer>1954</integer>
+			<key>Name</key><string>Fly</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5919547</integer>
+			<key>Total Time</key><integer>361184</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:42:46Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3252296520</integer>
+			<key>Play Date UTC</key><date>2007-01-22T15:42:00Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63B1</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/01%20Fly.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1955</key>
+		<dict>
+			<key>Track ID</key><integer>1955</integer>
+			<key>Name</key><string>Here I Come</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4627091</integer>
+			<key>Total Time</key><integer>280472</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:42:51Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>29</integer>
+			<key>Play Date</key><integer>3253683374</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:56:14Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-14T18:55:06Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63B4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/02%20Here%20I%20Come.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1956</key>
+		<dict>
+			<key>Track ID</key><integer>1956</integer>
+			<key>Name</key><string>Colours</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6165791</integer>
+			<key>Total Time</key><integer>375372</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:42:56Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>10</integer>
+			<key>Play Date</key><integer>3253626193</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:03:13Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63B6</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/03%20Colours.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1957</key>
+		<dict>
+			<key>Track ID</key><integer>1957</integer>
+			<key>Name</key><string>Nobody Never</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3999428</integer>
+			<key>Total Time</key><integer>241114</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:42:55Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3253626435</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:07:15Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63B8</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/04%20Nobody%20Never.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1958</key>
+		<dict>
+			<key>Track ID</key><integer>1958</integer>
+			<key>Name</key><string>Soto Mundo</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6400866</integer>
+			<key>Total Time</key><integer>388654</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:13Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>31</integer>
+			<key>Play Date</key><integer>3253711770</integer>
+			<key>Play Date UTC</key><date>2007-02-08T00:49:30Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63BA</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/05%20Soto%20Mundo.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1959</key>
+		<dict>
+			<key>Track ID</key><integer>1959</integer>
+			<key>Name</key><string>Pil</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4094363</integer>
+			<key>Total Time</key><integer>247685</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:30Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3253626682</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:11:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63BC</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/06%20Pil.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1960</key>
+		<dict>
+			<key>Track ID</key><integer>1960</integer>
+			<key>Name</key><string>Little Things</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7283717</integer>
+			<key>Total Time</key><integer>443244</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:15Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253625079</integer>
+			<key>Play Date UTC</key><date>2007-02-07T00:44:39Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63BE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/07%20Little%20Things.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1961</key>
+		<dict>
+			<key>Track ID</key><integer>1961</integer>
+			<key>Name</key><string>Mote</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4194556</integer>
+			<key>Total Time</key><integer>253212</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:26Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253626935</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:15:35Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63C0</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/08%20Mote.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1962</key>
+		<dict>
+			<key>Track ID</key><integer>1962</integer>
+			<key>Name</key><string>Slipaway</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4472288</integer>
+			<key>Total Time</key><integer>272507</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:27Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253627208</integer>
+			<key>Play Date UTC</key><date>2007-02-07T01:20:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63C2</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/09%20Slipaway.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1963</key>
+		<dict>
+			<key>Track ID</key><integer>1963</integer>
+			<key>Name</key><string>After Hours</string>
+			<key>Artist</key><string>2 Bit Pie</string>
+			<key>Album Artist</key><string>2 Bit Pie</string>
+			<key>Album</key><string>2 Pie Island</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7271699</integer>
+			<key>Total Time</key><integer>443383</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-26T17:43:41Z</date>
+			<key>Date Added</key><date>2006-11-26T17:42:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3253682117</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:35:17Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A63C4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/2%20Bit%20Pie/2%20Pie%20Island/10%20After%20Hours.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1964</key>
+		<dict>
+			<key>Track ID</key><integer>1964</integer>
+			<key>Name</key><string>Nothing At All</string>
+			<key>Artist</key><string>Wired All Wrong</string>
+			<key>Album Artist</key><string>Wired All Wrong</string>
+			<key>Album</key><string>Break Out the Battle Tapes</string>
+			<key>Genre</key><string>Alternative</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3262691</integer>
+			<key>Total Time</key><integer>198087</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>10</integer>
+			<key>Year</key><integer>2006</integer>
+			<key>Date Modified</key><date>2006-11-27T05:49:28Z</date>
+			<key>Date Added</key><date>2006-11-27T05:49:21Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253465074</integer>
+			<key>Play Date UTC</key><date>2007-02-05T04:17:54Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8D7DB9C4CF0A6BBE</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Wired%20All%20Wrong/Break%20Out%20the%20Battle%20Tapes/03%20Nothing%20At%20All.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1965</key>
+		<dict>
+			<key>Track ID</key><integer>1965</integer>
+			<key>Name</key><string>Groove Salad: a nicely chilled plate of ambient beats and grooves. [SomaFM]</string>
+			<key>Genre</key><string>Ambient Chill</string>
+			<key>Kind</key><string>MPEG audio stream</string>
+			<key>Date Added</key><date>2006-11-29T18:53:13Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>A nicely chilled plate of ambient beats and grooves. Listener supported, commercial free.</string>
+			<key>Play Count</key><integer>15</integer>
+			<key>Play Date</key><integer>3252582951</integer>
+			<key>Play Date UTC</key><date>2007-01-25T23:15:51Z</date>
+			<key>Persistent ID</key><string>B16FC77EA12CDEA4</string>
+			<key>Track Type</key><string>URL</string>
+			<key>Location</key><string>http://pri.kts-af.net/redir/index.pls?esid=8b4fbce948857b4cf0c1d9ba2f7d3f1e&#38;url_no=1&#38;client_id=7&#38;uid=68efed4d03ec7e45fd3978262c107180&#38;clicksrc=xml</string>
+		</dict>
+		<key>1966</key>
+		<dict>
+			<key>Track ID</key><integer>1966</integer>
+			<key>Name</key><string>This Is What It Means</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>1344234</integer>
+			<key>Total Time</key><integer>79526</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:52:01Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>16</integer>
+			<key>Play Date</key><integer>3253188850</integer>
+			<key>Play Date UTC</key><date>2007-02-01T23:34:10Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2006-12-03T17:19:28Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBF4</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/01%20This%20Is%20What%20It%20Means.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1967</key>
+		<dict>
+			<key>Track ID</key><integer>1967</integer>
+			<key>Name</key><string>True to Form</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>9074913</integer>
+			<key>Total Time</key><integer>554955</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:52:24Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>19</integer>
+			<key>Play Date</key><integer>3253285303</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:21:43Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBF7</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/02%20True%20to%20Form.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1968</key>
+		<dict>
+			<key>Track ID</key><integer>1968</integer>
+			<key>Name</key><string>Know Your Enemy</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5874644</integer>
+			<key>Total Time</key><integer>358143</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:52:22Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>16</integer>
+			<key>Play Date</key><integer>3253766826</integer>
+			<key>Play Date UTC</key><date>2007-02-08T16:07:06Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBF9</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/03%20Know%20Your%20Enemy.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1969</key>
+		<dict>
+			<key>Track ID</key><integer>1969</integer>
+			<key>Name</key><string>Marrakech</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5670878</integer>
+			<key>Total Time</key><integer>345627</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:52:23Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>16</integer>
+			<key>Play Date</key><integer>3253708135</integer>
+			<key>Play Date UTC</key><date>2007-02-07T23:48:55Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBFB</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/04%20Marrakech.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1970</key>
+		<dict>
+			<key>Track ID</key><integer>1970</integer>
+			<key>Name</key><string>I'm Still Awake</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6296708</integer>
+			<key>Total Time</key><integer>384056</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:53:09Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253532423</integer>
+			<key>Play Date UTC</key><date>2007-02-05T23:00:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBFD</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/05%20I'm%20Still%20Awake.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1971</key>
+		<dict>
+			<key>Track ID</key><integer>1971</integer>
+			<key>Name</key><string>Visible Noise</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7081170</integer>
+			<key>Total Time</key><integer>432354</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:53:16Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>26</integer>
+			<key>Play Date</key><integer>3253686182</integer>
+			<key>Play Date UTC</key><date>2007-02-07T17:43:02Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FBFF</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/06%20Visible%20Noise.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1972</key>
+		<dict>
+			<key>Track ID</key><integer>1972</integer>
+			<key>Name</key><string>We Are In Control</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5964550</integer>
+			<key>Total Time</key><integer>363646</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:53:13Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>19</integer>
+			<key>Play Date</key><integer>3253543690</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:08:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC01</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/07%20We%20Are%20In%20Control.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1973</key>
+		<dict>
+			<key>Track ID</key><integer>1973</integer>
+			<key>Name</key><string>Higher Than a Skyscraper</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5491053</integer>
+			<key>Total Time</key><integer>334574</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:53:38Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>15</integer>
+			<key>Play Date</key><integer>3253683093</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:51:33Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC03</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/08%20Higher%20Than%20a%20Skyscraper.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1974</key>
+		<dict>
+			<key>Track ID</key><integer>1974</integer>
+			<key>Name</key><string>Steal You Away</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5359555</integer>
+			<key>Total Time</key><integer>326401</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T19:24:20Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>19</integer>
+			<key>Play Date</key><integer>3251363360</integer>
+			<key>Play Date UTC</key><date>2007-01-11T20:29:20Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-06T00:02:07Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC05</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/09%20Steal%20You%20Away.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1975</key>
+		<dict>
+			<key>Track ID</key><integer>1975</integer>
+			<key>Name</key><string>Gravastar</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4960414</integer>
+			<key>Total Time</key><integer>301834</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T19:25:24Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3251288417</integer>
+			<key>Play Date UTC</key><date>2007-01-10T23:40:17Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC07</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/10%20Gravastar.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1976</key>
+		<dict>
+			<key>Track ID</key><integer>1976</integer>
+			<key>Name</key><string>Out of the Dark</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>7169172</integer>
+			<key>Total Time</key><integer>437717</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:53:54Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>16</integer>
+			<key>Play Date</key><integer>3252570751</integer>
+			<key>Play Date UTC</key><date>2007-01-25T19:52:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC09</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/11%20Out%20of%20the%20Dark.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1977</key>
+		<dict>
+			<key>Track ID</key><integer>1977</integer>
+			<key>Name</key><string>Blackout</string>
+			<key>Artist</key><string>Hybrid</string>
+			<key>Album Artist</key><string>Hybrid</string>
+			<key>Album</key><string>Morning Sci-Fi</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6402781</integer>
+			<key>Total Time</key><integer>392578</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>12</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-11-30T18:54:09Z</date>
+			<key>Date Added</key><date>2006-11-30T18:51:55Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>15</integer>
+			<key>Play Date</key><integer>3253680141</integer>
+			<key>Play Date UTC</key><date>2007-02-07T16:02:21Z</date>
+			<key>Rating</key><integer>40</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>109CFA90F099FC0B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Hybrid/Morning%20Sci-Fi/12%20Blackout.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1978</key>
+		<dict>
+			<key>Track ID</key><integer>1978</integer>
+			<key>Name</key><string>12 Visa Röster - M.U.L.E.</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6956641</integer>
+			<key>Total Time</key><integer>217391</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Date Modified</key><date>2006-12-14T03:08:20Z</date>
+			<key>Date Added</key><date>2006-12-14T03:08:26Z</date>
+			<key>Bit Rate</key><integer>256</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Persistent ID</key><string>AAC8FF0F51C01DB6</string>
+			<key>Track Type</key><string>File</string>
+			<key>File Type</key><integer>1297106739</integer>
+			<key>File Creator</key><integer>1752133483</integer>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Unknown%20Artist/Unknown%20Album/12%20Visa%20Ro%CC%88ster%20-%20M.U.L.E..mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1979</key>
+		<dict>
+			<key>Track ID</key><integer>1979</integer>
+			<key>Name</key><string>Sex On Wheels (Astro &#38; Glyde Summer Soltice Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6352688</integer>
+			<key>Total Time</key><integer>388120</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:10:48Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253374922</integer>
+			<key>Play Date UTC</key><date>2007-02-04T03:15:22Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85326</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/01%20Sex%20On%20Wheels%20(Astro%20&#38;%20Glyde%20Summer%20Soltice%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1980</key>
+		<dict>
+			<key>Track ID</key><integer>1980</integer>
+			<key>Name</key><string>Leathersex (Paul Lancaster Wipe Clean Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5806362</integer>
+			<key>Total Time</key><integer>354381</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:10:45Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253262228</integer>
+			<key>Play Date UTC</key><date>2007-02-02T19:57:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85329</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/02%20Leathersex%20(Paul%20Lancaster%20Wipe%20Clean%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1981</key>
+		<dict>
+			<key>Track ID</key><integer>1981</integer>
+			<key>Name</key><string>And This Is What the Devil Does (This Is What Ebon Does Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5209452</integer>
+			<key>Total Time</key><integer>317670</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:10:46Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>14</integer>
+			<key>Play Date</key><integer>3253191537</integer>
+			<key>Play Date UTC</key><date>2007-02-02T00:18:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8532B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/03%20And%20This%20Is%20What%20the%20Devil%20Does%20(This%20Is%20What%20Ebon%20Does%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1982</key>
+		<dict>
+			<key>Track ID</key><integer>1982</integer>
+			<key>Name</key><string>A Daisy Chain for Satan (P's White Rabbit Re-Rub)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5919809</integer>
+			<key>Total Time</key><integer>361510</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:06Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>8</integer>
+			<key>Play Date</key><integer>3253191898</integer>
+			<key>Play Date UTC</key><date>2007-02-02T00:24:58Z</date>
+			<key>Skip Count</key><integer>2</integer>
+			<key>Skip Date</key><date>2007-01-10T22:29:21Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8532D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/04%20A%20Daisy%20Chain%20for%20Satan%20(P's%20White%20Rabbit%20Re-Rub).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1983</key>
+		<dict>
+			<key>Track ID</key><integer>1983</integer>
+			<key>Name</key><string>Waiting for Mommy (Bryan Zentz Dealin' With the Devil Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5669082</integer>
+			<key>Total Time</key><integer>345975</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:09Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>15</integer>
+			<key>Play Date</key><integer>3251371588</integer>
+			<key>Play Date UTC</key><date>2007-01-11T22:46:28Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8532F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/05%20Waiting%20for%20Mommy%20(Bryan%20Zentz%20Dealin'%20With%20the%20Devil%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1984</key>
+		<dict>
+			<key>Track ID</key><integer>1984</integer>
+			<key>Name</key><string>Disko Fleshpot (Phunk Investigation's Club Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6271807</integer>
+			<key>Total Time</key><integer>383127</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:08Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>11</integer>
+			<key>Play Date</key><integer>3252380429</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:00:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85331</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/06%20Disko%20Fleshpot%20(Phunk%20Investigation's%20Club%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1985</key>
+		<dict>
+			<key>Track ID</key><integer>1985</integer>
+			<key>Name</key><string>Radio Silicon (Freakus' for Laura-Lorenza &#38; Mark Verbos Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5381772</integer>
+			<key>Total Time</key><integer>328305</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:22Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3252380757</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:05:57Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85333</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/07%20Radio%20Silicon%20(Freakus'%20for%20Laura-Lorenza%20&#38;%20Mark%20Verbos%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1986</key>
+		<dict>
+			<key>Track ID</key><integer>1986</integer>
+			<key>Name</key><string>Kooler Than Jesus (Tomie Sunshine &#38; Mark Verbos Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6036852</integer>
+			<key>Total Time</key><integer>368545</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:27Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>22</integer>
+			<key>Play Date</key><integer>3253558191</integer>
+			<key>Play Date UTC</key><date>2007-02-06T06:09:51Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85335</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/08%20Kooler%20Than%20Jesus%20(Tomie%20Sunshine%20&#38;%20Mark%20Verbos%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1987</key>
+		<dict>
+			<key>Track ID</key><integer>1987</integer>
+			<key>Name</key><string>Days of Swine &#38; Roses (D:Fuse &#38; Mike Hiratzka Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6190386</integer>
+			<key>Total Time</key><integer>378158</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:26Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>19</integer>
+			<key>Play Date</key><integer>3253251166</integer>
+			<key>Play Date UTC</key><date>2007-02-02T16:52:46Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85337</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/09%20Days%20of%20Swine%20&#38;%20Roses%20(D_Fuse%20&#38;%20Mike%20Hiratzka%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1988</key>
+		<dict>
+			<key>Track ID</key><integer>1988</integer>
+			<key>Name</key><string>Asylum Disciple (Blue Room Project Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6179783</integer>
+			<key>Total Time</key><integer>377438</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:38Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253349909</integer>
+			<key>Play Date UTC</key><date>2007-02-03T20:18:29Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D85339</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/10%20Asylum%20Disciple%20(Blue%20Room%20Project%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1989</key>
+		<dict>
+			<key>Track ID</key><integer>1989</integer>
+			<key>Name</key><string>Bad Life (Kemek the Dope Computer Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5961766</integer>
+			<key>Total Time</key><integer>364064</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:41Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>12</integer>
+			<key>Play Date</key><integer>3253251908</integer>
+			<key>Play Date UTC</key><date>2007-02-02T17:05:08Z</date>
+			<key>Rating</key><integer>20</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8533B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/11%20Bad%20Life%20(Kemek%20the%20Dope%20Computer%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1990</key>
+		<dict>
+			<key>Track ID</key><integer>1990</integer>
+			<key>Name</key><string>Cuz Its Hot (Nee &#38; Shreeve Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5036799</integer>
+			<key>Total Time</key><integer>307128</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:43Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>20</integer>
+			<key>Play Date</key><integer>3253712898</integer>
+			<key>Play Date UTC</key><date>2007-02-08T01:08:18Z</date>
+			<key>Rating</key><integer>60</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8533D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/12%20Cuz%20Its%20Hot%20(Nee%20&#38;%20Shreeve%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1991</key>
+		<dict>
+			<key>Track ID</key><integer>1991</integer>
+			<key>Name</key><string>Dimentia 66 (Grayarea Mix)</string>
+			<key>Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album Artist</key><string>My Life With the Thrill Kill Kult</string>
+			<key>Album</key><string>My Life Remixed - a Remix Tribute</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5620506</integer>
+			<key>Total Time</key><integer>342214</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Track Count</key><integer>13</integer>
+			<key>Year</key><integer>2005</integer>
+			<key>Date Modified</key><date>2006-12-30T00:11:50Z</date>
+			<key>Date Added</key><date>2006-12-30T00:10:25Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>13</integer>
+			<key>Play Date</key><integer>3253454582</integer>
+			<key>Play Date UTC</key><date>2007-02-05T01:23:02Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-11T23:01:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>8A29B85AE3D8533F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/My%20Life%20With%20the%20Thrill%20Kill%20Kult/My%20Life%20Remixed%20-%20a%20Remix%20Tribute/13%20Dimentia%2066%20(Grayarea%20Mix).m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1992</key>
+		<dict>
+			<key>Track ID</key><integer>1992</integer>
+			<key>Name</key><string>Back from Space</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4914777</integer>
+			<key>Total Time</key><integer>292755</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:57:46Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253357848</integer>
+			<key>Play Date UTC</key><date>2007-02-03T22:30:48Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F1C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/01%20Back%20from%20Space.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1993</key>
+		<dict>
+			<key>Track ID</key><integer>1993</integer>
+			<key>Name</key><string>Verbal Feat. Mc Decimal R.</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>3974468</integer>
+			<key>Total Time</key><integer>235286</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:57:43Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253459774</integer>
+			<key>Play Date UTC</key><date>2007-02-05T02:49:34Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F1F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/02%20Verbal%20Feat.%20Mc%20Decimal%20R..m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1994</key>
+		<dict>
+			<key>Track ID</key><integer>1994</integer>
+			<key>Name</key><string>Chronic Tronic</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>6124264</integer>
+			<key>Total Time</key><integer>367152</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:57:45Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253294452</integer>
+			<key>Play Date UTC</key><date>2007-02-03T04:54:12Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F21</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/03%20Chronic%20Tronic.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1995</key>
+		<dict>
+			<key>Track ID</key><integer>1995</integer>
+			<key>Name</key><string>Searchers</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5764115</integer>
+			<key>Total Time</key><integer>345000</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:00Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3251359171</integer>
+			<key>Play Date UTC</key><date>2007-01-11T19:19:31Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-17T15:24:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F23</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/04%20Searchers.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1996</key>
+		<dict>
+			<key>Track ID</key><integer>1996</integer>
+			<key>Name</key><string>Hey Blondie</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4562005</integer>
+			<key>Total Time</key><integer>271207</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:57:58Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3252557184</integer>
+			<key>Play Date UTC</key><date>2007-01-25T16:06:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F25</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/05%20Hey%20Blondie.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1997</key>
+		<dict>
+			<key>Track ID</key><integer>1997</integer>
+			<key>Name</key><string>Rosies</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5405088</integer>
+			<key>Total Time</key><integer>322918</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:02Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3251487850</integer>
+			<key>Play Date UTC</key><date>2007-01-13T07:04:10Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F27</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/06%20Rosies.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1998</key>
+		<dict>
+			<key>Track ID</key><integer>1998</integer>
+			<key>Name</key><string>Cosmo Retro Intro Outro</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>4181761</integer>
+			<key>Total Time</key><integer>247662</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:12Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>5</integer>
+			<key>Play Date</key><integer>3253546458</integer>
+			<key>Play Date UTC</key><date>2007-02-06T02:54:18Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F29</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/07%20Cosmo%20Retro%20Intro%20Outro.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>1999</key>
+		<dict>
+			<key>Track ID</key><integer>1999</integer>
+			<key>Name</key><string>Triple Science</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5006056</integer>
+			<key>Total Time</key><integer>298374</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:16Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F2B</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/08%20Triple%20Science.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2000</key>
+		<dict>
+			<key>Track ID</key><integer>2000</integer>
+			<key>Name</key><string>El Wraith</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5997859</integer>
+			<key>Total Time</key><integer>359373</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:19Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253426375</integer>
+			<key>Play Date UTC</key><date>2007-02-04T17:32:55Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F2D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/09%20El%20Wraith.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2001</key>
+		<dict>
+			<key>Track ID</key><integer>2001</integer>
+			<key>Name</key><string>Proper Hoodidge</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5452249</integer>
+			<key>Total Time</key><integer>325820</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:24Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252381811</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:23:31Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F2F</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/10%20Proper%20Hoodidge.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2002</key>
+		<dict>
+			<key>Track ID</key><integer>2002</integer>
+			<key>Name</key><string>Mighty Micro People</string>
+			<key>Artist</key><string>Amon Tobin</string>
+			<key>Album Artist</key><string>Amon Tobin</string>
+			<key>Album</key><string>Out from Out Where</string>
+			<key>Genre</key><string>Electronic</string>
+			<key>Kind</key><string>Protected AAC audio file</string>
+			<key>Size</key><integer>5779533</integer>
+			<key>Total Time</key><integer>348088</integer>
+			<key>Disc Number</key><integer>1</integer>
+			<key>Disc Count</key><integer>1</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Track Count</key><integer>11</integer>
+			<key>Year</key><integer>2002</integer>
+			<key>Date Modified</key><date>2007-01-11T18:58:28Z</date>
+			<key>Date Added</key><date>2007-01-11T18:57:28Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252407529</integer>
+			<key>Play Date UTC</key><date>2007-01-23T22:32:09Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>4513774E3D165F31</string>
+			<key>Track Type</key><string>File</string>
+			<key>Protected</key><true/>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Amon%20Tobin/Out%20from%20Out%20Where/11%20Mighty%20Micro%20People.m4p</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2003</key>
+		<dict>
+			<key>Track ID</key><integer>2003</integer>
+			<key>Name</key><string>Little Moon</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4161546</integer>
+			<key>Total Time</key><integer>164048</integer>
+			<key>Track Number</key><integer>11</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:20:56Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253284748</integer>
+			<key>Play Date UTC</key><date>2007-02-03T02:12:28Z</date>
+			<key>Skip Count</key><integer>1</integer>
+			<key>Skip Date</key><date>2007-01-25T00:20:11Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF3777D</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/11%20Little%20Moon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2004</key>
+		<dict>
+			<key>Track ID</key><integer>2004</integer>
+			<key>Name</key><string>Not My Friend</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4415498</integer>
+			<key>Total Time</key><integer>174550</integer>
+			<key>Track Number</key><integer>5</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:12:56Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252383367</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:49:27Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37780</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/05%20Not%20My%20Friend.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2005</key>
+		<dict>
+			<key>Track ID</key><integer>2005</integer>
+			<key>Name</key><string>Wake Me Up</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4229130</integer>
+			<key>Total Time</key><integer>166791</integer>
+			<key>Track Number</key><integer>9</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:18:20Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252384140</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:02:20Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37782</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/09%20Wake%20Me%20Up.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2006</key>
+		<dict>
+			<key>Track ID</key><integer>2006</integer>
+			<key>Name</key><string>Sinkin' Soon</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6905866</integer>
+			<key>Total Time</key><integer>278386</integer>
+			<key>Track Number</key><integer>2</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:08:56Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252382776</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:39:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37784</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/02%20Sinkin'%20Soon.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2007</key>
+		<dict>
+			<key>Track ID</key><integer>2007</integer>
+			<key>Name</key><string>My Dear Country</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5152778</integer>
+			<key>Total Time</key><integer>205296</integer>
+			<key>Track Number</key><integer>8</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:17:02Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253263936</integer>
+			<key>Play Date UTC</key><date>2007-02-02T20:25:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37786</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/08%20My%20Dear%20Country.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2008</key>
+		<dict>
+			<key>Track ID</key><integer>2008</integer>
+			<key>Name</key><string>Rosie's Lullaby</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5910538</integer>
+			<key>Total Time</key><integer>236852</integer>
+			<key>Track Number</key><integer>12</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:22:30Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252384758</integer>
+			<key>Play Date UTC</key><date>2007-01-23T16:12:38Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37788</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/12%20Rosie's%20Lullaby.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2009</key>
+		<dict>
+			<key>Track ID</key><integer>2009</integer>
+			<key>Name</key><string>The Sun Doesn't Like You</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>4540426</integer>
+			<key>Total Time</key><integer>179826</integer>
+			<key>Track Number</key><integer>3</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:10:08Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252382956</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:42:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF3778A</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/03%20The%20Sun%20Doesn't%20Like%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2010</key>
+		<dict>
+			<key>Track ID</key><integer>2010</integer>
+			<key>Name</key><string>Not Too Late</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5298186</integer>
+			<key>Total Time</key><integer>211408</integer>
+			<key>Track Number</key><integer>13</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:23:50Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:29Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>3</integer>
+			<key>Play Date</key><integer>3253282704</integer>
+			<key>Play Date UTC</key><date>2007-02-03T01:38:24Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF3778C</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/13%20Not%20Too%20Late.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2011</key>
+		<dict>
+			<key>Track ID</key><integer>2011</integer>
+			<key>Name</key><string>Until The End</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5900298</integer>
+			<key>Total Time</key><integer>236486</integer>
+			<key>Track Number</key><integer>4</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:11:50Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:30Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252383192</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:46:32Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF3778E</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/04%20Until%20The%20End.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2012</key>
+		<dict>
+			<key>Track ID</key><integer>2012</integer>
+			<key>Name</key><string>Broken</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5052426</integer>
+			<key>Total Time</key><integer>201090</integer>
+			<key>Track Number</key><integer>7</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:15:32Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:30Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252383768</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:56:08Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37790</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/07%20Broken.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2013</key>
+		<dict>
+			<key>Track ID</key><integer>2013</integer>
+			<key>Name</key><string>Thinking About You</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5042186</integer>
+			<key>Total Time</key><integer>200672</integer>
+			<key>Track Number</key><integer>6</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:14:14Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:31Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3253529436</integer>
+			<key>Play Date UTC</key><date>2007-02-05T22:10:36Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37792</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/06%20Thinking%20About%20You.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2014</key>
+		<dict>
+			<key>Track ID</key><integer>2014</integer>
+			<key>Name</key><string>Wish I Could</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>6428682</integer>
+			<key>Total Time</key><integer>258481</integer>
+			<key>Track Number</key><integer>1</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:07:08Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:32Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3252382498</integer>
+			<key>Play Date UTC</key><date>2007-01-23T15:34:58Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37794</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/01%20Wish%20I%20Could.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2015</key>
+		<dict>
+			<key>Track ID</key><integer>2015</integer>
+			<key>Name</key><string>Be My Somebody</string>
+			<key>Artist</key><string>Norah Jones</string>
+			<key>Album Artist</key><string>Norah Jones</string>
+			<key>Album</key><string>Not Too Late</string>
+			<key>Genre</key><string>Jazz</string>
+			<key>Kind</key><string>MPEG audio file</string>
+			<key>Size</key><integer>5425162</integer>
+			<key>Total Time</key><integer>216659</integer>
+			<key>Track Number</key><integer>10</integer>
+			<key>Year</key><integer>2007</integer>
+			<key>Date Modified</key><date>2007-01-18T02:19:50Z</date>
+			<key>Date Added</key><date>2007-01-23T15:29:32Z</date>
+			<key>Bit Rate</key><integer>192</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Play Count</key><integer>2</integer>
+			<key>Play Date</key><integer>3252561563</integer>
+			<key>Play Date UTC</key><date>2007-01-25T17:19:23Z</date>
+			<key>Artwork Count</key><integer>1</integer>
+			<key>Persistent ID</key><string>C1DB72E05EF37796</string>
+			<key>Track Type</key><string>File</string>
+			<key>Location</key><string>file://localhost/Users/Howard/Music/iTunes/iTunes%20Music/Norah%20Jones/Not%20Too%20Late/10%20Be%20My%20Somebody.mp3</string>
+			<key>File Folder Count</key><integer>-1</integer>
+			<key>Library Folder Count</key><integer>-1</integer>
+		</dict>
+		<key>2016</key>
+		<dict>
+			<key>Track ID</key><integer>2016</integer>
+			<key>Name</key><string>Analog Voyager - Various Esoteric Beats and Grooves with Shelby LaPre on RadioPower.org</string>
+			<key>Genre</key><string>downtempo,alternative,electronic/dance</string>
+			<key>Kind</key><string>MPEG audio stream</string>
+			<key>Date Added</key><date>2007-01-30T17:35:54Z</date>
+			<key>Bit Rate</key><integer>56</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Downtempo, Ambient, Trip-Hop, Electronica</string>
+			<key>Play Count</key><integer>1</integer>
+			<key>Play Date</key><integer>3253020327</integer>
+			<key>Play Date UTC</key><date>2007-01-31T00:45:27Z</date>
+			<key>Persistent ID</key><string>D03DAC75D3D46A1F</string>
+			<key>Track Type</key><string>URL</string>
+			<key>Location</key><string>http://pri.kts-af.net/redir/index.pls?esid=62756317921f57d916a10d5db366f8fe&#38;url_no=1&#38;client_id=7&#38;uid=68efed4d03ec7e45fd3978262c107180&#38;clicksrc=xml</string>
+		</dict>
+		<key>2017</key>
+		<dict>
+			<key>Track ID</key><integer>2017</integer>
+			<key>Name</key><string>radioioAmbient</string>
+			<key>Genre</key><string>Ambient</string>
+			<key>Kind</key><string>MPEG audio stream</string>
+			<key>Date Added</key><date>2007-01-30T17:36:32Z</date>
+			<key>Bit Rate</key><integer>128</integer>
+			<key>Sample Rate</key><integer>44100</integer>
+			<key>Comments</key><string>Sensual, evocative and thoughtful exotic electronica</string>
+			<key>Persistent ID</key><string>D03DAC75D3D46A23</string>
+			<key>Track Type</key><string>URL</string>
+			<key>Location</key><string>http://pri.kts-af.net/redir/index.pls?esid=3efcb31a424be238ba5cad88f8168980&#38;url_no=2&#38;client_id=7&#38;uid=68efed4d03ec7e45fd3978262c107180&#38;clicksrc=xml</string>
+		</dict>
+	</dict>
+	<key>Playlists</key>
+	<array>
+		<dict>
+			<key>Name</key><string>Library</string>
+			<key>Master</key><true/>
+			<key>Playlist ID</key><integer>2018</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DC6</string>
+			<key>Visible</key><false/>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>300</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>310</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>314</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>366</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>371</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>376</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>397</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>402</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>405</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>420</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>421</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>428</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>431</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>440</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>458</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>463</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>467</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>468</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>471</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>479</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>482</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>491</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>510</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>513</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>519</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>524</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>525</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>566</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>567</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>568</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>571</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>578</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>583</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>587</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>597</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>605</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>612</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>638</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>641</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>651</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>653</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>656</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>680</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>699</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>710</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>720</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>744</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>746</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>747</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>748</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>755</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>756</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>759</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>773</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>796</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>798</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>813</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>841</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>843</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>852</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>871</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>886</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>902</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>910</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>918</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>936</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>941</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>943</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>948</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>965</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>978</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1015</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1016</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1017</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1018</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1019</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1020</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1021</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1022</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1023</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1024</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1025</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1026</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1027</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1028</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1029</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1030</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1031</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1032</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1033</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1034</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1035</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1036</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1037</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1038</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1039</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1040</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1041</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1042</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1043</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1044</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1045</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1046</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1047</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1048</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1049</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1050</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1051</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1052</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1053</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1054</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1055</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1056</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1057</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1058</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1059</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1060</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1061</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1062</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1063</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1064</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1065</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1066</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1067</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1068</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1069</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1070</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1071</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1072</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1073</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1074</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1075</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1076</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1077</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1078</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1079</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1080</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1081</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1082</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1083</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1084</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1085</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1086</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1087</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1088</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1089</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1090</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1091</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1092</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1093</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1094</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1095</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1096</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1097</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1098</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1099</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1100</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1101</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1102</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1103</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1104</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1105</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1106</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1107</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1108</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1109</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1110</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1111</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1112</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1113</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1114</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1115</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1116</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1117</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1118</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1119</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1120</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1121</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1122</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1123</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1124</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1125</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1126</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1127</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1128</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1129</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1130</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1131</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1132</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1133</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1134</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1135</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1136</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1137</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1138</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1139</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1140</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1141</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1142</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1143</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1144</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1145</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1146</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1147</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1148</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1149</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1150</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1151</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1152</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1153</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1154</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1155</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1156</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1157</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1158</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1159</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1160</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1161</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1162</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1163</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1164</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1165</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1166</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1167</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1168</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1169</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1170</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1171</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1172</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1173</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1174</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1175</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1176</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1177</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1178</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1179</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1180</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1181</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1182</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1183</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1184</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1185</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1186</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1187</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1188</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1189</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1190</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1191</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1192</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1193</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1194</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1195</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1196</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1197</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1198</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1199</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1200</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1201</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1202</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1203</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1204</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1205</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1206</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1207</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1208</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1209</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1210</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1211</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1212</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1213</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1214</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1215</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1216</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1217</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1218</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1219</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1220</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1221</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1222</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1223</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1224</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1225</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1226</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1227</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1228</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1229</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1230</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1231</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1232</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1233</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1234</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1235</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1236</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1237</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1238</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1239</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1240</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1241</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1242</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1243</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1244</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1245</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1246</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1247</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1248</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1249</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1250</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1251</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1252</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1253</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1254</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1255</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1256</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1257</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1258</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1259</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1260</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1261</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1262</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1263</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1264</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1265</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1266</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1267</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1268</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1269</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1270</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1271</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1272</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1273</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1274</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1275</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1276</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1277</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1278</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1279</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1280</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1281</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1282</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1283</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1284</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1285</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1286</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1287</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1288</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1289</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1290</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1291</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1292</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1293</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1300</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1310</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1314</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1366</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1371</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1376</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1397</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1402</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1405</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1420</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1421</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1428</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1431</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1440</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1458</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1463</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1467</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1468</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1471</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1479</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1482</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1491</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1510</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1513</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1519</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1524</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1525</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1566</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1567</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1568</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1571</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1578</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1583</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1587</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1597</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1605</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1612</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1638</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1641</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1651</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1653</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1656</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1680</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1699</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1710</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1720</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1744</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1746</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1747</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1748</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1755</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1756</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1759</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1773</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1796</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1798</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1813</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1841</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1843</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1852</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1871</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1886</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1902</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1910</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1918</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1936</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1941</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1943</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1948</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1978</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2015</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Analog Voyager</string>
+			<key>Playlist ID</key><integer>7297</integer>
+			<key>Playlist Persistent ID</key><string>D03DAC75D3D46A1E</string>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>2016</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Audiobooks</string>
+			<key>Playlist ID</key><integer>5503</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DD3</string>
+			<key>Visible</key><false/>
+			<key>All Items</key><true/>
+			<key>Audiobooks</key><true/>
+		</dict>
+		<dict>
+			<key>Name</key><string>Groove Salad on SomaFM</string>
+			<key>Playlist ID</key><integer>7244</integer>
+			<key>Playlist Persistent ID</key><string>B16FC77EA12CDEA3</string>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>1965</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Movies</string>
+			<key>Playlist ID</key><integer>5497</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DD1</string>
+			<key>Visible</key><false/>
+			<key>All Items</key><true/>
+			<key>Movies</key><true/>
+		</dict>
+		<dict>
+			<key>Name</key><string>Music</string>
+			<key>Playlist ID</key><integer>3773</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DD0</string>
+			<key>All Items</key><true/>
+			<key>Music</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1202</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1203</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1236</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1421</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1597</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>813</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1137</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1138</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1192</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1205</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1260</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1261</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>910</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1026</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1061</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1085</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1093</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1100</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1111</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1139</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1157</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1169</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1193</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1195</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1204</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1206</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1209</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1240</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1249</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1252</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1259</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1275</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1291</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>638</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1468</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>510</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1941</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>468</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>300</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>491</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>513</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>519</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>310</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>587</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>371</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>471</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>376</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1566</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1567</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1578</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1612</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1638</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1641</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>525</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>583</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>710</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>720</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>744</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>746</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>747</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>748</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>755</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>756</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>759</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>796</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>467</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>841</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1680</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>852</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>871</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>421</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>918</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>941</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>943</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>948</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1030</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1032</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1078</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1116</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1127</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1156</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1159</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1164</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1181</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1186</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1191</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1218</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1230</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1267</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1271</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1272</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1314</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1366</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1405</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>605</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1699</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1420</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1440</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1479</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1482</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>656</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>463</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1798</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1813</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>651</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1886</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1902</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1910</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1936</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>524</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>314</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>440</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>420</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>567</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>366</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>597</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>571</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>397</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>402</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>405</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1568</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1571</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1583</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1587</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1605</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1651</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1653</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1656</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>680</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>699</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>773</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>798</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>653</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>843</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>886</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>902</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>936</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>965</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>978</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1015</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1016</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1017</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1018</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1019</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1020</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1021</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1022</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1023</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1024</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1025</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1027</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1028</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1029</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1031</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1033</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1034</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1035</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1036</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1037</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1038</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1039</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1040</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1041</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1042</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1043</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1044</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1045</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1046</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1047</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1048</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1049</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1050</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1051</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1052</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1053</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1054</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1055</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1056</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1057</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1058</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1059</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1060</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1062</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1063</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1064</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1065</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1066</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1067</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1068</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1069</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1070</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1071</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1072</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1073</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1074</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1075</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1076</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1077</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1079</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1080</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1081</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1082</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1083</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1084</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1086</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1087</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1088</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1089</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1090</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1091</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1092</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1094</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1095</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1096</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1097</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1098</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1099</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1101</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1102</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1103</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1104</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1105</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>482</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1106</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1107</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1108</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1109</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1110</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1112</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1113</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1114</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1115</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1117</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1118</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1119</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1120</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1121</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1122</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1123</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1124</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1125</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1126</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1128</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1129</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1130</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1131</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1132</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1133</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1134</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1135</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1136</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1140</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1141</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1142</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1143</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1144</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1145</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1146</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>641</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1147</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1148</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1149</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1150</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1151</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1152</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1153</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1154</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1155</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1158</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1160</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1161</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1162</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1163</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1165</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1166</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1167</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1168</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1170</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1171</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1172</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1173</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1174</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1175</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1176</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1177</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1178</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1179</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1180</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1182</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1183</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1184</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1185</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1187</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1188</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1189</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1190</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2015</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1194</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1196</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1197</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1198</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1199</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1200</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1201</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1207</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1208</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1210</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1211</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1212</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1213</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1214</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1215</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1216</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1217</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1219</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1220</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1221</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1222</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1223</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1224</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1225</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1226</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1227</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1228</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1229</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1231</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1232</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1233</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1234</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1235</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1237</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1238</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1239</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1241</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1242</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1243</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1244</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1245</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1246</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1247</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1248</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1250</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1251</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1253</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1254</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1255</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1256</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1257</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1258</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1262</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1263</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1264</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1265</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1266</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1268</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1269</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1270</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1273</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1274</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1276</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1277</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1278</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1279</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1280</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1281</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1282</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1283</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1284</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1285</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1286</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1287</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1288</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1289</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1290</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1292</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1293</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1300</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1310</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1371</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1376</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1397</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1402</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>612</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1710</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1428</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1431</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1458</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1463</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1467</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1471</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1491</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1510</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>431</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1513</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1519</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1524</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1525</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>566</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>428</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1720</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1744</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1746</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1747</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1748</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1755</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1756</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>578</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1759</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1773</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1796</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>479</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1841</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1843</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1852</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1871</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>568</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>458</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1918</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1943</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1948</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1978</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>New for Evaluation</string>
+			<key>Playlist ID</key><integer>7248</integer>
+			<key>Playlist Persistent ID</key><string>730096378DEDF386</string>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>1954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1991</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Party Shuffle</string>
+			<key>Playlist ID</key><integer>3742</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DCD</string>
+			<key>Party Shuffle</key><true/>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1117</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Podcasts</string>
+			<key>Playlist ID</key><integer>3766</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DCF</string>
+			<key>Visible</key><false/>
+			<key>Podcasts</key><true/>
+			<key>All Items</key><true/>
+		</dict>
+		<dict>
+			<key>Name</key><string>Purchased</string>
+			<key>Playlist ID</key><integer>5506</integer>
+			<key>Playlist Persistent ID</key><string>87139F8602B84FA1</string>
+			<key>Purchased Music</key><true/>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>1954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1991</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>radioioAmbient</string>
+			<key>Playlist ID</key><integer>7301</integer>
+			<key>Playlist Persistent ID</key><string>D03DAC75D3D46A22</string>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>2017</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>TV Shows</string>
+			<key>Playlist ID</key><integer>5500</integer>
+			<key>Playlist Persistent ID</key><string>C0BFB3784DAA9DD2</string>
+			<key>Visible</key><false/>
+			<key>All Items</key><true/>
+			<key>TV Shows</key><true/>
+		</dict>
+		<dict>
+			<key>Name</key><string>Two Stars</string>
+			<key>Playlist ID</key><integer>5555</integer>
+			<key>Playlist Persistent ID</key><string>8D7DB9C4CF0A5E54</string>
+			<key>All Items</key><true/>
+			<key>Smart Info</key>
+			<data>
+			AQEAAwAAAAIAAAAZAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAA==
+			</data>
+			<key>Smart Criteria</key>
+			<data>
+			U0xzdAABAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAAAQAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEAAAAAAAAACcAAAAAAAAAAAAAAAAAAAAB
+			AAAAAAAAACcAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+			</data>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1061</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1261</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1259</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1192</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>805</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1111</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1291</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1100</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1620</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1468</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1260</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1475</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>638</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1559</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1206</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1202</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1193</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1252</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1169</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1203</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1275</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1204</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1209</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1195</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1139</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>910</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1236</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1205</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1137</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1802</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1157</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1597</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>743</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1026</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1421</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1085</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1550</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1240</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1941</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>813</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1138</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1960</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1967</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1093</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1625</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1249</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>510</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Unrated Songs</string>
+			<key>Playlist ID</key><integer>5856</integer>
+			<key>Playlist Persistent ID</key><string>8D7DB9C4CF0A5E56</string>
+			<key>All Items</key><true/>
+			<key>Smart Info</key>
+			<data>
+			AQEAAwAAAAIAAAAZAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAA==
+			</data>
+			<key>Smart Criteria</key>
+			<data>
+			U0xzdAABAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAABAAAAAAAAAAAAAAAAAAAAAAAAA
+			AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAB
+			AAAAAAAAABQAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+			</data>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>1956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1957</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>575</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>630</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>496</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>514</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>515</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>314</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1995</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>356</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>440</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>420</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>567</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>366</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>367</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>576</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>563</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>571</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>383</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>397</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>405</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>582</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1556</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1568</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1570</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1583</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1587</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1592</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1594</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>577</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>616</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1601</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1605</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1617</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>553</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1619</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1622</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1631</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1633</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1634</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1639</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1645</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1646</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1649</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1651</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1652</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1653</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1655</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1656</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>598</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>632</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>642</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>532</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>659</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>660</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>661</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>662</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>663</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>664</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>665</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>667</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>674</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>680</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>615</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>647</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1668</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>593</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>627</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>599</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>699</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1669</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1670</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1671</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>718</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>723</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>724</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>798</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>801</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>807</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>808</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>812</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>648</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>821</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>826</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>595</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>835</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>840</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>560</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1672</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1673</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1675</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1676</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1677</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1678</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1679</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1681</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1682</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1683</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1684</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1685</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1686</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1687</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1688</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1689</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1690</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1691</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1692</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1693</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1694</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1695</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1696</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1697</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>849</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>411</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>636</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1974</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1975</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>886</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>902</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>904</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>906</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>913</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>914</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>917</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>922</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>933</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>936</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>953</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>954</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>956</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>959</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>961</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>962</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>963</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>965</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>966</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>968</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>969</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>970</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>972</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>973</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>976</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>977</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>978</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>982</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>989</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>992</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>993</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>994</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>996</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>997</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>998</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>999</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1000</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1001</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1002</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>658</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1015</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1016</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1017</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1018</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1019</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1020</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1021</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1022</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1023</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1024</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1025</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1027</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1028</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1029</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1031</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1033</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1034</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1035</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1036</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1037</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1038</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1039</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1040</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1041</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>609</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1042</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1044</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1045</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1046</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1047</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1048</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1049</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1050</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1051</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1052</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1053</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1054</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1055</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1056</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>581</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1058</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1059</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1060</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1062</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1063</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1064</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1065</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1066</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1067</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1068</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1069</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1070</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1071</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>555</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1072</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>590</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1073</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1074</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1075</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1076</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1077</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1079</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1080</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1081</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1082</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1083</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1084</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1086</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1087</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1088</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1089</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1090</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1091</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1092</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1094</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1096</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1097</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1098</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1099</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1101</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1102</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1103</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1104</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1105</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>482</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1106</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1107</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1108</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1109</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1110</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1112</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1113</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1114</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1115</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1117</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1118</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1119</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1120</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1121</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1122</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1123</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1124</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1125</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1126</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1128</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1129</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1130</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1131</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1132</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1133</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1134</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1135</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1136</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1140</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1141</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1142</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1143</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1144</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1145</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>635</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>574</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1979</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1980</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1981</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1983</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1984</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1985</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1988</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1991</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1146</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>641</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1147</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1148</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1149</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1150</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1151</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1152</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1153</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1154</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1155</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1158</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1160</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1161</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1162</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1163</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1165</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1166</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1167</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1168</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1170</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1171</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1172</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1173</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1174</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1175</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1176</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1177</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1178</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1179</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>626</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>604</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1182</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1183</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1184</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1185</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1187</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1188</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1189</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1190</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>572</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2014</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2006</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2009</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2011</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2004</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2013</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2012</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2007</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2005</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2015</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2003</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2008</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>2010</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>474</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1196</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1197</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1198</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1207</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1208</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1210</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1211</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1212</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>657</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1214</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1215</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1216</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1217</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1219</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1220</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1221</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1222</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1223</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1224</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1225</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1226</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1227</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1228</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1229</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1231</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1232</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1233</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1234</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1235</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>573</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>586</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>606</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>610</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>629</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1237</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>607</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1238</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1239</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1241</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1242</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1243</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1244</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1245</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1246</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1247</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1248</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1250</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>644</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>554</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1251</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1253</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1254</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1255</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1256</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1257</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1258</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1262</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1263</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1264</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1265</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1266</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1268</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1269</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1270</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1273</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1274</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1276</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1277</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1278</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1279</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1280</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1281</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1282</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1283</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1284</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1285</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1286</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1287</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1288</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1289</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1290</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1292</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1293</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1294</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1295</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1296</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1297</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1298</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1299</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1300</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1301</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1302</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1303</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1304</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1305</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1306</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1308</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1309</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1310</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1311</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1312</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1313</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1315</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1316</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1317</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1318</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1319</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1320</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1321</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1322</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1323</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1324</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1325</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1326</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1327</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1328</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1329</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1330</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1331</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1332</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1333</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1334</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1335</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1336</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1337</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1338</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1339</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1340</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1341</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1342</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1343</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1344</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1345</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1346</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1347</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1348</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1349</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1350</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1351</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1352</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1353</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1354</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1355</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1357</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1358</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1359</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1360</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1361</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1362</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1363</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1364</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1365</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1368</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1369</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1370</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1371</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1372</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1373</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1374</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1376</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1377</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1378</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1379</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1380</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1381</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1382</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1384</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1385</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1386</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1387</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1388</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1389</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1390</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1391</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1392</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1393</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1394</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1395</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1396</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1398</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>596</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1399</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1400</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1401</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1402</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1403</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1406</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1407</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1409</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>612</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>579</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1700</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1701</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1702</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1703</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1704</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1705</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1706</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1707</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1708</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1709</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1711</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>654</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1412</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1413</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1414</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1415</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1416</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1417</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>585</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1423</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1424</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1425</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1427</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1428</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1430</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1432</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1433</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1434</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1435</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1436</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1437</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1438</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1441</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1442</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1443</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1445</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1446</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1447</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1457</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1458</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1462</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1463</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1467</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1470</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1471</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1472</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1473</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1477</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1478</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>564</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1480</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1481</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1484</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1486</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1488</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1489</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1490</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1491</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>591</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1493</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1494</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1495</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1497</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1501</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1502</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1503</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1505</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1506</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1507</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1509</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1510</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>603</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>580</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>498</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>508</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>589</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>562</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>431</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>557</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>410</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1512</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>600</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1513</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>408</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1516</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1517</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1518</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1519</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1520</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1521</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1522</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1523</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1524</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1525</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1526</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1527</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1529</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1530</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>504</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>566</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>637</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>429</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1533</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1534</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1535</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1537</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1538</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1539</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1540</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1541</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1542</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>460</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>461</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>464</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>465</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>487</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1546</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1547</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1548</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1549</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1551</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1552</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1712</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1713</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1714</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1715</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1716</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1717</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1719</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1720</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1722</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1725</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1726</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1727</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1729</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1730</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1731</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1732</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1733</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1734</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1735</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1736</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1737</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1738</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1739</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1740</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1741</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>643</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1742</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1744</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1745</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1746</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1747</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1748</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1749</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1750</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1751</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1752</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1753</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1754</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>531</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>536</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1755</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>485</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1756</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>578</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1757</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1758</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1759</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1760</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1761</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1763</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1764</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1766</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1767</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1768</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1769</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1770</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1771</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1772</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1773</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1774</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1775</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1776</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1777</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1780</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1781</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1782</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1783</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1784</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1785</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1786</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1787</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1788</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1790</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1791</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1792</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1793</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1794</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1795</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1796</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1797</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>426</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>569</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1799</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1803</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1806</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1811</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1814</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1815</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1816</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1817</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1818</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1819</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1820</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1822</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1823</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1824</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1825</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>479</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1827</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1828</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1829</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1830</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1831</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>528</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1832</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1833</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1836</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1837</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1838</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1839</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1841</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1842</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1843</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1844</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1845</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1850</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1851</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1852</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>500</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1854</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>419</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1856</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1857</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1858</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1859</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1860</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1861</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1862</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1863</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1864</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1866</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1868</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1869</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1870</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1871</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1872</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1873</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1874</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1876</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>448</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>449</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>450</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>451</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>452</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>453</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>454</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>455</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>456</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>459</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1878</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1880</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1881</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1882</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1883</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1884</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1885</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1887</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1888</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1889</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1890</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1891</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>588</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>439</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1892</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1893</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1894</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1895</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1896</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1897</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1898</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1899</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1900</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1901</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1903</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>623</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>624</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1964</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>628</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1905</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1907</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1908</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1909</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1911</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1912</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1915</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1916</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1918</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1919</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1920</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1921</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1923</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1924</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1925</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1926</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1927</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1928</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1929</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1930</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1931</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1932</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1934</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1935</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1937</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1938</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>418</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>640</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1939</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1940</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1942</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1943</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1944</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1945</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1946</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1948</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1949</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1950</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1951</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1952</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>483</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1978</integer>
+				</dict>
+			</array>
+		</dict>
+		<dict>
+			<key>Name</key><string>Workout Mix</string>
+			<key>Playlist ID</key><integer>5783</integer>
+			<key>Playlist Persistent ID</key><string>8D7DB9C4CF0A5E55</string>
+			<key>All Items</key><true/>
+			<key>Playlist Items</key>
+			<array>
+				<dict>
+					<key>Track ID</key><integer>1511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>779</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>789</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>853</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1809</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1608</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>404</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1855</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1192</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1444</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1800</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>728</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1990</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1987</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1191</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>721</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1260</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1810</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>476</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>618</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>544</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>375</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>834</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1203</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1558</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>466</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>765</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>499</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1181</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1955</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>611</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>602</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1186</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>762</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1986</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1698</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>650</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>867</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>947</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1621</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1561</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>778</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1666</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1865</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1202</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1848</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1804</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>877</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>545</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1847</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1204</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1205</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>511</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>469</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>543</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1958</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1879</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1422</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1252</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1875</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>613</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>307</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1492</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1565</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>846</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1971</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>1614</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>584</integer>
+				</dict>
+				<dict>
+					<key>Track ID</key><integer>303</integer>
+				</dict>
+			</array>
+		</dict>
+	</array>
+</dict>
+</plist>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/components/SimpleLayout.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/components/SimpleLayout.tml
new file mode 100644
index 0000000..7304486
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/components/SimpleLayout.tml
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+      <title>Foo</title>
+  </head>
+  <body>
+      <t:body />
+  </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromComponent.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromComponent.tml
new file mode 100644
index 0000000..fb708e8
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromComponent.tml
@@ -0,0 +1,3 @@
+<html t:type="SimpleLayout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    flubber
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromPage.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromPage.tml
new file mode 100644
index 0000000..152eeca
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/DTDFromPage.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html>
+    <head>
+        <title>
+            DTDFromPage
+        </title>
+    </head>
+    <body>
+        slagheap
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/MultipleDTD.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/MultipleDTD.tml
new file mode 100644
index 0000000..76c3267
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/MultipleDTD.tml
@@ -0,0 +1,5 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html t:type="SimpleLayout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  blubber
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/NoDTD.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/NoDTD.tml
new file mode 100644
index 0000000..762eda2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/NoDTD.tml
@@ -0,0 +1,10 @@
+<html>
+    <head>
+        <title>
+            NoDTD
+        </title>
+    </head>
+    <body>
+        no_dtd_loser
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.tml
new file mode 100644
index 0000000..72fc7f2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/ResultPageForActionLink.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+<p>

+You chose: ${number}

+</p>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForASO.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForASO.tml
new file mode 100644
index 0000000..42ef2a1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForASO.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+FooString is: ${fooString}
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.tml
new file mode 100644
index 0000000..65a66ab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForActionLink.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <p>

+        <a t:id="link1" t:type="ActionLink" context="123" t:mixins="forceid">abc</a>

+    </p>

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForAsset.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForAsset.tml
new file mode 100644
index 0000000..83f2ce1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForAsset.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <link rel="stylesheet" href="${stylePath}" />
+  </head>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForForm.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForForm.tml
new file mode 100644
index 0000000..fe3c9c6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForForm.tml
@@ -0,0 +1,8 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+<p><t:form t:id="form1">

+	<input t:type="TextField" t:id="t1" value="value" size="50"/>

+</t:form></p>

+<p>

+	You entered: ${value}.

+</p>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForHead.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForHead.tml
new file mode 100644
index 0000000..cfa3c4c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForHead.tml
@@ -0,0 +1,8 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<head>
+	<title>testing</title>
+</head>
+<body>
+<p>OK!</p>
+</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForIf.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForIf.tml
new file mode 100644
index 0000000..65e4221
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForIf.tml
@@ -0,0 +1,26 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+  <t:if test="true">

+    <p id="1">abc.</p>

+  </t:if>

+  <t:if test="false">

+    <p id="2">def.</p>

+  </t:if>

+  <t:if test="property1">

+    <p id="3">111.</p>

+  </t:if>

+  <t:if test="property2">

+    <p id="4">222.</p>

+  </t:if>

+  <t:if test="true">

+      <p id="5">blah.</p>

+      <t:parameter name="else">

+          <p id="6">hey.</p>

+      </t:parameter>

+  </t:if>

+  <t:if test="false">

+      <p id="7">blah.</p>

+      <t:parameter name="else">

+          <p id="8">hey.</p>

+      </t:parameter>

+  </t:if>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale.tml
new file mode 100644
index 0000000..fe205ce
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale.tml
@@ -0,0 +1,4 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <p id="id1">English page</p>
+    <p t:type="ActionLink" t:id="changeLocale" t:mixins="forceid">Change locale</p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale_fr.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale_fr.tml
new file mode 100644
index 0000000..c01b354
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLocale_fr.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<p id="id1">French page</p>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLoop.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLoop.tml
new file mode 100644
index 0000000..3133536
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForLoop.tml
@@ -0,0 +1,8 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+<p>

+<t:loop source="1..3">abc</t:loop>

+</p>

+<p>

+<span id="1"><t:loop source="array" value="value">${value}</t:loop></span>

+</p>

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.tml
new file mode 100644
index 0000000..214bc8e
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForSubmit.tml
@@ -0,0 +1,15 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<p>
+<form t:id="form1">
+	<input t:id="t1" t:type="TextField"/>
+	<span t:id="capitalize1"/>
+</form>	
+<form t:id="form2">
+	<span t:id="capitalize2"/>
+	<input t:id="t2" t:type="TextField"/>
+</form></p>
+<input type="submit" id="orphanedSubmit"/>
+<p>
+Value is: ${value}.
+</p>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForUnless.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForUnless.tml
new file mode 100644
index 0000000..2309a60
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPageForUnless.tml
@@ -0,0 +1,26 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <t:unless test="true">
+    <p id="1">abc.</p>
+  </t:unless>
+  <t:unless test="false">
+    <p id="2">def.</p>
+  </t:unless>
+  <t:unless test="property1">
+    <p id="3">111.</p>
+  </t:unless>
+  <t:unless test="property2">
+    <p id="4">222.</p>
+  </t:unless>
+  <t:unless test="true">
+      <p id="5">blah.</p>
+      <t:parameter name="else">
+          <p id="6">hey.</p>
+      </t:parameter>
+  </t:unless>
+  <t:unless test="false">
+      <p id="7">blah.</p>
+      <t:parameter name="else">
+          <p id="8">hey.</p>
+      </t:parameter>
+  </t:unless>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.tml
new file mode 100644
index 0000000..8c45e92
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/integration/app2/pages/TestPrefixMethod.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <span id="value">${value}</span>
+    <span id="value2">${value2}</span>
+    <span id="value3">${value3}</span>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages.properties
new file mode 100644
index 0000000..9fe1731
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages.properties
@@ -0,0 +1,15 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+contributed=This message was contributed inside ValidationTestMessages.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages_fr.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages_fr.properties
new file mode 100644
index 0000000..24700af
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/ValidationTestMessages_fr.properties
@@ -0,0 +1,15 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+contributed=Zees eez Cohntributahd.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/pageload/Fred.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/pageload/Fred.tml
new file mode 100644
index 0000000..8990519
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/pageload/Fred.tml
@@ -0,0 +1 @@
+<html> Used by ComponentTemplateSourceImplTest </html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/AppCatalog.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/AppCatalog.properties
new file mode 100644
index 0000000..8940969
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/AppCatalog.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+app-catalog-source=AppCatalog
+app-catalog-overridden=Value from AppCatalog
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent.properties
new file mode 100644
index 0000000..4cd540c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent.properties
@@ -0,0 +1,18 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+color=color
+framework=Tapestry
+source=SimpleComponent
+app-catalog-overridden=Overridden by Component
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent_en_GB.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent_en_GB.properties
new file mode 100644
index 0000000..59e7ef9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SimpleComponent_en_GB.properties
@@ -0,0 +1,15 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+color=colour
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent.properties
new file mode 100644
index 0000000..254ff7c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent.properties
@@ -0,0 +1,16 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+metal=steel
+source=SubclassComponent
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent_en_GB.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent_en_GB.properties
new file mode 100644
index 0000000..654e1fb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/SubclassComponent_en_GB.properties
@@ -0,0 +1,15 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+metal=aluminium
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt
new file mode 100644
index 0000000..44045ab
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt
@@ -0,0 +1,8 @@
+<html><body><p>Ready to be updated with scripts.</p><script type="text/javascript">
+<!--
+Tapestry.onDOMLoaded(function() {
+doSomething();
+doSomethingElse();
+});
+// -->
+</script></body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_in_development_mode.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_in_development_mode.txt
new file mode 100644
index 0000000..96b206f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_in_development_mode.txt
@@ -0,0 +1,7 @@
+<html><body><p>Ready to be updated with scripts.</p><script src="foo.js" type="text/javascript"></script><script type="text/javascript">
+<!--
+Tapestry.DEBUG_ENABLED = true;
+Tapestry.onDOMLoaded(function() {
+});
+// -->
+</script></body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt
new file mode 100644
index 0000000..fa60a2a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<html><body><p>Ready to be updated with scripts.</p><script src="foo.js" type="text/javascript"/><script src="bar/baz.js" type="text/javascript"/></body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_style_links.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_style_links.txt
new file mode 100644
index 0000000..045fe90
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_style_links.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<html><head><link href="foo.css" rel="stylesheet" type="text/css"/><link href="bar/baz.css" media="print" rel="stylesheet" type="text/css"/></head><body><p>Ready to be updated with styles.</p></body></html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/basic.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/basic.tml
new file mode 100644
index 0000000..80785b6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/basic.tml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xmlns:bar="bar">
+    <head>
+        <title>Test</title>
+    </head>
+    <body>
+        <t:comp id="fred" type="If" value="foo">
+            <p>You have been served!</p>
+        </t:comp>
+        <p t:id="barney" class="error">
+            You are barney!<br/>You are barney!
+        </p>
+        pre<!-- A comment! -->post
+        
+        <pre>
+line 1
+line 2            
+line 3: <![CDATA[This text contains <invalid markup>]]>
+        </pre>
+        
+        <bar:baz biff="boo">
+            Zippy!
+        </bar:baz>        
+    </body>
+</html>  <!-- Spaces and comments at end -->
+
+
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/block_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/block_element.tml
new file mode 100644
index 0000000..de28436
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/block_element.tml
@@ -0,0 +1,10 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <t:block id="block0">
+        <!-- block0 content -->
+    </t:block>
+    
+    <t:block>
+        <!-- anon block content -->
+    </t:block>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/body_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/body_element.tml
new file mode 100644
index 0000000..397d2d0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/body_element.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+Before

+<t:body/>

+After

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/cdata.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/cdata.tml
new file mode 100644
index 0000000..f6ba4d3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/cdata.tml
@@ -0,0 +1,3 @@
+<html xml:space="preserve">
+    <![CDATA[CDATA: &lt;foo&gt; &amp; &lt;bar&gt; and <baz>]]>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/comment.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/comment.tml
new file mode 100644
index 0000000..f2f679c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/comment.tml
@@ -0,0 +1,3 @@
+<html>
+    <!-- Single line comment -->
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/complex_component_type.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/complex_component_type.tml
new file mode 100644
index 0000000..dda9171
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/complex_component_type.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <t:subfolder.nifty t:id="foo"/>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component.tml
new file mode 100644
index 0000000..1effd8a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component.tml
@@ -0,0 +1,4 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+    <t:somecomponent t:id="fred"/>

+</html>

+    
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithBody.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithBody.tml
new file mode 100644
index 0000000..7ec1938
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithBody.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">
+    <t:Fred t:id="fred">
+        fred's body
+    </t:Fred>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithParameters.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithParameters.tml
new file mode 100644
index 0000000..9fa92f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/componentWithParameters.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+    <t:Fred t:id="fred" cherry="bomb" align="right">

+        fred's body

+    </t:Fred>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_ids.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_ids.tml
new file mode 100644
index 0000000..9aee27b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_ids.tml
@@ -0,0 +1,5 @@
+<t:border t:id="border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+  <t:Zebra t:id="zebra"/>
+  <t:Nebraska/>
+  <t:comp t:id="bomb"/>
+</t:border>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_with_mixins.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_with_mixins.tml
new file mode 100644
index 0000000..add6166
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/component_with_mixins.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <t:comp t:id="fred" t:mixins="Barney"/>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml
new file mode 100644
index 0000000..e309b3a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/container_element.tml
@@ -0,0 +1,9 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+A bit of text.
+
+<foo/>
+
+Some more text.
+
+</t:container>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/content_within_body_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/content_within_body_element.tml
new file mode 100644
index 0000000..80b6cd0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/content_within_body_element.tml
@@ -0,0 +1,7 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+    <t:body>

+        Some text (starts on line 2)

+        <!-- A comment -->

+        <![CDATA[ CData text ]]>

+    </t:body>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt
new file mode 100644
index 0000000..4550909
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt
@@ -0,0 +1 @@
+<html><body><p>Ready to be updated with scripts.</p><script src="foo.js" type="text/javascript"></script><script src="bar/baz.js" type="text/javascript"></script><script src="biff.js" type="text/javascript"></script></body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_scripts_ignored_first_media_wins.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_scripts_ignored_first_media_wins.txt
new file mode 100644
index 0000000..6c58bbb
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/duplicate_scripts_ignored_first_media_wins.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<html><head><link href="foo.css" rel="stylesheet" type="text/css"/><link href="bar/baz.css" media="print" rel="stylesheet" type="text/css"/></head><body><p>Ready to be updated with styles.</p></body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/empty_string_mixins_is_null.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/empty_string_mixins_is_null.tml
new file mode 100644
index 0000000..179ce91
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/empty_string_mixins_is_null.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+    <span t:id="fred" t:mixins=""/>

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/existing_head_used_if_present.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/existing_head_used_if_present.txt
new file mode 100644
index 0000000..15b84cc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/existing_head_used_if_present.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<html><head><link href="foo.css" rel="stylesheet" type="text/css"/><!-- existing head --></head><body>body content</body></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_in_normal_text.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_in_normal_text.tml
new file mode 100644
index 0000000..213c769
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_in_normal_text.tml
@@ -0,0 +1,7 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+

+Expansion #1[${expansion1}]

+

+Expansion #2[${expansion2}]

+

+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_must_be_on_one_line.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_must_be_on_one_line.tml
new file mode 100644
index 0000000..20c24c4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_must_be_on_one_line.tml
@@ -0,0 +1,9 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+

+    ${expansions

+    must

+    be

+    on a single

+    line}

+

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_attributes.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_attributes.tml
new file mode 100644
index 0000000..9640d21
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_attributes.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" exp="${not-an-expansion}">

+

+</html>

diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_cdata.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_cdata.tml
new file mode 100644
index 0000000..c1e812f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/expansions_not_allowed_in_cdata.tml
@@ -0,0 +1,5 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">

+

+    <![CDATA[${not-an-expansion}]]>

+

+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_frameset_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_frameset_doctype.tml
new file mode 100644
index 0000000..2101b47
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_frameset_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC

+	"-//W3C//DTD HTML 4.01 Frameset//EN"

+	"http://www.w3.org/TR/html4/frameset.dtd">

+
+<html>
+	<head>
+		<title>HTML 4 Frameset Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_strict_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_strict_doctype.tml
new file mode 100644
index 0000000..f521290
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_strict_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC

+	"-//W3C//DTD HTML 4.01//EN"

+	"http://www.w3.org/TR/html4/strict.dtd">

+
+<html>
+	<head>
+		<title>HTML 4 Strict Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_transitional_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_transitional_doctype.tml
new file mode 100644
index 0000000..faa5490
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html4_transitional_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC

+	"-//W3C//DTD HTML 4.01 Transitional//EN"

+	"http://www.w3.org/TR/html4/loose.dtd">

+
+<html>
+	<head>
+		<title>HTML 4 Transitional Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html_entity.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html_entity.tml
new file mode 100644
index 0000000..92d959b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/html_entity.tml
@@ -0,0 +1,5 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

+<html>
+    nbsp:[&nbsp;]
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/illegal_nesting_within_body_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/illegal_nesting_within_body_element.tml
new file mode 100644
index 0000000..932bc8b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/illegal_nesting_within_body_element.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

+    <t:body><xyz/></t:body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/instrumented_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/instrumented_element.tml
new file mode 100644
index 0000000..9fe04f5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/instrumented_element.tml
@@ -0,0 +1 @@
+<html t:id="fred" t:type="Fred" param="value" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"/>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_block_id.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_block_id.tml
new file mode 100644
index 0000000..1e5e86b
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_block_id.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:block id="not-valid"/>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_component_id.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_component_id.tml
new file mode 100644
index 0000000..d5fc8b5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/invalid_component_id.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:foo t:id="not-valid"/>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/justHTML.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/justHTML.tml
new file mode 100644
index 0000000..18b24a2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/justHTML.tml
@@ -0,0 +1,12 @@
+<html xml:space="preserve">
+    <head>
+        <title>title</title>
+    </head>
+    <body>
+        <p class="important">Tapestry rocks!
+
+            Line 2
+
+        </p>
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml
new file mode 100644
index 0000000..0384fd4
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml
@@ -0,0 +1,8 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    Whitespace
+    <em>around tags</em>
+
+    is maintained.
+
+
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/mixin_requires_id_or_type.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/mixin_requires_id_or_type.tml
new file mode 100644
index 0000000..8ceb9f1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/mixin_requires_id_or_type.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <span t:mixins="Whatever" param="value" />    
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multilineComment.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multilineComment.tml
new file mode 100644
index 0000000..708a03f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multilineComment.tml
@@ -0,0 +1,5 @@
+<html xml:space="preserve">
+    <!-- Line one
+         Line two
+         Line three -->
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multiple_expansions_on_one_line.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multiple_expansions_on_one_line.tml
new file mode 100644
index 0000000..505439f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/multiple_expansions_on_one_line.tml
@@ -0,0 +1,3 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">
+    <dd>${classLoader} [${classLoader.class.name}]</dd>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_blank.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_blank.tml
new file mode 100644
index 0000000..3898be3
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_blank.tml
@@ -0,0 +1,7 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <t:comp id="foo">
+        <t:parameter name=""/>
+    </t:comp>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_omitted.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_omitted.tml
new file mode 100644
index 0000000..4f846e6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/name_attribute_of_parameter_element_omitted.tml
@@ -0,0 +1,7 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <t:comp id="foo">
+        <t:parameter/>
+    </t:comp>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/namespaced_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/namespaced_element.tml
new file mode 100644
index 0000000..de1575a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/namespaced_element.tml
@@ -0,0 +1,3 @@
+<foo:bar xmlns:foo="http://foo.com" foo:biff="baz" xml:space="preserve">
+    <gnip/>
+</foo:bar>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/no_body_element.txt b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/no_body_element.txt
new file mode 100644
index 0000000..2fec1d2
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/no_body_element.txt
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<html><notbody><p>Ready to be updated with scripts.</p></notbody></html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/parameter_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/parameter_element.tml
new file mode 100644
index 0000000..afafeb9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/parameter_element.tml
@@ -0,0 +1,9 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">
+
+    <t:mycomp t:id="foo">
+        <t:parameter name="fred">
+            <!-- fred content -->
+        </t:parameter>
+    </t:mycomp>
+
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.tml
new file mode 100644
index 0000000..493eb5c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/root_element_is_component.tml
@@ -0,0 +1 @@
+<t:Fred t:id="fred" param="value" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"/>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/simple.dtd b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/simple.dtd
new file mode 100644
index 0000000..be05ea6
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/simple.dtd
@@ -0,0 +1 @@
+<!ELEMENT foo (#PCDATA)>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_block.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_block.tml
new file mode 100644
index 0000000..77d25c0
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_block.tml
@@ -0,0 +1,5 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <t:block xml:space="preserve">
+        line in the middle
+    </t:block>
+</t:container>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_container.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_container.tml
new file mode 100644
index 0000000..25542f5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/space_preserved_in_container.tml
@@ -0,0 +1,5 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" xml:space="preserve">
+    <span>
+        some text
+    </span>
+</t:container>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/system_doctype.xml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/system_doctype.xml
new file mode 100644
index 0000000..134123f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/system_doctype.xml
@@ -0,0 +1,17 @@
+<!--
+   Copyright 2007, 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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 foo SYSTEM "src/test/resources/org/apache/tapestry/internal/services/simple.dtd" >
+<foo>bar</foo>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.css b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.css
new file mode 100644
index 0000000..9798fcc
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.css
@@ -0,0 +1,4 @@
+body {
+    margin: 0;
+    padding: 0;
+}
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.gif b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.gif
new file mode 100644
index 0000000..42118f9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.gif
Binary files differ
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.js b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.js
new file mode 100644
index 0000000..71f1a5a
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/test.js
@@ -0,0 +1 @@
+var x = 5;
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_block_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_block_element.tml
new file mode 100644
index 0000000..2f110b9
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_block_element.tml
@@ -0,0 +1,10 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <t:block name="block0">
+        <!-- block0 content -->
+    </t:block>
+    
+    <t:block>
+        <!-- anon block content -->
+    </t:block>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_parameter_element.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_parameter_element.tml
new file mode 100644
index 0000000..6865b62
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/unexpected_attribute_in_parameter_element.tml
@@ -0,0 +1,7 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    
+    <t:comp id="foo">
+    <t:parameter name="beverly" grok="clearly"/>
+    </t:comp>
+    
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_frameset_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_frameset_doctype.tml
new file mode 100644
index 0000000..fd5a661
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_frameset_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC
+	"-//W3C//DTD XHTML 1.0 Frameset//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+
+<html>
+	<head>
+		<title>XHTML 1.0 Frameset Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_strict_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_strict_doctype.tml
new file mode 100644
index 0000000..49c4c8f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_strict_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC
+	"-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html>
+	<head>
+		<title>XHTML 1.0 Strict Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_transitional_doctype.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_transitional_doctype.tml
new file mode 100644
index 0000000..45fae6c
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xhtml1_transitional_doctype.tml
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC
+	"-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+	<head>
+		<title>XHTML 1.0 Transitional Test</title>
+	</head>
+	<body>
+		&lt;Test&gt;
+	</body>
+</html>
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xmlEntity.tml b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xmlEntity.tml
new file mode 100644
index 0000000..e376de1
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/xmlEntity.tml
@@ -0,0 +1,3 @@
+<html>
+lt:&lt; gt:&gt; amp:&amp;
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/noversion.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/noversion.properties
new file mode 100644
index 0000000..521e65f
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/noversion.properties
@@ -0,0 +1 @@
+no-version-specified=here
diff --git a/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/version.properties b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/version.properties
new file mode 100644
index 0000000..5572ff5
--- /dev/null
+++ b/hlship-20080520/tapestry-core/src/test/resources/org/apache/tapestry/version.properties
@@ -0,0 +1 @@
+version=1.2.3.4
diff --git a/hlship-20080520/tapestry-hibernate/.classpath b/hlship-20080520/tapestry-hibernate/.classpath
new file mode 100644
index 0000000..6691182
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+  <classpathentry kind="src" output="bin"  path="src/main/java"/>
+  <classpathentry kind="src" output="bin-test"  path="src/test/java"/>
+  <classpathentry kind="lib" path="src/main/resources"/> 
+  <classpathentry kind="lib" path="src/test/resources"/> 
+  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+  <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+  <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-hibernate/.project b/hlship-20080520/tapestry-hibernate/.project
new file mode 100644
index 0000000..0506964
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+  <name>tapestry-hibernate</name>
+  <comment></comment>
+  <projects>
+  </projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+      <arguments>
+      </arguments>
+    </buildCommand>
+    <buildCommand>
+      <name>org.maven.ide.eclipse.maven2Builder</name>
+      <arguments>
+      </arguments>
+     </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.maven.ide.eclipse.maven2Nature</nature>
+  </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-hibernate/LICENSE.txt b/hlship-20080520/tapestry-hibernate/LICENSE.txt
new file mode 100644
index 0000000..18a3697
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/LICENSE.txt
@@ -0,0 +1,715 @@
+
+                                 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.
+
+
+-------------------------------------------------------------------------------
+   
+HIBERNATE
+
+Hibernate is not bundled with tapestry-hibernate, but is bound to it.   
+   
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+		     
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+   
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/NOTICE.txt b/hlship-20080520/tapestry-hibernate/NOTICE.txt
new file mode 100644
index 0000000..c5b9d10
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/NOTICE.txt
@@ -0,0 +1,10 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product makes use of the Hibernate Object Relational Mapping Framework, which
+is released under the Lesser GNU Public License.
+http://hibernate.org
+
+
+
+
diff --git a/hlship-20080520/tapestry-hibernate/pom.xml b/hlship-20080520/tapestry-hibernate/pom.xml
new file mode 100644
index 0000000..67f197c
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/pom.xml
@@ -0,0 +1,177 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-hibernate</artifactId>
+    <name>Tapestry/Hibernate Integration Library</name>
+    <description>
+        Provides support for simple CRUD applications built on top of
+        Tapestry and Hibernate
+    </description>
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <inceptionYear>2007</inceptionYear>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-core</artifactId>
+        </dependency>
+
+        <!-- Testing -->
+
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-test</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymockclassextension</artifactId>
+            <version>2.2.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>1.8.0.7</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+            <scope>test</scope>
+        </dependency>
+
+
+        <!-- Provided -->
+
+        <!-- The Hibernate dependencies are provided; which gives the final application
+the ability to choose the appropriate version.  Further, in many cases
+(such as JBoss deployment), they are, in fact, provided by the
+container.  For a Tomcat deployment, you're more likely to include
+the hibernate JARs and dependencies inside the WAR. -->
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate</artifactId>
+            <version>3.2.2.ga</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.transaction</groupId>
+                    <artifactId>jta</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>geronimo-spec</groupId>
+            <artifactId>geronimo-spec-jta</artifactId>
+            <version>1.0-M1</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- The annotation should be compatible with the 3.2.2.ga release of the
+      core package. -->
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-annotations</artifactId>
+            <version>3.2.1.ga</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>c3p0</groupId>
+            <artifactId>c3p0</artifactId>
+            <version>0.9.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+            <!-- This gets the plugin to clean up the cobertura.ser file left
+        in the root directory. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Tapestry-Module-Classes>
+                                org.apache.tapestry.hibernate.HibernateModule
+                            </Tapestry-Module-Classes>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+
+            <!--      <plugin>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-component-report</artifactId>
+            <version>5.0.2</version>
+            <configuration>
+            <rootPackage>org.apache.tapestry.corelib</rootPackage>
+            </configuration>
+            </plugin>-->
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateConfigurer.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateConfigurer.java
new file mode 100644
index 0000000..183f62f
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateConfigurer.java
@@ -0,0 +1,29 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+import org.hibernate.cfg.Configuration;
+
+/**
+ * Defines the interface for a chain-of-command that updates Hibernate configuration in some way before the {@link
+ * org.hibernate.SessionFactory} is created.
+ */
+public interface HibernateConfigurer
+{
+    /**
+     * Passed the configuration so as to make changes.
+     */
+    void configure(Configuration configuration);
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateEntityPackageManager.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateEntityPackageManager.java
new file mode 100644
index 0000000..2af224b
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateEntityPackageManager.java
@@ -0,0 +1,24 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+import java.util.Collection;
+
+/** Contains a set of contributed package names from which to load entities.
+ */
+public interface HibernateEntityPackageManager {
+	/** Returns packages from which read entity classes */ 
+	Collection<String> getPackageNames();
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
new file mode 100644
index 0000000..d98e92a
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
@@ -0,0 +1,193 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.internal.InternalConstants;
+import org.apache.tapestry.internal.hibernate.*;
+import org.apache.tapestry.ioc.*;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.InjectService;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.services.AliasContribution;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+import org.apache.tapestry.services.ValueEncoderFactory;
+import org.hibernate.Session;
+import org.hibernate.mapping.PersistentClass;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+@SuppressWarnings({ "JavaDoc" })
+public class HibernateModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(HibernateTransactionDecorator.class, HibernateTransactionDecoratorImpl.class);
+    }
+
+    public static HibernateEntityPackageManager build(final Collection<String> packageNames)
+    {
+        return new HibernateEntityPackageManager()
+        {
+            public Collection<String> getPackageNames()
+            {
+                return packageNames;
+            }
+        };
+    }
+
+    /**
+     * Contributes the package "&lt;root&gt;.entities" to the configuration, so that it will be scanned for annotated
+     * entity classes.
+     */
+    public static void contributeHibernateEntityPackageManager(Configuration<String> configuration,
+
+                                                               @Inject
+                                                               @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
+                                                               String appRootPackage)
+    {
+        configuration.add(appRootPackage + ".entities");
+    }
+
+    /**
+     * The session manager manages sessions on a per-thread/per-request basis. A {@link org.hibernate.Transaction} is
+     * created initially, and is committed at the end of the request.
+     */
+    @Scope(PERTHREAD_SCOPE)
+    public static HibernateSessionManager build(HibernateSessionSource sessionSource, PerthreadManager perthreadManager)
+    {
+        HibernateSessionManagerImpl service = new HibernateSessionManagerImpl(sessionSource);
+
+        perthreadManager.addThreadCleanupListener(service);
+
+        return service;
+    }
+
+    public static Session build(HibernateSessionManager sessionManager,
+                                PropertyShadowBuilder propertyShadowBuilder)
+    {
+        // Here's the thing: the tapestry.hibernate.Session class doesn't have to be per-thread,
+        // since
+        // it will invoke getSession() on the HibernateSessionManager service (which is per-thread).
+        // On
+        // first invocation per request,
+        // this forces the HSM into existence (which creates the session and begins the
+        // transaction).
+        // Thus we don't actually create
+        // a session until we first try to access it, then the session continues to exist for the
+        // rest
+        // of the request.
+
+        return propertyShadowBuilder.build(sessionManager, "session", Session.class);
+    }
+
+    /**
+     * Contributes the {@link #build(HibernateSessionManager, PropertyShadowBuilder) Session} service.
+     */
+    public static void contributeAlias(Configuration<AliasContribution> configuration,
+
+                                       @InjectService("Session")
+                                       Session session)
+    {
+        configuration.add(AliasContribution.create(Session.class, session));
+    }
+
+    public static HibernateSessionSource build(Logger logger, List<HibernateConfigurer> config,
+                                               RegistryShutdownHub hub)
+    {
+        HibernateSessionSourceImpl hss = new HibernateSessionSourceImpl(logger, config);
+
+        hub.addRegistryShutdownListener(hss);
+
+        return hss;
+    }
+
+    /**
+     * Adds the following configurers: <ul> <li>Default - performs default hibernate configuration</li> <li>PackageName
+     * - loads entities by package name</li> </ul>
+     */
+    public static void contributeHibernateSessionSource(OrderedConfiguration<HibernateConfigurer> config,
+                                                        final ClassNameLocator classNameLocator,
+                                                        final HibernateEntityPackageManager packageManager)
+    {
+        config.add("Default", new DefaultHibernateConfigurer());
+        config.add("PackageName", new PackageNameHibernateConfigurer(packageManager, classNameLocator));
+    }
+
+    /**
+     * Contributes {@link ValueEncoderFactory}s for all registered Hibernate entity classes. Encoding and decoding are
+     * based on the id property value of the entity using type coercion. Hence, if the id can be coerced to a String and
+     * back then the entity can be coerced.
+     */
+    @SuppressWarnings("unchecked")
+    public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
+                                                    final HibernateSessionSource sessionSource,
+                                                    final Session session,
+                                                    final TypeCoercer typeCoercer,
+                                                    final PropertyAccess propertyAccess,
+                                                    final LoggerSource loggerSource)
+    {
+        org.hibernate.cfg.Configuration config = sessionSource.getConfiguration();
+        Iterator<PersistentClass> mappings = config.getClassMappings();
+        while (mappings.hasNext())
+        {
+            final PersistentClass persistentClass = mappings.next();
+            final Class entityClass = persistentClass.getMappedClass();
+
+            ValueEncoderFactory factory = new ValueEncoderFactory()
+            {
+                public ValueEncoder create(Class type)
+                {
+                    return new HibernateEntityValueEncoder(entityClass, persistentClass, session, propertyAccess,
+                                                           typeCoercer, loggerSource.getLogger(entityClass));
+                }
+            };
+
+            configuration.add(entityClass, factory);
+        }
+    }
+
+    /**
+     * Contributes the following: <dl> <dt>entity</dt> <dd>Stores the id of the entity and reloads from the {@link
+     * Session}</dd> </dl>
+     */
+    public static void contributePersistentFieldManager(
+            MappedConfiguration<String, PersistentFieldStrategy> configuration,
+            ObjectLocator locator)
+    {
+        configuration.add("entity", locator.autobuild(EntityPersistentFieldStrategy.class));
+    }
+
+    /**
+     * Adds the CommitAfter annotation work, to process the {@link org.apache.tapestry.hibernate.annotations.CommitAfter}
+     * annotation.
+     */
+    public static void contributeComponentClassTransformWorker(
+            OrderedConfiguration<ComponentClassTransformWorker> configuration,
+            ObjectLocator locator)
+    {
+        // If logging is enabled, we want logging to be the first advice, wrapping around the commit advice.
+
+        configuration.add("CommitAfter", locator.autobuild(CommitAfterWorker.class), "after:Log");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionManager.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionManager.java
new file mode 100644
index 0000000..190bd69
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionManager.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+import org.hibernate.Session;
+
+/**
+ * Manages the Hibernate session for the current thread. This includes creating the session as
+ * needed, allowing the session to checkpoint (commit the current transaction and continue) and
+ * commit the transaction automatically at the end of the request.
+ * <p>
+ * Remember that in Tapestry, action requests and render requests are entirely separate, and you
+ * will see a separate request and a separate transaction for each. Care should be taken to ensure
+ * that entity objects that are retained (in the session, as persistent field values) between
+ * requests are handled correctly (they tend to become detached instances).
+ * <p>
+ * This implementation of this service is per-thread.
+ */
+public interface HibernateSessionManager
+{
+  /**
+   * Gets the active session for this request, creating it as necessary. When the session is first
+   * created, a transaction is started.
+   * 
+   * @return the request's session
+   * @see HibernateSessionSource
+   */
+  Session getSession();
+
+  /**
+   * Commits the current transaction (which will cause a flush of data to the database), then starts
+   * a new transaction to replace it.
+   */
+  void commit();
+
+  /**
+   * Aborts the current transaction, and starts a new transaction to replace it.
+   */
+  void abort();
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionSource.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionSource.java
new file mode 100644
index 0000000..0601128
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateSessionSource.java
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
+
+/**
+ * Responsible for creating a Hibernate session as needed. Internally, is responsible for Hibernate
+ * {@link Configuration}, resulting in a {@link SessionFactory}.
+ */
+public interface HibernateSessionSource
+{
+    /**
+     * Creates a new session using the {@link #getSessionFactory() SessionFactory} created at
+     * service startup.
+     */
+    Session create();
+
+    /** Returns the SessionFactory from which Hibernate sessions are created. */
+    SessionFactory getSessionFactory();
+    
+    /** Returns the final configuration used to create the {@link SessionFactory}.
+     * The configuration is immutable.
+     */
+    Configuration getConfiguration();
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateTransactionDecorator.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateTransactionDecorator.java
new file mode 100644
index 0000000..bbc6382
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateTransactionDecorator.java
@@ -0,0 +1,37 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate;
+
+/**
+ * Service that can create an interceptor that wraps around a service implementation. After invoking service methods
+ * marked by {@link org.apache.tapestry.hibernate.annotations.CommitAfter} the current transaction is committed.
+ * Declared exceptions will also {@linkplain org.apache.tapestry.hibernate.HibernateSessionManager#commit() commit the
+ * transaction}; runtime exceptions will {@linkplain org.apache.tapestry.hibernate.HibernateSessionManager#abort() the
+ * transaction}.
+ */
+public interface HibernateTransactionDecorator
+{
+    /**
+     * Builds a transaction interceptor instance around the delegate.
+     *
+     * @param <T>
+     * @param serviceInterface interface implemented by the delegate
+     * @param delegate         existing object to be wrapped
+     * @param serviceId        id of service
+     * @return a new object implementing the interface that can be used in place of the delegate, providing
+     *         transactional behavior
+     */
+    <T> T build(Class<T> serviceInterface, T delegate, String serviceId);
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/annotations/CommitAfter.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/annotations/CommitAfter.java
new file mode 100644
index 0000000..20cc32d
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/annotations/CommitAfter.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate.annotations;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a method of a service (or a component method) as transactional: the active transaction should {@linkplain
+ * org.apache.tapestry.hibernate.HibernateSessionManager#commit() commit} after invoking the method.  Runtime exceptions
+ * will abort the transaction, checked exceptions will <also commit> the transaction.
+ *
+ * @see org.apache.tapestry.hibernate.HibernateTransactionDecorator
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface CommitAfter
+{
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/CommitAfterWorker.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/CommitAfterWorker.java
new file mode 100644
index 0000000..47c944c
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/CommitAfterWorker.java
@@ -0,0 +1,64 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.*;
+
+/**
+ * Searches for methods that have the {@link org.apache.tapestry.hibernate.annotations.CommitAfter} annotation and adds
+ * logic around the method to commit or abort the transaction.  The commit/abort logic is the same as for the {@link
+ * org.apache.tapestry.hibernate.HibernateTransactionDecorator} service.
+ */
+public class CommitAfterWorker implements ComponentClassTransformWorker
+{
+    private final HibernateSessionManager manager;
+
+    private final ComponentMethodAdvice advice = new ComponentMethodAdvice()
+    {
+        public void advise(ComponentMethodInvocation invocation)
+        {
+            try
+            {
+                invocation.proceed();
+
+                // Success or checked exception:
+
+                manager.commit();
+            }
+            catch (RuntimeException ex)
+            {
+                manager.abort();
+
+                throw ex;
+            }
+        }
+    };
+
+    public CommitAfterWorker(HibernateSessionManager manager)
+    {
+        this.manager = manager;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        for (TransformMethodSignature sig : transformation.findMethodsWithAnnotation(CommitAfter.class))
+        {
+            transformation.advise(sig, advice);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurer.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurer.java
new file mode 100644
index 0000000..9494dd2
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurer.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateConfigurer;
+import org.hibernate.cfg.Configuration;
+
+/** Simply calls configure() to do the default Hibernate configuration.
+ */
+public final class DefaultHibernateConfigurer implements HibernateConfigurer {
+
+	public void configure(Configuration configuration) {
+		configuration.configure();
+	}
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategy.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategy.java
new file mode 100644
index 0000000..e813c9c
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategy.java
@@ -0,0 +1,133 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.internal.services.AbstractSessionPersistentFieldStrategy;
+import org.apache.tapestry.internal.services.PersistentFieldChangeImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.PersistentFieldChange;
+import org.apache.tapestry.services.PersistentFieldStrategy;
+import org.apache.tapestry.services.Request;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.metadata.ClassMetadata;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Persists Hibernate entities by storing their id in the session.
+ */
+public class EntityPersistentFieldStrategy implements PersistentFieldStrategy
+{
+    private static final Pattern KEY_PATTERN = Pattern.compile("^([^:]+):([^:]+):(.+)$");
+
+    private final PersistentFieldStrategy strategy;
+    private final Session session;
+    private final TypeCoercer typeCoercer;
+
+    public EntityPersistentFieldStrategy(Session session, TypeCoercer typeCoercer, Request request)
+    {
+        strategy = new EntityStrategy(request);
+        this.session = session;
+        this.typeCoercer = typeCoercer;
+    }
+
+    public void discardChanges(String pageName)
+    {
+        strategy.discardChanges(pageName);
+    }
+
+    public Collection<PersistentFieldChange> gatherFieldChanges(String pageName)
+    {
+        Collection<PersistentFieldChange> changes = CollectionFactory.newList();
+
+        for (PersistentFieldChange change : strategy.gatherFieldChanges(pageName))
+        {
+            if (change.getValue() == null)
+            {
+                changes.add(change);
+                continue;
+            }
+
+            String key = change.getValue().toString();
+            Matcher matcher = KEY_PATTERN.matcher(key);
+            matcher.matches();
+
+            String entityName = matcher.group(1);
+            String idClassName = matcher.group(2);
+            String stringId = matcher.group(3);
+
+            try
+            {
+                Class<?> idClass = Class.forName(idClassName);
+                Object idObj = typeCoercer.coerce(stringId, idClass);
+
+                Serializable id = Defense.cast(idObj, Serializable.class, "id");
+                Object entity = session.get(entityName, id);
+                changes.add(new PersistentFieldChangeImpl(change.getComponentId(), change.getFieldName(), entity));
+            }
+            catch (ClassNotFoundException e)
+            {
+                throw new RuntimeException(HibernateMessages.badEntityIdType(entityName, idClassName, stringId), e);
+            }
+        }
+
+        return changes;
+    }
+
+    /**
+     * Stores the entity id's as values in the form: entityName:idClass:id
+     */
+    public void postChange(String pageName, String componentId, String fieldName, Object newValue)
+    {
+        if (newValue != null)
+        {
+            try
+            {
+                String entityName = session.getEntityName(newValue);
+                ClassMetadata metadata = session.getSessionFactory().getClassMetadata(newValue.getClass());
+                Serializable id = metadata.getIdentifier(newValue, session.getEntityMode());
+                newValue = entityName + ":" + id.getClass().getCanonicalName() + ":" + typeCoercer.coerce(id,
+                                                                                                          String.class);
+
+            }
+            catch (HibernateException e)
+            {
+                throw new IllegalArgumentException(HibernateMessages.entityNotAttached(newValue), e);
+            }
+        }
+
+        strategy.postChange(pageName, componentId, fieldName, newValue);
+    }
+
+    /**
+     * We want to store the data in the session normally, we just need to control the values. We also need a separate
+     * instance so that we know it's using the right prefix for the values.
+     */
+    private static final class EntityStrategy extends AbstractSessionPersistentFieldStrategy
+    {
+
+        public EntityStrategy(Request request)
+        {
+            super("entity:", request);
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
new file mode 100644
index 0000000..fcd0bed
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
@@ -0,0 +1,94 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.hibernate.Session;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.slf4j.Logger;
+
+import java.io.Serializable;
+
+public final class HibernateEntityValueEncoder<E> implements ValueEncoder<E>
+{
+    private final Class<E> entityClass;
+
+    private final Session session;
+
+    private final TypeCoercer typeCoercer;
+
+    private final String idPropertyName;
+
+    private final PropertyAdapter propertyAdapter;
+
+    private final Logger logger;
+
+    public HibernateEntityValueEncoder(Class<E> entityClass, PersistentClass persistentClass, Session session,
+                                       PropertyAccess propertyAccess, TypeCoercer typeCoercer, Logger logger)
+    {
+        this.entityClass = entityClass;
+        this.session = session;
+        this.typeCoercer = typeCoercer;
+        this.logger = logger;
+
+        Property property = persistentClass.getIdentifierProperty();
+
+        idPropertyName = property.getName();
+
+        propertyAdapter = propertyAccess.getAdapter(this.entityClass).getPropertyAdapter(idPropertyName);
+    }
+
+
+    public String toClient(E value)
+    {
+        if (value == null) return null;
+
+        Object id = propertyAdapter.get(value);
+
+        if (id == null)
+            throw new IllegalStateException(String.format(
+                    "Entity %s has an %s property of null; this probably means that it has not been persisted yet.",
+                    value, idPropertyName));
+
+        return typeCoercer.coerce(id, String.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    public E toValue(String clientValue)
+    {
+        if (InternalUtils.isBlank(clientValue)) return null;
+
+        Object id = typeCoercer.coerce(clientValue, propertyAdapter.getType());
+
+        Serializable ser = Defense.cast(id, Serializable.class, "id");
+
+        E result = (E) session.get(entityClass, ser);
+
+        if (result == null)
+        {
+            // We don't identify the entity type in the message because the logger is based on the entity type.
+            logger.error(String.format("Unable to convert client value '%s' into an entity instance.", clientValue));
+        }
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateMessages.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateMessages.java
new file mode 100644
index 0000000..2897a6e
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateMessages.java
@@ -0,0 +1,56 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+import java.util.Collection;
+
+class HibernateMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(HibernateMessages.class);
+
+    static String startupTiming(long toConfigure, long overall)
+    {
+        return MESSAGES.format("startup-timing", toConfigure, overall);
+    }
+
+    static String entityCatalog(Collection entityNames)
+    {
+        return MESSAGES.format("entity-catalog", InternalUtils.joinSorted(entityNames));
+    }
+
+    static String configurationImmutable()
+    {
+        return MESSAGES.get("configuration-immutable");
+    }
+
+    static String badEntityIdType(String entityName, String idClassName, String id)
+    {
+        return MESSAGES.format("bad-entity-id-type", entityName, idClassName, id);
+    }
+
+    static String entityNotAttached(Object entity)
+    {
+        return MESSAGES.format("entity-not-attached", entity);
+    }
+
+    static String commitTransactionInterceptor(String serviceId, Class serviceInterface)
+    {
+        return MESSAGES.format("commit-transaction-interceptor", serviceId, serviceInterface.getName());
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionManagerImpl.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionManagerImpl.java
new file mode 100644
index 0000000..39ec2d1
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionManagerImpl.java
@@ -0,0 +1,65 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.hibernate.HibernateSessionSource;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
+public class HibernateSessionManagerImpl implements HibernateSessionManager, ThreadCleanupListener
+{
+    private final Session session;
+
+    private Transaction transaction;
+
+    public HibernateSessionManagerImpl(HibernateSessionSource source)
+    {
+        session = source.create();
+
+        transaction = session.beginTransaction();
+    }
+
+    public void abort()
+    {
+        transaction.rollback();
+        transaction.begin();
+    }
+
+    public void commit()
+    {
+        transaction.commit();
+        transaction.begin();
+    }
+
+    public Session getSession()
+    {
+        return session;
+    }
+
+    /**
+     * Rollsback the transaction at the end of the request, then closes the session. This means that any uncommitted
+     * changes are lost; code should inject the HSM and invoke {@link #commit()} after making any changes, if they
+     * should persist.
+     */
+    public void threadDidCleanup()
+    {
+        transaction.rollback();
+
+        session.close();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImpl.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImpl.java
new file mode 100644
index 0000000..8eb04ed
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImpl.java
@@ -0,0 +1,80 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateConfigurer;
+import org.apache.tapestry.hibernate.HibernateSessionSource;
+import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.cfg.Configuration;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+public class HibernateSessionSourceImpl implements HibernateSessionSource, RegistryShutdownListener
+{
+    private final SessionFactory sessionFactory;
+
+    private final Configuration configuration;
+
+    public HibernateSessionSourceImpl(Logger logger, List<HibernateConfigurer> hibernateConfigurers)
+    {
+        long startTime = System.currentTimeMillis();
+
+        Configuration configuration = new AnnotationConfiguration();
+
+        for (HibernateConfigurer configurer : hibernateConfigurers)
+            configurer.configure(configuration);
+
+        long configurationComplete = System.currentTimeMillis();
+
+        sessionFactory = configuration.buildSessionFactory();
+        this.configuration = new ImmutableConfiguration(configuration);
+
+        long factoryCreated = System.currentTimeMillis();
+
+        logger.info(HibernateMessages.startupTiming(
+                configurationComplete - startTime,
+                factoryCreated - startTime));
+
+        logger
+                .info(HibernateMessages.entityCatalog(sessionFactory.getAllClassMetadata()
+                        .keySet()));
+
+    }
+
+    public Session create()
+    {
+        return sessionFactory.openSession();
+    }
+
+    public SessionFactory getSessionFactory()
+    {
+        return sessionFactory;
+    }
+
+    public Configuration getConfiguration()
+    {
+        return configuration;
+    }
+
+    public void registryDidShutdown()
+    {
+        sessionFactory.close();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImpl.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImpl.java
new file mode 100644
index 0000000..f86d4f4
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImpl.java
@@ -0,0 +1,88 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.hibernate.HibernateTransactionDecorator;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.ioc.services.AspectInterceptorBuilder;
+
+import java.lang.reflect.Method;
+
+public class HibernateTransactionDecoratorImpl implements HibernateTransactionDecorator
+{
+    private final AspectDecorator aspectDecorator;
+
+    private final HibernateSessionManager manager;
+
+    /**
+     * The rules for advice are the same for any method: commit on success or checked exception, abort on thrown
+     * exception ... so we can use a single shared advice object.
+     */
+    private final MethodAdvice advice = new MethodAdvice()
+    {
+        public void advise(Invocation invocation)
+        {
+            try
+            {
+                invocation.proceed();
+            }
+            catch (RuntimeException ex)
+            {
+                manager.abort();
+
+                throw ex;
+            }
+
+            // For success or checked exception, commit the transaction.
+
+            manager.commit();
+        }
+    };
+
+    public HibernateTransactionDecoratorImpl(AspectDecorator aspectDecorator, HibernateSessionManager manager)
+    {
+        this.aspectDecorator = aspectDecorator;
+
+        this.manager = manager;
+    }
+
+    public <T> T build(Class<T> serviceInterface, T delegate, String serviceId)
+    {
+        Defense.notNull(serviceInterface, "serviceInterface");
+        Defense.notNull(delegate, "delegate");
+        Defense.notBlank(serviceId, "serviceId");
+
+        String description = String.format("<Hibernate Transaction interceptor for %s(%s)>",
+                                           serviceId,
+                                           serviceInterface.getName());
+
+        AspectInterceptorBuilder<T> builder = aspectDecorator.createBuilder(serviceInterface, delegate, description);
+
+        for (Method m : serviceInterface.getMethods())
+        {
+            if (m.getAnnotation(CommitAfter.class) != null)
+            {
+                builder.adviseMethod(m, advice);
+            }
+        }
+
+        return builder.build();
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/ImmutableConfiguration.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/ImmutableConfiguration.java
new file mode 100644
index 0000000..0f9e9cd
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/ImmutableConfiguration.java
@@ -0,0 +1,498 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.dom4j.Document;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.MappingException;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Mappings;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.Settings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.Mapping;
+import org.hibernate.event.EventListeners;
+import org.hibernate.mapping.AuxiliaryDatabaseObject;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
+import org.xml.sax.EntityResolver;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Delegates all method calls to another instance. Any calls that modify state or return objects that are meant to be
+ * used to change state will throw an {@link UnsupportedOperationException}. This class is specifically final because
+ * there are protected methods that cannot be called on the contained instance (because they are protected).
+ * <p/>
+ * Note that this class does not guarantee that the objects returned are mutable thus changes to the configuration are
+ * still possible.
+ */
+@SuppressWarnings("unchecked")
+final class ImmutableConfiguration extends Configuration
+{
+    private static final long serialVersionUID = -4039250481581260132L;
+
+    private final Configuration config;
+
+    public ImmutableConfiguration(Configuration configuration)
+    {
+        config = configuration;
+    }
+
+    @Override
+    protected void add(Document doc) throws MappingException
+    {
+        unsupported();
+    }
+
+    /**
+     * Throws an exception. Has a return value for convenience.
+     *
+     * @return nothing because it always throws an exception
+     */
+    private <T> T unsupported()
+    {
+        throw new UnsupportedOperationException(HibernateMessages.configurationImmutable());
+    }
+
+    @Override
+    public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject object)
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration addCacheableFile(File xmlFile) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addCacheableFile(String xmlFile) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addClass(Class persistentClass) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addDirectory(File dir) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addDocument(org.w3c.dom.Document doc) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addFile(File xmlFile) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addFile(String xmlFile) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void addFilterDefinition(FilterDefinition definition)
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration addInputStream(InputStream xmlInputStream) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addJar(File jar) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addProperties(Properties extraProperties)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addResource(String resourceName, ClassLoader classLoader) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addResource(String resourceName) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void addSqlFunction(String functionName, SQLFunction function)
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration addURL(URL url) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration addXML(String xml) throws MappingException
+    {
+        return unsupported();
+    }
+
+    /* Since this is called from the constructor of the superclass, it calls
+      * the superclass method rather than delegating to the contained instance.
+      * We could also just not override the method but for completeness I'll
+      * leave it in.
+      * It's unfortunate that Configuration isn't an interface.
+      */
+    @Override
+    public Mapping buildMapping()
+    {
+        return super.buildMapping();
+    }
+
+    @Override
+    public void buildMappings()
+    {
+        config.buildMappings();
+    }
+
+    @Override
+    public SessionFactory buildSessionFactory() throws HibernateException
+    {
+        return config.buildSessionFactory();
+    }
+
+    @Override
+    public Settings buildSettings() throws HibernateException
+    {
+        return config.buildSettings();
+    }
+
+    @Override
+    public Settings buildSettings(Properties props) throws HibernateException
+    {
+        return config.buildSettings(props);
+    }
+
+    @Override
+    public Configuration configure() throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration configure(org.w3c.dom.Document document) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration configure(File configFile) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration configure(String resource) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration configure(URL url) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Mappings createMappings()
+    {
+        return unsupported();
+    }
+
+    @Override
+    protected Configuration doConfigure(Document doc) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException
+    {
+        return unsupported();
+    }
+
+    @Override
+    protected Document findPossibleExtends()
+    {
+        return unsupported();
+    }
+
+    @Override
+    public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException
+    {
+        return config.generateDropSchemaScript(dialect);
+    }
+
+    @Override
+    public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException
+    {
+        return config.generateSchemaCreationScript(dialect);
+    }
+
+    @Override
+    public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
+            throws HibernateException
+    {
+        return config.generateSchemaUpdateScript(dialect, databaseMetadata);
+    }
+
+    @Override
+    public PersistentClass getClassMapping(String entityName)
+    {
+        return config.getClassMapping(entityName);
+    }
+
+    @Override
+    public Iterator getClassMappings()
+    {
+        return config.getClassMappings();
+    }
+
+    @Override
+    public Collection getCollectionMapping(String role)
+    {
+        return config.getCollectionMapping(role);
+    }
+
+    @Override
+    public Iterator getCollectionMappings()
+    {
+        return config.getCollectionMappings();
+    }
+
+    @Override
+    public EntityNotFoundDelegate getEntityNotFoundDelegate()
+    {
+        return config.getEntityNotFoundDelegate();
+    }
+
+    @Override
+    public EntityResolver getEntityResolver()
+    {
+        return config.getEntityResolver();
+    }
+
+    @Override
+    public EventListeners getEventListeners()
+    {
+        return config.getEventListeners();
+    }
+
+    @Override
+    public Map getFilterDefinitions()
+    {
+        return config.getFilterDefinitions();
+    }
+
+    @Override
+    public Map getImports()
+    {
+        return config.getImports();
+    }
+
+    @Override
+    public Interceptor getInterceptor()
+    {
+        return config.getInterceptor();
+    }
+
+    @Override
+    public Map getNamedQueries()
+    {
+        return config.getNamedQueries();
+    }
+
+    @Override
+    public Map getNamedSQLQueries()
+    {
+        return config.getNamedSQLQueries();
+    }
+
+    @Override
+    public NamingStrategy getNamingStrategy()
+    {
+        return config.getNamingStrategy();
+    }
+
+    @Override
+    public Properties getProperties()
+    {
+        return config.getProperties();
+    }
+
+    @Override
+    public String getProperty(String propertyName)
+    {
+        return config.getProperty(propertyName);
+    }
+
+    @Override
+    public Map getSqlFunctions()
+    {
+        return config.getSqlFunctions();
+    }
+
+    @Override
+    public Map getSqlResultSetMappings()
+    {
+        return config.getSqlResultSetMappings();
+    }
+
+    @Override
+    public Iterator getTableMappings()
+    {
+        return config.getTableMappings();
+    }
+
+    @Override
+    public Configuration mergeProperties(Properties properties)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
+            throws MappingException
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy) throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String region)
+            throws MappingException
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy)
+            throws MappingException
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void setEntityNotFoundDelegate(EntityNotFoundDelegate entityNotFoundDelegate)
+    {
+        unsupported();
+    }
+
+    @Override
+    public void setEntityResolver(EntityResolver entityResolver)
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration setInterceptor(Interceptor interceptor)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void setListener(String type, Object listener)
+    {
+        unsupported();
+    }
+
+    @Override
+    public void setListeners(String type, Object[] listeners)
+    {
+        unsupported();
+    }
+
+    @Override
+    public void setListeners(String type, String[] listenerClasses)
+    {
+        unsupported();
+    }
+
+    @Override
+    public Configuration setNamingStrategy(NamingStrategy namingStrategy)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration setProperties(Properties properties)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public Configuration setProperty(String propertyName, String value)
+    {
+        return unsupported();
+    }
+
+    @Override
+    public void validateSchema(Dialect dialect, DatabaseMetadata databaseMetadata) throws HibernateException
+    {
+        config.validateSchema(dialect, databaseMetadata);
+    }
+
+    @Override
+    public String toString()
+    {
+        return "ImmutableConfiguration[" + config + "]";
+	}
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/PackageNameHibernateConfigurer.java b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/PackageNameHibernateConfigurer.java
new file mode 100644
index 0000000..80982f6
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/PackageNameHibernateConfigurer.java
@@ -0,0 +1,67 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateConfigurer;
+import org.apache.tapestry.hibernate.HibernateEntityPackageManager;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.cfg.Configuration;
+
+/**
+ * Adds entity classes from a given set of packages to the configuration.
+ */
+public final class PackageNameHibernateConfigurer implements HibernateConfigurer
+{
+    private final HibernateEntityPackageManager packageManager;
+
+    private final ClassNameLocator classNameLocator;
+
+    public PackageNameHibernateConfigurer(HibernateEntityPackageManager packageManager,
+                                          ClassNameLocator classNameLocator)
+    {
+        this.packageManager = packageManager;
+        this.classNameLocator = classNameLocator;
+    }
+
+    public void configure(Configuration configuration)
+    {
+        Defense.cast(configuration, AnnotationConfiguration.class, "configuration");
+        AnnotationConfiguration cfg = (AnnotationConfiguration) configuration;
+
+        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+        for (String packageName : packageManager.getPackageNames())
+        {
+            cfg.addPackage(packageName);
+
+            for (String className : classNameLocator.locateClassNames(packageName))
+            {
+                try
+                {
+                    Class entityClass = contextClassLoader.loadClass(className);
+
+                    cfg.addAnnotatedClass(entityClass);
+                }
+                catch (ClassNotFoundException ex)
+                {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/main/resources/org/apache/tapestry/internal/hibernate/HibernateStrings.properties b/hlship-20080520/tapestry-hibernate/src/main/resources/org/apache/tapestry/internal/hibernate/HibernateStrings.properties
new file mode 100644
index 0000000..27b489d
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/main/resources/org/apache/tapestry/internal/hibernate/HibernateStrings.properties
@@ -0,0 +1,20 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+startup-timing=Hibernate startup: %,d ms to configure, %,d ms overall.
+entity-catalog=Configured Hibernate entities: %s
+configuration-immutable=The Hibernate configuration is now immutable since the SessionFactory has already been created.
+bad-entity-id-type=Failed to load the entity id class while loading a persisted entity. entity: %s, id class: %s, id: %s
+entity-not-attached=Failed persisting an entity in the session. Only entities attached to a Hibernate Session can be persisted. entity: %s
+commit-transaction-interceptor=<Hibernate Transaction interceptor for %s(%s)>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/site/apt/conf.apt b/hlship-20080520/tapestry-hibernate/src/site/apt/conf.apt
new file mode 100644
index 0000000..2637f59
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/site/apt/conf.apt
@@ -0,0 +1,51 @@
+  ----
+  Configuration
+  ----
+  
+Configuring Hibernate
+
+  The Tapestry Hibernate Library is responsible for configuring Hibernate for you. This is done in a just-in-time manner, the first time
+  a Hibernate Session is required.
+  
+  One way to configure hibernate is to create a <<<hibernate.cfg.xml>>> file and place it in the root of your application (i.e., under src/main/resources).  Most Hibernate-specific
+  configuration occurs in this file. Another way is to contribute objects that perform configuration (such as setting event listeners). Example:
+  
++----+
+public static void contributeHibernateSessionSource(OrderedConfiguration<HibernateConfigurer> config)
+{
+  config.add("Widget", new WidgetHibernateConfigurer());
+}
++----+
+
+  Note that the configuration is an OrderedConfiguration. The library contributes two configurers by default:
+  
+   * <<Default>> - performs default hibernate configuration
+   
+   * <<PackageName>> - loads entities by package name as contributed to the HibernateEntityPackageManager service
+  
+  For each package contributed the library will:
+  
+  * {{{http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/cfg/AnnotationConfiguration.html#addPackage(java.lang.String)}Add the package to the configuration}},
+    which will load annotations from the package-info class within the named package, if present.
+    
+  * Every Java class in the package (or any subpackage) will be {{{http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/cfg/AnnotationConfiguration.html#addAnnotatedClass(java.lang.Class)}added as an annotated class}}.
+    This excludes inner classes, but includes all other classes.
+  
+  []
+  
+  By default, the package <application-root-package>.entities is scanned as described above. If you have additional packages containing 
+  entities, you must 
+  {{{../tapestry-ioc/configuration.html}contribute}} them to the tapestry.hibernate.HibernateEntityPackageManager 
+  service configuration.
+  
+  Example:
+  
++----+
+public static void contributeHibernateEntityPackageManager(Configuration<String> configuration)
+{
+  configuration.add("org.example.myapp.domain");
+} 
++----+
+
+  You may add as many packages in this manner as you wish. This option is most often used when the entities themselves are contained in a library included
+  within an application, rather than part of the application directly.
diff --git a/hlship-20080520/tapestry-hibernate/src/site/apt/index.apt b/hlship-20080520/tapestry-hibernate/src/site/apt/index.apt
new file mode 100644
index 0000000..2dbf3d9
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/site/apt/index.apt
@@ -0,0 +1,33 @@
+ ----
+ About Tapestry/Hibernate
+ ----
+
+Tapestry/Hibernate Integration Library
+
+  This library integrates into Tapestry 5 to provide out-of-the-box support for using Hibernate 3 as the backend for
+  normal CRUD style applications.
+  
+  For at least, the first pass, this will represent access to the native Hibernate interfaces, exposed in a
+  thread-safe manner, within a <session-per-request> strategy.
+  
+  A number of more esoteric ideas in Hibernate are not supported, including nested transactions and supporting multiple
+  persistence units. 
+  
+Licensing Issues
+
+  Hibernate is licensed under the Lesser GNU Public License. This is more restrictive license than the Apache Software
+  License used by the rest of Tapestry. The restrictions mostly apply to redistricuting Hibernate, especially in
+  any altered form, and will likely be irrelvant to the vast majority of users, but you should be aware.
+  
+  This library is compiled against version <<3.2.2.ga>> of Hibernate, but does not establish that as a dependency (it
+  uses the "provided" scope);
+  you will have to manually setup a dependency against your preferred version of Hibernate in your project's Maven POM.
+  Once the library has stabilized, a Maven archetype (project template) will be created to help with this step.
+
+What's New?
+
+  * Transactions are now <aborted> (no longer <committed>) at the end of each request: you must now
+    explicitly commit the transaction if changes are to be saved.
+
+  * The new @CommitAfter annotation for component and service methods can now commit the transaction
+    automatically after the method is invoked.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/site/apt/userguide.apt b/hlship-20080520/tapestry-hibernate/src/site/apt/userguide.apt
new file mode 100644
index 0000000..a9f4a59
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/site/apt/userguide.apt
@@ -0,0 +1,160 @@
+  ----
+  User Guide
+  ----
+  
+Entity value encoding
+
+  Value encoders are automatically created for all mapped Hibernate entity types. This is done by encoding the entity as it's 
+  id (coerced to a String) and decoding the entity by looking it up in the Hibernate Session using the encoded id. Consider
+  the following example:
+  
++----+
+public class ViewPerson
+{
+  @Property
+  private Person person;
+  
+  void onActivate(Person person)
+  {
+    this.person = person;
+  }
+  
+  Person onPassivate()
+  {
+    return person;
+  }
+}
++----+   
+
++----+
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+  The person's name is: ${person.name}
+</body>
+</html>
++----+
+
+  Accessing the page as <</viewperson/152>> would load the Person entity with id 152 and use that as the page context.
+
+Using @Persist with entities
+
+  If you wish to persist an entity in the session, you may use the "entity" persistence strategy:
+  
++----+
+public class ViewPerson
+{
+  @Persist("entity")
+  @Property
+  private Person person;
+  
+  void onActivate(Person person)
+  {
+    this.person = person;
+  }
+  
+}
++----+   
+  
+  This persistence strategy works with any Hibernate entity that is associated with a valid Hibernate Session by persisting only the id
+  of the entity. Notice that no onPassivate() method is needed; when the page renders the entity is loaded by the id stored in the session.
+
+Committing Changes
+
+  All Hibernate operations occur in a transaction, but that transaction is aborted at the end of each request; thus
+  any changes you make will be <lost> unless the transaction is committed.
+
+  The correct way to commit the transaction is via the @CommitAfter annotation:
+
++----+
+public class EditPerson
+{
+  @Persist("entity")
+  @Property
+  private Person person;
+
+  @InjectPage
+  private PersonIndex personIndex;
+
+  void onActivate(Person person)
+  {
+    this.person = person;
+  }
+
+  Object onPassivate() { return person; }
+
+  @CommitAfter
+  Object onSuccess()
+  {
+    return personIndex;
+  }
+}
++----+
+
+  In this example, the Person object may be updated by a form; the form's success event handler method,
+  onSuccess() has the @CommitAfter annotation.
+
+  Behind the scenes, the @CommitAfter annotation causes the
+  {{{../apidocs/org/apache/tapestry/hibernate/HibernateSessionManager.html}HibernateSessionManager}}'s commit() method to be
+  executed before the method returns.
+
+  The transaction will be committed when the method completes normally.
+
+  The transaction will be <aborted> if the method throws a RuntimeException.
+
+  The transaction will be <<committed>> if the method throws a <checked> exception (one listed in the throws clause of the method).
+
+Managing Transactions using DAOs
+
+   As your application grows, you will likely create a Data Access Object layer between your pages and the Hibernate APIs.
+
+   The @CommitAfter annotation can be useful there as well.
+
+   You may use @CommitAfter on method of your service interface, then use a decorator to provide the transaction
+   management logic.
+
+   First definine your DAO's service interface:
+
++---+
+public interface PersonDAO
+{
+  Person findByName(String name);
+
+  @CommitAfter
+  void add(Person newPerson);
+
+  @CommitAfter
+  void update(Person person);
+
+  @CommitAfter
+  void delete(Person person);
+}
++---+
+
+   Next, define your service in your application's Module class:
+
++---+
+public class AppModule
+{
+   public static void bind(ServiceBinder binder)
+   {
+      binder.bind(PersonDAO.class, PersonDAOImpl.class);
+   }
+}
++---+
+
+   Finally, add a decorator method to your module:
+
++---+
+    @Match("*DAO")
+    public static <T> T decorateTransactionally(HibernateTransactionDecorator decorator, Class<T> serviceInterface,
+                                                T delegate,
+                                                String serviceId)
+    {
+        return decorator.build(serviceInterface, delegate, serviceId);
+    }
++---+
+
+  This one is configured to match against any service whose id ends with "DAO", such as "PersonDAO".
+  The HibernateTransactionDecorator
+  service builds an interceptor around the delegate (which is, basically, the service) that understands
+  the @CommitAfter annotation.  Methods that don't have @CommitAfter pass right on through unchanged.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/site/site.xml b/hlship-20080520/tapestry-hibernate/src/site/site.xml
new file mode 100644
index 0000000..61f9ba1
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/site/site.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Hibernate Integration">
+  <bannerLeft>
+    <name>Tapestry 5</name>
+    <href>http://tapestry.apache.org/tapestry5/</href>
+    <src>images/tapestry_banner.gif</src>
+  </bannerLeft>
+  <bannerRight>
+    <name>Apache</name>
+    <href>http://www.apache.org</href>
+    <src>images/asf_logo_wide.gif</src>
+  </bannerRight>
+  <skin>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>maven-skin</artifactId>
+    <version>1.1</version>
+  </skin>
+  
+  <publishDate format="dd MMM yyyy" />
+  
+  <body>
+
+    
+    <menu name="Quick Links">
+      <item name="About" href="index.html"/>
+      <item name="Configuration" href="conf.html"/>
+      <item name="User guide" href="userguide.html" />
+      <item name="Download" href="http://tapestry.apache.org/download.html"/>
+    </menu>
+        
+    <menu ref="reports"/>
+    
+  </body>
+</project>
diff --git a/hlship-20080520/tapestry-hibernate/src/test/conf/testng.xml b/hlship-20080520/tapestry-hibernate/src/test/conf/testng.xml
new file mode 100644
index 0000000..aa4db0f
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/conf/testng.xml
@@ -0,0 +1,30 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Hibernate" parallel="false" thread-count="10" annotations="1.5" verbose="2">
+  <parameter name="tapestry.integration-webapp" value="src/test/webapp"/>
+  <test name="Tapestry Hibernate Internal APIs">
+    <packages>
+      <package name="org.apache.tapestry.internal.hibernate"/>
+    </packages>
+  </test>
+  <test name="Tapestry Hibernate Integration Tests">
+    <packages>
+      <package name="org.apache.tapestry.hibernate.integration"/>
+    </packages>
+  </test>  
+</suite>
diff --git a/hlship-20080520/tapestry-hibernate/src/test/conf/webdefault.xml b/hlship-20080520/tapestry-hibernate/src/test/conf/webdefault.xml
new file mode 100644
index 0000000..34083c9
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/conf/webdefault.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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">
+
+    <description>
+        Default web.xml file.
+        This file is applied to a Web application before it's own WEB_INF/web.xml file
+    </description>
+
+
+    <!-- ==================================================================== -->
+    <!-- Context params to control Session Cookies                            -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <!-- UNCOMMENT TO ACTIVATE
+    <context-param>
+      <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>
+      <param-value>127.0.0.1</param-value>
+    </context-param>
+
+    <context-param>
+      <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
+      <param-value>/</param-value>
+    </context-param>
+
+    <context-param>
+      <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>
+      <param-value>-1</param-value>
+    </context-param>
+    -->
+
+
+    <!-- ==================================================================== -->
+    <!-- The default servlet.                                                 -->
+    <!-- This servlet, normally mapped to /, provides the handling for static -->
+    <!-- content, OPTIONS and TRACE methods for the context.                  -->
+    <!-- The following initParameters are supported:                          -->
+    <!--                                                                      -->
+    <!--   acceptRanges     If true, range requests and responses are         -->
+    <!--                    supported                                         -->
+    <!--                                                                      -->
+    <!--   dirAllowed       If true, directory listings are returned if no    -->
+    <!--                    welcome file is found. Else 403 Forbidden.        -->
+    <!--                                                                      -->
+    <!--   putAllowed       If true, the PUT method is allowed                -->
+    <!--                                                                      -->
+    <!--   delAllowed       If true, the DELETE method is allowed             -->
+    <!--                                                                      -->
+    <!--   redirectWelcome  If true, redirect welcome file requests           -->
+    <!--                    else use request dispatcher forwards              -->
+    <!--                                                                      -->
+    <!--   minGzipLength    If set to a positive integer, then static content -->
+    <!--                    larger than this will be served as gzip content   -->
+    <!--                    encoded if a matching resource is found ending    -->
+    <!--                    with ".gz"                                        -->
+    <!--                                                                      -->
+    <!--   resoureBase      Can be set to replace the context resource base   -->
+    <!--                                                                      -->
+    <!--   relativeResourceBase                                               -->
+    <!--                    Set with a pathname relative to the base of the   -->
+    <!--                    servlet context root. Useful for only serving     -->
+    <!--                    static content from only specific subdirectories. -->
+    <!--                                                                      -->
+    <!-- The MOVE method is allowed if PUT and DELETE are allowed             -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+    <servlet>
+        <servlet-name>default</servlet-name>
+        <servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>
+        <init-param>
+            <param-name>acceptRanges</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>dirAllowed</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>putAllowed</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>delAllowed</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>redirectWelcome</param-name>
+            <param-value>false</param-value>
+        </init-param>
+        <init-param>
+            <param-name>minGzipLength</param-name>
+            <param-value>8192</param-value>
+        </init-param>
+        <load-on-startup>0</load-on-startup>
+    </servlet>
+
+
+    <servlet-mapping>
+        <servlet-name>default</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+
+    <!-- ==================================================================== -->
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+
+
+    <!-- ==================================================================== -->
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+        <welcome-file>index.htm</welcome-file>
+    </welcome-file-list>
+
+    <!-- ==================================================================== -->
+    <locale-encoding-mapping-list>
+        <locale-encoding-mapping>
+            <locale>ar</locale>
+            <encoding>ISO-8859-6</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>be</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>bg</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ca</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>cs</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>da</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>de</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>el</locale>
+            <encoding>ISO-8859-7</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>en</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>es</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>et</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fi</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>fr</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hr</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>hu</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>is</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>it</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>iw</locale>
+            <encoding>ISO-8859-8</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ja</locale>
+            <encoding>Shift_JIS</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ko</locale>
+            <encoding>EUC-KR</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lt</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>lv</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>mk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>nl</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>no</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>pt</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ro</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>ru</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sh</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sk</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sl</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sq</locale>
+            <encoding>ISO-8859-2</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sr</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>sv</locale>
+            <encoding>ISO-8859-1</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>tr</locale>
+            <encoding>ISO-8859-9</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>uk</locale>
+            <encoding>ISO-8859-5</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh</locale>
+            <encoding>GB2312</encoding>
+        </locale-encoding-mapping>
+        <locale-encoding-mapping>
+            <locale>zh_TW</locale>
+            <encoding>Big5</encoding>
+        </locale-encoding-mapping>
+    </locale-encoding-mapping-list>
+
+
+</web-app>
+
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
new file mode 100644
index 0000000..ce0c436
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
@@ -0,0 +1,110 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.hibernate.integration;
+
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+@Test(sequential = true, groups = "integration")
+public class TapestryHibernateIntegrationTests extends AbstractIntegrationTestSuite
+{
+    public TapestryHibernateIntegrationTests()
+    {
+        super("src/test/webapp");
+    }
+
+    public void valueencode_all_entity_types() throws Exception
+    {
+        open("/encodeentities");
+
+        assertEquals(0, getText("//span[@id='name']").length());
+
+        // need to create an entity in order to link with one
+        clickAndWait("link=create an entity");
+        assertEquals("name", getText("//span[@id='name']"));
+
+        // should return null for missing objects
+        open("/encodeentities/9999");
+        assertEquals(0, getText("//span[@id='name']").length());
+    }
+
+    public void persist_entities()
+    {
+        open("/persistentity");
+        assertEquals(0, getText("//span[@id='name']").length());
+
+        clickAndWait("link=create entity");
+        assertText("//span[@id='name']", "name");
+
+        // shouldn't save the change to the name because it's reloaded every time
+        clickAndWait("link=change the name");
+        assertText("//span[@id='name']", "name");
+
+        // can set back to null
+        clickAndWait("link=set to null");
+        assertEquals(getText("//span[@id='name']").length(), 0);
+
+        // deleting an entity that is still persisted. just remove the entity from the session if it's not found.
+        clickAndWait("link=create entity");
+        assertText("//span[@id='name']", "name");
+        clickAndWait("link=delete");
+        assertEquals(getText("//span[@id='name']").length(), 0);
+
+        // transient objects cannot be persisted
+        clickAndWait("link=set to transient");
+        assertTextPresent("Error persisting");
+    }
+
+    /**
+     * TAPESTRY-2244
+     */
+    public void using_cached_with_form()
+    {
+        open("/cachedform");
+        assertTextSeries("name_%d", 0);
+
+        type("name", "name1");
+        clickAndWait(SUBMIT);
+        assertTextSeries("name_%d", 0, "name1");
+
+        type("name", "name2");
+        clickAndWait(SUBMIT);
+        assertTextSeries("name_%d", 0, "name1", "name2");
+    }
+
+    public void commit_after_on_component_methods()
+    {
+        open("/");
+
+        clickAndWait("link=CommitAfter Demo");
+
+        assertText("name", "Diane");
+
+        clickAndWait("link=change name");
+
+        assertText("name", "Frank");
+
+        clickAndWait("link=runtime exception");
+
+        assertText("name", "Frank");
+
+        clickAndWait("link=checked exception");
+
+        assertText("name", "Troy");
+
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurerFilterTest.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurerFilterTest.java
new file mode 100644
index 0000000..0b78cfd
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/DefaultHibernateConfigurerFilterTest.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+
+import org.hibernate.cfg.Configuration;
+import org.testng.annotations.Test;
+
+@Test
+public class DefaultHibernateConfigurerFilterTest {
+	public void testConfigure() throws Exception {
+		Configuration config = createMock(Configuration.class);
+		expect(config.configure()).andReturn(config);
+		
+		replay(config);
+		new DefaultHibernateConfigurer().configure(config);
+		verify(config);
+	}
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategyTest.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategyTest.java
new file mode 100644
index 0000000..0b9d770
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/EntityPersistentFieldStrategyTest.java
@@ -0,0 +1,36 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.test.TapestryTestCase;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.testng.annotations.Test;
+
+@Test
+public class EntityPersistentFieldStrategyTest extends TapestryTestCase {
+	public void not_an_entity() {
+		Session session = newMock(Session.class);
+		EntityPersistentFieldStrategy strategy = new EntityPersistentFieldStrategy(session, null, null);
+		
+		expect(session.getEntityName("foo")).andThrow(new HibernateException("error"));
+		replay();
+		try {
+			strategy.postChange(null, null, null, "foo");
+			fail("did not throw");
+		} catch (IllegalArgumentException e) { }
+		verify();		
+	}
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoderTest.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoderTest.java
new file mode 100644
index 0000000..afdd246
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoderTest.java
@@ -0,0 +1,118 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.hibernate.Session;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.RootClass;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class HibernateEntityValueEncoderTest extends IOCTestCase
+{
+    private Registry registry;
+    private PropertyAccess access;
+    private TypeCoercer typeCoercer;
+
+    @BeforeClass
+    public void setup()
+    {
+        registry = buildRegistry();
+
+        access = registry.getService(PropertyAccess.class);
+        typeCoercer = registry.getService(TypeCoercer.class);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        registry.shutdown();
+
+        registry = null;
+        access = null;
+        typeCoercer = null;
+    }
+
+    @Test
+    public void to_client_id_null()
+    {
+        Session session = mockSession();
+        Logger logger = mockLogger();
+
+        replay();
+
+        RootClass persistentClass = new RootClass();
+        Property idProperty = new Property();
+        idProperty.setName("id");
+        persistentClass.setIdentifierProperty(idProperty);
+        SampleEntity entity = new SampleEntity();
+
+        HibernateEntityValueEncoder<SampleEntity> encoder = new HibernateEntityValueEncoder<SampleEntity>(
+                SampleEntity.class, persistentClass, session, access, typeCoercer, logger);
+
+
+        try
+        {
+            encoder.toClient(entity);
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertMessageContains(ex, "Entity org.apache.tapestry.internal.hibernate.SampleEntity",
+                                  "has an id property of null");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void to_value_not_found()
+    {
+        Session session = mockSession();
+        Logger logger = mockLogger();
+
+        expect(session.get(SampleEntity.class, new Long(12345))).andReturn(null);
+
+        logger.error("Unable to convert client value '12345' into an entity instance.");
+
+        replay();
+
+        RootClass persistentClass = new RootClass();
+        Property idProperty = new Property();
+        idProperty.setName("id");
+        persistentClass.setIdentifierProperty(idProperty);
+        SampleEntity entity = new SampleEntity();
+
+        HibernateEntityValueEncoder<SampleEntity> encoder = new HibernateEntityValueEncoder<SampleEntity>(
+                SampleEntity.class, persistentClass, session, access, typeCoercer, logger);
+
+
+        assertNull(encoder.toValue("12345"));
+
+        verify();
+
+    }
+
+    protected final Session mockSession()
+    {
+        return newMock(Session.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImplTest.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImplTest.java
new file mode 100644
index 0000000..7353022
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateSessionSourceImplTest.java
@@ -0,0 +1,96 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateConfigurer;
+import org.apache.tapestry.hibernate.HibernateEntityPackageManager;
+import org.apache.tapestry.hibernate.HibernateSessionSource;
+import org.apache.tapestry.ioc.internal.services.ClassNameLocatorImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.example.app0.entities.User;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.metadata.ClassMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+public class HibernateSessionSourceImplTest extends TapestryTestCase
+{
+    private final Logger log = LoggerFactory
+            .getLogger("tapestry.hibernate.HibernateSessionSourceTest");
+
+    @Test
+    public void startup_without_packages()
+    {
+        Collection<String> packageNames = CollectionFactory.newList(
+                "org.example.myapp.entities",
+                "org.example.app0.entities");
+        HibernateEntityPackageManager packageManager = newMock(HibernateEntityPackageManager.class);
+        expect(packageManager.getPackageNames()).andReturn(packageNames);
+
+        List<HibernateConfigurer> filters = Arrays.asList(
+                new DefaultHibernateConfigurer(),
+                new PackageNameHibernateConfigurer(packageManager, new ClassNameLocatorImpl()));
+
+        replay();
+        HibernateSessionSource source = new HibernateSessionSourceImpl(log, filters);
+
+        Session session = source.create();
+        assertNotNull(session);
+
+        // make sure it found the entity in the package
+        ClassMetadata meta = session.getSessionFactory().getClassMetadata(User.class);
+        assertEquals(meta.getEntityName(), "org.example.app0.entities.User");
+
+        verify();
+    }
+
+    @Test
+    public void get_configuration()
+    {
+        HibernateConfigurer configurer = new HibernateConfigurer()
+        {
+            public void configure(Configuration configuration)
+            {
+                configuration.setProperty("foo", "bar");
+                configuration.configure();
+            }
+        };
+        HibernateSessionSource source = new HibernateSessionSourceImpl(log, Arrays
+                .asList(configurer));
+
+        Configuration config = source.getConfiguration();
+        assertNotNull(config);
+        assertEquals("bar", config.getProperty("foo"));
+
+        // configuration should be immutable
+        try
+        {
+            config.setProperty("hibernate.dialect", "foo");
+            fail("did not throw");
+        }
+        catch (UnsupportedOperationException e)
+        {
+            assertTrue(e.getMessage().contains("immutable"));
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImplTest.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImplTest.java
new file mode 100644
index 0000000..cf51699
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/HibernateTransactionDecoratorImplTest.java
@@ -0,0 +1,267 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.hibernate.HibernateTransactionDecorator;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.ioc.IOCUtilities;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.sql.SQLException;
+
+@SuppressWarnings({ "ThrowableInstanceNeverThrown" })
+public class HibernateTransactionDecoratorImplTest extends TapestryTestCase
+{
+    private Registry registry;
+
+    private AspectDecorator aspectDecorator;
+
+    @BeforeClass
+    public void setup()
+    {
+        registry = IOCUtilities.buildDefaultRegistry();
+
+        aspectDecorator = registry.getService(AspectDecorator.class);
+    }
+
+
+    @AfterClass
+    public void shutdown()
+    {
+        registry.shutdown();
+
+        aspectDecorator = null;
+        registry = null;
+    }
+
+    @Test
+    public void undecorated()
+    {
+        VoidService delegate = newMock(VoidService.class);
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        VoidService interceptor = decorator.build(VoidService.class, delegate, "foo.Bar");
+
+        delegate.undecorated();
+
+        replay();
+        interceptor.undecorated();
+        verify();
+
+        assertToString(interceptor);
+    }
+
+    @Test
+    public void void_method()
+    {
+        VoidService delegate = newMock(VoidService.class);
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        VoidService interceptor = decorator.build(VoidService.class, delegate, "foo.Bar");
+
+        delegate.voidMethod();
+        manager.commit();
+
+        replay();
+        interceptor.voidMethod();
+        verify();
+
+        assertToString(interceptor);
+    }
+
+    @Test
+    public void void_method_with_param()
+    {
+        VoidService delegate = newMock(VoidService.class);
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        VoidService interceptor = decorator.build(VoidService.class, delegate, "foo.Bar");
+
+        delegate.voidMethodWithParam(777);
+        manager.commit();
+
+        replay();
+        interceptor.voidMethodWithParam(777);
+        verify();
+
+        assertToString(interceptor);
+    }
+
+    @Test
+    public void runtime_exception_will_abort_transaction() throws Exception
+    {
+        Performer delegate = newMock(Performer.class);
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        RuntimeException re = new RuntimeException("Unexpected.");
+
+        delegate.perform();
+        setThrowable(re);
+        manager.abort();
+
+        replay();
+
+        Performer interceptor = decorator.build(Performer.class, delegate, "foo.Bar");
+
+        try
+        {
+            interceptor.perform();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertSame(ex, re);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void checked_exception_will_commit_transaction() throws Exception
+    {
+        Performer delegate = newMock(Performer.class);
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        SQLException se = new SQLException("Checked.");
+
+        delegate.perform();
+        setThrowable(se);
+        manager.commit();
+
+        replay();
+
+        Performer interceptor = decorator.build(Performer.class, delegate, "foo.Bar");
+
+        try
+        {
+            interceptor.perform();
+            unreachable();
+        }
+        catch (SQLException ex)
+        {
+            assertSame(ex, se);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void return_type_method()
+    {
+        ReturnTypeService delegate = newTestService();
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        ReturnTypeService interceptor = decorator.build(ReturnTypeService.class, delegate, "foo.Bar");
+
+        delegate.returnTypeMethod();
+
+        manager.commit();
+
+        replay();
+        assertEquals(interceptor.returnTypeMethod(), "Foo");
+        verify();
+
+    }
+
+    @Test
+    public void return_type_method_with_param()
+    {
+        ReturnTypeService delegate = newTestService();
+        HibernateSessionManager manager = newMock(HibernateSessionManager.class);
+        HibernateTransactionDecorator decorator = newHibernateSessionManagerDecorator(manager);
+        ReturnTypeService interceptor = decorator.build(ReturnTypeService.class, delegate, "foo.Bar");
+
+        delegate.returnTypeMethodWithParam(5, 3);
+
+        manager.commit();
+
+        replay();
+        assertEquals(interceptor.returnTypeMethodWithParam(5, 3), 8);
+        verify();
+
+        assertEquals(
+                interceptor.toString(),
+                "Baz");
+    }
+
+    private HibernateTransactionDecorator newHibernateSessionManagerDecorator(HibernateSessionManager manager)
+    {
+        return new HibernateTransactionDecoratorImpl(aspectDecorator, manager);
+    }
+
+    private void assertToString(VoidService interceptor)
+    {
+        assertEquals(
+                interceptor.toString(),
+                "<Hibernate Transaction interceptor for foo.Bar(" + getClass().getName() + "$VoidService)>");
+    }
+
+    private ReturnTypeService newTestService()
+    {
+        return new ReturnTypeService()
+        {
+
+            public String returnTypeMethod()
+            {
+                return "Foo";
+            }
+
+            public int returnTypeMethodWithParam(int first, int second)
+            {
+                return first + second;
+            }
+
+            public String toString()
+            {
+                return "Baz";
+            }
+
+        };
+    }
+
+    public interface ReturnTypeService
+    {
+        @CommitAfter
+        String returnTypeMethod();
+
+        @CommitAfter
+        int returnTypeMethodWithParam(int first, int second);
+
+        String toString();
+    }
+
+    public interface VoidService
+    {
+        void undecorated();
+
+        @CommitAfter
+        void voidMethod();
+
+        @CommitAfter
+        void voidMethodWithParam(long id);
+    }
+
+    public interface Performer
+    {
+        @CommitAfter
+        void perform() throws SQLException;
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/SampleEntity.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/SampleEntity.java
new file mode 100644
index 0000000..5c6ba74
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/apache/tapestry/internal/hibernate/SampleEntity.java
@@ -0,0 +1,38 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * Fake entity used by {@link org.apache.tapestry.internal.hibernate.HibernateEntityValueEncoderTest}.
+ */
+@Entity
+public class SampleEntity
+{
+    @Id
+    private Long id;
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
new file mode 100644
index 0000000..a6fb6ab
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
@@ -0,0 +1,89 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity
+public class User
+{
+	// NOTE: Hibernate doesn't understand the '_' syntax. It will end up putting underscores on all the properties
+    @Id @GeneratedValue
+    private Long id;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String email;
+
+    private String encodedPassword;
+
+    @Version
+    private int version;
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public String getEncodedPassword()
+    {
+        return encodedPassword;
+    }
+
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    public int getVersion()
+    {
+        return version;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    public void setEncodedPassword(String encodedPassword)
+    {
+        this.encodedPassword = encodedPassword;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CachedForm.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CachedForm.java
new file mode 100644
index 0000000..a31ad79
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CachedForm.java
@@ -0,0 +1,62 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.pages;
+
+import org.apache.tapestry.annotation.Cached;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.example.app0.entities.User;
+import org.hibernate.Session;
+
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class CachedForm
+{
+    @Property
+    private String name;
+
+    @Property
+    private User user;
+
+    @Property
+    private int index;
+
+    @Inject
+    private Session session;
+
+    @Inject
+    private HibernateSessionManager manager;
+
+    void onSuccess()
+    {
+        User user = new User();
+        user.setFirstName(name);
+
+        session.save(user);
+
+        manager.commit();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Cached
+    public List<User> getUsers()
+    {
+        return session.createQuery("from User").list();
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CommitAfterDemo.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CommitAfterDemo.java
new file mode 100644
index 0000000..bf8ada5
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/CommitAfterDemo.java
@@ -0,0 +1,82 @@
+package org.example.app0.pages;
+
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.example.app0.entities.User;
+
+import java.sql.SQLException;
+
+/**
+ * Demos the CommitAfter annotation on component methods.
+ */
+public class CommitAfterDemo
+{
+    private User user;
+
+    void onActivate(User user)
+    {
+        this.user = user;
+    }
+
+    Object onPassivate()
+    {
+        return user;
+    }
+
+    public User getUser()
+    {
+        return user;
+    }
+
+    public void setUser(User user)
+    {
+        this.user = user;
+    }
+
+
+    @CommitAfter
+    void onChangeName()
+    {
+        user.setFirstName("Frank");
+    }
+
+    @CommitAfter
+    void doChangeNameWithRuntimeException()
+    {
+        user.setFirstName("Bill");
+
+        throw new RuntimeException("To avoid commit.");
+    }
+
+    void onChangeNameWithRuntimeException()
+    {
+        try
+        {
+            doChangeNameWithRuntimeException();
+        }
+        catch (Exception ex)
+        {
+            // Ignore
+        }
+    }
+
+    @CommitAfter
+    void doChangeNameWithCheckedException() throws SQLException
+
+    {
+        user.setFirstName("Troy");
+
+        throw new SQLException("Doesn't matter.");
+    }
+
+    void onChangeNameWithCheckedException()
+    {
+        try
+        {
+            doChangeNameWithCheckedException();
+        }
+        catch (Exception ex)
+        {
+            // Ignore
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
new file mode 100644
index 0000000..6a95048
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
@@ -0,0 +1,57 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.pages;
+
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.example.app0.entities.User;
+import org.hibernate.Session;
+
+import java.util.List;
+
+public class EncodeEntities
+{
+    @Inject
+    private Session session;
+
+    @SuppressWarnings("unused")
+    @Property
+    private User user;
+
+    @CommitAfter
+    void onCreate()
+    {
+        User user = new User();
+        user.setFirstName("name");
+
+        session.save(user);
+    }
+
+    @SuppressWarnings("unchecked")
+    User onPassivate()
+    {
+        List<User> users = session.createQuery("from User").list();
+        if (users.isEmpty())
+            return null;
+
+        return users.get(0);
+    }
+
+    void onActivate(User user)
+    {
+        this.user = user;
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/PersistEntity.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/PersistEntity.java
new file mode 100644
index 0000000..c9c0e01
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/PersistEntity.java
@@ -0,0 +1,75 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.hibernate.HibernateSessionManager;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.example.app0.entities.User;
+import org.example.app0.services.UserDAO;
+import org.hibernate.Session;
+
+import java.util.List;
+
+public class PersistEntity
+{
+    @Persist("entity")
+    @Property
+    private User user;
+
+    @Inject
+    private UserDAO userDAO;
+
+    @Inject
+    private Session session;
+
+    @Inject
+    private HibernateSessionManager manager;
+
+    void onCreateEntity()
+    {
+        User user = new User();
+        user.setFirstName("name");
+
+        userDAO.add(user);
+
+        this.user = user;
+    }
+
+    void onChangeName()
+    {
+        user.setFirstName("name2");
+
+        // No commit, so no real change.
+    }
+
+    void onSetToTransient()
+    {
+        user = new User();
+    }
+
+    void onSetToNull()
+    {
+        user = null;
+    }
+
+    void onDelete()
+    {
+        List<User> users = userDAO.findAll();
+
+        userDAO.delete(users.toArray(new User[0]));
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
new file mode 100644
index 0000000..20ace43
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
@@ -0,0 +1,43 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.example.app0.entities.User;
+import org.example.app0.services.UserDAO;
+
+public class Start
+{
+
+    @InjectPage
+    private CommitAfterDemo commitAfterDemo;
+
+    @Inject
+    private UserDAO userDAO;
+
+    Object onActionFromCommitAfter()
+    {
+        User user = new User();
+
+        user.setFirstName("Diane");
+
+        userDAO.add(user);
+
+        commitAfterDemo.setUser(user);
+
+        return commitAfterDemo;
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/AppModule.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/AppModule.java
new file mode 100644
index 0000000..31814d3
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/AppModule.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.hibernate.HibernateModule;
+import org.apache.tapestry.hibernate.HibernateTransactionDecorator;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.annotation.Match;
+import org.apache.tapestry.ioc.annotation.SubModule;
+
+@SubModule(HibernateModule.class)
+public class AppModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(UserDAO.class, UserDAOImpl.class);
+    }
+
+    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
+    }
+
+    @Match("*DAO")
+    public static <T> T decorateTransactionally(HibernateTransactionDecorator decorator, Class<T> serviceInterface,
+                                                T delegate,
+                                                String serviceId)
+    {
+        return decorator.build(serviceInterface, delegate, serviceId);
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAO.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAO.java
new file mode 100644
index 0000000..73efac7
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAO.java
@@ -0,0 +1,31 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.services;
+
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.example.app0.entities.User;
+
+import java.util.List;
+
+public interface UserDAO
+{
+    @CommitAfter
+    void add(User user);
+
+    List<User> findAll();
+
+    @CommitAfter
+    void delete(User... users);
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAOImpl.java b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAOImpl.java
new file mode 100644
index 0000000..d01c9e8
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/java/org/example/app0/services/UserDAOImpl.java
@@ -0,0 +1,46 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.app0.services;
+
+import org.example.app0.entities.User;
+import org.hibernate.Session;
+
+import java.util.List;
+
+public class UserDAOImpl implements UserDAO
+{
+    private final Session session;
+
+    public UserDAOImpl(Session session)
+    {
+        this.session = session;
+    }
+
+    public void add(User user)
+    {
+        session.save(user);
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public List<User> findAll()
+    {
+        return (List<User>) session.createQuery("from User").list();
+    }
+
+    public void delete(User... users)
+    {
+        for (User user : users) session.delete(user);
+    }
+}
diff --git a/hlship-20080520/tapestry-hibernate/src/test/resources/hibernate.cfg.xml b/hlship-20080520/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
new file mode 100644
index 0000000..f7511e7
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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 hibernate-configuration PUBLIC
+    "-//Hibernate/Hibernate Configuration DTD//EN"
+    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+    
+<hibernate-configuration>
+
+  <session-factory>
+    <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
+    <property name="hibernate.connection.url">jdbc:hsqldb:mem:test</property>
+    <property name="hibernate.connection.username">sa</property>
+    <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
+    
+    <property name="show_sql">true</property>
+    <property name="format_sql">true</property>
+    <property name="hbm2ddl.auto">update</property>
+
+    <property name="hibernate.c3p0.min_size">5</property>
+    <property name="hibernate.c3p0.max_size">20</property>
+    <property name="hibernate.c3p0.timeout">300</property>
+    <property name="hibernate.c3p0.max_statements">50</property>
+    <property name="hibernate.c3p0.idle_test_period">3000</property>
+  </session-factory>
+
+
+</hibernate-configuration>
diff --git a/hlship-20080520/tapestry-hibernate/src/test/resources/log4j.properties b/hlship-20080520/tapestry-hibernate/src/test/resources/log4j.properties
new file mode 100644
index 0000000..3949f39
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/resources/log4j.properties
@@ -0,0 +1,29 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootCategory=WARN, A1
+
+# A1 is set to be a ConsoleAppender. 
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=[%p] %c{1} %m%n
+
+log4j.category.org.apache.tapestry.TapestryFilter=info
+log4j.category.org.apache.tapestry=error
+log4j.category.tapestry=error
+log4j.category.tapestry.ioc.ClassFactory=error
+
+log4j.category.tapestry.hibernate=info
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/CachedForm.tml b/hlship-20080520/tapestry-hibernate/src/test/webapp/CachedForm.tml
new file mode 100644
index 0000000..4ce1014
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/CachedForm.tml
@@ -0,0 +1,21 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+  <h1>@Cached with a form</h1>
+
+  <p> Entered data: </p>
+
+  <ul>
+  <t:loop index="index" source="users" value="user">
+    <li id="name_${index}">${user.firstName}</li>
+  </t:loop>
+  </ul>
+
+  <hr/>
+
+  <t:form>
+    <t:label for="name" />: <t:textfield t:id="name" t:validate="required"/>
+    <input type="submit" />
+  </t:form>
+
+</body>
+</html>
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/CommitAfterDemo.tml b/hlship-20080520/tapestry-hibernate/src/test/webapp/CommitAfterDemo.tml
new file mode 100644
index 0000000..db25443
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/CommitAfterDemo.tml
@@ -0,0 +1,26 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <p>Entity name:
+            <span id="name">${user?.firstName}</span>
+        </p>
+
+        <ul>
+            <li>
+                <t:eventlink event="changeName">change name</t:eventlink>
+                (succesfully)
+            </li>
+
+            <li>
+                <t:eventlink event="changeNameWithRuntimeException">runtime exception</t:eventlink>
+                (will abort, so no change)
+            </li>
+
+            <li>
+                <t:eventlink event="changeNameWithCheckedException">checked exception</t:eventlink>
+                (will commit, so we'll see the change)
+            </li>
+        </ul>
+
+
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/EncodeEntities.tml b/hlship-20080520/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
new file mode 100644
index 0000000..098573f
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
@@ -0,0 +1,6 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+	<p>entity name: <span id="name"><t:if test="user">${user.firstName}</t:if></span></p>
+	<p>create entity: <t:eventlink event="create" t:id="createentity">create an entity</t:eventlink></p>
+</body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/PersistEntity.tml b/hlship-20080520/tapestry-hibernate/src/test/webapp/PersistEntity.tml
new file mode 100644
index 0000000..6329cf5
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/PersistEntity.tml
@@ -0,0 +1,10 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+	<p>entity name: <span id="name"><t:if test="user">${user.firstName}</t:if></span></p>
+	<p><t:eventlink event="createEntity">create entity</t:eventlink></p>
+	<p><t:eventlink event="changeName">change the name</t:eventlink></p>
+	<p><t:eventlink event="setToNull">set to null</t:eventlink></p>
+	<p><t:eventlink event="delete">delete</t:eventlink></p>
+	<p><t:eventlink event="setToTransient">set to transient</t:eventlink></p>
+</body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/Start.tml b/hlship-20080520/tapestry-hibernate/src/test/webapp/Start.tml
new file mode 100644
index 0000000..4f87c2c
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/Start.tml
@@ -0,0 +1,14 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Start Page</title>
+    </head>
+    <body>
+        <h2>Test application for tapestry-hibernate integration tests</h2>
+
+        <ul>
+            <li>
+                <t:actionlink t:id="commitAfter">CommitAfter Demo</t:actionlink>
+            </li>
+        </ul>
+    </body>
+</html>
diff --git a/hlship-20080520/tapestry-hibernate/src/test/webapp/WEB-INF/web.xml b/hlship-20080520/tapestry-hibernate/src/test/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..4d57a56
--- /dev/null
+++ b/hlship-20080520/tapestry-hibernate/src/test/webapp/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Tapestry-Hibernate Integration Test Application</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.example.app0</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
diff --git a/hlship-20080520/tapestry-ioc/.classpath b/hlship-20080520/tapestry-ioc/.classpath
new file mode 100644
index 0000000..df0c639
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="src" output="bin-test" path="src/test/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="lib" path="src/test/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-ioc/.project b/hlship-20080520/tapestry-ioc/.project
new file mode 100644
index 0000000..2121900
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-ioc</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.core.prefs b/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b87f3c0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,306 @@
+#Sun May 27 17:47:46 PDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=_
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=48
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
diff --git a/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.ui.prefs b/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..dc02f17
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,10 @@
+#Mon Nov 20 20:08:12 PST 2006
+eclipse.preferences.version=1
+formatter_profile=_Tapestry Project
+formatter_settings_version=10
+org.eclipse.jdt.ui.exception.name=ex
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
diff --git a/hlship-20080520/tapestry-ioc/LICENSE.txt b/hlship-20080520/tapestry-ioc/LICENSE.txt
new file mode 100644
index 0000000..61b38cc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/LICENSE.txt
@@ -0,0 +1,380 @@
+
+                                 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.
+
+   
+-------------------------------------------------------------------------------
+
+JAVASSIST
+
+Javassist is not bundled with tapestry-ioc, but tapestry-ioc is not functional without Javassist.
+Javassist is distributed under a dual license: Mozilla Public License or LGPL (Lesser Gnu Public License). Tapestry
+invokes the MPL for compatibility with the Apache Software License.
+
+MOZILLA PUBLIC LICENSE
+Version 1.1
+
+1. Definitions.
+
+      1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party.
+
+      1.1. ''Contributor'' means each entity that creates or contributes to the creation of Modifications.
+
+      1.2. ''Contributor Version'' means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor.
+
+      1.3. ''Covered Code'' means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof.
+
+      1.4. ''Electronic Distribution Mechanism'' means a mechanism generally accepted in the software development community for the electronic transfer of data.
+
+      1.5. ''Executable'' means Covered Code in any form other than Source Code.
+
+      1.6. ''Initial Developer'' means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A.
+
+      1.7. ''Larger Work'' means a work which combines Covered Code or portions thereof with code not governed by the terms of this License.
+
+      1.8. ''License'' means this document.
+
+      1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+
+      1.9. ''Modifications'' means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is:
+            A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications.
+
+            B. Any new file that contains any part of the Original Code or previous Modifications.
+
+      1.10. ''Original Code'' means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License.
+
+      1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation,  method, process, and apparatus claims, in any patent Licensable by grantor.
+
+      1.11. ''Source Code'' means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge.
+
+      1.12. "You'' (or "Your")  means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You'' includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control'' means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+
+      2.1. The Initial Developer Grant.
+      The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:
+            (a)  under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and
+
+            (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof).
+            (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License.
+
+            (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code;  or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices.
+
+      2.2. Contributor Grant.
+      Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license
+
+            (a)  under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and
+
+            (b) under Patent Claims infringed by the making, using, or selling of  Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of  Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+
+            (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code.
+
+            (d)    Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2)  separate from the Contributor Version;  3)  for infringements caused by: i) third party modifications of Contributor Version or ii)  the combination of Modifications made by that Contributor with other software  (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor.
+
+
+3. Distribution Obligations.
+
+      3.1. Application of License.
+      The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5.
+
+      3.2. Availability of Source Code.
+      Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.
+
+      3.3. Description of Modifications.
+      You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code.
+
+      3.4. Intellectual Property Matters
+            (a) Third Party Claims.
+            If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL'' which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained.
+
+            (b) Contributor APIs.
+            If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file.
+
+                (c)    Representations.
+            Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License.
+
+
+      3.5. Required Notices.
+      You must duplicate the notice in Exhibit A in each file of the Source Code.  If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice.  If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A.  You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code.  You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
+
+      3.6. Distribution of Executable Versions.
+      You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
+
+      3.7. Larger Works.
+      You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+      If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Application of this License.
+
+      This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+      6.1. New Versions.
+      Netscape Communications Corporation (''Netscape'') may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.
+
+      6.2. Effect of New Versions.
+      Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License.
+
+      6.3. Derivative Works.
+      If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+      COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+      8.1.  This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+
+      8.2.  If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant")  alleging that:
+
+      (a)  such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i)  agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant.  If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above.
+
+      (b)  any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant.
+
+      8.3.  If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+      8.4.  In the event of termination under Sections 8.1 or 8.2 above,  all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+      UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+      The Covered Code is a ''commercial item,'' as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and ''commercial computer software documentation,'' as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein.
+
+11. MISCELLANEOUS.
+
+      This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+      As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+      Initial Developer may designate portions of the Covered Code as ÒMultiple-Licensed?.  ÒMultiple-Licensed? means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A.
+
+
+EXHIBIT A -Mozilla Public License.
+
+      The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+      http://www.mozilla.org/MPL/
+
+      Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+      ANY KIND, either express or implied. See the License for the specific language governing rights and
+      limitations under the License.
+
+      The Original Code is Javassist.
+
+      The Initial Developer of the Original Code is Shigeru Chiba. Portions created by the Initial Developer are
+        Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
+
+      Contributor(s): ______________________________________.
+
+      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.
+
diff --git a/hlship-20080520/tapestry-ioc/NOTICE.txt b/hlship-20080520/tapestry-ioc/NOTICE.txt
new file mode 100644
index 0000000..a588f98
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/NOTICE.txt
@@ -0,0 +1,6 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product makes use of the Javassist library, distributed under
+the terms of the Mozilla Public License.
+http://www.jboss.com/products/javassist
diff --git a/hlship-20080520/tapestry-ioc/pom.xml b/hlship-20080520/tapestry-ioc/pom.xml
new file mode 100644
index 0000000..71be44f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/pom.xml
@@ -0,0 +1,130 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-ioc</artifactId>
+    <packaging>jar</packaging>
+    <!-- This should change to tapestry-project -->
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <name>Tapestry Inversion of Control Container</name>
+    <description>
+        A code-centric, high-performance, simple Inversion of Control
+        container.
+    </description>
+    <inceptionYear>2006</inceptionYear>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry5-annotations</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>javassist</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.4.3</version>
+        </dependency>
+
+        <!-- 0.00001% of applications will need to override this dependency to not use Log4J. -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.3</version>
+            <exclusions>
+                <!-- Exclude log4j to make sure we use the latest Log4J version. -->
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+
+
+        <!-- Override parent pom: needed at compile time. -->
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Override parent pom: needed at compile time. -->
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <!-- Looks like if you override scope, you have to provide version (and classifier) as well.
+   Or perhaps this has something to do with classifier. -->
+            <version>5.1</version>
+            <classifier>jdk15</classifier>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+            <!-- This gets the plugin to clean up the cobertura.ser file left
+        in the root directory. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <!-- Version 2.1 is broken. -->
+                <version>${cobertura-plugin-version}</version>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-ioc/src/images/ioc-overview.graffle b/hlship-20080520/tapestry-ioc/src/images/ioc-overview.graffle
new file mode 100644
index 0000000..1221344
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/images/ioc-overview.graffle
Binary files differ
diff --git a/hlship-20080520/tapestry-ioc/src/images/type-coercer.graffle b/hlship-20080520/tapestry-ioc/src/images/type-coercer.graffle
new file mode 100644
index 0000000..35e04be
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/images/type-coercer.graffle
@@ -0,0 +1,2138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>ApplicationVersion</key>
+	<array>
+		<string>com.omnigroup.OmniGraffle</string>
+		<string>129.18</string>
+	</array>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2007-02-11 09:26:40 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Bounds</key>
+			<string>{{161.5, 168.6}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>65</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\i\fs24 \cf0 null}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>80</integer>
+			<key>Points</key>
+			<array>
+				<string>{167.455, 204.571}</string>
+				<string>{102.33, 252.254}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>65</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{165, 558}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>78</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 File}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{46.5, 472.8}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>48</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Object}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{32, 168.6}, {90, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>ID</key>
+			<integer>59</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Collection}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{43, 320.8}, {68, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>54</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Object[]}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{46.5, 396.8}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>52</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 List}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+			<key>ID</key>
+			<integer>51</integer>
+			<key>Points</key>
+			<array>
+				<string>{341, 426}</string>
+				<string>{341, 386}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>50</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{307, 427}, {68, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>50</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Number}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+			<key>ID</key>
+			<integer>49</integer>
+			<key>Points</key>
+			<array>
+				<string>{108.5, 490.8}</string>
+				<string>{164, 490.8}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>48</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>47</integer>
+			<key>Points</key>
+			<array>
+				<string>{314.254, 357.254}</string>
+				<string>{109.572, 282.669}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{43, 252.8}, {68, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>42</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Boolean}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{442.5, 333}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>NSKern</key>
+				<real>0.0</real>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>40</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 \expnd0\expndtw0\kerning0
+Float}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{217, 259}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>37</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Integer}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{446, 259}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>35</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Short}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{312.5, 259}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>33</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Byte}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{314, 349}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>30</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Long}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{147, 349}, {90, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 BigInteger}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{165, 472.8}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>4</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 String}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{296, 525}, {90, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>b</key>
+					<string>0</string>
+					<key>g</key>
+					<string>0</string>
+					<key>r</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>ID</key>
+			<integer>25</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 BigDecimal}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{442.5, 472.8}, {61, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Helvetica</string>
+				<key>NSKern</key>
+				<real>0.0</real>
+				<key>Size</key>
+				<real>12</real>
+			</dict>
+			<key>ID</key>
+			<integer>5</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.721691</string>
+						<key>g</key>
+						<string>0.996139</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+					<key>FillType</key>
+					<integer>2</integer>
+					<key>GradientColor</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>1</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.156298</string>
+						<key>g</key>
+						<string>0.676951</string>
+						<key>r</key>
+						<string>0.684443</string>
+					</dict>
+					<key>CornerRadius</key>
+					<real>6</real>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 \expnd0\expndtw0\kerning0
+Double}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>43</integer>
+			<key>Points</key>
+			<array>
+				<string>{180.943, 471.937}</string>
+				<string>{158, 432.8}</string>
+				<string>{130, 349}</string>
+				<string>{89.7605, 289.628}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>40</integer>
+			</dict>
+			<key>ID</key>
+			<integer>41</integer>
+			<key>Points</key>
+			<array>
+				<string>{473, 471.8}</string>
+				<string>{473, 370}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>5</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+			<key>ID</key>
+			<integer>39</integer>
+			<key>Points</key>
+			<array>
+				<string>{453.078, 472.116}</string>
+				<string>{360.91, 385.673}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>FilledArrow</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>5</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>37</integer>
+			</dict>
+			<key>ID</key>
+			<integer>38</integer>
+			<key>Points</key>
+			<array>
+				<string>{321.58, 348.307}</string>
+				<string>{266.92, 295.693}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>35</integer>
+			</dict>
+			<key>ID</key>
+			<integer>36</integer>
+			<key>Points</key>
+			<array>
+				<string>{364.747, 350.809}</string>
+				<string>{449.253, 293.191}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>33</integer>
+			</dict>
+			<key>ID</key>
+			<integer>34</integer>
+			<key>Points</key>
+			<array>
+				<string>{340.683, 348}</string>
+				<string>{339.817, 296}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+			<key>ID</key>
+			<integer>32</integer>
+			<key>Points</key>
+			<array>
+				<string>{213.727, 472.748}</string>
+				<string>{319.273, 385.052}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+			<key>ID</key>
+			<integer>31</integer>
+			<key>Points</key>
+			<array>
+				<string>{238, 367}</string>
+				<string>{313, 367}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>28</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>28</integer>
+			</dict>
+			<key>ID</key>
+			<integer>29</integer>
+			<key>Points</key>
+			<array>
+				<string>{192, 471.8}</string>
+				<string>{192, 386}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>5</integer>
+			</dict>
+			<key>ID</key>
+			<integer>27</integer>
+			<key>Points</key>
+			<array>
+				<string>{386.694, 539.111}</string>
+				<string>{435, 535}</string>
+				<string>{456.873, 509.558}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>25</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>25</integer>
+			</dict>
+			<key>ID</key>
+			<integer>26</integer>
+			<key>Points</key>
+			<array>
+				<string>{218.84, 500.203}</string>
+				<string>{300.079, 528.664}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>5</integer>
+			</dict>
+			<key>ID</key>
+			<integer>24</integer>
+			<key>Points</key>
+			<array>
+				<string>{220, 490.828}</string>
+				<string>{393, 491}</string>
+				<string>{441.5, 490.879}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>52</integer>
+			</dict>
+			<key>ID</key>
+			<integer>53</integer>
+			<key>Points</key>
+			<array>
+				<string>{77, 471.8}</string>
+				<string>{77, 433.8}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>48</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>52</integer>
+			</dict>
+			<key>ID</key>
+			<integer>55</integer>
+			<key>Points</key>
+			<array>
+				<string>{77, 357.8}</string>
+				<string>{77, 395.8}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>54</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>60</integer>
+			<key>Points</key>
+			<array>
+				<string>{77, 205.6}</string>
+				<string>{77, 251.8}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>59</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>78</integer>
+			</dict>
+			<key>ID</key>
+			<integer>79</integer>
+			<key>Points</key>
+			<array>
+				<string>{192, 509.8}</string>
+				<string>{192, 557}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>YES</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>4</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2008-03-27 17:18:27 -0700</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>coded</string>
+			<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>coded</string>
+			<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>coded</string>
+			<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>coded</string>
+			<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<integer>0</integer>
+		<key>DrawerOpen</key>
+		<true/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>209</real>
+		<key>Frame</key>
+		<string>{{506, 384}, {591, 809}}</string>
+		<key>VisibleRegion</key>
+		<string>{{0, 61}, {576, 695}}</string>
+		<key>Zoom</key>
+		<real>1</real>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/AnnotationProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/AnnotationProvider.java
new file mode 100644
index 0000000..7b70921
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/AnnotationProvider.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * A source of annotations. This interface is used to mask where the annotations come from (for
+ * example, from a Method, a Class, or some other source).
+ */
+public interface AnnotationProvider
+{
+    /**
+     * Searches for the specified annotation, returning the matching annotation instance.
+     *
+     * @param <T>
+     * @param annotationClass used to select the annotation to return«
+     * @return the annotation, or null if not found
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/BaseLocatable.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/BaseLocatable.java
new file mode 100644
index 0000000..1b61c26
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/BaseLocatable.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc;

+

+/**

+ * Base implementation of {@link org.apache.tapestry.ioc.Locatable}.

+ */

+public class BaseLocatable implements Locatable

+{

+    private final Location location;

+

+    protected BaseLocatable(Location location)

+    {

+        this.location = location;

+    }

+

+    public final Location getLocation()

+    {

+        return location;

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Configuration.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Configuration.java
new file mode 100644
index 0000000..14a8928
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Configuration.java
@@ -0,0 +1,42 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Object passed into a service contributor method that allows the method provide contributed values

+ * to the service's configuration.

+ * <p/>

+ * A service can <em>collect</em> contributions in three different ways:

+ * <ul>

+ * <li>As an un-ordered collection of values</li>

+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and

+ * post-requisites)</li>

+ * <li>As a map of keys and values

+ * </ul>

+ * <p/>

+ * This implementation is used for un-ordered configuration data.

+ * <p/>

+ * The service defines the <em>type</em> of contribution, in terms of a base class or service

+ * interface. Contributions must be compatible with the type.

+ */

+public interface Configuration<T>

+{

+    /**

+     * Adds an object to the service's contribution.

+     *

+     * @param object to add to the service's configuration

+     */

+    void add(T object);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCConstants.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCConstants.java
new file mode 100644
index 0000000..ffdd06a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCConstants.java
@@ -0,0 +1,30 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class IOCConstants
+{
+    public static final String DEFAULT_SCOPE = "singleton";
+
+    public static final String PERTHREAD_SCOPE = "perthread";
+
+    public static final String MODULE_BUILDER_MANIFEST_ENTRY_NAME = "Tapestry-Module-Classes";
+
+    public static final String MASTER_OBJECT_PROVIDER_SERVICE_ID = "MasterObjectProvider";
+
+    private IOCConstants()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java
new file mode 100644
index 0000000..4c1244f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java
@@ -0,0 +1,143 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import static org.apache.tapestry.ioc.IOCConstants.MODULE_BUILDER_MANIFEST_ENTRY_NAME;
+import org.apache.tapestry.ioc.annotation.SubModule;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.jar.Manifest;
+
+/**
+ * A collection of utility methods for a couple of different areas, including creating the initial {@link
+ * org.apache.tapestry.ioc.Registry}.
+ */
+public final class IOCUtilities
+{
+    private IOCUtilities()
+    {
+    }
+
+    /**
+     * Construct a default Registry, including modules identifed via the Tapestry-Module-Classes Manifest entry. The
+     * registry will have been {@linkplain Registry#performRegistryStartup() started up} before it is returned.
+     *
+     * @return constructed Registry, after startup
+     * @see #addDefaultModules(RegistryBuilder)
+     */
+    public static Registry buildDefaultRegistry()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        addDefaultModules(builder);
+
+        Registry registry = builder.build();
+
+        registry.performRegistryStartup();
+
+        return registry;
+    }
+
+    /**
+     * Scans the classpath for JAR Manifests that contain the Tapestry-Module-Classes attribute and adds each
+     * corresponding class to the RegistryBuilder. In addition, looks for a system property named "tapestry.modules" and
+     * adds all of those modules as well. The tapestry.modules approach is intended for development.
+     *
+     * @param builder the builder to which modules will be added
+     * @see SubModule
+     * @see RegistryBuilder#add(String)
+     */
+    public static void addDefaultModules(RegistryBuilder builder)
+    {
+        try
+        {
+            Enumeration<URL> urls = builder.getClassLoader().getResources("META-INF/MANIFEST.MF");
+
+            while (urls.hasMoreElements())
+            {
+                URL url = urls.nextElement();
+
+                addModulesInManifest(builder, url);
+            }
+
+            addModulesInList(builder, System.getProperty("tapestry.modules"));
+
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
+    }
+
+    private static void addModulesInManifest(RegistryBuilder builder, URL url) throws IOException
+    {
+        InputStream in = null;
+
+        try
+        {
+            in = url.openStream();
+
+            Manifest mf = new Manifest(in);
+
+            in.close();
+
+            in = null;
+
+            String list = mf.getMainAttributes().getValue(MODULE_BUILDER_MANIFEST_ENTRY_NAME);
+
+            addModulesInList(builder, list);
+        }
+        finally
+        {
+            close(in);
+        }
+    }
+
+    static void addModulesInList(RegistryBuilder builder, String list)
+    {
+        if (list == null) return;
+
+        String[] classnames = list.split(",");
+
+        for (String classname : classnames)
+        {
+            builder.add(classname.trim());
+        }
+    }
+
+    /**
+     * Closes an input stream (or other Closeable), ignoring any exception.
+     *
+     * @param closeable the thing to close, or null to close nothing
+     */
+    private static void close(Closeable closeable)
+    {
+        if (closeable != null)
+        {
+            try
+            {
+                closeable.close();
+            }
+            catch (IOException ex)
+            {
+                // Ignore.
+            }
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IdMatcher.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IdMatcher.java
new file mode 100644
index 0000000..b21d2db
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/IdMatcher.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * A matcher of <em>fully qualified<em> ids.

+ */

+public interface IdMatcher

+{

+    /**

+     * Returns true if the provided input id matches the pattern defined by this matcher instance.

+     *

+     * @param id the fully qualfied id

+     * @return true on match, false otherwise

+     */

+    boolean matches(String id);

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Invocation.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Invocation.java
new file mode 100644
index 0000000..ff9437f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Invocation.java
@@ -0,0 +1,94 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * A method invocation passed to an {@link org.apache.tapestry.ioc.MethodAdvice}.
+ */
+public interface Invocation
+{
+    /**
+     * Returns the name of the method being invoked.
+     */
+    String getMethodName();
+
+    /**
+     * Returns the type of the method result, which may be a primitive type (i.e., int.class) or even void
+     * (void.class).
+     */
+    Class getResultType();
+
+    /**
+     * Returns the number of parameters passed to the method.
+     */
+    int getParameterCount();
+
+    /**
+     * Returns the type of the parameter at the index.
+     */
+    Class getParameterType(int index);
+
+    /**
+     * Returns the indicated parameter (may return null if the parameter is null).
+     */
+    Object getParameter(int index);
+
+    /**
+     * Replaces a parameter in the invocation.
+     *
+     * @param index        of parameter to update
+     * @param newParameter new parameter value (may be null)
+     */
+    void override(int index, Object newParameter);
+
+    /**
+     * Processed with the invocation.  If the invocation results in a <em>runtime</em> exception, that is thrown.
+     */
+    void proceed();
+
+    /**
+     * If true, then the proceeded invocation threw a checked exception.
+     */
+    boolean isFail();
+
+    /**
+     * After invoking {@link #proceed()}, used to obtain the thrown (checked) exception, if assignable to the provided
+     * type.
+     *
+     * @param throwableClass the type of exception to match
+     * @return the exception, if the proceeded invocation threw a checked exception, and the exception is assignable to
+     *         the provided type.
+     */
+    <T extends Throwable> T getThrown(Class<T> throwableClass);
+
+    /**
+     * Overrides the thrown exception. The passed exception should be a checked exception of the method. Note that for
+     * runtime exceptions, or even {@link Error}s, those can just be thrown. Sets the fail flag.
+     *
+     * @param thrown
+     * @throws IllegalArgumentException if thrown is null, or not a declared exception of the method
+     */
+    void overrideThrown(Exception thrown);
+
+    /**
+     * The return value after {@link #proceed()}, which may be null.
+     */
+    Object getResult();
+
+    /**
+     * Overrides the result. Clears the thrown exception (if any).
+     */
+    void overrideResult(Object newResult);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Locatable.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Locatable.java
new file mode 100644
index 0000000..dfb70b7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Locatable.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Interface implemented by objects which carry a location tag. Defines a readable property,

+ * location.

+ */

+public interface Locatable

+{

+    /**

+     * Returns the location associated with this object for error reporting purposes.

+     */

+    Location getLocation();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Location.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Location.java
new file mode 100644
index 0000000..185f300
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Location.java
@@ -0,0 +1,39 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * A kind of tag applied to other objects to identify where they came from, in terms of a file (the

+ * resource), a line number, and a column number. This is part of "line precise exception

+ * reporting", whereby errors at runtime can be tracked backwards to the files from which they were

+ * parsed or otherwise constructed.

+ */

+public interface Location

+{

+    /**

+     * The resource from which the object tagged with a location was derived.

+     */

+    Resource getResource();

+

+    /**

+     * The line number within the resource, if known, or -1 otherwise.

+     */

+    int getLine();

+

+    /**

+     * The column number within the line if known, or -1 otherwise.

+     */

+    int getColumn();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java
new file mode 100644
index 0000000..bb1fecb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/LoggerSource.java
@@ -0,0 +1,34 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.slf4j.Logger;
+
+/**
+ * A wrapper around SLF4J's LoggerFactory that exists to allow particular projects to "hook" the
+ * creation of Logger instances.
+ */
+public interface LoggerSource
+{
+    /**
+     * Creates or retrieves a log based on Class. This is rarely used in Tapestry IOC.
+     */
+    Logger getLogger(Class clazz);
+
+    /**
+     * Creates or retrieves a log based on name. Typically, the name will be a service id.
+     */
+    Logger getLogger(String name);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java
new file mode 100644
index 0000000..da3ead6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MappedConfiguration.java
@@ -0,0 +1,44 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Object passed into a service contributor method that allows the method provide contributed values

+ * to the service's configuration.

+ * <p/>

+ * A service can <em>collect</em> contributions in three different ways:

+ * <ul>

+ * <li>As an un-ordered collection of values</li>

+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and

+ * post-requisites)</li>

+ * <li>As a map of keys and values

+ * </ul>

+ * <p/>

+ * The service defines the <em>type</em> of contribution, in terms of a base class or service

+ * interface. Contributions must be compatible with the type.

+ */

+public interface MappedConfiguration<K, V>

+{

+

+    /**

+     * Adds a keyed object to the service's contribution.

+     *

+     * @param key   unique id for the value

+     * @param value to contribute

+     * @throws IllegalArgumentException if key is not unique

+     */

+

+    void add(K key, V value);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MessageFormatter.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MessageFormatter.java
new file mode 100644
index 0000000..c5323ff
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MessageFormatter.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Obtained from a {@link org.apache.tapestry.ioc.Messages}, used to format messages for a specific

+ * localized message key.

+ */

+public interface MessageFormatter

+{

+    /**

+     * Formats the message. The arguments are passed to {@link java.util.Formatter} as is with one

+     * exception: Object of type {@link Throwable} are converted to their

+     * {@link Throwable#getMessage()} (or, if that is null, to the name of the class).

+     *

+     * @param args

+     * @return formatted string

+     */

+    String format(Object... args);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Messages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Messages.java
new file mode 100644
index 0000000..a18d31e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Messages.java
@@ -0,0 +1,52 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Provides access to a messages catalog, a set of properties files that provide localized messages
+ * for a particular locale. The message catalog consists of keys and values and follows the
+ * semantics of a Java {@link java.util.ResourceBundle} with some changes.
+ */
+public interface Messages
+{
+    /**
+     * Returns true if the bundle contains the named key.
+     */
+    boolean contains(String key);
+
+    /**
+     * Returns the localized message for the given key. If catalog does not contain such a key, then
+     * a modified version of the key is returned (converted to upper case and enclosed in brackets).
+     *
+     * @param key
+     * @return localized message for key, or placeholder
+     */
+    String get(String key);
+
+    /**
+     * Returns a formatter for the message, which can be used to substitute arguments (as per
+     * {@link java.util.Formatter}).
+     *
+     * @param key
+     * @return formattable object
+     */
+    MessageFormatter getFormatter(String key);
+
+    /**
+     * Convienience for accessing a formatter and formatting a localized message with arguments.
+     */
+
+    String format(String key, Object... args);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MethodAdvice.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MethodAdvice.java
new file mode 100644
index 0000000..d27e7f5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/MethodAdvice.java
@@ -0,0 +1,35 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * For Tapestry IoC, Aspects provide a limited amount of advise, i.e., advising method invocations. That's the only join
+ * point available (method invocations of service interface methods); full AOP systems such as AspectJ can do much, much
+ * such as advising field access and even object construction.
+ *
+ * @see org.apache.tapestry.ioc.services.AspectDecorator
+ */
+public interface MethodAdvice
+{
+    /**
+     * Allows the Aspect to advise the invocation.  The Aspect is free to inspect and even replace parameters. Most
+     * Aspects will then invoke {@link org.apache.tapestry.ioc.Invocation#proceed()}.  The Aspect may then inspect and
+     * replace any checked thrown exceptions. Some Aspects (for example, caching) may selectively decide to bypass the
+     * invocation entirely, and instead invoke some other method or otherwise set a return value or thrown exception.
+     *
+     * @param invocation to advise
+     */
+    void advise(Invocation invocation);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java
new file mode 100644
index 0000000..07c9e76
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ModuleBuilderSource.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * The source for the module builder instance needed by most (but not all) service builders, service

+ * contributors and service decorators. Allows the creation of the moduleBuilder instance to be

+ * deferred until actually needed; in practical terms, when the builder/decorator/contributor is a

+ * <em>static</em> method on the module builder class, then a module builder instance is not

+ * needed. This allows Tapestry IOC to work around a tricky chicken-and-the-egg problem, whereby the

+ * constructor of a module builder instance requires contributions that originate in the same

+ * module.

+ */

+public interface ModuleBuilderSource

+{

+    Object getModuleBuilder();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectCreator.java
new file mode 100644
index 0000000..a5e7dc1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectCreator.java
@@ -0,0 +1,28 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc;

+

+/**

+ * Interface used to encapsulate any strategy used defer the creation of some object until just as

+ * needed.

+ */

+public interface ObjectCreator

+{

+    /**

+     * Create and return the object.  In some limited circumstances, the implementation may cache

+     * the result, returning the same object for repeated calls.

+     */

+    Object createObject();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectLocator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectLocator.java
new file mode 100644
index 0000000..bde67d3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectLocator.java
@@ -0,0 +1,95 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.services.MasterObjectProvider;
+
+/**
+ * Defines an object which can provide access to services defined within a {@link org.apache.tapestry.ioc.Registry}, or
+ * to objects or object instances available by other means. Services are accessed via service id, or (when appropriate)
+ * by just service interface. The Registry itself implements this interface, as does {@link
+ * org.apache.tapestry.ioc.ServiceResources}.
+ */
+public interface ObjectLocator
+{
+
+    /**
+     * Obtains a service via its unique service id. Returns the service's proxy. The service proxy implements the same
+     * interface as the actual service, and is used to instantiate the actual service only as needed (this is
+     * transparent to the application).
+     *
+     * @param <T>
+     * @param serviceId        unique Service id used to locate the service object (may contain <em>symbols</em>, which
+     *                         will be expanded), case is ignored
+     * @param serviceInterface the interface implemented by the service (or an interface extended by the service
+     *                         interface)
+     * @return the service instance
+     * @throws RuntimeException if the service is not defined, or if an error occurs instantiating it
+     */
+    <T> T getService(String serviceId, Class<T> serviceInterface);
+
+    /**
+     * Locates a service given just a service interface. A single service must implement the service interface (which
+     * can be hard to guarantee). The search takes into account inheritance of the service interface (not the service
+     * <em>implementation</em>), which may result in a failure due to extra matches.
+     *
+     * @param <T>
+     * @param serviceInterface the interface the service implements
+     * @return the service's proxy
+     * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
+     *                          services directly implement, or extend from, the service interface
+     */
+    <T> T getService(Class<T> serviceInterface);
+
+    /**
+     * Obtains an object indirectly, using an {@link org.apache.tapestry.ioc.ObjectProvider} identified by the prefix of
+     * the reference.
+     *
+     * @param objectType         the type of object to be returned
+     * @param annotationProvider provides access to annotations on the field or parameter for which a value is to be
+     *                           obtained, which may be utilized in selecting an appropriate object, use
+     *                           <strong>null</strong> when annotations are not available (in which case, selection will
+     *                           be based only on the object type)
+     * @param <T>
+     * @return the requested object
+     * @see ObjectProvider
+     */
+    <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider);
+
+    /**
+     * Autobuilds a class by finding the public constructor with the most parameters. Services and resources will be
+     * injected into the parameters of the constructor.
+     *
+     * @param <T>
+     * @param clazz the type of object to instantiate
+     * @return the instantiated instance
+     * @throws RuntimeException if the autobuild fails
+     * @see MasterObjectProvider
+     */
+    <T> T autobuild(Class<T> clazz);
+
+    /**
+     * Creates a proxy. The proxy will defer invocation of {@link #autobuild(Class)} until just-in-time (that is, first
+     * method invocation). In a limited number of cases, it is necessary to use such a proxy to prevent service
+     * construction cycles, particularly when contributing (directly or indirectly) to the {@link
+     * org.apache.tapestry.ioc.services.MasterObjectProvider} (which is itself at the heart of autobuilding).
+     *
+     * @param <T>
+     * @param interfaceClass      the interface implemented by the proxy
+     * @param implementationClass a concrete class that implements the interface
+     * @return a proxy
+     */
+    <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass);
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java
new file mode 100644
index 0000000..d2e5cc0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ObjectProvider.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Object providers represent an alternate way to locate an object provided somewhere in the
+ * {@link org.apache.tapestry.ioc.Registry}. Instead of using a just the service id to gain access
+ * to a service within the Registry, object providers in different flavors are capable of vending,
+ * or even creating, objects of disparate types from disparate sources.
+ * <p/>
+ * Object providers are consulted in a strict order, and the first non-null result is taken.
+ * <p/>
+ * In many cases, an object provider searches for additional annotations on the element (usually a
+ * parameter, or perhaps a field) for which a value is required.
+ */
+public interface ObjectProvider
+{
+    /**
+     * Provides an object based on an expression. The process of providing objects occurs within a
+     * particular <em>context</em>, which will typically be a service builder method, service
+     * contributor method, or service decorator method. The locator parameter provides access to the
+     * services visible <em>to that context</em>.
+     *
+     * @param objectType         the expected object type
+     * @param annotationProvider provides access to annotations (typically, the field or parameter to which an
+     *                           injection-related annotation is attached); annotations on the field or parameter
+     *                           may also be used when resolving the desired object
+     * @param locator            locator for the <em>context</em> in which the provider is being used
+     * @param <T>
+     * @return the requested object, or null if this object provider can not supply an object
+     * @throws RuntimeException if the expression can not be evaluated, or the type of object identified is not
+     *                          assignable to the type specified by the objectType parameter
+     */
+    <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Orderable.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Orderable.java
new file mode 100644
index 0000000..429aa13
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Orderable.java
@@ -0,0 +1,80 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc;

+

+import org.apache.tapestry.ioc.internal.util.Defense;

+

+/**

+ * A wrapper that allows objects of a target type to be ordered. Each Orderable object is given a unique id and a set of

+ * pre-requisites (objects which should be ordered earlier) and post-requisites (objects which should be ordered

+ * later).

+ *

+ * @param <T>

+ */

+public class Orderable<T>

+{

+    private final String id;

+

+    private final T target;

+

+    private final String[] constraints;

+

+    /**

+     * @param id     unique identifier for the target object

+     * @param target the object to be ordered; this may also be null (in which case the id represents a placeholder)

+     */

+

+    public Orderable(String id, T target, String... constraints)

+    {

+        this.id = Defense.notBlank(id, "id");

+        this.target = target;

+        this.constraints = constraints;

+    }

+

+    public String getId()

+    {

+        return id;

+    }

+

+    public T getTarget()

+    {

+        return target;

+    }

+

+    public String[] getConstraints()

+    {

+        return constraints;

+    }

+

+    @Override

+    public String toString()

+    {

+        StringBuilder buffer = new StringBuilder("Orderable[");

+

+        buffer.append(id);

+

+        for (String c : constraints)

+        {

+            buffer.append(" ");

+            buffer.append(c);

+        }

+

+        buffer.append(" ");

+        buffer.append(target.toString());

+        buffer.append("]");

+

+        return buffer.toString();

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java
new file mode 100644
index 0000000..a0ae838
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/OrderedConfiguration.java
@@ -0,0 +1,45 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Object passed into a service contributor method that allows the method provide contributed values

+ * to the service's configuration.

+ * <p/>

+ * A service can <em>collect</em> contributions in three different ways:

+ * <ul>

+ * <li>As an un-ordered collection of values</li>

+ * <li>As an ordered list of values (where each value has a unique id, pre-requisited and

+ * post-requisites)</li>

+ * <li>As a map of keys and values

+ * </ul>

+ * <p/>

+ * The service defines the <em>type</em> of contribution, in terms of a base class or service

+ * interface. Contributions must be compatible with the type.

+ */

+public interface OrderedConfiguration<T>

+{

+    /**

+     * Adds an ordered object to a service's contribution. Each object has an id (which must be

+     * unique). Optionally, pre-requisites (a list of ids that must precede this object) and

+     * post-requisites (ids that must follow) can be provided.

+     *

+     * @param id          a unique id for the object; the id will be fully qualified with the contributing

+     *                    module's id

+     * @param constraints used to order the object relative to other contributed objects

+     * @parm object to add to the service's configuration

+     */

+    void add(String id, T object, String... constraints);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Registry.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Registry.java
new file mode 100644
index 0000000..4c6c084
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Registry.java
@@ -0,0 +1,47 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+
+/**
+ * Public access to the IoC service registry.
+ */
+public interface Registry extends ObjectLocator
+{
+    /**
+     * Invoked at the end of a request to discard any thread-specific information accumulated during the current
+     * request.
+     *
+     * @see org.apache.tapestry.ioc.services.PerthreadManager
+     * @see org.apache.tapestry.ioc.services.ThreadCleanupListener
+     */
+    void cleanupThread();
+
+    /**
+     * Shuts down a Registry instance. Notifies all listeners that the registry has shutdown. Further method invocations
+     * on the Registry are no longer allowed, and the Registry instance should be discarded.
+     *
+     * @see org.apache.tapestry.ioc.services.RegistryShutdownHub
+     * @see org.apache.tapestry.ioc.services.RegistryShutdownListener
+     */
+    void shutdown();
+
+    /**
+     * Invoked to eagerly load services marked with the {@link EagerLoad} annotation, and to execute all contributions
+     * to the Startup service.
+     */
+    void performRegistryStartup();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
new file mode 100644
index 0000000..d4c1568
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
@@ -0,0 +1,180 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.SubModule;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.internal.DefaultModuleDefImpl;
+import org.apache.tapestry.ioc.internal.LoggerSourceImpl;
+import org.apache.tapestry.ioc.internal.RegistryImpl;
+import org.apache.tapestry.ioc.internal.RegistryWrapper;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.TapestryIOCModule;
+import org.slf4j.Logger;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Used to construct the IoC {@link org.apache.tapestry.ioc.Registry}. This class is <em>not</em> thread-safe. The
+ * Registry, once created, <em>is</em> thread-safe.
+ */
+public final class RegistryBuilder
+{
+    private final OneShotLock lock = new OneShotLock();
+
+    /**
+     * Module defs, keyed on module id.
+     */
+    final List<ModuleDef> modules = CollectionFactory.newList();
+
+    private final ClassLoader classLoader;
+
+    private final Logger logger;
+
+    private final LoggerSource loggerSource;
+
+    private final ClassFactory classFactory;
+
+    private final Set<Class> addedModuleClasses = CollectionFactory.newSet();
+
+    public RegistryBuilder()
+    {
+        this(Thread.currentThread().getContextClassLoader());
+    }
+
+    public RegistryBuilder(ClassLoader classLoader)
+    {
+        this(classLoader, new LoggerSourceImpl());
+    }
+
+    public RegistryBuilder(ClassLoader classLoader, LoggerSource loggerSource)
+    {
+        this.classLoader = classLoader;
+        this.loggerSource = loggerSource;
+        logger = loggerSource.getLogger(RegistryBuilder.class);
+
+        // Make the ClassFactory appear to be a service inside TapestryIOCModule, even before that
+        // module exists.
+
+        Logger classFactoryLogger = loggerSource.getLogger(TapestryIOCModule.class.getName() + ".ClassFactory");
+
+        classFactory = new ClassFactoryImpl(this.classLoader, classFactoryLogger);
+
+        add(TapestryIOCModule.class);
+    }
+
+    /**
+     * Adds a {@link ModuleDef} to the registry, returning the builder for further configuration.
+     */
+    public RegistryBuilder add(ModuleDef moduleDef)
+    {
+        lock.check();
+
+        // TODO: Some way to ensure that duplicate modules are not being added.
+        // Part of TAPESTRY-2117 is in add(Class...) and that may be as much as we can
+        // do as there is no concept of ModuleDef identity.
+
+        modules.add(moduleDef);
+
+        return this;
+    }
+
+    /**
+     * Adds a number of modules (as module classes) to the registry, returning the builder for further configuration.
+     *
+     * @see org.apache.tapestry.ioc.annotation.SubModule
+     */
+    public RegistryBuilder add(Class... moduleBuilderClasses)
+    {
+        lock.check();
+
+        List<Class> queue = CollectionFactory.newList(Arrays.asList(moduleBuilderClasses));
+
+        while (!queue.isEmpty())
+        {
+            Class c = queue.remove(0);
+
+            // Quietly ignore previously added classes.
+
+            if (addedModuleClasses.contains(c)) continue;
+
+            addedModuleClasses.add(c);
+
+            ModuleDef def = new DefaultModuleDefImpl(c, logger, classFactory);
+            add(def);
+
+            SubModule annotation = ((AnnotatedElement) c).getAnnotation(SubModule.class);
+
+            if (annotation == null) continue;
+
+            queue.addAll(Arrays.asList(annotation.value()));
+        }
+
+        return this;
+    }
+
+    /**
+     * Adds a number of module classes (specified by fully qualified class name) to the registry, returning the builder
+     * for further configuration.
+     *
+     * @see org.apache.tapestry.ioc.annotation.SubModule
+     */
+    public RegistryBuilder add(String classname)
+    {
+        lock.check();
+
+        try
+        {
+            Class builderClass = Class.forName(classname, true, classLoader);
+
+            add(builderClass);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            throw new IllegalArgumentException(ex);
+        }
+
+        return this;
+    }
+
+    /**
+     * Constructs and returns the registry; this may only be done once. The caller is responsible for invoking {@link
+     * org.apache.tapestry.ioc.Registry#performRegistryStartup()}.
+     */
+    public Registry build()
+    {
+        lock.lock();
+
+        RegistryImpl registry = new RegistryImpl(modules, classFactory, loggerSource);
+
+        return new RegistryWrapper(registry);
+    }
+
+    public ClassLoader getClassLoader()
+    {
+        return classLoader;
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Resource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Resource.java
new file mode 100644
index 0000000..e257452
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/Resource.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Locale;
+
+/**
+ * Represents a resource on the server that may be used for server side processing, or may be exposed to the client
+ * side. Generally, this represents an abstraction on top of files on the class path and files stored in the web
+ * application context.
+ * <p/>
+ * Resources are often used as map keys; they should be immutable and should implement hashCode() and equals().
+ */
+public interface Resource
+{
+
+    /**
+     * Returns true if the resource exists; if a stream to the content of the file may be openned.
+     *
+     * @return true if the resource exists, false if it does not
+     */
+    boolean exists();
+
+    /**
+     * Opens a stream to the content of the resource, or returns null if the resource does not exist.
+     *
+     * @return an open, buffered stream to the content, if available
+     */
+    InputStream openStream() throws IOException;
+
+    /**
+     * Returns the URL for the resource, or null if it does not exist.
+     */
+    URL toURL();
+
+    /**
+     * Returns a localized version of the resource. May return null if no such resource exists.
+     */
+    Resource forLocale(Locale locale);
+
+    /**
+     * Returns a Resource based on a relative path, relative to the folder containing the resource. Understands the "."
+     * (current folder) and ".." (parent folder) conventions, and treats multiple sequential slashes as a single slash.
+     */
+    Resource forFile(String relativePath);
+
+    /**
+     * Returns a new Resource with the extension changed (or, if the resource does not have an extension, the extension
+     * is added). The new Resource may not exist (that is, {@link #toURL()} may return null.
+     *
+     * @param extension to apply to the resource, such as "html" or "properties"
+     * @return the new resource
+     */
+    Resource withExtension(String extension);
+
+    /**
+     * Returns the portion of the path up to the last forward slash; this is the directory or folder portion of the
+     * Resource.
+     */
+    String getFolder();
+
+    /**
+     * Returns the file portion of the Resource path, everything that follows the final forward slash.
+     */
+    String getFile();
+
+    /**
+     * Return the path (the combination of folder and file).
+     */
+    String getPath();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBinder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBinder.java
new file mode 100644
index 0000000..2a741c1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBinder.java
@@ -0,0 +1,51 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * Allows a module to bind service interfaces to service implementation classes in support of autobuilding services. A
+ * ServiceBinder is passed to to a method with the following signature: <code>public static void bind(ServiceBinder
+ * binder)</code>. This is an adaptation of ideas from <a href="http://code.google.com/p/google-guice/">Guice</a>.
+ */
+public interface ServiceBinder
+{
+    /**
+     * Defines a service in terms of an implementation class, without a service interface. In this case, the service
+     * will not be proxiable (proxying requires a service interface) and {@link ServiceDef#getServiceInterface()} will
+     * return the implementation class. In this situation, the service will not be proxied; it will be instantiated
+     * fully on first reference (ignoring its scope, if any) and will not be decorated.
+     *
+     * @param <T>
+     * @param implementationClass
+     * @return
+     */
+    <T> ServiceBindingOptions bind(Class<T> implementationClass);
+
+    /**
+     * Binds the service interface to a service implementation class. The default service name is the unqualified name
+     * of the service interface. The default service scope is "singleton", unless the service implementation class
+     * includes the {@link Scope} annotation.
+     *
+     * @param <T>
+     * @param serviceInterface      service interface (used when locating services, and when building proxies)
+     * @param serviceImplementation implementation class that implements the service interface
+     * @return binding options, used to specify additional details about the service.
+     */
+    <T> ServiceBindingOptions bind(Class<T> serviceInterface,
+                                   Class<? extends T> serviceImplementation);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java
new file mode 100644
index 0000000..2aca3ee
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBindingOptions.java
@@ -0,0 +1,68 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Allows additional options for a service to be specified, overriding hard coded defaults or defaults from annotations
+ * on the service.
+ *
+ * @see ServiceDef
+ */
+public interface ServiceBindingOptions
+{
+    /**
+     * Allows a specific service id for the service to be provided, rather than the default (from the service
+     * interface). This is useful when multiple services implement the same interface, since service ids must be
+     * unique.
+     *
+     * @param id
+     * @return this binding options, for further configuration
+     */
+    ServiceBindingOptions withId(String id);
+
+    /**
+     * Sets the scope of the service, overriding the {@link Scope} annotation on the service implementation class.
+     *
+     * @param scope
+     * @return this binding options, for further configuration
+     */
+    ServiceBindingOptions scope(String scope);
+
+    /**
+     * Turns eager loading on for this service. This may also be accomplished using the {@link EagerLoad} annotation on
+     * the service implementation class.
+     *
+     * @return this binding options, for further configuration
+     */
+    ServiceBindingOptions eagerLoad();
+
+    /**
+     * Defines the marker interface(s) for the service, used to connect injections by type at the point of injection
+     * with a particular service implementation, based on the intersection of type and marker interface. The containing
+     * module will sometimes provide a set of default marker annotations for all services within the module, this method
+     * allows that default to be extended.
+     *
+     * @param <T>
+     * @param marker one or more markers to add
+     * @return this binding options, for further configuration
+     */
+    <T extends Annotation> ServiceBindingOptions withMarker(Class<T>... marker);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java
new file mode 100644
index 0000000..33df6fe
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceBuilderResources.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Extends {@link org.apache.tapestry.ioc.ServiceResources} with additional methods needed only by
+ * the service builder method, related to accessing a service's configuration. Services may have a
+ * <em>single</em> configuration in one of three flavors: unordered, ordered or mapped.
+ */
+public interface ServiceBuilderResources extends ServiceResources, ModuleBuilderSource
+{
+    <T> Collection<T> getUnorderedConfiguration(Class<T> valueType);
+
+    <T> List<T> getOrderedConfiguration(Class<T> valueType);
+
+    <K, V> Map<K, V> getMappedConfiguration(Class<K> keyType, Class<V> valueType);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
new file mode 100644
index 0000000..526d72f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceDecorator.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * A service decorator is derived from a {@link org.apache.tapestry.ioc.def.DecoratorDef} and is

+ * responsible for building an interceptor around an existing implementation (called the

+ * "delegate").

+ */

+public interface ServiceDecorator

+{

+    /**

+     * Creates a new interceptor object implementing the same service interface as the delegate

+     * object.

+     *

+     * @param delegate an existing object implementing the service interface.

+     * @return a new object implementing the same service interface, or delegate or null if the

+     *         decorator chooses not to create a new interceptor.

+     */

+    public Object createInterceptor(Object delegate);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java
new file mode 100644
index 0000000..6f1f2d8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceLifecycle.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Allows certain types of lifecycles to control exactly how services are instantiated.

+ */

+public interface ServiceLifecycle

+{

+    /**

+     * Returns the same creator, or a new one, that encapsulates the creation of the core service

+     * implementation.

+     *

+     * @param resources source of information about the service to be created, and source of additional

+     *                  services or other resources that may be needed when constructing the core service

+     *                  implementation

+     * @param creator   object capable of creating the service implementation on demand. This is a wrapper

+     *                  around the service's builder method.

+     * @return the service or equivalent service proxy

+     */

+    Object createService(ServiceResources resources, ObjectCreator creator);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceResources.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceResources.java
new file mode 100644
index 0000000..6f00be5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/ServiceResources.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.slf4j.Logger;
+
+/**
+ * Contains resources that may be provided to a service when it initializes, which includes other
+ * services defined in the registry. ServiceResources provides access to other services (it extends
+ * {@link org.apache.tapestry.ioc.ObjectLocator}).
+ */
+public interface ServiceResources extends ObjectLocator
+{
+    /**
+     * Returns the fully qualified id of the service.
+     */
+    String getServiceId();
+
+    /**
+     * Returns the service interface implemented by the service.
+     */
+    Class getServiceInterface();
+
+    /**
+     * Returns a Logger appropriate for logging messages. This includes debug level messages about
+     * the creation and configuration of the underlying service, as well as debug, warning, or error
+     * level messages from the service itself. Often service interceptors will make use of the
+     * service's logger.
+     */
+    Logger getLogger();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/EagerLoad.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/EagerLoad.java
new file mode 100644
index 0000000..892d41f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/EagerLoad.java
@@ -0,0 +1,41 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marker annotation placed on a service builder method to indicate that the service should be eagerly loaded: realized
+ * as if a service method had been invoked. Service realization invokes the service builder method and applys any
+ * decorators to the service.
+ * <p/>
+ * This annotation may also be placed directly on a service implementation class, when using autobuilding via the {@link
+ * ServiceBinder}.
+ */
+@Target(
+        { TYPE, METHOD })
+@Retention(RUNTIME)
+@Documented
+public @interface EagerLoad
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Marker.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Marker.java
new file mode 100644
index 0000000..0127e5b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Marker.java
@@ -0,0 +1,46 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to define one or more {@linkplain ServiceDef#getMarkers() marker annotations} for a service implementation. This
+ * allows for injection based on the combination of type and marker interface. These marker interfaces should not have
+ * any values. The mere presence of the marker annotation is all that is needed.
+ * <p/>
+ * When applied to a module class, this sets the default markers for all services within the module.  Markers are
+ * additive, so a Marker annotation on the implementation class and/or specified with {@link
+ * org.apache.tapestry.ioc.ServiceBindingOptions#withMarker(Class[])} will accumulate; a service may have any number of
+ * markers.  Generally one or two is enough.
+ */
+@Target(
+        { TYPE, METHOD })
+@Retention(RUNTIME)
+@Documented
+public @interface Marker
+{
+    /**
+     * The type of annotation (which will be present at the injection point).
+     */
+    Class[] value();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Match.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Match.java
new file mode 100644
index 0000000..0578dbe
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Match.java
@@ -0,0 +1,45 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Optional, but typically used, annotation for service decorator methods, used to define which services the decorator

+ * applies to. This annotation defines a number of <em>patterns</em> that allow services across multiple modules to be

+ * selected. A decorator is applied to a service if any of its patterns match the service.

+ * <p/>

+ * TODO: Describe pattern glob-match syntax

+ * <p/>

+ * When the Match annotation is not supplied, then the decorator only applies to a single service: the service whose id

+ * matches the decorators id; that is, method <code>decorateMyService()</code> would decorate only the service provided

+ * by the <code>buildMyService()</code> method, within the same module.

+ */

+@Target(METHOD)

+@Retention(RUNTIME)

+@Documented

+public @interface Match

+{

+

+    /**

+     * Defines a list of patterns matched against potential service ids to identify to which services the decorator

+     * applies. A decorator is applied if <em>any</em> of the patterns match.

+     */

+    String[] value();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Order.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Order.java
new file mode 100644
index 0000000..9d9e5fe
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Order.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Used with a service decorator method to control the order in which decorations occur. Identifies other decorators

+ * which should occur before the annotated decorator.

+ *

+ * @see org.apache.tapestry.ioc.def.DecoratorDef

+ */

+@Target(METHOD)

+@Retention(RUNTIME)

+@Documented

+public @interface Order

+{

+    /**

+     * Any number of ordering constraint strings.

+     */

+    String[] value();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Scope.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Scope.java
new file mode 100644
index 0000000..511d605
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/Scope.java
@@ -0,0 +1,49 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.annotation;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.services.ServiceLifecycleSource;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * An optional annotation that may be placed on a service building method of a module, or on the implementation class
+ * (when using service binding). The annotation overrides the default scope for services (the default being a global
+ * singleton that is instantiated on demand) for an alternate lifecycle. Alternate lifecycles are typically used to bind
+ * a service implementation to a single thread or request. Modules may define new scopes. Each scope should have a
+ * corresponding {@link ServiceLifecycle} implementation. The linkage from scope name to service lifecycle occurs via a
+ * contribution to the {@link ServiceLifecycleSource} service configuration.
+ * <p/>
+ * The annotation may also be placed directly on a service implementation class, when using service autobuilding (via
+ * the {@link ServiceBinder}.
+ */
+@Target(
+        { TYPE, METHOD })
+@Retention(RUNTIME)
+@Documented
+public @interface Scope
+{
+    /**
+     * An identifier used to look up a non-default lifecycle.
+     */
+    String value();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/SubModule.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/SubModule.java
new file mode 100644
index 0000000..7a1e58c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/annotation/SubModule.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.annotation;

+

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.TYPE;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+

+/**

+ * Attached to a module class, this annotation identifies other module classes that should also be added to the

+ * Registry. This is often easier than updating the JAR Manifest.

+ */

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+public @interface SubModule

+{

+

+    /**

+     * One or more classes that are also modules and should also be loaded.

+     */

+    Class[] value();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
new file mode 100644
index 0000000..38eaf72
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ContributionDef.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.def;
+
+import org.apache.tapestry.ioc.*;
+
+/**
+ * Contribution to a service configuration.
+ * <p/>
+ * The toString() method of the ContributionDef will be used for some exception reporting and should
+ * clearly identify where the contribution comes from; the normal behavior is to identify the class
+ * and method of the contribution method.
+ */
+public interface ContributionDef
+{
+    /**
+     * Identifies the service contributed to.
+     */
+    String getServiceId();
+
+    /**
+     * Performs the work needed to contribute into the standard, unordered configuration.
+     *
+     * @param moduleBuilderSource the source, if needed, of the module builder instance associated with the
+     *                            contribution
+     * @param locator             allows access to services visible to the module builder instance
+     * @param configuration       the unordered configuration into which values should be loaded. This instance will
+     *                            encapsulate all related error checks (such as passing of nulls or inappropriate
+     *                            classes).
+     */
+    void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                    Configuration configuration);
+
+    /**
+     * Performs the work needed to contribute into the ordered configuration.
+     *
+     * @param moduleBuilderSource the source, if needed, of the module builder instance associated with the
+     *                            contribution
+     * @param locator             allows access to services visible to the module builder instance
+     * @param configuration       the ordered configuration into which values should be loaded. This instance will
+     *                            encapsulate all related error checks (such as passing of nulls or inappropriate
+     *                            classes).
+     */
+    void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                    OrderedConfiguration configuration);
+
+    /**
+     * Performs the work needed to contribute into the mapped configuration.
+     *
+     * @param moduleBuilderSource the source, if needed, of the module builder instance associated with the
+     *                            contribution
+     * @param locator             allows access to services visible to the module builder instance
+     * @param configuration       the mapped configuration into which values should be loaded. This instance will
+     *                            encapsulate all related error checks (such as passing of null keys or values or
+     *                            inappropriate classes, or duplicate keys).
+     */
+    void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                    MappedConfiguration configuration);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
new file mode 100644
index 0000000..769312d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/DecoratorDef.java
@@ -0,0 +1,77 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.def;
+
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+
+/**
+ * Definition of a service decorator, which (by default) is derived from a service decorator method.
+ * <p/>
+ * A note on decorator scheduling. The scheduling is based on the desired order of <em>behavior</em>.
+ * Thus, if logging should occur before security checks, and security checks should occur before
+ * transaction management, then the desired decorator order is Logging, Security, Transactions. This
+ * might be specified as having Security occur after Logging, and Transactions occur after Security.
+ * It might also be specified by having Logging ordered "before:*", and Transactions ordered
+ * "after:*" with no specified scheduling for Security.
+ * <p/>
+ * Once this order is established, decorators are <em>applied</em> in reverse order. Each
+ * decorator's job is to create an <em>interceptor</em> for the service, that delegates to the
+ * next implementation. This implies that the decorators are executed last to first. In the above
+ * example, the core service implementation would be passed to the Transaction decorator, resulting
+ * in the Transaction interceptor. The Transaction interceptor would be passed to the Security
+ * decorator, resulting in the Security interceptor. The Security interceptor would be passed to the
+ * Logging decorator, resulting in the Logging interceptor. Thus at runtime, the Logging interceptor
+ * will execute first, then delegate to the Security interceptor, which would delegate to the
+ * Transaction interceptor, which would finally delegate to the core service implementation.
+ */
+public interface DecoratorDef
+{
+    /**
+     * Returns the id of the decorator, which is derived from the decorator method name.
+     */
+    String getDecoratorId();
+
+    /**
+     * Returns zero or more ordering constraint strings, used to order the decorated relative to the
+     * other decorators.
+     */
+
+    String[] getConstraints();
+
+    /**
+     * Creates an object that can perform the decoration (in the default case, by invoking the
+     * decorator method on the module builder instance.
+     *
+     * @param moduleBuilderSource the module builder instance associated with the module containing the decorator
+     *                            (not necessarily the module containing the service being decorated)
+     * @param resources           the resources visible <em>to the decorator</em> (which may be in a different
+     *                            module than the service being decorated). Other resource properties (serviceId,
+     *                            serviceInterface, log, etc.) are for the service being decorated.
+     */
+    ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource,
+                                     ServiceResources resources);
+
+    /**
+     * Used to determine which services may be decorated by this decorator. When decorating a
+     * service, first the decorators that target the service are identified, then ordering occurs,
+     * then the {@link ServiceDecorator}s are invoked.
+     *
+     * @param serviceDef
+     * @return true if the decorator applies to the service
+     */
+    boolean matches(ServiceDef serviceDef);
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
new file mode 100644
index 0000000..d4f2dd2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ModuleDef.java
@@ -0,0 +1,62 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.def;
+
+import org.slf4j.Logger;
+
+import java.util.Set;
+
+/**
+ * Defines the contents of a module. In the default case, this is information about the services
+ * provided by the module builder class.
+ */
+public interface ModuleDef
+{
+    /**
+     * Returns the ids of the services built/provided by the module.
+     */
+    Set<String> getServiceIds();
+
+    /**
+     * Returns a service definition via the service's id.
+     *
+     * @param serviceId the id of the service to retrieve
+     * @return service definition or null if it doesn't exist
+     */
+    ServiceDef getServiceDef(String serviceId);
+
+    /**
+     * Returns all the decorator definitions built/provided by this module.
+     */
+    Set<DecoratorDef> getDecoratorDefs();
+
+    /**
+     * Returns all the contribution definitions built/provided by this module.
+     */
+    Set<ContributionDef> getContributionDefs();
+
+    /**
+     * Returns the class that will be instantiated. Annotated instance methods of this class are
+     * invoked to build services, to decorate/intercept services, and make contributions to other
+     * services.
+     */
+    Class getBuilderClass();
+
+    /**
+     * Returns the name used to create a {@link Logger} instance. This is typically the builder class
+     * name.
+     */
+    String getLoggerName();
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java
new file mode 100644
index 0000000..4672dcc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/def/ServiceDef.java
@@ -0,0 +1,74 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.def;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+
+import java.util.Set;
+
+/**
+ * Service definition derived, by default, from a service builder method.
+ */
+public interface ServiceDef
+{
+    /**
+     * Returns an {@link ObjectCreator} that can create the core service implementation.
+     *
+     * @param resources used to resolve dependencies of the service, or access its configuration
+     * @return an object that can (later) be used to instantiate the service itself
+     */
+    ObjectCreator createServiceCreator(ServiceBuilderResources resources);
+
+    /**
+     * Returns the service id, derived from the method name or the unqualified service interface name. Service ids must
+     * be unique among <em>all</em> services in all modules. Service ids are used in a heavy handed way to support
+     * ultimate disambiguation, but their primary purpose is to support service contribution methods.
+     */
+    String getServiceId();
+
+    /**
+     * Returns an optional <em>marker annotation</em>. Marker annotations are used to disambiguate services; the
+     * combination of a marker annotation and a service type is expected to be unique. The annotation is placed on the
+     * field or method/constructor parameter and the service is located by combining the marker with service type (the
+     * parameter or field type).
+     *
+     * @return the annotation, or null if the service has no annotation
+     */
+    Set<Class> getMarkers();
+
+    /**
+     * Returns the service interface associated with this service. This is the interface exposed to the outside world,
+     * as well as the one used to build proxies. In cases where the service is <em>not</em> defined in terms of an
+     * interface, this will return the actual implementation class of the service. Services without a true service
+     * interfaced are <strong>not proxied</strong>.
+     */
+    Class getServiceInterface();
+
+    /**
+     * Returns the lifecycle defined for the service. This is indicated by adding a {@link
+     * org.apache.tapestry.ioc.annotation.Scope} annotation to the service builder method for the service.
+     * <p/>
+     * Services that are not proxied will ignore their scope; such services are always treated as singletons.
+     */
+    String getServiceScope();
+
+    /**
+     * Returns true if the service should be eagerly loaded at Registry startup.
+     *
+     * @see org.apache.tapestry.ioc.annotation.EagerLoad
+     */
+    boolean isEagerLoad();
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/AbstractServiceCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/AbstractServiceCreator.java
new file mode 100644
index 0000000..9f66d6a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/AbstractServiceCreator.java
@@ -0,0 +1,206 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.ServiceResources;
+import static org.apache.tapestry.ioc.internal.ConfigurationType.*;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.slf4j.Logger;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract implementation of {@link ObjectCreator} geared towards the creation of the core service implementation,
+ * either by invoking a service builder method on a module, or by invoking a constructor.
+ */
+public abstract class AbstractServiceCreator implements ObjectCreator
+{
+    protected final String serviceId;
+
+    private final Map<Class, Object> parameterDefaults = CollectionFactory.newMap();
+
+    protected final ServiceBuilderResources resources;
+
+    protected final Logger logger;
+
+    private final static Map<Class, ConfigurationType> PARAMETER_TYPE_TO_CONFIGURATION_TYPE = CollectionFactory.newMap();
+
+    protected final String creatorDescription;
+
+    static
+    {
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(Collection.class, UNORDERED);
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(List.class, ORDERED);
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(Map.class, MAPPED);
+    }
+
+    public AbstractServiceCreator(ServiceBuilderResources resources, String creatorDescription)
+    {
+        serviceId = resources.getServiceId();
+        this.resources = resources;
+        this.creatorDescription = creatorDescription;
+        logger = resources.getLogger();
+
+        parameterDefaults.put(String.class, serviceId);
+        parameterDefaults.put(ObjectLocator.class, resources);
+        parameterDefaults.put(ServiceResources.class, resources);
+        parameterDefaults.put(Logger.class, logger);
+        parameterDefaults.put(Class.class, resources.getServiceInterface());
+    }
+
+    /**
+     * Returns a map (based on _parameterDefaults) that includes (possibly) an additional mapping containing the
+     * collected configuration data. This involves scanning the parameters and generic types.
+     */
+    protected final Map<Class, Object> getParameterDefaultsWithConfiguration(Class[] parameterTypes,
+                                                                             Type[] genericParameterTypes)
+    {
+        Map<Class, Object> result = CollectionFactory.newMap(parameterDefaults);
+        ConfigurationType type = null;
+
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            Class parameterType = parameterTypes[i];
+
+            ConfigurationType thisType = PARAMETER_TYPE_TO_CONFIGURATION_TYPE.get(parameterType);
+
+            if (thisType == null) continue;
+
+            if (type != null)
+            {
+                logger.warn(IOCMessages.tooManyConfigurationParameters(creatorDescription));
+                break;
+            }
+
+            // Remember that we've seen a configuration parameter, in case there
+            // is another.
+
+            type = thisType;
+
+            Type genericType = genericParameterTypes[i];
+
+            switch (type)
+            {
+
+                case UNORDERED:
+
+                    addUnorderedConfigurationParameter(result, genericType);
+
+                    break;
+
+                case ORDERED:
+
+                    addOrderedConfigurationParameter(result, genericType);
+
+                    break;
+
+                case MAPPED:
+
+                    addMappedConfigurationParameter(result, genericType);
+
+                    break;
+            }
+        }
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void addOrderedConfigurationParameter(Map<Class, Object> parameterDefaults, Type genericType)
+    {
+        Class valueType = findParameterizedTypeFromGenericType(genericType);
+        List configuration = resources.getOrderedConfiguration(valueType);
+
+        parameterDefaults.put(List.class, configuration);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void addUnorderedConfigurationParameter(Map<Class, Object> parameterDefaults, Type genericType)
+    {
+        Class valueType = findParameterizedTypeFromGenericType(genericType);
+        Collection configuration = resources.getUnorderedConfiguration(valueType);
+
+        parameterDefaults.put(Collection.class, configuration);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void addMappedConfigurationParameter(Map<Class, Object> parameterDefaults, Type genericType)
+    {
+        Class keyType = findParameterizedTypeFromGenericType(genericType, 0);
+        Class valueType = findParameterizedTypeFromGenericType(genericType, 1);
+
+        if (keyType == null || valueType == null)
+            throw new IllegalArgumentException(IOCMessages.genericTypeNotSupported(genericType));
+
+        Map configuration = resources.getMappedConfiguration(keyType, valueType);
+
+        parameterDefaults.put(Map.class, configuration);
+    }
+
+    /**
+     * Extracts from a generic type the underlying parameterized type. I.e., for List<Runnable>, will return Runnable.
+     * This is limited to simple parameterized types, not the more complex cases involving wildcards and upper/lower
+     * boundaries.
+     *
+     * @param type the genetic type of the parameter, i.e., List<Runnable>
+     * @return the parameterize type (i.e. Runnable.class if type represents List<Runnable>).
+     */
+
+    // package private for testing
+    static Class findParameterizedTypeFromGenericType(Type type)
+    {
+        Class result = findParameterizedTypeFromGenericType(type, 0);
+
+        if (result == null) throw new IllegalArgumentException(IOCMessages.genericTypeNotSupported(type));
+
+        return result;
+    }
+
+    /**
+     * "Sniffs" a generic type to find the underlying parameterized type. If the Type is a class, then Object.class is
+     * returned. Otherwise, the type must be a ParameterizedType. We check to make sure it has the correct number of a
+     * actual types (1 for a Collection or List, 2 for a Map). The actual types must be classes (wildcards just aren't
+     * supported)
+     *
+     * @param type      a Class or ParameterizedType to inspect
+     * @param typeIndex the index within the ParameterizedType to extract
+     * @return the actual type, or Object.class if the input type is not generic, or null if any other pre-condition is
+     *         not met
+     */
+    private static Class findParameterizedTypeFromGenericType(Type type, int typeIndex)
+    {
+        // For a raw Class type, it means the parameter is not parameterized (i.e. Collection, not
+        // Collection<Foo>), so we can return Object.class to allow no restriction.
+
+        if (type instanceof Class) return Object.class;
+
+        if (!(type instanceof ParameterizedType)) return null;
+
+        ParameterizedType pt = (ParameterizedType) type;
+
+        Type[] types = pt.getActualTypeArguments();
+
+        Type actualType = types[typeIndex];
+
+        return actualType instanceof Class ? (Class) actualType : null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConfigurationType.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConfigurationType.java
new file mode 100644
index 0000000..abc70e6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConfigurationType.java
@@ -0,0 +1,35 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Defines the three types of configurations a service may request.

+ */

+public enum ConfigurationType

+{

+

+    /**

+     * @see org.apache.tapestry.ioc.Configuration

+     */

+    UNORDERED,

+    /**

+     * @see org.apache.tapestry.ioc.OrderedConfiguration

+     */

+    ORDERED,

+    /**

+     * @see org.apache.tapestry.ioc.MappedConfiguration

+     */

+    MAPPED

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConstructorServiceCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConstructorServiceCreator.java
new file mode 100644
index 0000000..4e5b391
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ConstructorServiceCreator.java
@@ -0,0 +1,73 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+/**
+ * A service creator based on an implementation class' constructor, rather than a service builder method.
+ */
+public class ConstructorServiceCreator extends AbstractServiceCreator
+{
+    private final Constructor constructor;
+
+    public ConstructorServiceCreator(ServiceBuilderResources resources, String creatorDescription,
+                                     Constructor constructor)
+    {
+        super(resources, creatorDescription);
+
+        this.constructor = constructor;
+    }
+
+    public Object createObject()
+    {
+        Throwable failure;
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForConstructor(constructor, resources,
+                                                                                  getParameterDefaultsWithConfigurations());
+
+            if (logger.isDebugEnabled()) logger.debug(IOCMessages.invokingConstructor(creatorDescription));
+
+            return constructor.newInstance(parameters);
+        }
+        catch (InvocationTargetException ite)
+        {
+            failure = ite.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            failure = ex;
+        }
+
+        throw new RuntimeException(IOCMessages.constructorError(creatorDescription, serviceId, failure), failure);
+    }
+
+    /**
+     * Returns a map that includes (possibly) an additional mapping containing the collected configuration data. This
+     * involves scanning the constructor's parameters.
+     */
+    private Map<Class, Object> getParameterDefaultsWithConfigurations()
+    {
+        return getParameterDefaultsWithConfiguration(constructor.getParameterTypes(), constructor
+                .getGenericParameterTypes());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java
new file mode 100644
index 0000000..767d60c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java
@@ -0,0 +1,110 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+public class ContributionDefImpl implements ContributionDef
+{
+    private final String serviceId;
+
+    private final Method contributorMethod;
+
+    private final ClassFactory classFactory;
+
+    public ContributionDefImpl(String serviceId, Method contributorMethod, ClassFactory classFactory)
+    {
+        this.serviceId = serviceId;
+        this.contributorMethod = contributorMethod;
+        this.classFactory = classFactory;
+    }
+
+    @Override
+    public String toString()
+    {
+        return InternalUtils.asString(contributorMethod, classFactory);
+    }
+
+    public String getServiceId()
+    {
+        return serviceId;
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           Configuration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, Configuration.class, configuration);
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           OrderedConfiguration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, OrderedConfiguration.class, configuration);
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ObjectLocator locator,
+                           MappedConfiguration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, MappedConfiguration.class, configuration);
+    }
+
+    private <T> void invokeMethod(ModuleBuilderSource source, ObjectLocator locator,
+                                  Class<T> parameterType, T parameterValue)
+    {
+        Map<Class, Object> parameterDefaults = CollectionFactory.newMap();
+
+        // The way it works is: the method will take Configuration, OrderedConfiguration or
+        // MappedConfiguration. So, if the method is for one type and the service is for a different
+        // type, then we'll see an error putting together the parameter.
+
+        parameterDefaults.put(parameterType, parameterValue);
+        parameterDefaults.put(ObjectLocator.class, locator);
+
+        Throwable fail = null;
+
+        Object moduleBuilder = InternalUtils.isStatic(contributorMethod) ? null : source
+                .getModuleBuilder();
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForMethod(
+                    contributorMethod,
+                    locator,
+                    parameterDefaults);
+
+            contributorMethod.invoke(moduleBuilder, parameters);
+        }
+        catch (InvocationTargetException ex)
+        {
+            fail = ex.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            fail = ex;
+        }
+
+        if (fail != null)
+            throw new RuntimeException(IOCMessages
+                    .contributionMethodError(contributorMethod, fail), fail);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java
new file mode 100644
index 0000000..4f239eb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java
@@ -0,0 +1,98 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.IdMatcher;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class DecoratorDefImpl implements DecoratorDef
+{
+    private final String decoratorId;
+
+    private final Method decoratorMethod;
+
+    private final IdMatcher idMatcher;
+
+    private final String[] constraints;
+
+    private final ClassFactory classFactory;
+
+    public DecoratorDefImpl(String decoratorId, Method decoratorMethod, String[] patterns,
+                            String[] constraints, ClassFactory classFactory)
+    {
+        this.decoratorId = notBlank(decoratorId, "decoratorId");
+        this.decoratorMethod = notNull(decoratorMethod, "decoratorMethod");
+
+        List<IdMatcher> matchers = CollectionFactory.newList();
+
+        for (String pattern : notNull(patterns, "patterns"))
+        {
+            IdMatcher matcher = new IdMatcherImpl(pattern);
+            matchers.add(matcher);
+        }
+
+        idMatcher = new OrIdMatcher(matchers);
+
+        this.constraints = constraints != null ? constraints : new String[0];
+
+        this.classFactory = classFactory;
+    }
+
+    @Override
+    public String toString()
+    {
+        return InternalUtils.asString(decoratorMethod, classFactory);
+    }
+
+    public String[] getConstraints()
+    {
+        return constraints;
+    }
+
+    public String getDecoratorId()
+    {
+        return decoratorId;
+    }
+
+    public ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource,
+                                            ServiceResources resources)
+    {
+        return new ServiceDecoratorImpl(decoratorMethod, moduleBuilderSource, resources,
+                                        classFactory);
+    }
+
+    /**
+     * Returns true if <em>any</em> provided pattern matches the id of the service.
+     */
+    public boolean matches(ServiceDef serviceDef)
+    {
+        String serviceId = serviceDef.getServiceId();
+
+        return idMatcher.matches(serviceId);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
new file mode 100644
index 0000000..09304bd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
@@ -0,0 +1,419 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.ioc.internal.ConfigurationType.*;
+import static org.apache.tapestry.ioc.internal.IOCMessages.*;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Starting from the Class for a module builder, identifies all the services (service builder methods), decorators
+ * (service decorator methods) and (not yet implemented) contributions (service contributor methods).
+ */
+public class DefaultModuleDefImpl implements ModuleDef, ServiceDefAccumulator
+{
+    /**
+     * The prefix used to identify service builder methods.
+     */
+    private static final String BUILD_METHOD_NAME_PREFIX = "build";
+
+    /**
+     * The prefix used to identify service decorator methods.
+     */
+    private static final String DECORATE_METHOD_NAME_PREFIX = "decorate";
+
+    /**
+     * The prefix used to identify service contribution methods.
+     */
+    private static final String CONTRIBUTE_METHOD_NAME_PREFIX = "contribute";
+
+    private final static Map<Class, ConfigurationType> PARAMETER_TYPE_TO_CONFIGURATION_TYPE = newMap();
+
+    private final Class builderClass;
+
+    private final Logger logger;
+
+    private final ClassFactory classFactory;
+
+    /**
+     * Keyed on service id.
+     */
+    private final Map<String, ServiceDef> serviceDefs = newCaseInsensitiveMap();
+
+    /**
+     * Keyed on decorator id.
+     */
+    private final Map<String, DecoratorDef> decoratorDefs = newCaseInsensitiveMap();
+
+    private final Set<ContributionDef> contributionDefs = newSet();
+
+    private final Set<Class> defaultMarkers = newSet();
+
+    static
+    {
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(Configuration.class, UNORDERED);
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(OrderedConfiguration.class, ORDERED);
+        PARAMETER_TYPE_TO_CONFIGURATION_TYPE.put(MappedConfiguration.class, MAPPED);
+    }
+
+    /**
+     * @param builderClass the class that is responsible for building services, etc.
+     * @param logger       based on the class name of the module
+     * @param classFactory factory used to create new classes at runtime or locate method line numbers for error
+     *                     reporting
+     */
+    public DefaultModuleDefImpl(Class<?> builderClass, Logger logger, ClassFactory classFactory)
+    {
+        this.builderClass = builderClass;
+        this.logger = logger;
+        this.classFactory = classFactory;
+
+        Marker annotation = builderClass.getAnnotation(Marker.class);
+
+        if (annotation != null)
+        {
+            InternalUtils.validateMarkerAnnotations(annotation.value());
+            defaultMarkers.addAll(Arrays.asList(annotation.value()));
+        }
+
+        grind();
+        bind();
+    }
+
+    /**
+     * Identifies the module builder class and a list of service ids within the module.
+     */
+    @Override
+    public String toString()
+    {
+        return String.format("ModuleDef[%s %s]", builderClass.getName(), InternalUtils
+                .joinSorted(serviceDefs.keySet()));
+    }
+
+    public Class getBuilderClass()
+    {
+        return builderClass;
+    }
+
+    public Set<String> getServiceIds()
+    {
+        return serviceDefs.keySet();
+    }
+
+    public ServiceDef getServiceDef(String serviceId)
+    {
+        return serviceDefs.get(serviceId);
+    }
+
+    private void grind()
+    {
+        Method[] methods = builderClass.getMethods();
+
+        Comparator<Method> c = new Comparator<Method>()
+        {
+            // By name, ascending, then by parameter count, descending.
+
+            public int compare(Method o1, Method o2)
+            {
+                int result = o1.getName().compareTo(o2.getName());
+
+                if (result == 0) result = o2.getParameterTypes().length - o1.getParameterTypes().length;
+
+                return result;
+            }
+
+        };
+
+        Arrays.sort(methods, c);
+
+        for (Method m : methods)
+        {
+            String name = m.getName();
+
+            if (name.startsWith(BUILD_METHOD_NAME_PREFIX))
+            {
+                addServiceDef(m);
+                continue;
+            }
+
+            if (name.startsWith(DECORATE_METHOD_NAME_PREFIX))
+            {
+                addDecoratorDef(m);
+                continue;
+            }
+
+            if (name.startsWith(CONTRIBUTE_METHOD_NAME_PREFIX))
+            {
+                addContributionDef(m);
+                continue;
+            }
+
+        }
+    }
+
+    private void addContributionDef(Method method)
+    {
+        String serviceId = stripMethodPrefix(method, CONTRIBUTE_METHOD_NAME_PREFIX);
+
+        Class returnType = method.getReturnType();
+        if (!returnType.equals(void.class)) logger.warn(IOCMessages.contributionWrongReturnType(method));
+
+        ConfigurationType type = null;
+
+        for (Class parameterType : method.getParameterTypes())
+        {
+            ConfigurationType thisParameter = PARAMETER_TYPE_TO_CONFIGURATION_TYPE
+                    .get(parameterType);
+
+            if (thisParameter != null)
+            {
+                if (type != null)
+                {
+                    logger.warn(IOCMessages.tooManyContributionParameters(method));
+                    return;
+                }
+
+                type = thisParameter;
+            }
+        }
+
+        if (type == null)
+        {
+            logger.warn(IOCMessages.noContributionParameter(method));
+            return;
+        }
+
+        ContributionDef def = new ContributionDefImpl(serviceId, method, classFactory);
+
+        contributionDefs.add(def);
+    }
+
+    private void addDecoratorDef(Method method)
+    {
+        // TODO: methods just named "decorate"
+
+        String decoratorId = stripMethodPrefix(method, DECORATE_METHOD_NAME_PREFIX);
+
+        // TODO: Check for duplicates
+
+        Class returnType = method.getReturnType();
+
+        if (returnType.isPrimitive() || returnType.isArray())
+        {
+            logger.warn(decoratorMethodWrongReturnType(method));
+            return;
+        }
+
+        if (!methodContainsObjectParameter(method))
+        {
+            logger.warn(IOCMessages.decoratorMethodNeedsDelegateParameter(method));
+            return;
+        }
+
+        // TODO: Check that at least one parameter is type java.lang.Object,
+        // since that's how the delegate is passed in.
+
+        Order orderAnnotation = method.getAnnotation(Order.class);
+        Match match = method.getAnnotation(Match.class);
+
+        String[] constraints = orderAnnotation != null ? orderAnnotation.value() : null;
+
+        // TODO: Validate constraints here?
+
+        String[] patterns = match == null ? new String[] { decoratorId } : match.value();
+
+        DecoratorDef def = new DecoratorDefImpl(decoratorId, method, patterns, constraints, classFactory);
+
+        decoratorDefs.put(decoratorId, def);
+    }
+
+    private boolean methodContainsObjectParameter(Method method)
+    {
+        for (Class parameterType : method.getParameterTypes())
+        {
+            // TODO: But what if the type Object parameter has an injection?
+            // We should skip it and look for a different parameter.
+
+            if (parameterType.equals(Object.class)) return true;
+        }
+
+        return false;
+    }
+
+    private String stripMethodPrefix(Method method, String prefix)
+    {
+        return method.getName().substring(prefix.length());
+    }
+
+    /**
+     * Invoked for public methods that have the proper prefix.
+     */
+    private void addServiceDef(final Method method)
+    {
+        String serviceId = stripMethodPrefix(method, BUILD_METHOD_NAME_PREFIX);
+
+        // If the method name was just "build()", then work from the return type.
+
+        if (serviceId.equals("")) serviceId = method.getReturnType().getSimpleName();
+
+        // Any number of parameters is fine, we'll adapt. Eventually we have to check
+        // that we can satisfy the parameters requested. Thrown exceptions of the method
+        // will be caught and wrapped, so we don't need to check those. But we do need a proper
+        // return type.
+
+        Class returnType = method.getReturnType();
+
+        if (returnType.isPrimitive() || returnType.isArray())
+        {
+            logger.warn(buildMethodWrongReturnType(method));
+            return;
+        }
+
+        String scope = extractServiceScope(method);
+        boolean eagerLoad = method.isAnnotationPresent(EagerLoad.class);
+
+        ObjectCreatorSource source = new ObjectCreatorSource()
+        {
+            public ObjectCreator constructCreator(ServiceBuilderResources resources)
+            {
+                return new ServiceBuilderMethodInvoker(resources, getDescription(), method);
+            }
+
+            public String getDescription()
+            {
+                return InternalUtils.asString(method, classFactory);
+            }
+        };
+
+        Set<Class> markers = newSet(defaultMarkers);
+        markers.addAll(extractMarkers(method));
+
+        ServiceDefImpl serviceDef = new ServiceDefImpl(returnType, serviceId, markers, scope, eagerLoad, source);
+
+        addServiceDef(serviceDef);
+    }
+
+    private Collection<Class> extractMarkers(Method method)
+    {
+        Marker annotation = method.getAnnotation(Marker.class);
+
+        if (annotation == null) return Collections.emptyList();
+
+        return CollectionFactory.newList(annotation.value());
+    }
+
+    public void addServiceDef(ServiceDef serviceDef)
+    {
+        String serviceId = serviceDef.getServiceId();
+
+        ServiceDef existing = serviceDefs.get(serviceId);
+
+        if (existing != null)
+        {
+            logger.warn(buildMethodConflict(serviceDef.toString(), existing.toString()));
+            return;
+        }
+
+        serviceDefs.put(serviceId, serviceDef);
+    }
+
+    private String extractServiceScope(Method method)
+    {
+        Scope scope = method.getAnnotation(Scope.class);
+
+        return scope != null ? scope.value() : IOCConstants.DEFAULT_SCOPE;
+    }
+
+    public Set<DecoratorDef> getDecoratorDefs()
+    {
+        return newSet(decoratorDefs.values());
+    }
+
+    public Set<ContributionDef> getContributionDefs()
+    {
+        return contributionDefs;
+    }
+
+    public String getLoggerName()
+    {
+        return builderClass.getName();
+    }
+
+    /**
+     * See if the build class defined a bind method and invoke it.
+     */
+    private void bind()
+    {
+        Throwable failure;
+        Method bindMethod = null;
+
+        try
+        {
+            bindMethod = builderClass.getMethod("bind", ServiceBinder.class);
+
+            if (!Modifier.isStatic(bindMethod.getModifiers()))
+            {
+                logger.error(IOCMessages.bindMethodMustBeStatic(InternalUtils.asString(bindMethod, classFactory)));
+
+                return;
+            }
+
+            ServiceBinderImpl binder = new ServiceBinderImpl(this, classFactory, defaultMarkers);
+
+            bindMethod.invoke(null, binder);
+
+            binder.finish();
+
+            return;
+        }
+        catch (NoSuchMethodException ex)
+        {
+            // No problem! Many modules will not have such a method.
+
+            return;
+        }
+        catch (IllegalArgumentException ex)
+        {
+            failure = ex;
+        }
+        catch (IllegalAccessException ex)
+        {
+            failure = ex;
+        }
+        catch (InvocationTargetException ex)
+        {
+            failure = ex.getTargetException();
+        }
+
+        String methodId = InternalUtils.asString(bindMethod, classFactory);
+
+        throw new RuntimeException(IOCMessages.errorInBindMethod(methodId, failure), failure);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/EagerLoadServiceProxy.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/EagerLoadServiceProxy.java
new file mode 100644
index 0000000..afa42d1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/EagerLoadServiceProxy.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Interface implemented by all service proxies. Service proxies are always

+ * {@link org.apache.tapestry.ioc.services.RegistryShutdownListener}s, they also can be eager-load

+ */

+public interface EagerLoadServiceProxy

+{

+    void eagerLoadService();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/GlobPatternMatcher.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/GlobPatternMatcher.java
new file mode 100644
index 0000000..c5505a8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/GlobPatternMatcher.java
@@ -0,0 +1,95 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import static org.apache.tapestry.ioc.internal.MatchType.*;
+
+public class GlobPatternMatcher
+{
+    private String substring;
+
+    private MatchType type;
+
+    public GlobPatternMatcher(String pattern)
+    {
+        analyze(pattern);
+    }
+
+    private void analyze(String pattern)
+    {
+        if (pattern.equals("*"))
+        {
+            type = ANY;
+            return;
+        }
+
+        boolean globPrefix = pattern.startsWith("*");
+        boolean globSuffix = pattern.endsWith("*");
+
+        if (globPrefix && globSuffix)
+        {
+            substring = pattern.substring(1, pattern.length() - 1);
+            type = INFIX;
+            return;
+        }
+
+        if (globPrefix)
+        {
+            substring = pattern.substring(1);
+            type = SUFFIX;
+            return;
+        }
+
+        if (globSuffix)
+        {
+            substring = pattern.substring(0, pattern.length() - 1);
+            type = PREFIX;
+            return;
+        }
+
+        type = MatchType.EXACT;
+        substring = pattern;
+    }
+
+    public boolean matches(String input)
+    {
+        switch (type)
+        {
+            case ANY:
+                return true;
+
+            case EXACT:
+
+                return input.equalsIgnoreCase(substring);
+
+            case INFIX:
+
+                return input.toLowerCase().contains(substring.toLowerCase());
+
+            case PREFIX:
+
+                return input.regionMatches(true, 0, substring, 0, substring.length());
+
+            default:
+
+                return input.regionMatches(
+                        true,
+                        input.length() - substring.length(),
+                        substring,
+                        0,
+                        substring.length());
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
new file mode 100644
index 0000000..83787a2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
@@ -0,0 +1,153 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import static org.easymock.EasyMock.isA;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+
+import java.util.Collections;
+import java.util.List;
+
+public class IOCInternalTestCase extends IOCTestCase implements Registry
+{
+    private static Registry registry;
+
+    private static ClassFactory classFactory;
+
+    @AfterMethod
+    public final void cleanupThread()
+    {
+        registry.cleanupThread();
+    }
+
+    public final ClassFactory getClassFactory()
+    {
+        return classFactory;
+    }
+
+    public final <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
+    {
+        return registry.getObject(objectType, annotationProvider);
+    }
+
+    public final <T> T getService(Class<T> serviceInterface)
+    {
+        return registry.getService(serviceInterface);
+    }
+
+    public final <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        return registry.getService(serviceId, serviceInterface);
+    }
+
+    public final <T> T autobuild(Class<T> clazz)
+    {
+        return registry.autobuild(clazz);
+    }
+
+    public final void performRegistryStartup()
+    {
+        registry.performRegistryStartup();
+    }
+
+    public <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass)
+    {
+        return registry.proxy(interfaceClass, implementationClass);
+    }
+
+
+    @BeforeSuite
+    public final void setup_registry()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        registry = builder.build();
+
+        registry.performRegistryStartup();
+
+        classFactory = registry.getService(ClassFactory.class);
+    }
+
+    public final void shutdown()
+    {
+        throw new UnsupportedOperationException("No registry shutdown until @AfterSuite.");
+    }
+
+
+    @AfterSuite
+    public final void shutdown_registry()
+    {
+        registry.shutdown();
+
+        registry = null;
+        classFactory = null;
+    }
+
+    protected final InternalRegistry mockInternalRegistry()
+    {
+        return newMock(InternalRegistry.class);
+    }
+
+    protected final Module mockModule()
+    {
+        return newMock(Module.class);
+    }
+
+    protected final ObjectCreatorSource mockObjectCreatorSource()
+    {
+        return newMock(ObjectCreatorSource.class);
+    }
+
+    protected final void train_findDecoratorsForService(InternalRegistry registry)
+    {
+        List<ServiceDecorator> result = Collections.emptyList();
+
+        expect(registry.findDecoratorsForService(isA(ServiceDef.class))).andReturn(result);
+    }
+
+    protected final void train_findDecoratorsForService(Module module, String serviceId,
+                                                        List<ServiceDecorator> decorators)
+    {
+        expect(module.findDecoratorsForService(serviceId)).andReturn(decorators);
+    }
+
+    protected final void train_getDescription(ObjectCreatorSource source, String description)
+    {
+        expect(source.getDescription()).andReturn(description).atLeastOnce();
+    }
+
+    protected final void train_getLifecycle(InternalRegistry registry, String scope, ServiceLifecycle lifecycle)
+    {
+        expect(registry.getServiceLifecycle(scope)).andReturn(lifecycle);
+    }
+
+    protected final <T> void train_getService(InternalRegistry registry, String serviceId, Class<T> serviceInterface,
+                                              T service)
+    {
+        expect(registry.getService(serviceId, serviceInterface)).andReturn(service);
+    }
+
+    protected ServiceActivityTracker mockServiceActivityTracker()
+    {
+        return newMock(ServiceActivityTracker.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java
new file mode 100644
index 0000000..7b37ce4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java
@@ -0,0 +1,309 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import static org.apache.tapestry.ioc.internal.util.InternalUtils.asString;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import static org.apache.tapestry.ioc.services.ClassFabUtils.toJavaClassName;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+final class IOCMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(IOCMessages.class);
+
+    static String buildMethodConflict(String conflict, String existing)
+    {
+        return MESSAGES.format("build-method-conflict", conflict, existing);
+    }
+
+    static String buildMethodWrongReturnType(Method method)
+    {
+        return MESSAGES.format("build-method-wrong-return-type", asString(method), method
+                .getReturnType().getCanonicalName());
+    }
+
+    static String decoratorMethodWrongReturnType(Method method)
+    {
+        return MESSAGES.format("decorator-method-wrong-return-type", asString(method), method
+                .getReturnType().getCanonicalName());
+    }
+
+    public static String builderLocked()
+    {
+        return MESSAGES.get("builder-locked");
+    }
+
+    static String serviceWrongInterface(String serviceId, Class actualInterface, Class requestedInterface)
+    {
+        return MESSAGES.format("service-wrong-interface", serviceId, actualInterface.getName(),
+                               requestedInterface.getName());
+    }
+
+    static String instantiateBuilderError(Class builderClass, Throwable cause)
+    {
+        return MESSAGES.format("instantiate-builder-error", builderClass.getName(), cause);
+    }
+
+    static String builderMethodError(String methodId, String serviceId, Throwable cause)
+    {
+        return MESSAGES.format("builder-method-error", methodId, serviceId, cause);
+    }
+
+    static String constructorError(String creatorDescription, String serviceId, Throwable cause)
+    {
+        return MESSAGES.format("constructor-error", creatorDescription, serviceId, cause);
+    }
+
+    static String decoratorMethodError(Method method, String serviceId, Throwable cause)
+    {
+        return MESSAGES.format("decorator-method-error", asString(method), serviceId, cause);
+    }
+
+    static String builderMethodReturnedNull(String methodId, String serviceId)
+    {
+        return MESSAGES.format("builder-method-returned-null", methodId, serviceId);
+    }
+
+    static String noServiceMatchesType(Class serviceInterface)
+    {
+        return MESSAGES.format("no-service-matches-type", serviceInterface.getName());
+    }
+
+    static String manyServiceMatches(Class serviceInterface, List<String> ids)
+    {
+        StringBuilder buffer = new StringBuilder();
+
+        for (int i = 0; i < ids.size(); i++)
+        {
+            if (i > 0) buffer.append(", ");
+
+            buffer.append(ids.get(i));
+        }
+
+        return MESSAGES.format("many-service-matches", serviceInterface.getName(), ids.size(), buffer.toString());
+    }
+
+    static String unknownScope(String name)
+    {
+        return MESSAGES.format("unknown-scope", name);
+    }
+
+    static String decoratorMethodNeedsDelegateParameter(Method method)
+    {
+        return MESSAGES.format("decorator-method-needs-delegate-parameter", asString(method));
+    }
+
+    static String decoratorReturnedWrongType(Method method, String serviceId, Object returned, Class serviceInterface)
+    {
+        return MESSAGES.format("decorator-returned-wrong-type", asString(method), serviceId, returned,
+                               serviceInterface.getName());
+    }
+
+    static String creatingService(String serviceId)
+    {
+        return MESSAGES.format("creating-service", serviceId);
+    }
+
+    static String invokingMethod(String methodId)
+    {
+        return MESSAGES.format("invoking-method", methodId);
+    }
+
+    static String invokingConstructor(String creatorDescription)
+    {
+        return MESSAGES.format("invoking-constructor", creatorDescription);
+    }
+
+    static String invokingMethod(ContributionDef def)
+    {
+        // The toString() of a contribution def is the name of the method.
+        return MESSAGES.format("invoking-method", def);
+    }
+
+    static String recursiveServiceBuild(ServiceDef def)
+    {
+        return MESSAGES.format("recursive-service-build", def.getServiceId(), def.toString());
+    }
+
+    static String contributionWrongReturnType(Method method)
+    {
+        return MESSAGES.format("contribution-wrong-return-type", asString(method),
+                               toJavaClassName(method.getReturnType()));
+    }
+
+    static String tooManyContributionParameters(Method method)
+    {
+        return MESSAGES.format("too-many-contribution-parameters", asString(method));
+    }
+
+    static String noContributionParameter(Method method)
+    {
+        return MESSAGES.format("no-contribution-parameter", asString(method));
+    }
+
+    static String contributionMethodError(Method method, Throwable cause)
+    {
+        return MESSAGES.format("contribution-method-error", asString(method), cause);
+    }
+
+    static String contributionWasNull(String serviceId, ContributionDef def)
+    {
+        return MESSAGES.format("contribution-was-null", serviceId, def);
+    }
+
+    static String contributionKeyWasNull(String serviceId, ContributionDef def)
+    {
+        return MESSAGES.format("contribution-key-was-null", serviceId, def);
+    }
+
+    static String contributionWrongValueType(String serviceId, ContributionDef def, Class actualClass,
+                                             Class expectedClass)
+    {
+        return MESSAGES.format("contribution-wrong-value-type", serviceId, def, actualClass
+                .getName(), expectedClass.getName());
+    }
+
+    static String contributionWrongKeyType(String serviceId, ContributionDef def, Class actualClass,
+                                           Class expectedClass)
+    {
+        return MESSAGES.format("contribution-wrong-key-type", serviceId, def, actualClass.getName(),
+                               expectedClass.getName());
+    }
+
+    static String tooManyConfigurationParameters(String methodId)
+    {
+        return MESSAGES.format("too-many-configuration-parameters", methodId);
+    }
+
+    static String genericTypeNotSupported(Type type)
+    {
+        return MESSAGES.format("generic-type-not-supported", type);
+    }
+
+    static String contributionDuplicateKey(String serviceId, ContributionDef contributionDef,
+                                           ContributionDef existingDef)
+    {
+        return MESSAGES.format("contribution-duplicate-key", serviceId, contributionDef, existingDef);
+    }
+
+    static String errorBuildingService(String serviceId, ServiceDef serviceDef, Throwable cause)
+    {
+        return MESSAGES.format("error-building-service", serviceId, serviceDef, cause);
+    }
+
+    static String noPublicConstructors(Class moduleBuilderClass)
+    {
+        return MESSAGES.format("no-public-constructors", moduleBuilderClass.getName());
+    }
+
+    static String tooManyPublicConstructors(Class moduleBuilderClass, Constructor constructor)
+    {
+        return MESSAGES.format("too-many-public-constructors", moduleBuilderClass.getName(), constructor);
+    }
+
+    static String recursiveModuleConstructor(Class builderClass, Constructor constructor)
+    {
+        return MESSAGES.format("recursive-module-constructor", builderClass.getName(), constructor);
+    }
+
+    static String constructedConfiguration(Collection result)
+    {
+        return MESSAGES.format("constructed-configuration", result);
+    }
+
+    static String constructedConfiguration(Map result)
+    {
+        return MESSAGES.format("constructed-configuration", result);
+    }
+
+    static String serviceConstructionFailed(ServiceDef serviceDef, Throwable cause)
+    {
+        return MESSAGES.format("service-construction-failed", serviceDef.getServiceId(), cause);
+    }
+
+    static String noSuchService(String serviceId, Collection<String> serviceIds)
+    {
+        return MESSAGES.format("no-such-service", serviceId, InternalUtils.joinSorted(serviceIds));
+    }
+
+    static String serviceIdConflict(String serviceId, ServiceDef existing, ServiceDef conflicting)
+    {
+        return MESSAGES.format("service-id-conflict", serviceId, existing, conflicting);
+    }
+
+    static String noConstructor(Class implementationClass, String serviceId)
+    {
+        return MESSAGES.format("no-constructor", implementationClass.getName(), serviceId);
+    }
+
+    static String bindMethodMustBeStatic(String methodId)
+    {
+        return MESSAGES.format("bind-method-must-be-static", methodId);
+    }
+
+    static String errorInBindMethod(String methodId, Throwable cause)
+    {
+        return MESSAGES.format("error-in-bind-method", methodId, cause);
+    }
+
+    static String noAutobuildConstructor(Class clazz)
+    {
+        return MESSAGES.format("no-autobuild-constructor", clazz.getName());
+    }
+
+    static String autobuildConstructorError(String constructorDescription, Throwable cause)
+    {
+        return MESSAGES.format("autobuild-constructor-error", constructorDescription, cause);
+    }
+
+    static String noServicesMatchMarker(Class objectType, Class marker)
+    {
+        return MESSAGES.format("no-services-match-marker", ClassFabUtils
+                .toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker));
+    }
+
+    static String manyServicesMatchMarker(Class objectType, Class marker, Collection<ServiceDef> matchingServices)
+    {
+        return MESSAGES.format("many-services-match-marker", ClassFabUtils
+                .toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker), InternalUtils
+                .joinSorted(matchingServices));
+    }
+
+    static String overlappingServiceProxyProviders()
+    {
+        return MESSAGES.get("overlapping-service-proxy-providers");
+    }
+
+    static String unexpectedServiceProxyProvider()
+    {
+        return MESSAGES.get("unexpected-service-proxy-provider");
+    }
+
+    static String noProxyProvider(String serviceId)
+    {
+        return MESSAGES.format("no-proxy-provider", serviceId);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IdMatcherImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IdMatcherImpl.java
new file mode 100644
index 0000000..1a570e3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IdMatcherImpl.java
@@ -0,0 +1,35 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.IdMatcher;
+
+/**
+ * A wrapper around a {@link GlobPatternMatcher} used to glob-match service ids.
+ */
+public class IdMatcherImpl implements IdMatcher
+{
+    private final GlobPatternMatcher globMatcher;
+
+    public IdMatcherImpl(String pattern)
+    {
+        globMatcher = new GlobPatternMatcher(pattern);
+    }
+
+    public boolean matches(String id)
+    {
+        return globMatcher.matches(id);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilder.java
new file mode 100644
index 0000000..ba515d2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilder.java
@@ -0,0 +1,76 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceDecorator;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Responsible for constructing the interceptor stack, on demand, by invoking an ordered series of decorators ({@link
+ * org.apache.tapestry.ioc.def.DecoratorDef} (which are converted into {@link ServiceDecorator}s).
+ */
+public class InterceptorStackBuilder implements ObjectCreator
+{
+    private final String serviceId;
+
+    private final ObjectCreator coreServiceCreator;
+
+    private final Module module;
+
+    /**
+     * @param module             the module containing the decorator method
+     * @param serviceId          identifies the service to be decorated
+     * @param coreServiceCreator responsible for creating the core service which is then decorated with a stack of
+     *                           interceptors
+     */
+    public InterceptorStackBuilder(Module module, String serviceId, ObjectCreator coreServiceCreator)
+    {
+        this.module = module;
+        this.serviceId = serviceId;
+        this.coreServiceCreator = coreServiceCreator;
+    }
+
+    public Object createObject()
+    {
+        Object current = coreServiceCreator.createObject();
+
+        List<ServiceDecorator> decorators = module.findDecoratorsForService(serviceId);
+
+        // We get the decorators ordered according to their dependencies. However, we want to
+        // process from the last interceptor to the first, so we reverse the list.
+
+        Collections.reverse(decorators);
+
+        for (ServiceDecorator decorator : decorators)
+        {
+            Object interceptor = decorator.createInterceptor(current);
+
+            // Decorator methods may return null; this indicates that the decorator chose not to
+            // decorate.
+
+            if (interceptor != null) current = interceptor;
+        }
+
+        // The stack of interceptors (plus the core service implementation) are "represented" to the
+        // outside world
+        // as the outermost interceptor. That will still be buried inside the service proxy.
+
+        return current;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InternalRegistry.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InternalRegistry.java
new file mode 100644
index 0000000..002f8b0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/InternalRegistry.java
@@ -0,0 +1,114 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.RegistryShutdownHub;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Internal view of the module registry, adding additional methods needed by modules.
+ */
+public interface InternalRegistry extends Registry, RegistryShutdownHub
+{
+    /**
+     * Returns a service lifecycle by service scope name.
+     *
+     * @param scope the name of the service scope (case insensitive)
+     * @return the lifecycle corresponding to the scope
+     * @throws RuntimeException if the lifecycle name does not match a known lifecycle
+     */
+    ServiceLifecycle getServiceLifecycle(String scope);
+
+    /**
+     * Searches for decorators for a particular service. The resulting
+     * {@link org.apache.tapestry.ioc.def.DecoratorDef}s are ordered, then converted into
+     * {@link ServiceDecorator}s.
+     */
+    List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef);
+
+    /**
+     * Builds up an unordered collection by invoking service contributor methods that target the
+     * service (from any module, unless the service is private).
+     *
+     * @param <T>
+     * @param serviceDef defines the service for which configuration data is being assembled
+     * @param valueType  identifies the type of object allowed into the collection
+     * @return the final collection
+     */
+    <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
+
+    /**
+     * Builds up an ordered collection by invoking service contributor methods that target the
+     * service (from any module, unless the service is private). Once all values have been added
+     * (each with an id, and pre/post constraints), the values are ordered, null values dropped, and
+     * the final sorted list is returned.
+     *
+     * @param <T>
+     * @param serviceDef defines the service for which configuration data is being assembled
+     * @param valueType  identifies the type of object allowed into the collection
+     * @return the final ordered list
+     */
+    <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> valueType);
+
+    /**
+     * Builds up a map of key/value pairs by invoking service contribution methods that tharget the
+     * service (from any module, unless the service is private). Values and keys may not be null.
+     * Invalid values (keys or values that are the wrong type, or duplicate keys) result in warnings
+     * and are ignored.
+     *
+     * @param <K,        V>
+     * @param serviceDef defines the service for which configuration data is being assembled
+     * @param keyType    identifies the type of key object allowed into the map
+     * @param valueType  identifies the type of value object allowed into the map
+     * @return the final ordered list
+     */
+    <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType,
+                                            Class<V> valueType);
+
+    /**
+     * Convieience for creating a new {@link ClassFab} instance using a
+     * {@link org.apache.tapestry.ioc.services.ClassFactory}.
+     *
+     * @param serviceInterface the interface to be implemented by the provided class
+     */
+    ClassFab newClass(Class serviceInterface);
+
+    /**
+     * Given an input string that <em>may</em> contain symbols, returns the string with any and
+     * all symbols fully expanded.
+     *
+     * @param input
+     * @return expanded input
+     */
+    String expandSymbols(String input);
+
+    /**
+     * Returns a logger for the service, which consists of the Module's
+     * {@link Module#getLoggerName() log name} suffixed with a period and the service id.
+     *
+     * @param serviceId
+     * @return the logger for the service
+     */
+    Logger getServiceLogger(String serviceId);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LifecycleWrappedServiceCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LifecycleWrappedServiceCreator.java
new file mode 100644
index 0000000..39d0ee2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LifecycleWrappedServiceCreator.java
@@ -0,0 +1,55 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceResources;
+
+/**
+ * Wrapper around a lifecycle, a set of resources for a service, and an underlying {@link ObjectCreator} for a service
+ * that allows the service lifecycle to alter the way that the service is created (this is needed for the more advanced,
+ * non-singleton types of service lifecycles).
+ */
+public class LifecycleWrappedServiceCreator implements ObjectCreator
+{
+    private final InternalRegistry registry;
+
+    private final String serviceScope;
+
+    private final ServiceResources resources;
+
+    private final ObjectCreator creator;
+
+    public LifecycleWrappedServiceCreator(InternalRegistry registry, String serviceScope,
+                                          ServiceResources resources, ObjectCreator creator)
+    {
+        this.registry = registry;
+        this.serviceScope = serviceScope;
+        this.resources = resources;
+        this.creator = creator;
+    }
+
+    /**
+     * Passes the resources and the service creator through the {@link org.apache.tapestry.ioc.ServiceLifecycle}.
+     */
+    public Object createObject()
+    {
+        ServiceLifecycle lifecycle = registry.getServiceLifecycle(serviceScope);
+
+        return lifecycle.createService(resources, creator);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java
new file mode 100644
index 0000000..11d48c0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/LoggerSourceImpl.java
@@ -0,0 +1,38 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.LoggerSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Simple wrapper around SLF4J's LoggerFactory. The concept here is that Log implementations could
+ * be provided that promote warnings or errors upto thrown exceptions, for people who like their IOC
+ * container extra finicky. In addition, the extra layer makes things a lot easier to mock.
+ */
+public class LoggerSourceImpl implements LoggerSource
+{
+    public Logger getLogger(Class clazz)
+    {
+        return LoggerFactory.getLogger(clazz);
+    }
+
+    public Logger getLogger(String name)
+    {
+        return LoggerFactory.getLogger(name);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/MatchType.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/MatchType.java
new file mode 100644
index 0000000..918597f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/MatchType.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**

+ *

+ */

+package org.apache.tapestry.ioc.internal;

+

+enum MatchType

+{

+    EXACT, PREFIX, SUFFIX, INFIX, ANY

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java
new file mode 100644
index 0000000..8dfbda5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java
@@ -0,0 +1,101 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding module builder instance;
+ * the methods and annotations of that instance define the services provided by the module.
+ */
+public interface Module extends ModuleBuilderSource
+{
+    /**
+     * Locates a service given a service id and the corresponding service interface type.
+     *
+     * @param <T>
+     * @param serviceId        identifies the service to access
+     * @param serviceInterface the interface the service implements
+     * @return the service's proxy
+     * @throws RuntimeException if there is an error instantiating the service proxy
+     */
+    <T> T getService(String serviceId, Class<T> serviceInterface);
+
+    /**
+     * Locates the ids of all services that implement the provided service interface, or whose service interface is
+     * assignable to the provided service interface (is a super-class or super-interface).
+     *
+     * @param serviceInterface the interface to search for
+     * @return a collection of service ids
+     */
+    Collection<String> findServiceIdsForInterface(Class serviceInterface);
+
+    /**
+     * Locates all the decorators that should apply the identified service. This includes visibility rules (private
+     * services may only be decorated by decorators in the same module) and other filtering rules. The resulting list is
+     * ordered and from the list of {@link org.apache.tapestry.ioc.def.DecoratorDef}s, a list of {@link
+     * ServiceDecorator}s is returned.
+     *
+     * @param serviceId identifies the service to be decorated
+     * @return the ordered list of service decorators
+     */
+    List<ServiceDecorator> findDecoratorsForService(String serviceId);
+
+    /**
+     * Iterates over any decorator definitions defined by the module and returns those that apply to the provided
+     * service definition.
+     *
+     * @param serviceDef for which decorators are being assembled
+     * @return set of decorators, possibly empty (but not null)
+     */
+    Set<DecoratorDef> findMatchingDecoratorDefs(ServiceDef serviceDef);
+
+    /**
+     * Finds any contributions that are targetted at the indicated service.
+     */
+    Set<ContributionDef> getContributorDefsForService(String serviceId);
+
+    /**
+     * Locates services with the {@link org.apache.tapestry.ioc.annotation.EagerLoad} annotation and generates proxies
+     * for them, then adds them to the proxies list for instantiation.
+     *
+     * @param proxies collection of proxies to which any eager load services in the module should be added
+     */
+    void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies);
+
+    /**
+     * Returns the service definition for the given service id.
+     *
+     * @param serviceId unique id for the service (caseless)
+     * @return the service definition or null
+     */
+    ServiceDef getServiceDef(String serviceId);
+
+    /**
+     * Returns the name used to obtain a logger for the module. Services within the module suffix this with a period and
+     * the service id.
+     *
+     * @return module logger name
+     */
+    String getLoggerName();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
new file mode 100644
index 0000000..0cdd82e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
@@ -0,0 +1,408 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.services.JustInTimeObjectCreator;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.*;
+import org.slf4j.Logger;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import static java.lang.String.format;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+public class ModuleImpl implements Module
+{
+    private final InternalRegistry registry;
+
+    private final ServiceActivityTracker tracker;
+
+    private final ModuleDef moduleDef;
+
+    private final ClassFactory classFactory;
+
+    private final Logger logger;
+
+    // Guarded by MUTEX
+    private Object moduleBuilder;
+
+    /**
+     * A single mutex, shared by all modules, that serializes creation of services across all threads. This is a bit
+     * draconian, but appears to be necessary. Fortunately, service creation is a very tiny part of any individual
+     * service's lifecycle.
+     */
+    private static final Object MUTEX = new Object();
+
+    // Set to true when invoking the module constructor. Used to
+    // detect endless loops caused by irresponsible dependencies in
+    // the constructor. Guarded by MUTEX.
+    private boolean insideConstructor;
+
+    /**
+     * Keyed on fully qualified service id; values are instantiated services (proxies).
+     */
+    private final Map<String, Object> services = newCaseInsensitiveMap();
+
+    public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker, ModuleDef moduleDef,
+                      ClassFactory classFactory, Logger logger)
+    {
+        this.registry = registry;
+        this.tracker = tracker;
+        this.moduleDef = moduleDef;
+        this.classFactory = classFactory;
+        this.logger = logger;
+    }
+
+    public <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        notBlank(serviceId, "serviceId");
+        notNull(serviceInterface, "serviceInterface");
+        // module may be null.
+
+        ServiceDef def = moduleDef.getServiceDef(serviceId);
+
+        // RegistryImpl should already have checked that the service exists.
+        assert def != null;
+
+        Object service = findOrCreate(def, null);
+
+        try
+        {
+            return serviceInterface.cast(service);
+        }
+        catch (ClassCastException ex)
+        {
+            // This may be overkill: I don't know how this could happen
+            // given that the return type of the method determines
+            // the service interface.
+
+            throw new RuntimeException(IOCMessages.serviceWrongInterface(serviceId, def
+                    .getServiceInterface(), serviceInterface));
+        }
+    }
+
+    public Set<DecoratorDef> findMatchingDecoratorDefs(ServiceDef serviceDef)
+    {
+        Set<DecoratorDef> result = newSet();
+
+        for (DecoratorDef def : moduleDef.getDecoratorDefs())
+        {
+            if (def.matches(serviceDef)) result.add(def);
+        }
+
+        return result;
+    }
+
+    public List<ServiceDecorator> findDecoratorsForService(String serviceId)
+    {
+        ServiceDef sd = moduleDef.getServiceDef(serviceId);
+
+        return registry.findDecoratorsForService(sd);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<String> findServiceIdsForInterface(Class serviceInterface)
+    {
+        notNull(serviceInterface, "serviceInterface");
+
+        Collection<String> result = newList();
+
+        for (String id : moduleDef.getServiceIds())
+        {
+            ServiceDef def = moduleDef.getServiceDef(id);
+
+            if (serviceInterface.isAssignableFrom(def.getServiceInterface())) result.add(id);
+        }
+
+        return result;
+    }
+
+    /**
+     * Locates the service proxy for a particular service (from the service definition).
+     * <p/>
+     * Access is synchronized via {@link #MUTEX}.
+     *
+     * @param def              defines the service
+     * @param eagerLoadProxies TODO
+     * @return the service proxy
+     */
+    private Object findOrCreate(ServiceDef def, Collection<EagerLoadServiceProxy> eagerLoadProxies)
+    {
+        synchronized (MUTEX)
+        {
+            String key = def.getServiceId();
+
+            Object result = services.get(key);
+
+            if (result == null)
+            {
+                result = create(def, eagerLoadProxies);
+                services.put(key, result);
+            }
+
+            return result;
+        }
+    }
+
+    public void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies)
+    {
+        synchronized (MUTEX)
+        {
+            for (String serviceId : moduleDef.getServiceIds())
+            {
+                ServiceDef def = moduleDef.getServiceDef(serviceId);
+
+                if (def.isEagerLoad()) findOrCreate(def, proxies);
+            }
+        }
+    }
+
+    /**
+     * Creates the service and updates the cache of created services. Access is synchronized via {@link #MUTEX}.
+     *
+     * @param eagerLoadProxies a list into which any eager loaded proxies should be added
+     */
+    private Object create(ServiceDef def, Collection<EagerLoadServiceProxy> eagerLoadProxies)
+    {
+        String serviceId = def.getServiceId();
+
+        Logger logger = registry.getServiceLogger(serviceId);
+
+        if (logger.isDebugEnabled()) logger.debug(IOCMessages.creatingService(serviceId));
+
+        try
+        {
+            ServiceBuilderResources resources = new ServiceResourcesImpl(registry, this, def, classFactory, logger);
+
+            // Build up a stack of operations that will be needed to realize the service
+            // (by the proxy, at a later date).
+
+            ObjectCreator creator = def.createServiceCreator(resources);
+
+            Class serviceInterface = def.getServiceInterface();
+
+            // For non-proxyable services, we immediately create the service implementation
+            // and return it. There's no interface to proxy, which throws out the possibility of
+            // deferred instantiation, service lifecycles, and decorators.
+
+            if (!serviceInterface.isInterface()) return creator.createObject();
+
+            creator = new LifecycleWrappedServiceCreator(registry, def.getServiceScope(), resources, creator);
+
+            // Don't allow the core IOC services services to be decorated.
+
+            if (!TapestryIOCModule.class.equals(moduleDef.getBuilderClass()))
+                creator = new InterceptorStackBuilder(this, serviceId, creator);
+
+            // Add a wrapper that checks for recursion.
+
+            creator = new RecursiveServiceCreationCheckWrapper(def, creator, logger);
+
+            JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(tracker, creator, serviceId);
+
+            Object proxy = createProxy(resources, delegate);
+
+            registry.addRegistryShutdownListener(delegate);
+
+            // Occasionally service A may invoke service B from its service builder method; if
+            // service B
+            // is eager loaded, we'll hit this method but eagerLoadProxies will be null. That's OK
+            // ... service B
+            // is being realized anyway.
+
+            if (def.isEagerLoad() && eagerLoadProxies != null) eagerLoadProxies.add(delegate);
+
+            tracker.setStatus(serviceId, Status.VIRTUAL);
+
+            return proxy;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(IOCMessages.errorBuildingService(serviceId, def, ex), ex);
+        }
+    }
+
+    public Object getModuleBuilder()
+    {
+        synchronized (MUTEX)
+        {
+            if (moduleBuilder == null) moduleBuilder = instantiateModuleBuilder();
+
+            return moduleBuilder;
+        }
+    }
+
+    /**
+     * Access synchronized by MUTEX.
+     */
+    private Object instantiateModuleBuilder()
+    {
+        Class builderClass = moduleDef.getBuilderClass();
+
+        Constructor[] constructors = builderClass.getConstructors();
+
+        if (constructors.length == 0) throw new RuntimeException(IOCMessages.noPublicConstructors(builderClass));
+
+        if (constructors.length > 1)
+        {
+            // Sort the constructors ascending by number of parameters (descending); this is really
+            // just to allow the test suite to work properly across different JVMs (which will
+            // often order the constructors differently).
+
+            Comparator<Constructor> comparator = new Comparator<Constructor>()
+            {
+                public int compare(Constructor c1, Constructor c2)
+                {
+                    return c2.getParameterTypes().length - c1.getParameterTypes().length;
+                }
+            };
+
+            Arrays.sort(constructors, comparator);
+
+            logger.warn(IOCMessages.tooManyPublicConstructors(builderClass, constructors[0]));
+        }
+
+        Constructor constructor = constructors[0];
+
+        if (insideConstructor)
+            throw new RuntimeException(IOCMessages.recursiveModuleConstructor(builderClass, constructor));
+
+        ObjectLocator locator = new ObjectLocatorImpl(registry, this);
+        Map<Class, Object> parameterDefaults = newMap();
+
+        parameterDefaults.put(Logger.class, logger);
+        parameterDefaults.put(ObjectLocator.class, locator);
+
+        Throwable fail = null;
+
+        try
+        {
+            insideConstructor = true;
+
+            Object[] parameterValues = InternalUtils.calculateParameters(locator, parameterDefaults,
+                                                                         constructor.getParameterTypes(),
+                                                                         constructor.getParameterAnnotations());
+
+            return constructor.newInstance(parameterValues);
+        }
+        catch (InvocationTargetException ex)
+        {
+            fail = ex.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            fail = ex;
+        }
+        finally
+        {
+            insideConstructor = false;
+        }
+
+        throw new RuntimeException(IOCMessages.instantiateBuilderError(builderClass, fail), fail);
+    }
+
+    private Object createProxy(ServiceResources resources, ObjectCreator creator)
+    {
+        String serviceId = resources.getServiceId();
+        Class serviceInterface = resources.getServiceInterface();
+
+        String toString = format("<Proxy for %s(%s)>", serviceId, serviceInterface.getName());
+
+        return createProxyInstance(creator, serviceId, serviceInterface, toString);
+    }
+
+    private Object createProxyInstance(ObjectCreator creator, String serviceId, Class serviceInterface,
+                                       String description)
+    {
+        ServiceProxyToken token = SerializationSupport.createToken(serviceId);
+
+        ClassFab classFab = registry.newClass(serviceInterface);
+
+        classFab.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
+        classFab.addField("_token", Modifier.PRIVATE | Modifier.FINAL, ServiceProxyToken.class);
+
+        classFab.addConstructor(new Class[] { ObjectCreator.class, ServiceProxyToken.class }, null,
+                                "{ _creator = $1; _token = $2; }");
+
+        // Make proxies serializable by writing the token to the stream.
+
+        classFab.addInterface(Serializable.class);
+
+        // This is the "magic" signature that allows an object to substitute some other
+        // object for itself.
+        MethodSignature writeReplaceSig = new MethodSignature(Object.class, "writeReplace", null,
+                                                              new Class[] { ObjectStreamException.class });
+
+        classFab.addMethod(Modifier.PRIVATE, writeReplaceSig, "return _token;");
+
+        // Now delegate all the methods.
+
+        String body = format("return (%s) _creator.createObject();", serviceInterface.getName());
+
+        MethodSignature sig = new MethodSignature(serviceInterface, "_delegate", null, null);
+
+        classFab.addMethod(Modifier.PRIVATE, sig, body);
+
+        classFab.proxyMethodsToDelegate(serviceInterface, "_delegate()", description);
+
+        Class proxyClass = classFab.createClass();
+
+        try
+        {
+            return proxyClass.getConstructors()[0].newInstance(creator, token);
+        }
+        catch (Exception ex)
+        {
+            // Exceptions should not happen.
+
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
+    }
+
+    public Set<ContributionDef> getContributorDefsForService(String serviceId)
+    {
+        Set<ContributionDef> result = newSet();
+
+        for (ContributionDef def : moduleDef.getContributionDefs())
+        {
+            if (def.getServiceId().equals(serviceId)) result.add(def);
+        }
+
+        return result;
+    }
+
+    public ServiceDef getServiceDef(String serviceId)
+    {
+        return moduleDef.getServiceDef(serviceId);
+    }
+
+    public String getLoggerName()
+    {
+        return moduleDef.getLoggerName();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/NullAnnotationProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/NullAnnotationProvider.java
new file mode 100644
index 0000000..f22f489
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/NullAnnotationProvider.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * A null implementation of {@link AnnotationProvider}, used when there is not appropriate source
+ * of annotations.
+ */
+public class NullAnnotationProvider implements AnnotationProvider
+{
+    /**
+     * Always returns null.
+     */
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectCreatorSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectCreatorSource.java
new file mode 100644
index 0000000..b8c1ad5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectCreatorSource.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+
+/**
+ * An object which can, when passed a {@link ServiceBuilderResources}, create a corresponding
+ * {@link ObjectCreator}. A secondary responsibility is to provide a description of the creator,
+ * which is usually based on the name of the method or constructor to be invoked, and is ultimately
+ * used in some debugging or error output.
+ */
+public interface ObjectCreatorSource
+{
+    /**
+     * Provides an ObjectCreator that can be used to ultimately instantiate the core service
+     * implementation.
+     */
+    ObjectCreator constructCreator(ServiceBuilderResources resources);
+
+    /**
+     * Returns a description of the method or constructor that creates the service.
+     */
+    String getDescription();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectLocatorImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectLocatorImpl.java
new file mode 100644
index 0000000..dcf9c9d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ObjectLocatorImpl.java
@@ -0,0 +1,72 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+
+/**
+ * Base service locator class used when only the module is known (i.e., when instantiating a module builder class).
+ */
+public class ObjectLocatorImpl implements ObjectLocator
+{
+    private final InternalRegistry registry;
+
+    private final Module module;
+
+    public ObjectLocatorImpl(InternalRegistry registry, Module module)
+    {
+        this.registry = registry;
+        this.module = module;
+    }
+
+    public <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        String expandedServiceId = registry.expandSymbols(serviceId);
+
+        return registry.getService(expandedServiceId, serviceInterface);
+    }
+
+    public <T> T getService(Class<T> serviceInterface)
+    {
+        return registry.getService(serviceInterface);
+    }
+
+    public <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
+    {
+        return registry.getObject(objectType, annotationProvider);
+    }
+
+    protected InternalRegistry getRegistry()
+    {
+        return registry;
+    }
+
+    protected Module getModule()
+    {
+        return module;
+    }
+
+    public <T> T autobuild(Class<T> clazz)
+    {
+        return registry.autobuild(clazz);
+    }
+
+    public <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass)
+    {
+        return registry.proxy(interfaceClass, implementationClass);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java
new file mode 100644
index 0000000..35e6ec4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/OrIdMatcher.java
@@ -0,0 +1,41 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal;

+

+import org.apache.tapestry.ioc.IdMatcher;

+

+import java.util.Collection;

+

+/**

+ * A wrapper around a collection of IdMatchers. A match occurs if <em>any</em> matcher matches.

+ */

+public final class OrIdMatcher implements IdMatcher

+{

+    private final IdMatcher[] matchers;

+

+    public OrIdMatcher(Collection<IdMatcher> matchers)

+    {

+        this.matchers = matchers.toArray(new IdMatcher[matchers.size()]);

+    }

+

+    public boolean matches(String id)

+    {

+        for (IdMatcher m : matchers)

+            if (m.matches(id)) return true;

+

+        return false;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapper.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapper.java
new file mode 100644
index 0000000..3c766f8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapper.java
@@ -0,0 +1,75 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.slf4j.Logger;
+
+/**
+ * Decorator for {@link org.apache.tapestry.ioc.ObjectCreator} that ensures the service is only created once. This
+ * detects a situation where the service builder for a service directly or indirectly invokes methods on the service
+ * itself. This would show up as a second call up the ServiceCreator stack injected into the proxy, potentially leading
+ * to endless recursion. We try to identify that recursion and produce a useable exception report.
+ */
+public class RecursiveServiceCreationCheckWrapper implements ObjectCreator
+{
+    private final ServiceDef serviceDef;
+
+    private final ObjectCreator delegate;
+
+    private final Logger logger;
+
+    private boolean locked;
+
+    public RecursiveServiceCreationCheckWrapper(ServiceDef serviceDef, ObjectCreator delegate,
+                                                Logger logger)
+    {
+        this.serviceDef = serviceDef;
+        this.delegate = delegate;
+        this.logger = logger;
+    }
+
+    /**
+     * We could make this method synchronized, but in the context of creating a service for a proxy, it will already be
+     * synchronized (inside the proxy).
+     */
+    public Object createObject()
+    {
+        if (locked)
+            throw new IllegalStateException(IOCMessages.recursiveServiceBuild(serviceDef));
+
+        // Set the lock, to ensure that recursive service construction fails.
+
+        locked = true;
+
+        try
+        {
+            return delegate.createObject();
+        }
+        catch (RuntimeException ex)
+        {
+            logger.error(IOCMessages.serviceConstructionFailed(serviceDef, ex), ex);
+
+            // Release the lock on failure; the service is now in an unknown state, but we may
+            // be able to continue from here.
+
+            locked = false;
+
+            throw ex;
+        }
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
new file mode 100644
index 0000000..4e77237
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
@@ -0,0 +1,786 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.services.PerthreadManagerImpl;
+import org.apache.tapestry.ioc.internal.services.RegistryShutdownHubImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.internal.util.Orderer;
+import org.apache.tapestry.ioc.services.*;
+import org.slf4j.Logger;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+public class RegistryImpl implements Registry, InternalRegistry, ServiceProxyProvider
+{
+    private static final String SYMBOL_SOURCE_SERVICE_ID = "SymbolSource";
+
+    private static final String REGISTRY_SHUTDOWN_HUB_SERVICE_ID = "RegistryShutdownHub";
+
+    static final String PERTHREAD_MANAGER_SERVICE_ID = "PerthreadManager";
+
+    private static final String SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID = "ServiceActivityScoreboard";
+
+    /**
+     * The set of marker annotations for a builtin service.
+     */
+    private final static Set<Class> BUILTIN = CollectionFactory.newSet();
+
+    static
+    {
+        BUILTIN.add(Builtin.class);
+    }
+
+    /**
+     * Used to obtain the {@link org.apache.tapestry.ioc.services.ClassFactory} service, which is crucial when creating
+     * runtime classes for proxies and the like.
+     */
+    static final String CLASS_FACTORY_SERVICE_ID = "ClassFactory";
+
+    static final String LOGGER_SOURCE_SERVICE_ID = "LoggerSource";
+
+    private final OneShotLock lock = new OneShotLock();
+
+    private final OneShotLock eagerLoadLock = new OneShotLock();
+
+    private final Map<String, Object> builtinServices = newCaseInsensitiveMap();
+
+    private final Map<String, Class> builtinTypes = newCaseInsensitiveMap();
+
+    private final RegistryShutdownHubImpl registryShutdownHub;
+
+    private final LoggerSource loggerSource;
+
+    /**
+     * Map from service id to the Module that contains the service.
+     */
+    private final Map<String, Module> serviceIdToModule = newCaseInsensitiveMap();
+
+    private final Map<String, ServiceLifecycle> lifecycles = newCaseInsensitiveMap();
+
+    private final PerthreadManager perthreadManager;
+
+    private final ClassFactory classFactory;
+
+    private final ServiceActivityTracker tracker;
+
+    private SymbolSource symbolSource;
+
+    private final List<Module> modules = newList();
+
+    /**
+     * From marker type to a list of marked service instances.
+     */
+    private final Map<Class, List<ServiceDef>> markerToServiceDef = newMap();
+
+
+    public static final class OrderedConfigurationToOrdererAdaptor<T> implements OrderedConfiguration<T>
+    {
+        private final Orderer<T> orderer;
+
+        public OrderedConfigurationToOrdererAdaptor(Orderer<T> orderer)
+        {
+            this.orderer = orderer;
+        }
+
+        public void add(String id, T object, String... constraints)
+        {
+            orderer.add(id, object, constraints);
+        }
+    }
+
+    /**
+     * Constructs the registry from a set of module definitions and other resources.
+     *
+     * @param moduleDefs   defines the modules (and builders, decorators, etc., within)
+     * @param classFactory TODO
+     * @param loggerSource used to obtain Logger instances
+     */
+    public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassFactory classFactory, LoggerSource loggerSource)
+    {
+        this.loggerSource = loggerSource;
+
+        final ServiceActivityTrackerImpl scoreboardAndTracker = new ServiceActivityTrackerImpl();
+
+        tracker = scoreboardAndTracker;
+
+        addBuiltin(SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID, ServiceActivityScoreboard.class, scoreboardAndTracker);
+
+        addBuiltin(LOGGER_SOURCE_SERVICE_ID, LoggerSource.class, this.loggerSource);
+
+        this.classFactory = classFactory;
+
+        addBuiltin(CLASS_FACTORY_SERVICE_ID, ClassFactory.class, this.classFactory);
+
+        Logger logger = loggerForBuiltinService(PERTHREAD_MANAGER_SERVICE_ID);
+
+        perthreadManager = new PerthreadManagerImpl(logger);
+
+        addBuiltin(PERTHREAD_MANAGER_SERVICE_ID, PerthreadManager.class, perthreadManager);
+
+        logger = loggerForBuiltinService(REGISTRY_SHUTDOWN_HUB_SERVICE_ID);
+
+        registryShutdownHub = new RegistryShutdownHubImpl(logger);
+
+        addBuiltin(REGISTRY_SHUTDOWN_HUB_SERVICE_ID, RegistryShutdownHub.class, registryShutdownHub);
+
+        lifecycles.put("singleton", new SingletonServiceLifecycle());
+
+        registryShutdownHub.addRegistryShutdownListener(new RegistryShutdownListener()
+        {
+            public void registryDidShutdown()
+            {
+                scoreboardAndTracker.shutdown();
+            }
+        });
+
+        for (ModuleDef def : moduleDefs)
+        {
+            logger = this.loggerSource.getLogger(def.getLoggerName());
+
+            Module module = new ModuleImpl(this, tracker, def, classFactory, logger);
+
+            modules.add(module);
+
+            for (String serviceId : def.getServiceIds())
+            {
+                ServiceDef serviceDef = module.getServiceDef(serviceId);
+
+                Module existing = serviceIdToModule.get(serviceId);
+
+                if (existing != null) throw new RuntimeException(IOCMessages.serviceIdConflict(serviceId, existing
+                        .getServiceDef(serviceId), serviceDef));
+
+                serviceIdToModule.put(serviceId, module);
+
+                // The service is defined but will not have gone further than that.
+                tracker.define(serviceDef, Status.DEFINED);
+
+                for (Class marker : serviceDef.getMarkers())
+                    InternalUtils.addToMapList(markerToServiceDef, marker, serviceDef);
+
+            }
+        }
+
+        scoreboardAndTracker.startup();
+
+        SerializationSupport.setProvider(this);
+    }
+
+    /**
+     * It's not unreasonable for an eagerly-loaded service to decide to start a thread, at which point we raise issues
+     * about improper publishing of the Registry instance from the RegistryImpl constructor. Moving eager loading of
+     * services out to its own method should ensure thread safety.
+     */
+    public void performRegistryStartup()
+    {
+        eagerLoadLock.lock();
+
+        List<EagerLoadServiceProxy> proxies = CollectionFactory.newList();
+
+        for (Module m : modules)
+            m.collectEagerLoadServices(proxies);
+
+        // TAPESTRY-2267: Gather up all the proxies before instantiating any of them.
+
+        for (EagerLoadServiceProxy proxy : proxies)
+            proxy.eagerLoadService();
+
+        getService("RegistryStartup", Runnable.class).run();
+
+        cleanupThread();
+    }
+
+    public Logger getServiceLogger(String serviceId)
+    {
+        Module module = serviceIdToModule.get(serviceId);
+
+        assert module != null;
+
+        return loggerSource.getLogger(module.getLoggerName() + "." + serviceId);
+    }
+
+    private Logger loggerForBuiltinService(String serviceId)
+    {
+        return loggerSource.getLogger(TapestryIOCModule.class + "." + serviceId);
+    }
+
+    private <T> void addBuiltin(final String serviceId, final Class<T> serviceInterface, T service)
+    {
+        builtinTypes.put(serviceId, serviceInterface);
+        builtinServices.put(serviceId, service);
+
+        // Make sure each of the builtin services is also available via the Builtin annotation
+        // marker.
+
+        ServiceDef serviceDef = new ServiceDef()
+        {
+            public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
+            {
+                return null;
+            }
+
+            public Set<Class> getMarkers()
+            {
+                return BUILTIN;
+            }
+
+            public String getServiceId()
+            {
+                return serviceId;
+            }
+
+            public Class getServiceInterface()
+            {
+                return serviceInterface;
+            }
+
+            public String getServiceScope()
+            {
+                return IOCConstants.DEFAULT_SCOPE;
+            }
+
+            public boolean isEagerLoad()
+            {
+                return false;
+            }
+        };
+
+        for (Class marker : serviceDef.getMarkers())
+            InternalUtils.addToMapList(markerToServiceDef, marker, serviceDef);
+
+        tracker.define(serviceDef, Status.BUILTIN);
+    }
+
+    public synchronized void shutdown()
+    {
+        lock.lock();
+
+        registryShutdownHub.fireRegistryDidShutdown();
+
+        SerializationSupport.clearProvider(this);
+    }
+
+    public <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        lock.check();
+
+        T result = checkForBuiltinService(serviceId, serviceInterface);
+        if (result != null) return result;
+
+        // Checking serviceId and serviceInterface is overkill; they have been checked and rechecked
+        // all the way to here.
+
+        Module containingModule = locateModuleForService(serviceId);
+
+        return containingModule.getService(serviceId, serviceInterface);
+    }
+
+    private <T> T checkForBuiltinService(String serviceId, Class<T> serviceInterface)
+    {
+        Object service = builtinServices.get(serviceId);
+
+        if (service == null) return null;
+
+        try
+        {
+            return serviceInterface.cast(service);
+        }
+        catch (ClassCastException ex)
+        {
+            throw new RuntimeException(IOCMessages.serviceWrongInterface(serviceId, builtinTypes
+                    .get(serviceId), serviceInterface));
+        }
+    }
+
+    public void cleanupThread()
+    {
+        lock.check();
+
+        perthreadManager.cleanup();
+    }
+
+    private Module locateModuleForService(String serviceId)
+    {
+        Module module = serviceIdToModule.get(serviceId);
+
+        if (module == null) throw new RuntimeException(IOCMessages.noSuchService(serviceId, serviceIdToModule
+                .keySet()));
+
+        return module;
+    }
+
+    public <T> Collection<T> getUnorderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
+    {
+        lock.check();
+
+        final Collection<T> result = newList();
+
+        Configuration<T> configuration = new Configuration<T>()
+        {
+            public void add(T object)
+            {
+                result.add(object);
+            }
+        };
+
+        Collection<Module> modules = this.modules;
+
+        for (Module m : modules)
+            addToUnorderedConfiguration(configuration, objectType, serviceDef, m);
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> List<T> getOrderedConfiguration(ServiceDef serviceDef, Class<T> objectType)
+    {
+        lock.check();
+
+        String serviceId = serviceDef.getServiceId();
+        Logger logger = getServiceLogger(serviceId);
+
+        final Orderer<T> orderer = new Orderer<T>(logger);
+
+        OrderedConfiguration<T> configuration = new OrderedConfigurationToOrdererAdaptor<T>(orderer);
+
+        Collection<Module> modules = this.modules;
+
+        for (Module m : modules)
+            addToOrderedConfiguration(configuration, objectType, serviceDef, m);
+
+        // An ugly hack ... perhaps we should introduce a new builtin service so that this can be
+        // accomplished in the normal way?
+
+        if (serviceId.equals("MasterObjectProvider"))
+        {
+            ObjectProvider contribution = new ObjectProvider()
+            {
+                public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+                {
+                    return findServiceByMarkerAndType(objectType, annotationProvider);
+                }
+            };
+
+            configuration.add("ServiceByMarker", (T) contribution);
+        }
+
+        return orderer.getOrdered();
+    }
+
+    public <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType, Class<V> objectType)
+    {
+        lock.check();
+
+        // When the key type is String, then a case insensitive map is used for both cases.
+
+        final Map<K, V> result = newConfigurationMap(keyType);
+        Map<K, ContributionDef> keyToContribution = newConfigurationMap(keyType);
+
+        MappedConfiguration<K, V> configuration = new MappedConfiguration<K, V>()
+        {
+            public void add(K key, V value)
+            {
+                result.put(key, value);
+            }
+        };
+
+        Collection<Module> modules = this.modules;
+
+        for (Module m : modules)
+            addToMappedConfiguration(configuration, keyToContribution, keyType, objectType, serviceDef, m);
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <K, V> Map<K, V> newConfigurationMap(Class<K> keyType)
+    {
+        if (keyType.equals(String.class))
+        {
+            Map<String, K> result = newCaseInsensitiveMap();
+
+            return (Map<K, V>) result;
+        }
+
+        return newMap();
+    }
+
+    private <K, V> void addToMappedConfiguration(MappedConfiguration<K, V> configuration,
+                                                 Map<K, ContributionDef> keyToContribution, Class<K> keyClass,
+                                                 Class<V> valueType, ServiceDef serviceDef, Module module)
+    {
+        String serviceId = serviceDef.getServiceId();
+        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+
+        if (contributions.isEmpty()) return;
+
+        Logger logger = getServiceLogger(serviceId);
+
+        boolean debug = logger.isDebugEnabled();
+
+        ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, classFactory, logger);
+
+        for (ContributionDef def : contributions)
+        {
+            MappedConfiguration<K, V> validating = new ValidatingMappedConfigurationWrapper<K, V>(serviceId, def,
+                                                                                                  logger, keyClass,
+                                                                                                  valueType,
+                                                                                                  keyToContribution,
+                                                                                                  configuration);
+
+            if (debug) logger.debug(IOCMessages.invokingMethod(def));
+
+            def.contribute(module, locator, validating);
+        }
+
+    }
+
+    private <T> void addToUnorderedConfiguration(Configuration<T> configuration, Class<T> valueType,
+                                                 ServiceDef serviceDef, Module module)
+    {
+        String serviceId = serviceDef.getServiceId();
+        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+
+        if (contributions.isEmpty()) return;
+
+        Logger logger = getServiceLogger(serviceId);
+
+        boolean debug = logger.isDebugEnabled();
+
+        ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, classFactory, logger);
+
+        for (ContributionDef def : contributions)
+        {
+            Configuration<T> validating = new ValidatingConfigurationWrapper<T>(serviceId, logger, valueType, def,
+                                                                                configuration);
+
+            if (debug) logger.debug(IOCMessages.invokingMethod(def));
+
+            def.contribute(module, locator, validating);
+        }
+    }
+
+    private <T> void addToOrderedConfiguration(OrderedConfiguration<T> configuration, Class<T> valueType,
+                                               ServiceDef serviceDef, Module module)
+    {
+        String serviceId = serviceDef.getServiceId();
+        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+
+        if (contributions.isEmpty()) return;
+
+        Logger logger = getServiceLogger(serviceId);
+        boolean debug = logger.isDebugEnabled();
+
+        ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, classFactory, logger);
+
+        for (ContributionDef def : contributions)
+        {
+            OrderedConfiguration<T> validating = new ValidatingOrderedConfigurationWrapper<T>(serviceId, def, logger,
+                                                                                              valueType, configuration);
+
+            if (debug) logger.debug(IOCMessages.invokingMethod(def));
+
+            def.contribute(module, locator, validating);
+        }
+    }
+
+    public <T> T getService(Class<T> serviceInterface)
+    {
+        lock.check();
+
+        List<String> serviceIds = findServiceIdsForInterface(serviceInterface);
+
+        if (serviceIds == null) serviceIds = Collections.emptyList();
+
+        switch (serviceIds.size())
+        {
+            case 0:
+
+                throw new RuntimeException(IOCMessages.noServiceMatchesType(serviceInterface));
+
+            case 1:
+
+                String serviceId = serviceIds.get(0);
+
+                return getService(serviceId, serviceInterface);
+
+            default:
+
+                Collections.sort(serviceIds);
+
+                throw new RuntimeException(IOCMessages.manyServiceMatches(serviceInterface, serviceIds));
+        }
+    }
+
+    private List<String> findServiceIdsForInterface(Class serviceInterface)
+    {
+        List<String> result = newList();
+
+        for (Module module : modules)
+            result.addAll(module.findServiceIdsForInterface(serviceInterface));
+
+        for (Map.Entry<String, Object> entry : builtinServices.entrySet())
+        {
+            if (serviceInterface.isInstance(entry.getValue())) result.add(entry.getKey());
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    public ServiceLifecycle getServiceLifecycle(String scope)
+    {
+        lock.check();
+
+        ServiceLifecycle result = lifecycles.get(scope);
+
+        if (result == null)
+        {
+            ServiceLifecycleSource source = getService("ServiceLifecycleSource", ServiceLifecycleSource.class);
+            result = source.get(scope);
+        }
+
+        if (result == null) throw new RuntimeException(IOCMessages.unknownScope(scope));
+
+        return result;
+    }
+
+    public List<ServiceDecorator> findDecoratorsForService(ServiceDef serviceDef)
+    {
+        lock.check();
+
+        assert serviceDef != null;
+
+        Logger logger = getServiceLogger(serviceDef.getServiceId());
+
+        Orderer<ServiceDecorator> orderer = new Orderer<ServiceDecorator>(logger);
+
+        for (Module module : modules)
+        {
+            Set<DecoratorDef> decorators = module.findMatchingDecoratorDefs(serviceDef);
+
+            if (decorators.isEmpty()) continue;
+
+            ServiceResources resources = new ServiceResourcesImpl(this, module, serviceDef, classFactory, logger);
+
+            for (DecoratorDef dd : decorators)
+            {
+                ServiceDecorator sd = dd.createDecorator(module, resources);
+
+                orderer.add(dd.getDecoratorId(), sd, dd.getConstraints());
+            }
+        }
+
+        return orderer.getOrdered();
+    }
+
+    public ClassFab newClass(Class serviceInterface)
+    {
+        lock.check();
+
+        return classFactory.newClass(serviceInterface);
+    }
+
+    private <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+    {
+        lock.check();
+
+        AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider : new NullAnnotationProvider();
+
+        // We do a check here for known marker/type combinations, so that you can use a marker
+        // annotation
+        // to inject into a contribution method that contributes to MasterObjectProvider.
+        // We also force a contribution into MasterObjectProvider to accomplish the same thing.
+
+        T result = findServiceByMarkerAndType(objectType, annotationProvider);
+
+        if (result != null) return result;
+
+        MasterObjectProvider masterProvider = getService(IOCConstants.MASTER_OBJECT_PROVIDER_SERVICE_ID,
+                                                         MasterObjectProvider.class);
+
+        return masterProvider.provide(objectType, effectiveProvider, locator, true);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T findServiceByMarkerAndType(Class<T> objectType, AnnotationProvider provider)
+    {
+        if (provider == null) return null;
+
+        for (Class marker : markerToServiceDef.keySet())
+        {
+            if (provider.getAnnotation(marker) == null) continue;
+
+            List<ServiceDef> matches = newList();
+
+            for (ServiceDef def : markerToServiceDef.get(marker))
+            {
+                if (objectType.isAssignableFrom(def.getServiceInterface())) matches.add(def);
+            }
+
+            switch (matches.size())
+            {
+
+                case 1:
+
+                    ServiceDef def = matches.get(0);
+
+                    return getService(def.getServiceId(), objectType);
+
+                case 0:
+
+                    // It's no accident that the user put the marker annotation at the injection
+                    // point, since it matches a known marker annotation, it better be there for
+                    // a reason. So if we don't get a match, we have to assume the user expected
+                    // one, and that is an error.
+
+                    // This doesn't help when the user places an annotation they *think* is a marker
+                    // but isn't really a marker (because no service is marked by the annotation).
+
+                    throw new RuntimeException(IOCMessages
+                            .noServicesMatchMarker(objectType, marker));
+
+                default:
+                    throw new RuntimeException(IOCMessages.manyServicesMatchMarker(objectType, marker, matches));
+            }
+
+        }
+
+        return null;
+    }
+
+    public <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
+    {
+        lock.check();
+
+        return getObject(objectType, annotationProvider, this);
+    }
+
+    public void addRegistryShutdownListener(RegistryShutdownListener listener)
+    {
+        lock.check();
+
+        registryShutdownHub.addRegistryShutdownListener(listener);
+    }
+
+    public String expandSymbols(String input)
+    {
+        lock.check();
+
+        // Again, a bit of work to avoid instantiating the SymbolSource until absolutely necessary.
+
+        if (!InternalUtils.containsSymbols(input)) return input;
+
+        return getSymbolSource().expandSymbols(input);
+    }
+
+    /**
+     * Defers obtaining the symbol source until actually needed.
+     */
+    private synchronized SymbolSource getSymbolSource()
+    {
+        if (symbolSource == null) symbolSource = getService(SYMBOL_SOURCE_SERVICE_ID, SymbolSource.class);
+
+        return symbolSource;
+    }
+
+    public <T> T autobuild(Class<T> clazz)
+    {
+        notNull(clazz, "clazz");
+
+        Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
+
+        if (constructor == null) throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
+
+        Throwable failure;
+        // An empty map, because when performing autobuilding outside the context of building a
+        // service, we don't have defaults for Log, service id, etc.
+
+        Map<Class, Object> empty = Collections.emptyMap();
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForConstructor(constructor, this, empty);
+
+            return clazz.cast(constructor.newInstance(parameters));
+        }
+        catch (InvocationTargetException ite)
+        {
+            failure = ite.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            failure = ex;
+        }
+
+        String description = classFactory.getConstructorLocation(constructor).toString();
+
+        throw new RuntimeException(IOCMessages.autobuildConstructorError(description, failure), failure);
+    }
+
+    public <T> T proxy(Class<T> interfaceClass, final Class<? extends T> implementationClass)
+    {
+        notNull(interfaceClass, "interfaceClass");
+        notNull(implementationClass, "implementationClass");
+
+        // TODO: Check really an interface
+        // TODO: Check impl class extends interfaceClass and is concrete
+
+        final ObjectCreator autobuildCreator = new ObjectCreator()
+        {
+            public Object createObject()
+            {
+                return autobuild(implementationClass);
+            }
+        };
+
+        ObjectCreator justInTime = new ObjectCreator()
+        {
+            private Object delegate;
+
+            public synchronized Object createObject()
+            {
+                if (delegate == null) delegate = autobuildCreator.createObject();
+
+                return delegate;
+            }
+        };
+
+        ClassFab cf = classFactory.newClass(interfaceClass);
+
+        String description = String.format("<Autobuild proxy %s(%s)>", implementationClass
+                .getName(), interfaceClass.getName());
+
+        return ClassFabUtils.createObjectCreatorProxy(cf, interfaceClass, justInTime, description);
+    }
+
+    public Object provideServiceProxy(String serviceId)
+    {
+        return getService(serviceId, Object.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java
new file mode 100644
index 0000000..4eb7eb8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryWrapper.java
@@ -0,0 +1,76 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.Registry;
+
+/**
+ * A wrapper around {@link InternalRegistry} that exists to expand symbols in a service id before invoking {@link
+ * ObjectLocator#getService(Class)}.
+ */
+public class RegistryWrapper implements Registry
+{
+    private final InternalRegistry registry;
+
+    public RegistryWrapper(final InternalRegistry registry)
+    {
+        this.registry = registry;
+    }
+
+    public void cleanupThread()
+    {
+        registry.cleanupThread();
+    }
+
+    public void shutdown()
+    {
+        registry.shutdown();
+    }
+
+    public <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider)
+    {
+        return registry.getObject(objectType, annotationProvider);
+    }
+
+    public <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        String expandedServiceId = registry.expandSymbols(serviceId);
+
+        return registry.getService(expandedServiceId, serviceInterface);
+    }
+
+    public <T> T getService(Class<T> serviceInterface)
+    {
+        return registry.getService(serviceInterface);
+    }
+
+    public <T> T autobuild(Class<T> clazz)
+    {
+        return registry.autobuild(clazz);
+    }
+
+    public void performRegistryStartup()
+    {
+        registry.performRegistryStartup();
+    }
+
+    public <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass)
+    {
+        return registry.proxy(interfaceClass, implementationClass);
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java
new file mode 100644
index 0000000..24af031
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java
@@ -0,0 +1,81 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Serialization support for service proxies.
+ */
+class SerializationSupport
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(SerializationSupport.class);
+
+    // We use a weak reference so that the underlying Registry can be reclaimed by the garbage collector
+    // even if it is not explicitly shut down.
+
+    private static WeakReference<ServiceProxyProvider> providerRef;
+
+    static synchronized void setProvider(ServiceProxyProvider proxyProvider)
+    {
+        ServiceProxyProvider existing = currentProvider();
+
+        if (existing != null) LOGGER.error(IOCMessages.overlappingServiceProxyProviders());
+
+        providerRef = new WeakReference<ServiceProxyProvider>(proxyProvider);
+    }
+
+    private static ServiceProxyProvider currentProvider()
+    {
+        return providerRef == null ? null : providerRef.get();
+    }
+
+    static synchronized void clearProvider(ServiceProxyProvider proxyProvider)
+    {
+        ServiceProxyProvider existing = currentProvider();
+
+        // The registry does a setProvider() at startup, and we want to make sure that we're the only Registry, that
+        // there hasn't been another setProvider() by another Registry.
+
+        if (existing != proxyProvider)
+        {
+            LOGGER.error(IOCMessages.unexpectedServiceProxyProvider());
+            return;
+        }
+
+        // Good. It's all the expected simple case, without duelling registries. Kill the reference
+        // to the registry.
+
+        providerRef = null;
+    }
+
+    static synchronized Object readResolve(String serviceId)
+    {
+        ServiceProxyProvider provider = currentProvider();
+
+        if (provider == null) throw new RuntimeException(IOCMessages.noProxyProvider(serviceId));
+
+        return provider.provideServiceProxy(serviceId);
+    }
+
+    static ServiceProxyToken createToken(String serviceId)
+    {
+        return new ServiceProxyToken(serviceId);
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java
new file mode 100644
index 0000000..5f903ee
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java
@@ -0,0 +1,42 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
+
+/**
+ * Used to update the status of services defined by the {@link ServiceActivityScoreboard}.
+ */
+public interface ServiceActivityTracker
+{
+
+    /**
+     * Defines a service in the tracker with an initial status.
+     *
+     * @param serviceDef    the service being defined
+     * @param initialStatus typically {@link Status#BUILTIN} or {@link Status#DEFINED}
+     */
+    void define(ServiceDef serviceDef, Status initialStatus);
+
+    /**
+     * Updates the status for the service.
+     *
+     * @param serviceId identifies the service, which must be previously defined
+     * @param status    the new status value
+     */
+    void setStatus(String serviceId, Status status);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java
new file mode 100644
index 0000000..2b947a4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java
@@ -0,0 +1,112 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
+
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class ServiceActivityTrackerImpl implements ServiceActivityScoreboard,
+        ServiceActivityTracker
+{
+    public static class MutableServiceActivity implements ServiceActivity
+    {
+        private final ServiceDef serviceDef;
+
+        private Status status;
+
+        public MutableServiceActivity(ServiceDef serviceDef, Status status)
+        {
+            this.serviceDef = serviceDef;
+            this.status = status;
+        }
+
+        public String getServiceId()
+        {
+            return serviceDef.getServiceId();
+        }
+
+        public Class getServiceInterface()
+        {
+            return serviceDef.getServiceInterface();
+        }
+
+        public String getScope()
+        {
+            return serviceDef.getServiceScope();
+        }
+
+        // Mutable properties must be synchronized
+
+        public synchronized Status getStatus()
+        {
+            return status;
+        }
+
+        synchronized void setStatus(Status status)
+        {
+            this.status = status;
+        }
+    }
+
+    /**
+     * Tree map keeps everything in order by key (serviceId).
+     */
+    private final Map<String, MutableServiceActivity> serviceIdToServiceStatus = new TreeMap<String, MutableServiceActivity>();
+
+    public synchronized List<ServiceActivity> getServiceActivity()
+    {
+        // Need to wrap the values in a new list because
+        // a) we don't want people arbitrarily changing the internal state of
+        // _serviceIdtoServiceStatus
+        // b) values() is Collection and we want to return List
+
+        // Note: ugly code here to keep Sun compiler happy.
+
+        List<ServiceActivity> result = CollectionFactory.newList();
+
+        result.addAll(serviceIdToServiceStatus.values());
+
+        return result;
+    }
+
+    void startup()
+    {
+        // Does nothing, first pass does not use a worker thread
+    }
+
+    void shutdown()
+    {
+        // Does nothing, first pass does not use a worker thread
+    }
+
+    public synchronized void define(ServiceDef serviceDef, Status initialStatus)
+    {
+        serviceIdToServiceStatus.put(serviceDef.getServiceId(), new MutableServiceActivity(
+                serviceDef, initialStatus));
+    }
+
+    public synchronized void setStatus(String serviceId, Status status)
+    {
+        serviceIdToServiceStatus.get(serviceId).setStatus(status);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java
new file mode 100644
index 0000000..24c4183
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBinderImpl.java
@@ -0,0 +1,194 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+import org.apache.tapestry.ioc.annotation.Marker;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.Set;
+
+public class ServiceBinderImpl implements ServiceBinder, ServiceBindingOptions
+{
+    private final OneShotLock lock = new OneShotLock();
+
+    private final ServiceDefAccumulator accumulator;
+
+    private final ClassFactory classFactory;
+
+    private final Set<Class> defaultMarkers;
+
+    public ServiceBinderImpl(ServiceDefAccumulator accumulator, ClassFactory classFactory, Set<Class> defaultMarkers)
+    {
+        this.accumulator = accumulator;
+        this.classFactory = classFactory;
+        this.defaultMarkers = defaultMarkers;
+    }
+
+    private String serviceId;
+
+    private Class serviceInterface;
+
+    private final Set<Class> markers = CollectionFactory.newSet();
+
+    private Class serviceImplementation;
+
+    private boolean eagerLoad;
+
+    private String scope;
+
+    public void finish()
+    {
+        lock.lock();
+
+        flush();
+    }
+
+    protected void flush()
+    {
+        if (serviceInterface == null) return;
+
+        final Constructor constructor = findConstructor();
+
+        ObjectCreatorSource source = new ObjectCreatorSource()
+        {
+            public ObjectCreator constructCreator(ServiceBuilderResources resources)
+            {
+                return new ConstructorServiceCreator(resources, getDescription(), constructor);
+            }
+
+            public String getDescription()
+            {
+                return classFactory.getConstructorLocation(constructor).toString();
+            }
+        };
+
+        // Combine service-specific markers with those inherited form the module.
+        Set<Class> markers = CollectionFactory.newSet(defaultMarkers);
+        markers.addAll(this.markers);
+
+        ServiceDef serviceDef = new ServiceDefImpl(serviceInterface, serviceId, markers, scope, eagerLoad, source);
+
+        accumulator.addServiceDef(serviceDef);
+
+        serviceId = null;
+        serviceInterface = null;
+        this.markers.clear();
+        serviceImplementation = null;
+        eagerLoad = false;
+        scope = null;
+    }
+
+    private Constructor findConstructor()
+    {
+        Constructor result = InternalUtils.findAutobuildConstructor(serviceImplementation);
+
+        if (result == null) throw new RuntimeException(IOCMessages
+                .noConstructor(serviceImplementation, serviceId));
+
+        return result;
+    }
+
+    public <T> ServiceBindingOptions bind(Class<T> implementationClass)
+    {
+        return bind(implementationClass, implementationClass);
+    }
+
+    public <T> ServiceBindingOptions bind(Class<T> serviceInterface, Class<? extends T> serviceImplementation)
+    {
+        notNull(serviceInterface, "serviceIterface");
+        notNull(serviceImplementation, "serviceImplementation");
+
+        lock.check();
+
+        flush();
+
+        this.serviceInterface = serviceInterface;
+        this.serviceImplementation = serviceImplementation;
+
+        // Set defaults for the other properties.
+
+        eagerLoad = serviceImplementation.getAnnotation(EagerLoad.class) != null;
+        serviceId = serviceInterface.getSimpleName();
+
+        Scope scope = serviceImplementation.getAnnotation(Scope.class);
+
+        this.scope = scope != null ? scope.value() : IOCConstants.DEFAULT_SCOPE;
+
+        Marker marker = serviceImplementation.getAnnotation(Marker.class);
+
+        if (marker != null)
+        {
+            InternalUtils.validateMarkerAnnotations(marker.value());
+            markers.addAll(Arrays.asList(marker.value()));
+        }
+
+        return this;
+    }
+
+    public ServiceBindingOptions eagerLoad()
+    {
+        lock.check();
+
+        eagerLoad = true;
+
+        return this;
+    }
+
+    public ServiceBindingOptions withId(String id)
+    {
+        notBlank(id, "id");
+
+        lock.check();
+
+        serviceId = id;
+
+        return this;
+    }
+
+    public ServiceBindingOptions scope(String scope)
+    {
+        notBlank(scope, "scope");
+
+        lock.check();
+
+        this.scope = scope;
+
+        return this;
+    }
+
+    public <T extends Annotation> ServiceBindingOptions withMarker(Class<T>... marker)
+    {
+        lock.check();
+
+        InternalUtils.validateMarkerAnnotations(marker);
+
+        markers.addAll(Arrays.asList(marker));
+
+        return this;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvoker.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvoker.java
new file mode 100644
index 0000000..54b327d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvoker.java
@@ -0,0 +1,99 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * Basic implementation of {@link org.apache.tapestry.ioc.ObjectCreator} that handles invoking a method on the module
+ * builder, and figures out the correct parameters to pass into the annotated method.
+ */
+public class ServiceBuilderMethodInvoker extends AbstractServiceCreator
+{
+    private final Method builderMethod;
+
+    public ServiceBuilderMethodInvoker(ServiceBuilderResources resources,
+                                       String creatorDescription, Method method)
+    {
+        super(resources, creatorDescription);
+
+        builderMethod = method;
+    }
+
+    /**
+     * Returns a map that includes (possibly) an additional mapping containing the collected configuration data. This
+     * involves scanning the builder method's parameters.
+     */
+    private Map<Class, Object> getParameterDefaultsWithConfigurations()
+    {
+        return getParameterDefaultsWithConfiguration(
+                builderMethod.getParameterTypes(),
+                builderMethod.getGenericParameterTypes());
+    }
+
+    /**
+     * Invoked from the proxy to create the actual service implementation.
+     */
+    public Object createObject()
+    {
+        // Defer getting (and possibly instantitating) the module builder until the last possible
+        // moment. If the method is static, there's no need to even get the builder.
+
+        Object moduleBuilder = InternalUtils.isStatic(builderMethod) ? null : resources
+                .getModuleBuilder();
+
+        Object result = null;
+        Throwable failure = null;
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForMethod(
+                    builderMethod,
+                    resources,
+                    getParameterDefaultsWithConfigurations());
+
+            if (logger.isDebugEnabled())
+                logger.debug(IOCMessages.invokingMethod(creatorDescription));
+
+            result = builderMethod.invoke(moduleBuilder, parameters);
+        }
+        catch (InvocationTargetException ite)
+        {
+            failure = ite.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            failure = ex;
+        }
+
+        if (failure != null)
+            throw new RuntimeException(IOCMessages.builderMethodError(
+                    creatorDescription,
+                    serviceId,
+                    failure), failure);
+
+        if (result == null)
+            throw new RuntimeException(IOCMessages.builderMethodReturnedNull(
+                    creatorDescription,
+                    serviceId));
+
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImpl.java
new file mode 100644
index 0000000..c1d50f0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImpl.java
@@ -0,0 +1,129 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * A wrapper around a decorator method.
+ */
+public class ServiceDecoratorImpl implements ServiceDecorator
+{
+    private final ModuleBuilderSource moduleBuilderSource;
+
+    private final String serviceId;
+
+    private final Map<Class, Object> parameterDefaults = newMap();
+
+    private final Logger logger;
+
+    private final ServiceResources resources;
+
+    private final ClassFactory classFactory;
+
+    private final Method decoratorMethod;
+
+    private final Class serviceInterface;
+
+    public ServiceDecoratorImpl(Method method, ModuleBuilderSource moduleBuilderSource,
+                                ServiceResources resources, ClassFactory classFactory)
+    {
+        serviceId = resources.getServiceId();
+        decoratorMethod = method;
+        this.moduleBuilderSource = moduleBuilderSource;
+        this.resources = resources;
+        serviceInterface = resources.getServiceInterface();
+        logger = resources.getLogger();
+        this.classFactory = classFactory;
+
+        parameterDefaults.put(String.class, serviceId);
+        parameterDefaults.put(ServiceResources.class, resources);
+        parameterDefaults.put(Logger.class, logger);
+        parameterDefaults.put(Class.class, serviceInterface);
+
+    }
+
+    private String methodId()
+    {
+        return InternalUtils.asString(decoratorMethod, classFactory);
+    }
+
+    public Object createInterceptor(Object delegate)
+    {
+        // Create a copy of the parameters map so that Object.class points to the delegate instance.
+
+        Map<Class, Object> parameterDefaults = newMap(this.parameterDefaults);
+        parameterDefaults.put(Object.class, delegate);
+
+        if (logger.isDebugEnabled()) logger.debug(IOCMessages.invokingMethod(methodId()));
+
+        Object result = null;
+        Throwable failure = null;
+
+        Object moduleBuilder = InternalUtils.isStatic(decoratorMethod) ? null
+                               : moduleBuilderSource.getModuleBuilder();
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForMethod(
+                    decoratorMethod,
+                    resources,
+                    parameterDefaults);
+
+            result = decoratorMethod.invoke(moduleBuilder, parameters);
+        }
+        catch (InvocationTargetException ite)
+        {
+            failure = ite.getTargetException();
+        }
+
+        catch (Exception ex)
+        {
+            failure = ex;
+        }
+
+        if (failure != null)
+            throw new RuntimeException(IOCMessages.decoratorMethodError(
+                    decoratorMethod,
+                    serviceId,
+                    failure), failure);
+
+        if (result != null && !serviceInterface.isInstance(result))
+        {
+            logger.warn(IOCMessages.decoratorReturnedWrongType(
+                    decoratorMethod,
+                    serviceId,
+                    result,
+                    serviceInterface));
+
+            // Change the result to null so that we won't use the interceptor,
+            // and so that ClassCastExceptions don't occur later down the pipeline.
+
+            result = null;
+        }
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefAccumulator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefAccumulator.java
new file mode 100644
index 0000000..1421c1e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefAccumulator.java
@@ -0,0 +1,22 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+public interface ServiceDefAccumulator
+{
+    void addServiceDef(ServiceDef serviceDef);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java
new file mode 100644
index 0000000..1e75b01
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java
@@ -0,0 +1,95 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+import java.util.Set;
+
+public class ServiceDefImpl implements ServiceDef
+{
+    private final Class serviceInterface;
+
+    private final String serviceId;
+
+    private final String scope;
+
+    private final boolean eagerLoad;
+
+    private final ObjectCreatorSource source;
+
+    private final Set<Class> markers;
+
+    /**
+     * @param serviceInterface interface implemented by the service (or the service implementation class, for
+     *                         non-proxied services)
+     * @param serviceId        unique id for the service
+     * @param markers          set of marker annotation classes (will be retained not copied)
+     * @param scope            scope of the service (i.e., {@link IOCConstants#DEFAULT_SCOPE}).
+     * @param eagerLoad        if true, the service is realized at startup, rather than on-demand
+     * @param source           used to create the service implementation when needed
+     */
+    ServiceDefImpl(Class serviceInterface, String serviceId, Set<Class> markers, String scope,
+                   boolean eagerLoad, ObjectCreatorSource source)
+    {
+        this.serviceInterface = serviceInterface;
+        this.serviceId = serviceId;
+        this.scope = scope;
+        this.eagerLoad = eagerLoad;
+        this.source = source;
+
+        this.markers = markers;
+    }
+
+    @Override
+    public String toString()
+    {
+        return source.getDescription();
+    }
+
+    public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
+    {
+        return source.constructCreator(resources);
+    }
+
+    public String getServiceId()
+    {
+        return serviceId;
+    }
+
+    public Class getServiceInterface()
+    {
+        return serviceInterface;
+    }
+
+    public String getServiceScope()
+    {
+        return scope;
+    }
+
+    public boolean isEagerLoad()
+    {
+        return eagerLoad;
+    }
+
+    public Set<Class> getMarkers()
+    {
+        return markers;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java
new file mode 100644
index 0000000..d5ac7ef
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+/**
+ * Used in concert with {@link org.apache.tapestry.ioc.internal.SerializationSupport} to
+ * convert service tokens back into service proxies.
+ */
+public interface ServiceProxyProvider
+{
+    /**
+     * Look up the service and return it's proxy.
+     *
+     * @param serviceId the id of the service to obtain
+     * @return the service proxy
+     * @throws RuntimeException if the service does not exist or does not have a proxy
+     */
+    Object provideServiceProxy(String serviceId);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java
new file mode 100644
index 0000000..125e6c6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java
@@ -0,0 +1,48 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * Token that replaces a service proxy when the proxy is serialized.
+ */
+class ServiceProxyToken implements Serializable
+{
+    private final String serviceId;
+
+    ServiceProxyToken(String serviceId)
+    {
+        this.serviceId = serviceId;
+    }
+
+    Object readResolve() throws ObjectStreamException
+    {
+        try
+        {
+            return SerializationSupport.readResolve(serviceId);
+        }
+        catch (Exception ex)
+        {
+            ObjectStreamException ose = new InvalidObjectException(ex.getMessage());
+            ose.initCause(ex);
+
+            throw ose;
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceResourcesImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceResourcesImpl.java
new file mode 100644
index 0000000..06dbaff
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceResourcesImpl.java
@@ -0,0 +1,124 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+
+import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of {@link org.apache.tapestry.ioc.ServiceBuilderResources}. We just have one implementation that fills
+ * the purposes of methods that need a {@link org.apache.tapestry.ioc.ServiceResources} (which includes service
+ * decorator methods) as well as methods that need a {@link org.apache.tapestry.ioc.ServiceBuilderResources} (which is
+ * just service builder methods). Since it is most commonly used for the former, we'll just leave the name as
+ * ServiceResourcesImpl.
+ */
+public class ServiceResourcesImpl extends ObjectLocatorImpl implements ServiceBuilderResources
+{
+    private final ServiceDef serviceDef;
+
+    private final Logger logger;
+
+    private final ClassFactory classFactory;
+
+    public ServiceResourcesImpl(InternalRegistry registry, Module module, ServiceDef serviceDef,
+                                ClassFactory classFactory, Logger logger)
+    {
+        super(registry, module);
+
+        this.serviceDef = serviceDef;
+        this.classFactory = classFactory;
+        this.logger = logger;
+    }
+
+    public String getServiceId()
+    {
+        return serviceDef.getServiceId();
+    }
+
+    public Class getServiceInterface()
+    {
+        return serviceDef.getServiceInterface();
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public <T> Collection<T> getUnorderedConfiguration(Class<T> valueType)
+    {
+        Collection<T> result = getRegistry().getUnorderedConfiguration(serviceDef, valueType);
+
+        logConfiguration(result);
+
+        return result;
+    }
+
+    private void logConfiguration(Collection configuration)
+    {
+        if (logger.isDebugEnabled())
+            logger.debug(IOCMessages.constructedConfiguration(configuration));
+    }
+
+    public <T> List<T> getOrderedConfiguration(Class<T> valueType)
+    {
+        List<T> result = getRegistry().getOrderedConfiguration(serviceDef, valueType);
+
+        logConfiguration(result);
+
+        return result;
+    }
+
+    public <K, V> Map<K, V> getMappedConfiguration(Class<K> keyType, Class<V> valueType)
+    {
+        Map<K, V> result = getRegistry().getMappedConfiguration(serviceDef, keyType, valueType);
+
+        if (logger.isDebugEnabled()) logger.debug(IOCMessages.constructedConfiguration(result));
+
+        return result;
+    }
+
+    public Object getModuleBuilder()
+    {
+        return getModule().getModuleBuilder();
+    }
+
+    @Override
+    public <T> T autobuild(Class<T> clazz)
+    {
+        notNull(clazz, "clazz");
+
+        Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
+
+        if (constructor == null)
+            throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
+
+        String description = classFactory.getConstructorLocation(constructor).toString();
+
+        ObjectCreator creator = new ConstructorServiceCreator(this, description, constructor);
+
+        return clazz.cast(creator.createObject());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java
new file mode 100644
index 0000000..15c1135
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycle.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+import org.apache.tapestry.ioc.ObjectCreator;

+import org.apache.tapestry.ioc.ServiceLifecycle;

+import org.apache.tapestry.ioc.ServiceResources;

+

+/**

+ * The basic implementation of a service lifecycle, which simply uses the

+ * {@link org.apache.tapestry.ioc.ObjectCreator} to create an instance of the service when asked.

+ */

+public class SingletonServiceLifecycle implements ServiceLifecycle

+{

+    public Object createService(ServiceResources resources, ObjectCreator creator)

+    {

+        return creator.createObject();

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapper.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapper.java
new file mode 100644
index 0000000..cb66fa2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapper.java
@@ -0,0 +1,71 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.slf4j.Logger;
+
+/**
+ * Performs some validation before delegating to another Configuration.
+ */
+public class ValidatingConfigurationWrapper<T> implements Configuration<T>
+{
+    private final String serviceId;
+
+    private final ContributionDef contributionDef;
+
+    private final Logger logger;
+
+    private final Configuration<T> delegate;
+
+    private final Class expectedType;
+
+    // Need a strategy for determing the right order for this mass of parameters!
+
+    public ValidatingConfigurationWrapper(String serviceId, Logger logger, Class expectedType,
+                                          ContributionDef contributionDef, Configuration<T> delegate)
+    {
+        this.serviceId = serviceId;
+        this.logger = logger;
+        this.expectedType = expectedType;
+        this.contributionDef = contributionDef;
+        this.delegate = delegate;
+    }
+
+    public void add(T object)
+    {
+        if (object == null)
+        {
+            logger.warn(IOCMessages.contributionWasNull(serviceId, contributionDef));
+            return;
+        }
+
+        // Sure, we say it is type T ... but is it really?
+
+        if (!expectedType.isInstance(object))
+        {
+            logger.warn(IOCMessages.contributionWrongValueType(
+                    serviceId,
+                    contributionDef,
+                    object.getClass(),
+                    expectedType));
+            return;
+        }
+
+        delegate.add(object);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapper.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapper.java
new file mode 100644
index 0000000..6cbf8b4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapper.java
@@ -0,0 +1,110 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+/**
+ * Provides two forms of validation for mapped configurations: <ul> <li>If either key or value is null, then a warning
+ * is logged </li> <li>If the key has previously been stored (by some other {@link
+ * org.apache.tapestry.ioc.def.ContributionDef}, then a warning is logged</li> </ul>
+ * <p/>
+ * When a warning is logged, the key/value pair is not added to the delegate.
+ *
+ * @param <K>
+ * @param <V>
+ */
+public class ValidatingMappedConfigurationWrapper<K, V> implements MappedConfiguration<K, V>
+{
+    private final String serviceId;
+
+    private final ContributionDef contributionDef;
+
+    private final Logger logger;
+
+    private final Class<K> expectedKeyType;
+
+    private final Class<V> expectedValueType;
+
+    private final Map<K, ContributionDef> keyToContributor;
+
+    private final MappedConfiguration<K, V> delegate;
+
+    public ValidatingMappedConfigurationWrapper(String serviceId, ContributionDef contributionDef,
+                                                Logger logger, Class<K> expectedKeyType, Class<V> expectedValueType,
+                                                Map<K, ContributionDef> keyToContributor,
+                                                MappedConfiguration<K, V> delegate)
+    {
+        this.serviceId = serviceId;
+        this.contributionDef = contributionDef;
+        this.logger = logger;
+        this.expectedKeyType = expectedKeyType;
+        this.expectedValueType = expectedValueType;
+        this.keyToContributor = keyToContributor;
+        this.delegate = delegate;
+    }
+
+    public void add(K key, V value)
+    {
+        if (key == null)
+        {
+            logger.warn(IOCMessages.contributionKeyWasNull(serviceId, contributionDef));
+            return;
+        }
+
+        if (value == null)
+        {
+            logger.warn(IOCMessages.contributionWasNull(serviceId, contributionDef));
+            return;
+        }
+
+        if (!expectedKeyType.isInstance(key))
+        {
+            logger.warn(IOCMessages.contributionWrongKeyType(serviceId, contributionDef, key
+                    .getClass(), expectedKeyType));
+            return;
+        }
+
+        if (!expectedValueType.isInstance(value))
+        {
+            logger.warn(IOCMessages.contributionWrongValueType(serviceId, contributionDef, value
+                    .getClass(), expectedValueType));
+            return;
+        }
+
+        ContributionDef existing = keyToContributor.get(key);
+
+        if (existing != null)
+        {
+            logger.warn(IOCMessages.contributionDuplicateKey(
+                    serviceId,
+                    contributionDef,
+                    existing));
+            return;
+        }
+
+        delegate.add(key, value);
+
+        // Remember that this key is provided by this contribution, when looking
+        // for future conflicts.
+
+        keyToContributor.put(key, contributionDef);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapper.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapper.java
new file mode 100644
index 0000000..6bcdd7a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapper.java
@@ -0,0 +1,65 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.slf4j.Logger;
+
+/**
+ * Implements validation of values provided to an {@link org.apache.tapestry.ioc.OrderedConfiguration}. If you provide
+ * an incorrect value type, the value is converted to null but added anyway. This ensures that incorrect values
+ * contributed in don't screw up the {@link org.apache.tapestry.ioc.internal.util.Orderer} (and generate a bunch of
+ * error messages there).
+ *
+ * @param <T>
+ */
+public class ValidatingOrderedConfigurationWrapper<T> implements OrderedConfiguration<T>
+{
+    private final String serviceId;
+
+    private final ContributionDef contributionDef;
+
+    private final Logger logger;
+
+    private final Class expectedType;
+
+    private final OrderedConfiguration<T> delegate;
+
+    public ValidatingOrderedConfigurationWrapper(String serviceId, ContributionDef contributionDef,
+                                                 Logger logger, Class expectedType, OrderedConfiguration<T> delegate)
+    {
+        this.serviceId = serviceId;
+        this.contributionDef = contributionDef;
+        this.logger = logger;
+        this.expectedType = expectedType;
+        this.delegate = delegate;
+    }
+
+    public void add(String id, T object, String... constraints)
+    {
+        delegate.add(id, validVersionOf(object), constraints);
+    }
+
+    private T validVersionOf(T object)
+    {
+        if (object == null || expectedType.isInstance(object)) return object;
+
+        logger.warn(IOCMessages.contributionWrongValueType(serviceId, contributionDef, object
+                .getClass(), expectedType));
+
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractFab.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractFab.java
new file mode 100644
index 0000000..0ef4dae
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractFab.java
@@ -0,0 +1,102 @@
+// Copyright 2005, 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.slf4j.Logger;
+
+/**
+ * Base class for {@link org.apache.tapestry.ioc.internal.services.ClassFabImpl}. This code is a fork from HiveMind; it
+ * is kept seperate from ClassFabImpl in case we want to re-introduce the idea of an InterfaceFab.
+ */
+public class AbstractFab
+{
+    protected final OneShotLock lock = new OneShotLock();
+
+    private final CtClass ctClass;
+
+    private final CtClassSource source;
+
+    private final Logger logger;
+
+    public AbstractFab(CtClassSource source, CtClass ctClass, Logger logger)
+    {
+        this.ctClass = ctClass;
+        this.source = source;
+        this.logger = logger;
+    }
+
+    public void addInterface(Class interfaceClass)
+    {
+        lock.check();
+
+        CtClass ctInterfaceClass = source.toCtClass(interfaceClass);
+
+        try
+        {
+            for (CtClass existing : ctClass.getInterfaces())
+                if (existing == ctInterfaceClass) return;
+        }
+        catch (Exception ex)
+        {
+            // Don't think this code is actually reachable.
+        }
+
+        ctClass.addInterface(ctInterfaceClass);
+    }
+
+    protected CtClass[] toCtClasses(Class[] inputClasses)
+    {
+        if (inputClasses == null || inputClasses.length == 0) return null;
+
+        int count = inputClasses.length;
+        CtClass[] result = new CtClass[count];
+
+        for (int i = 0; i < count; i++)
+        {
+            CtClass ctClass = toCtClass(inputClasses[i]);
+
+            result[i] = ctClass;
+        }
+
+        return result;
+    }
+
+    protected CtClass toCtClass(Class inputClass)
+    {
+        return source.toCtClass(inputClass);
+    }
+
+    public Class createClass()
+    {
+        lock.lock();
+
+        if (logger.isDebugEnabled()) logger.debug(String.format("Creating class from %s", this));
+
+        return source.createClass(ctClass);
+    }
+
+    protected CtClass getCtClass()
+    {
+        return ctClass;
+    }
+
+    protected CtClassSource getSource()
+    {
+        return source;
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractInvocation.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractInvocation.java
new file mode 100644
index 0000000..40eb520
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AbstractInvocation.java
@@ -0,0 +1,106 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.internal.util.Defense;
+
+import java.lang.reflect.Method;
+
+/**
+ * Base class for {@link org.apache.tapestry.ioc.Invocation}, which is extended with a dynamically generated class
+ * generated for each individual class and method.
+ */
+public abstract class AbstractInvocation implements Invocation
+{
+    private final Method method;
+
+    private Throwable thrown;
+
+    private Object result;
+
+    @Override
+    public String toString()
+    {
+        return String.format("Invocation[%s]", method);
+    }
+
+    protected AbstractInvocation(Method method)
+    {
+        this.method = method;
+    }
+
+    public String getMethodName()
+    {
+        return method.getName();
+    }
+
+    public Class getResultType()
+    {
+        return method.getReturnType();
+    }
+
+    public int getParameterCount()
+    {
+        return method.getParameterTypes().length;
+    }
+
+    public Class getParameterType(int index)
+    {
+        return method.getParameterTypes()[index];
+    }
+
+    public boolean isFail()
+    {
+        return thrown != null;
+    }
+
+    public <T extends Throwable> T getThrown(Class<T> throwableClass)
+    {
+        Defense.notNull(throwableClass, "throwableClass");
+
+        if (throwableClass.isInstance(thrown)) return throwableClass.cast(thrown);
+
+        return null;
+    }
+
+    public void overrideThrown(Exception thrown)
+    {
+        Defense.notNull(thrown, "thrown");
+
+        for (Class t : method.getExceptionTypes())
+        {
+            if (t.isInstance(thrown))
+            {
+                this.thrown = thrown;
+                return;
+            }
+        }
+
+        throw new IllegalArgumentException(String.format("Exception %s is not a declared exception of method %s.",
+                                                         thrown.getClass().getName(), method));
+    }
+
+    public Object getResult()
+    {
+        return result;
+    }
+
+    public void overrideResult(Object newResult)
+    {
+        result = newResult;
+        thrown = null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectDecoratorImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectDecoratorImpl.java
new file mode 100644
index 0000000..2fd9c22
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectDecoratorImpl.java
@@ -0,0 +1,78 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.ioc.services.AspectInterceptorBuilder;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.lang.reflect.Method;
+
+public class AspectDecoratorImpl implements AspectDecorator
+{
+    private final ClassFactory classFactory;
+
+    public AspectDecoratorImpl(@Builtin ClassFactory classFactory)
+    {
+        this.classFactory = classFactory;
+    }
+
+    public <T> T build(Class<T> serviceInterface, T delegate, MethodAdvice advice, String description)
+    {
+        Defense.notNull(advice, "advice");
+
+        AspectInterceptorBuilder<T> builder = createBuilder(serviceInterface, delegate, description);
+
+        // Use the same advice for all methods.
+
+        for (Method m : serviceInterface.getMethods())
+            builder.adviseMethod(m, advice);
+
+        return builder.build();
+    }
+
+    public <T> AspectInterceptorBuilder<T> createBuilder(final Class<T> serviceInterface, final T delegate,
+                                                         final String description)
+    {
+        Defense.notNull(serviceInterface, "serviceInterface");
+        Defense.notNull(delegate, "delegate");
+        Defense.notBlank(description, "description");
+
+        // Defer creating the real builder until a method gets advised.  If no method is advised then
+        // the delegate can be used unchanged.
+
+        return new AspectInterceptorBuilder<T>()
+        {
+            private AspectInterceptorBuilder<T> builder;
+
+            public void adviseMethod(Method method, MethodAdvice advice)
+            {
+                if (builder == null)
+                    builder = new AspectInterceptorBuilderImpl<T>(classFactory, serviceInterface, delegate,
+                                                                  description);
+
+                builder.adviseMethod(method, advice);
+            }
+
+            public T build()
+            {
+                return builder == null ? delegate : builder.build();
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImpl.java
new file mode 100644
index 0000000..8fcf3fb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImpl.java
@@ -0,0 +1,392 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * TODO: Perhaps some caching, would be useful if the same interface has multiple Aspects of interception.
+ */
+public class AspectInterceptorBuilderImpl<T> implements AspectInterceptorBuilder<T>
+{
+    private static final String PARAMETER_FIELD = "_p";
+
+    private static final int PRIVATE_FINAL = Modifier.PRIVATE | Modifier.FINAL;
+
+    private final ClassFactory classFactory;
+
+    private final Class<T> serviceInterface;
+
+    private final ClassFab interceptorFab;
+
+    private final String delegateFieldName;
+
+    private final String description;
+
+    private boolean sawToString;
+
+    private final OneShotLock lock = new OneShotLock();
+
+    private static class Injection
+    {
+        final String _fieldName;
+        final Class _fieldType;
+        final Object _injectedValue;
+
+        private Injection(String fieldName, Class fieldType, Object injectedValue)
+        {
+            _fieldName = fieldName;
+            _fieldType = fieldType;
+            _injectedValue = injectedValue;
+        }
+    }
+
+    private final List<Injection> injections = CollectionFactory.newList();
+
+    private final Map<Object, Injection> objectToInjection = CollectionFactory.newMap();
+
+    private final Set<Method> remainingMethods = CollectionFactory.newSet();
+
+    private final Set<Method> advisedMethods = CollectionFactory.newSet();
+
+    public AspectInterceptorBuilderImpl(ClassFactory classFactory, Class<T> serviceInterface, T delegate,
+                                        String description)
+    {
+        this.classFactory = classFactory;
+        this.serviceInterface = serviceInterface;
+        this.description = description;
+
+        interceptorFab = this.classFactory.newClass(serviceInterface);
+
+        delegateFieldName = inject(serviceInterface, delegate);
+
+        remainingMethods.addAll(Arrays.asList(serviceInterface.getMethods()));
+    }
+
+    public void adviseMethod(Method method, MethodAdvice advice)
+    {
+        Defense.notNull(method, "method");
+        Defense.notNull(advice, "advice");
+
+        lock.check();
+
+        if (advisedMethods.contains(method))
+            throw new IllegalArgumentException(String.format("Method %s has already been advised.", method));
+
+        if (!remainingMethods.contains(method))
+            throw new IllegalArgumentException(
+                    String.format("Method %s is not defined for interface %s.", method, serviceInterface));
+
+        sawToString |= ClassFabUtils.isToString(method);
+
+        String invocationClassName = createInvocationClass(method);
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        String methodFieldName = inject(Method.class, method);
+        String aspectFieldName = inject(MethodAdvice.class, advice);
+
+        builder.addln("%s invocation = new %s(%s, %s, $$);", Invocation.class.getName(), invocationClassName,
+                      methodFieldName, delegateFieldName);
+
+        builder.addln("%s.advise(invocation);", aspectFieldName);
+
+        Class[] exceptionTypes = method.getExceptionTypes();
+
+        builder.addln("if (invocation.isFail())").begin();
+
+        for (Class exceptionType : exceptionTypes)
+        {
+            String name = exceptionType.getSimpleName().toLowerCase();
+
+            String exceptionTypeFieldName = inject(Class.class, exceptionType);
+
+            builder.addln("%s %s = (%s) invocation.getThrown(%s);", exceptionType.getName(), name,
+                          exceptionType.getName(), exceptionTypeFieldName);
+            builder.addln("if (%s != null) throw %s;", name, name);
+        }
+
+        builder.addln(
+                "throw new IllegalStateException(\"Impossible exception thrown from intercepted invocation.\");");
+
+        builder.end(); // if fail
+
+        builder.addln("return ($r) invocation.getResult();");
+
+        builder.end();
+
+        interceptorFab.addMethod(Modifier.PUBLIC, new MethodSignature(method), builder.toString());
+
+        remainingMethods.remove(method);
+        advisedMethods.add(method);
+    }
+
+    private String createInvocationClass(Method method)
+    {
+        String baseName = serviceInterface.getSimpleName() + "$" + method.getName();
+        String className = ClassFabUtils.generateClassName(baseName);
+
+        ClassFab invocationFab = classFactory.newClass(className, AbstractInvocation.class);
+
+        List<Class> constructorTypes = CollectionFactory.newList();
+
+        // The first two parameters are fixed:
+
+        constructorTypes.add(Method.class); // And passed up to the super class
+
+        invocationFab.addField("_delegate", PRIVATE_FINAL, serviceInterface);
+        constructorTypes.add(serviceInterface);
+
+        BodyBuilder constructorBuilder = new BodyBuilder().begin().addln("super($1);").addln("_delegate = $2;");
+
+        for (int i = 0; i < method.getParameterTypes().length; i++)
+        {
+            Class type = method.getParameterTypes()[i];
+
+            String name = PARAMETER_FIELD + i;
+
+            invocationFab.addField(name, type);
+
+            constructorTypes.add(type);
+
+            // $0 is this
+            // $1 is Method
+            // $2 is delegate
+            // $3 is first method parameter ...
+
+            constructorBuilder.addln("%s = $%d;", name, i + 3);
+        }
+
+        addProceed(method, invocationFab);
+        addGetParameter(method, invocationFab);
+        addOverride(method, invocationFab);
+
+        constructorBuilder.end(); // constructor
+
+        Class[] typesArray = constructorTypes.toArray(new Class[constructorTypes.size()]);
+
+        invocationFab.addConstructor(typesArray, null, constructorBuilder.toString());
+
+        invocationFab.createClass();
+
+        return className;
+    }
+
+    private void addProceed(Method method, ClassFab fab)
+    {
+        Class returnType = method.getReturnType();
+        Class[] exceptionTypes = method.getExceptionTypes();
+
+        boolean isNonVoid = !returnType.equals(void.class);
+        boolean hasChecked = exceptionTypes.length > 0;
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        if (hasChecked) builder.addln("try").begin();
+
+        if (isNonVoid)
+            builder.add("%s result = ", ClassFabUtils.toJavaClassName(returnType));
+
+        builder.add("_delegate.%s(", method.getName());
+
+        for (int i = 0; i < method.getParameterTypes().length; i++)
+        {
+            if (i > 0) builder.add(", ");
+
+            builder.add(PARAMETER_FIELD + i);
+        }
+
+        builder.addln(");"); // Call on delegate
+
+        if (isNonVoid)
+        {
+            builder.add("overrideResult(($w) result);");
+        }
+
+        if (hasChecked)
+        {
+            builder.end();   // try
+
+            for (Class exception : exceptionTypes)
+            {
+                builder.addln("catch (%s ex) { overrideThrown(ex); }", exception.getName());
+            }
+        }
+
+        builder.end(); // method
+
+        MethodSignature sig = new MethodSignature(void.class, "proceed", null, null);
+
+        fab.addMethod(Modifier.PUBLIC, sig, builder.toString());
+    }
+
+    private void addGetParameter(Method method, ClassFab fab)
+    {
+        Class[] parameterTypes = method.getParameterTypes();
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        builder.addln("switch ($1)").begin();
+
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            // ($w) will wrap a primitive as a wrapper type
+            builder.addln("case %d: return ($w) %s%d;", i, PARAMETER_FIELD, i);
+        }
+
+        builder.addln("default: throw new IllegalArgumentException(\"Parameter index out of range.\");");
+
+        builder.end().end(); // switch and method
+
+        fab.addMethod(Modifier.PUBLIC,
+                      new MethodSignature(Object.class, "getParameter", new Class[] { int.class }, null),
+                      builder.toString());
+
+    }
+
+    private void addOverride(Method method, ClassFab fab)
+    {
+        Class[] parameterTypes = method.getParameterTypes();
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        builder.addln("switch ($1)").begin();
+
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            Class type = parameterTypes[i];
+            String typeName = ClassFabUtils.toJavaClassName(type);
+
+            builder.addln("case %d: %s%d = %s; return;",
+                          i, PARAMETER_FIELD, i,
+                          ClassFabUtils.castReference("$2", typeName));
+        }
+
+        builder.addln("default: throw new IllegalArgumentException(\"Parameter index out of range.\");");
+
+        builder.end().end(); // switch and method
+
+        fab.addMethod(Modifier.PUBLIC,
+                      new MethodSignature(void.class, "override", new Class[] { int.class, Object.class }, null),
+                      builder.toString());
+    }
+
+    public T build()
+    {
+        lock.lock();
+
+        // Hit all the methods that haven't been referenced so far.
+
+        addPassthruMethods();
+
+        // And if we haven't seend a toString(), we can add it now.
+
+        if (!sawToString)
+            interceptorFab.addToString(description);
+
+        Object[] parameters = createConstructor();
+
+        try
+        {
+            Class c = interceptorFab.createClass();
+
+            // There's only ever the one constructor.
+
+            Constructor cc = c.getConstructors()[0];
+
+            Object interceptor = cc.newInstance(parameters);
+
+            return serviceInterface.cast(interceptor);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private Object[] createConstructor()
+    {
+        // Time to add the constructor.
+
+        Class[] parameterTypes = new Class[injections.size()];
+        Object[] parameters = new Object[injections.size()];
+
+        BodyBuilder builder = new BodyBuilder().begin();
+
+        for (int i = 0; i < injections.size(); i++)
+        {
+            Injection injection = injections.get(i);
+
+            builder.addln("%s = $%d;", injection._fieldName, i + 1);
+
+            parameterTypes[i] = injection._fieldType;
+            parameters[i] = injection._injectedValue;
+        }
+
+        builder.end();
+
+        interceptorFab.addConstructor(parameterTypes, null, builder.toString());
+
+        return parameters;
+    }
+
+    private void addPassthruMethods()
+    {
+        for (Method m : remainingMethods)
+        {
+            sawToString |= ClassFabUtils.isToString(m);
+
+            MethodSignature sig = new MethodSignature(m);
+
+            String body = String.format("return ($r) %s.%s($$);", delegateFieldName, m.getName());
+
+            interceptorFab.addMethod(Modifier.PUBLIC, sig, body);
+        }
+    }
+
+    private <T> String inject(Class<T> fieldType, T injectedValue)
+    {
+        Injection injection = objectToInjection.get(injectedValue);
+
+        if (injection == null)
+        {
+            String name = "_" + fieldType.getSimpleName().toLowerCase() + "_" + injections.size();
+
+            interceptorFab.addField(name, PRIVATE_FINAL, fieldType);
+
+            injection = new Injection(name, fieldType, injectedValue);
+
+            injections.add(injection);
+            objectToInjection.put(injectedValue, injection);
+        }
+
+        return injection._fieldName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/BridgeBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/BridgeBuilder.java
new file mode 100644
index 0000000..2569cad
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/BridgeBuilder.java
@@ -0,0 +1,237 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodIterator;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.slf4j.Logger;
+
+import static java.lang.String.format;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Used by the {@link org.apache.tapestry.ioc.internal.services.PipelineBuilderImpl} to create bridge classes and to
+ * create instances of bridge classes. A bridge class implements the <em>service</em> interface. Within the chain,
+ * bridge 1 is passed to filter 1. Invoking methods on bridge 1 will invoke methods on filter 2.
+ */
+class BridgeBuilder<S, F>
+{
+    private final Logger logger;
+
+    private final Class<S> serviceInterface;
+
+    private final Class<F> filterInterface;
+
+    private final ClassFab classFab;
+
+    private final FilterMethodAnalyzer filterMethodAnalyzer;
+
+    private Constructor constructor;
+
+    BridgeBuilder(Logger logger, Class<S> serviceInterface, Class<F> filterInterface,
+                  ClassFactory classFactory)
+    {
+        this.logger = logger;
+        this.serviceInterface = serviceInterface;
+        this.filterInterface = filterInterface;
+
+        classFab = classFactory.newClass(this.serviceInterface);
+
+        filterMethodAnalyzer = new FilterMethodAnalyzer(serviceInterface);
+    }
+
+    private void createClass()
+    {
+        List<MethodSignature> serviceMethods = newList();
+        List<MethodSignature> filterMethods = newList();
+
+        createInfrastructure();
+
+        MethodIterator mi = new MethodIterator(serviceInterface);
+
+        while (mi.hasNext())
+        {
+            serviceMethods.add(mi.next());
+        }
+
+        boolean toStringMethodExists = mi.getToString();
+
+        mi = new MethodIterator(filterInterface);
+
+        while (mi.hasNext())
+        {
+            filterMethods.add(mi.next());
+        }
+
+        while (!serviceMethods.isEmpty())
+        {
+            MethodSignature ms = serviceMethods.remove(0);
+
+            addBridgeMethod(ms, filterMethods);
+        }
+
+        reportExtraFilterMethods(filterMethods);
+
+        if (!toStringMethodExists)
+        {
+            String toString = format(
+                    "<PipelineBridge from %s to %s>",
+                    serviceInterface.getName(),
+                    filterInterface.getName());
+            classFab.addToString(toString);
+        }
+
+        Class bridgeClass = classFab.createClass();
+
+        constructor = bridgeClass.getConstructors()[0];
+    }
+
+    private void createInfrastructure()
+    {
+        classFab.addField("_next", Modifier.PRIVATE | Modifier.FINAL, serviceInterface);
+        classFab.addField("_filter", Modifier.PRIVATE | Modifier.FINAL, filterInterface);
+
+        classFab.addConstructor(new Class[]
+                { serviceInterface, filterInterface }, null, "{ _next = $1; _filter = $2; }");
+
+        classFab.addInterface(serviceInterface);
+    }
+
+    /**
+     * Instantiates a bridge object.
+     *
+     * @param nextBridge the next Bridge object in the pipeline, or the terminator service
+     * @param filter     the filter object for this step of the pipeline
+     */
+    public S instantiateBridge(S nextBridge, F filter)
+    {
+        if (constructor == null) createClass();
+
+        try
+        {
+            Object instance = constructor.newInstance(nextBridge, filter);
+
+            return serviceInterface.cast(instance);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private void reportExtraFilterMethods(List filterMethods)
+    {
+        Iterator i = filterMethods.iterator();
+
+        while (i.hasNext())
+        {
+            MethodSignature ms = (MethodSignature) i.next();
+
+            logger.error(ServiceMessages
+                    .extraFilterMethod(ms, filterInterface, serviceInterface));
+        }
+    }
+
+    /**
+     * Finds a matching method in filterMethods for the given service method. A matching method has the same signature
+     * as the service interface method, but with an additional parameter matching the service interface itself.
+     * <p/>
+     * The matching method signature from the list of filterMethods is removed and code generation strategies for making
+     * the two methods call each other are added.
+     */
+    private void addBridgeMethod(MethodSignature ms, List filterMethods)
+    {
+        Iterator i = filterMethods.iterator();
+
+        while (i.hasNext())
+        {
+            MethodSignature fms = (MethodSignature) i.next();
+
+            int position = filterMethodAnalyzer.findServiceInterfacePosition(ms, fms);
+
+            if (position >= 0)
+            {
+                addBridgeMethod(position, ms, fms);
+                i.remove();
+                return;
+            }
+        }
+
+        String message = ServiceMessages.unmatchedServiceMethod(ms, filterInterface);
+
+        logger.error(message);
+
+        String code = format("throw new %s(\"%s\");", RuntimeException.class.getName(), message);
+
+        classFab.addMethod(Modifier.PUBLIC, ms, code);
+    }
+
+    /**
+     * Adds a method to the class which bridges from the service method to the corresponding method in the filter
+     * interface. The next service (either another Bridge, or the terminator at the end of the pipeline) is passed to
+     * the filter).
+     */
+    private void addBridgeMethod(int position, MethodSignature ms, MethodSignature fms)
+    {
+        StringBuilder buffer = new StringBuilder(100);
+
+        buffer.append("return ($r) _filter.");
+        buffer.append(ms.getName());
+        buffer.append("(");
+
+        boolean comma = false;
+        int filterParameterCount = fms.getParameterTypes().length;
+
+        for (int i = 0; i < position; i++)
+        {
+            if (comma) buffer.append(", ");
+
+            buffer.append("$");
+            // Add one to the index to get the parameter symbol ($0 is the implicit
+            // this parameter).
+            buffer.append(i + 1);
+
+            comma = true;
+        }
+
+        if (comma) buffer.append(", ");
+
+        // _next is the variable in -this- Bridge that points to the -next- Bridge
+        // or the terminator for the pipeline. The filter is expected to reinvoke the
+        // method on the _next that's passed to it.
+
+        buffer.append("_next");
+
+        for (int i = position + 1; i < filterParameterCount; i++)
+        {
+            buffer.append(", $");
+            buffer.append(i);
+        }
+
+        buffer.append(");");
+
+        // This should work, unless the exception types turn out to not be compatble. We still
+        // don't do a check on that, and not sure that Javassist does either!
+
+        classFab.addMethod(Modifier.PUBLIC, ms, buffer.toString());
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImpl.java
new file mode 100644
index 0000000..35c1e46
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImpl.java
@@ -0,0 +1,202 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+
+import static java.lang.String.format;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Map;
+
+public class ChainBuilderImpl implements ChainBuilder
+{
+    private final ClassFactory classFactory;
+
+    /**
+     * Map, keyed on service interface, of implementation Class.
+     */
+
+    private final Map<Class, Class> cache = newConcurrentMap();
+
+    public ChainBuilderImpl(@Builtin ClassFactory classFactory)
+    {
+        this.classFactory = classFactory;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T build(Class<T> commandInterface, List<T> commands)
+    {
+        Class<T> chainClass = findImplementationClass(commandInterface);
+
+        return createInstance(chainClass, commands);
+    }
+
+    private Class findImplementationClass(Class commandInterface)
+    {
+        Class result = cache.get(commandInterface);
+
+        if (result == null)
+        {
+            result = constructImplementationClass(commandInterface);
+            cache.put(commandInterface, result);
+        }
+
+        return result;
+    }
+
+    private Class constructImplementationClass(Class commandInterface)
+    {
+        // In rare, rare cases, a race condition to create an implementation class
+        // for the same interface may occur. We just let that happen, and there'll
+        // be two different classes corresponding to the same interface.
+
+        String name = ClassFabUtils.generateClassName(commandInterface);
+
+        ClassFab cf = classFactory.newClass(name, Object.class);
+
+        addInfrastructure(cf, commandInterface);
+
+        addMethods(cf, commandInterface);
+
+        return cf.createClass();
+    }
+
+    private void addInfrastructure(ClassFab cf, Class commandInterface)
+    {
+        // Array types are very, very tricky to deal with.
+        // Also, generics don't help (<T> new T[]) is still java.lang.Object[].
+
+        String arrayClassName = commandInterface.getCanonicalName() + "[]";
+        String jvmName = ClassFabUtils.toJVMBinaryName(arrayClassName);
+
+        Class array;
+
+        try
+        {
+            ClassLoader loader = commandInterface.getClass().getClassLoader();
+            if (loader == null) loader = Thread.currentThread().getContextClassLoader();
+
+            array = Class.forName(jvmName, true, loader);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+
+        cf.addInterface(commandInterface);
+        cf.addField("_commands", Modifier.PRIVATE | Modifier.FINAL, array);
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.addln("_commands = (%s[]) $1.toArray(new %<s[0]);", commandInterface.getName());
+
+        cf.addConstructor(new Class[] { List.class }, null, builder.toString());
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T createInstance(Class<T> instanceClass, List<T> commands)
+    {
+        try
+        {
+            Constructor<T> ctor = (Constructor<T>) instanceClass.getConstructors()[0];
+
+            return instanceClass.cast(ctor.newInstance(commands));
+        }
+        catch (Exception ex)
+        {
+            // This should not be reachable!
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+    private void addMethods(ClassFab cf, Class commandInterface)
+    {
+        MethodIterator mi = new MethodIterator(commandInterface);
+
+        while (mi.hasNext())
+        {
+            MethodSignature sig = mi.next();
+
+            addMethod(cf, commandInterface, sig);
+        }
+
+        if (!mi.getToString()) cf.addToString(format("<Command chain of %s>", commandInterface.getName()));
+    }
+
+    private void addMethod(ClassFab cf, Class commandInterface, MethodSignature sig)
+    {
+        Class returnType = sig.getReturnType();
+
+        if (returnType.equals(void.class))
+        {
+            addVoidMethod(cf, commandInterface, sig);
+            return;
+        }
+
+        String defaultValue = defaultForReturnType(returnType);
+
+        BodyBuilder builder = new BodyBuilder();
+        builder.begin();
+
+        builder.addln("%s result = %s;", ClassFabUtils.toJavaClassName(returnType), defaultValue);
+        builder.addln("for (int i = 0; i < _commands.length; i++)");
+
+        builder.begin();
+        builder.addln("result = _commands[i].%s($$);", sig.getName());
+
+        builder.addln("if (result != %s) break;", defaultValue);
+
+        builder.end();
+
+        builder.addln("return result;");
+        builder.end();
+
+        cf.addMethod(Modifier.PUBLIC, sig, builder.toString());
+    }
+
+    private String defaultForReturnType(Class returnType)
+    {
+        // For all object and array types.
+
+        if (!returnType.isPrimitive()) return "null";
+
+        if (returnType.equals(boolean.class)) return "false";
+
+        // Assume, then, that it is a numeric type (this method
+        // isn't called for type void). Javassist seems to be
+        // able to handle 0 for all numeric types.
+
+        return "0";
+    }
+
+    private void addVoidMethod(ClassFab cf, Class commandInterface, MethodSignature sig)
+    {
+        BodyBuilder builder = new BodyBuilder();
+
+        builder.begin();
+
+        builder.addln("for (int i = 0; i < _commands.length; i++)");
+        builder.addln("  _commands[i].%s($$);", sig.getName());
+
+        builder.end();
+
+        cf.addMethod(Modifier.PUBLIC, sig, builder.toString());
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFabImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFabImpl.java
new file mode 100644
index 0000000..f71904a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFabImpl.java
@@ -0,0 +1,332 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.*;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.MethodIterator;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.slf4j.Logger;
+
+import static java.lang.String.format;
+import java.lang.reflect.Modifier;
+import java.util.Formatter;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implementation of {@link org.apache.tapestry.ioc.services.ClassFab}. Hides, as much as possible, the underlying
+ * library (Javassist).
+ */
+public class ClassFabImpl extends AbstractFab implements ClassFab
+{
+    private static final Map<Class, String> DEFAULT_RETURN = newMap();
+
+    static
+    {
+        DEFAULT_RETURN.put(boolean.class, "false");
+        DEFAULT_RETURN.put(long.class, "0L");
+        DEFAULT_RETURN.put(float.class, "0.0f");
+        DEFAULT_RETURN.put(double.class, "0.0d");
+    }
+
+    /**
+     * Add fields, methods, and constructors are added, their psuedo-code is appended to this description, which is used
+     * by toString().
+     */
+    private final StringBuilder description = new StringBuilder();
+
+    private final Formatter formatter = new Formatter(description);
+
+    private final Set<MethodSignature> addedSignatures = newSet();
+
+    public ClassFabImpl(CtClassSource source, CtClass ctClass, Logger logger)
+    {
+        super(source, ctClass, logger);
+    }
+
+    /**
+     * Returns a representation of the fabricated class, including inheritance, fields, constructors, methods and method
+     * bodies.
+     *
+     * @since 1.1
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder buffer = new StringBuilder("ClassFab[\n");
+
+        try
+        {
+            buffer.append(buildClassAndInheritance());
+
+            buffer.append(description.toString());
+        }
+        catch (Exception ex)
+        {
+            buffer.append(" *** ");
+            buffer.append(ex);
+        }
+
+        buffer.append("\n]");
+
+        return buffer.toString();
+    }
+
+    private String buildClassAndInheritance() throws NotFoundException
+    {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(Modifier.toString(getCtClass().getModifiers()));
+        buffer.append(" class ");
+        buffer.append(getName());
+        buffer.append(" extends ");
+        buffer.append(getCtClass().getSuperclass().getName());
+        buffer.append("\n");
+
+        CtClass[] interfaces = getCtClass().getInterfaces();
+
+        if (interfaces.length > 0)
+        {
+            buffer.append("  implements ");
+
+            for (int i = 0; i < interfaces.length; i++)
+            {
+                if (i > 0) buffer.append(", ");
+
+                buffer.append(interfaces[i].getName());
+            }
+
+            buffer.append("\n\n");
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Returns the name of the class fabricated by this instance.
+     */
+    String getName()
+    {
+        return getCtClass().getName();
+    }
+
+    public void addField(String name, Class type)
+    {
+        addField(name, Modifier.PRIVATE, type);
+    }
+
+    public void addField(String name, int modifiers, Class type)
+    {
+        lock.check();
+
+        CtClass ctType = toCtClass(type);
+
+        try
+        {
+            CtField field = new CtField(ctType, name, getCtClass());
+            field.setModifiers(modifiers);
+
+            getCtClass().addField(field);
+        }
+        catch (CannotCompileException ex)
+        {
+            // Have yet to find a way to make this happen!
+            throw new RuntimeException(ServiceMessages.unableToAddField(name, getCtClass(), ex), ex);
+        }
+
+        formatter.format("%s %s %s;\n\n", Modifier.toString(modifiers), ClassFabUtils
+                .toJavaClassName(type), name);
+    }
+
+    public void proxyMethodsToDelegate(Class serviceInterface, String delegateExpression,
+                                       String toString)
+    {
+        lock.check();
+
+        addInterface(serviceInterface);
+
+        MethodIterator mi = new MethodIterator(serviceInterface);
+
+        while (mi.hasNext())
+        {
+            MethodSignature sig = mi.next();
+
+            // ($r) properly handles void methods for us, which keeps this simple.
+
+            String body = format("return ($r) %s.%s($$);", delegateExpression, sig.getName());
+
+            addMethod(Modifier.PUBLIC, sig, body);
+        }
+
+        if (!mi.getToString()) addToString(toString);
+    }
+
+    public void addToString(String toString)
+    {
+        lock.check();
+
+        MethodSignature sig = new MethodSignature(String.class, "toString", null, null);
+
+        // TODO: Very simple quoting here, will break down if the string itself contains
+        // double quotes or various other characters that need escaping.
+
+        addMethod(Modifier.PUBLIC, sig, format("return \"%s\";", toString));
+    }
+
+    public void addMethod(int modifiers, MethodSignature ms, String body)
+    {
+        lock.check();
+
+        if (addedSignatures.contains(ms))
+            throw new RuntimeException(ServiceMessages.duplicateMethodInClass(ms, this));
+
+        CtClass ctReturnType = toCtClass(ms.getReturnType());
+
+        CtClass[] ctParameters = toCtClasses(ms.getParameterTypes());
+        CtClass[] ctExceptions = toCtClasses(ms.getExceptionTypes());
+
+        CtMethod method = new CtMethod(ctReturnType, ms.getName(), ctParameters, getCtClass());
+
+        try
+        {
+            method.setModifiers(modifiers);
+            method.setBody(body);
+            method.setExceptionTypes(ctExceptions);
+
+            getCtClass().addMethod(method);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServiceMessages.unableToAddMethod(ms, getCtClass(), ex), ex);
+        }
+
+        addedSignatures.add(ms);
+
+        // modifiers, return type, name
+
+        formatter.format("%s %s %s", Modifier.toString(modifiers), ClassFabUtils
+                .toJavaClassName(ms.getReturnType()), ms.getName());
+
+        // parameters, exceptions and body from this:
+        addMethodDetailsToDescription(ms.getParameterTypes(), ms.getExceptionTypes(), body);
+
+        description.append("\n\n");
+    }
+
+    public void addNoOpMethod(MethodSignature signature)
+    {
+        lock.check();
+
+        Class returnType = signature.getReturnType();
+
+        if (returnType.equals(void.class))
+        {
+            addMethod(Modifier.PUBLIC, signature, "return;");
+            return;
+        }
+
+        String value = "null";
+        if (returnType.isPrimitive())
+        {
+            value = DEFAULT_RETURN.get(returnType);
+            if (value == null) value = "0";
+        }
+
+        addMethod(Modifier.PUBLIC, signature, "return " + value + ";");
+    }
+
+    public void addConstructor(Class[] parameterTypes, Class[] exceptions, String body)
+    {
+        Defense.notBlank(body, "body");
+
+        lock.check();
+
+        CtClass[] ctParameters = toCtClasses(parameterTypes);
+        CtClass[] ctExceptions = toCtClasses(exceptions);
+
+        try
+        {
+            CtConstructor constructor = new CtConstructor(ctParameters, getCtClass());
+            constructor.setExceptionTypes(ctExceptions);
+            constructor.setBody(body);
+
+            getCtClass().addConstructor(constructor);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServiceMessages.unableToAddConstructor(getCtClass(), ex), ex);
+        }
+
+        description.append("public ");
+
+        // This isn't quite right; we should strip the package portion off of the name.
+        // However, fabricated classes are almost always in the "default" package, so
+        // this is OK.
+
+        description.append(getName());
+
+        addMethodDetailsToDescription(parameterTypes, exceptions, body);
+
+        description.append("\n\n");
+    }
+
+    /**
+     * Adds a listing of method (or constructor) parameters and thrown exceptions, and the body, to the description
+     *
+     * @param parameterTypes types of method parameters, or null
+     * @param exceptions     types of throw exceptions, or null
+     * @param body           body of method or constructor
+     */
+    private void addMethodDetailsToDescription(Class[] parameterTypes, Class[] exceptions,
+                                               String body)
+    {
+        description.append("(");
+
+        int count = InternalUtils.size(parameterTypes);
+        for (int i = 0; i < count; i++)
+        {
+            if (i > 0) description.append(", ");
+
+            description.append(ClassFabUtils.toJavaClassName(parameterTypes[i]));
+
+            description.append(" $");
+            description.append(i + 1);
+        }
+
+        description.append(")");
+
+        count = InternalUtils.size(exceptions);
+        for (int i = 0; i < count; i++)
+        {
+            if (i == 0)
+                description.append("\n  throws ");
+            else
+                description.append(", ");
+
+            // Since this can never be an array type, we don't need to use getJavaClassName
+
+            description.append(exceptions[i].getName());
+        }
+
+        description.append("\n");
+        description.append(body);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
new file mode 100644
index 0000000..8555849
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryClassPool.java
@@ -0,0 +1,115 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.*;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Used to ensure that {@link javassist.ClassPool#appendClassPath(javassist.ClassPath)} is invoked within a synchronized
+ * lock, and also handles tricky class loading issues (caused by the creation of classes, and class loaders, at
+ * runtime).
+ */
+public class ClassFactoryClassPool extends ClassPool
+{
+    /**
+     * Used to identify which class loaders have already been integrated into the pool.
+     */
+    private final Set<ClassLoader> allLoaders = newSet();
+
+    private final Map<ClassLoader, ClassPath> leafLoaders = newMap();
+
+    public ClassFactoryClassPool(ClassLoader contextClassLoader)
+    {
+        super(null);
+
+        addClassLoaderIfNeeded(contextClassLoader);
+    }
+
+    /**
+     * Returns the nearest super-class of the provided class that can be converted to a {@link CtClass}. This is used to
+     * filter out Hibernate-style proxies (created as subclasses of oridnary classes). This will automatically add the
+     * class' classLoader to the pool's class path.
+     *
+     * @param clazz class to import
+     * @return clazz, or a super-class of clazz
+     */
+    public Class importClass(Class clazz)
+    {
+        addClassLoaderIfNeeded(clazz.getClassLoader());
+
+        while (true)
+        {
+            try
+            {
+                String name = ClassFabUtils.toJavaClassName(clazz);
+
+                get(name);
+
+                break;
+            }
+            catch (NotFoundException ex)
+            {
+                clazz = clazz.getSuperclass();
+            }
+        }
+
+        return clazz;
+    }
+
+    /**
+     * Convienience method for adding to the ClassPath for a particular class loader.
+     * <p/>
+     *
+     * @param loader the class loader to add (derived from a loaded class, and may be null for some system classes)
+     */
+    public synchronized void addClassLoaderIfNeeded(ClassLoader loader)
+    {
+        Set<ClassLoader> leaves = leafLoaders.keySet();
+        if (loader == null || leaves.contains(loader) || allLoaders.contains(loader)) return;
+
+        // Work out if this loader is a child of a loader we have already.
+        ClassLoader existingLeaf = loader;
+        while (existingLeaf != null && !leaves.contains(existingLeaf))
+        {
+            existingLeaf = existingLeaf.getParent();
+        }
+
+        if (existingLeaf != null)
+        {
+            // The new loader is a child of an existing leaf.
+            // So we remove the old leaf before we add the new loader
+            ClassPath priorPath = leafLoaders.get(existingLeaf);
+            removeClassPath(priorPath);
+            leafLoaders.remove(existingLeaf);
+        }
+
+        ClassPath path = new LoaderClassPath(loader);
+        leafLoaders.put(loader, path);
+        insertClassPath(path);
+
+        ClassLoader l = loader;
+        while (l != null)
+        {
+            allLoaders.add(l);
+            l = l.getParent();
+        }
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java
new file mode 100644
index 0000000..b31fe8c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java
@@ -0,0 +1,222 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtMethod;
+import org.apache.tapestry.ioc.Location;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * Implementation of {@link org.apache.tapestry.ioc.services.ClassFactory}.
+ */
+public class ClassFactoryImpl implements ClassFactory
+{
+    private final Logger logger;
+
+    /**
+     * ClassPool shared by all modules (all CtClassSource instances).
+     */
+    private final ClassFactoryClassPool pool;
+
+    private final CtClassSource classSource;
+
+    private final ClassLoader loader;
+
+    public ClassFactoryImpl(ClassLoader classLoader)
+    {
+        this(classLoader, LoggerFactory.getLogger(ClassFactoryImpl.class));
+    }
+
+    public ClassFactoryImpl()
+    {
+        this(Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Main constructor where a specific class loader and log is provided.
+     */
+    public ClassFactoryImpl(ClassLoader classLoader, Logger log)
+    {
+        this(classLoader, new ClassFactoryClassPool(classLoader), log);
+    }
+
+    /**
+     * Special constructor used when the class pool is provided externally.
+     */
+    public ClassFactoryImpl(ClassLoader classLoader, ClassFactoryClassPool pool, Logger logger)
+    {
+        this(classLoader, pool, new CtClassSourceImpl(pool, classLoader), logger);
+    }
+
+    public ClassFactoryImpl(ClassLoader classLoader, ClassFactoryClassPool pool, CtClassSource classSource,
+                            Logger logger)
+    {
+        loader = classLoader;
+
+        this.pool = pool;
+
+        this.classSource = classSource;
+
+        this.logger = logger;
+    }
+
+
+    public ClassFab newClass(Class serviceInterface)
+    {
+        String name = ClassFabUtils.generateClassName(serviceInterface);
+
+        ClassFab cf = newClass(name, Object.class);
+
+        cf.addInterface(serviceInterface);
+
+        return cf;
+    }
+
+    public ClassFab newClass(String name, Class superClass)
+    {
+        if (logger.isDebugEnabled())
+            logger.debug(String.format("Create ClassFab for %s (extends %s)", name, superClass
+                    .getName()));
+
+        try
+        {
+            CtClass ctNewClass = classSource.newClass(name, superClass);
+
+            return new ClassFabImpl(classSource, ctNewClass, logger);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServiceMessages.unableToCreateClass(name, superClass, ex), ex);
+        }
+    }
+
+    public Class importClass(Class clazz)
+    {
+        return pool.importClass(clazz);
+    }
+
+    public int getCreatedClassCount()
+    {
+        return classSource.getCreatedClassCount();
+    }
+
+    public ClassLoader getClassLoader()
+    {
+        return loader;
+    }
+
+    public Location getMethodLocation(Method method)
+    {
+        notNull(method, "method");
+
+        // TODO: Is it worth caching this? Probably not as it usually is only
+        // invoked perhaps at startup and in the event of errors.
+
+        Class declaringClass = method.getDeclaringClass();
+        Class effectiveClass = importClass(declaringClass);
+
+        CtClass ctClass = classSource.toCtClass(effectiveClass);
+
+        StringBuilder builder = new StringBuilder("(");
+
+        for (Class parameterType : method.getParameterTypes())
+        {
+            builder.append(ClassFabUtils.getTypeCode(parameterType));
+        }
+
+        builder.append(")");
+        builder.append(ClassFabUtils.getTypeCode(method.getReturnType()));
+
+        try
+        {
+            CtMethod ctMethod = ctClass.getMethod(method.getName(), builder.toString());
+
+            int lineNumber = ctMethod.getMethodInfo().getLineNumber(0);
+
+            String sourceFile = ctMethod.getDeclaringClass().getClassFile2().getSourceFile();
+
+            String description = String.format("%s (at %s:%d)", InternalUtils.asString(method), sourceFile, lineNumber);
+
+            return new StringLocation(description, lineNumber);
+        }
+        catch (Exception ex)
+        {
+            return new StringLocation(InternalUtils.asString(method), 0);
+        }
+    }
+
+    public Location getConstructorLocation(Constructor constructor)
+    {
+        notNull(constructor, "constructor");
+
+        StringBuilder builder = new StringBuilder();
+
+        Class declaringClass = constructor.getDeclaringClass();
+
+        builder.append(declaringClass.getName());
+        builder.append("(");
+
+        CtClass ctClass = classSource.toCtClass(declaringClass);
+
+        StringBuilder descripton = new StringBuilder("(");
+
+        Class[] parameterTypes = constructor.getParameterTypes();
+        for (int i = 0; i < parameterTypes.length; i++)
+        {
+            Class parameterType = parameterTypes[i];
+
+            if (i > 0) builder.append(", ");
+
+            builder.append(parameterType.getSimpleName());
+
+            descripton.append(ClassFabUtils.getTypeCode(parameterType));
+        }
+
+        builder.append(")");
+
+        // A constructor resembles a method of type void
+        descripton.append(")V");
+
+        int lineNumber = 0;
+
+        try
+        {
+            CtConstructor ctConstructor = ctClass.getConstructor(descripton.toString());
+
+            lineNumber = ctConstructor.getMethodInfo().getLineNumber(0);
+
+            String sourceFile = ctConstructor.getDeclaringClass().getClassFile2().getSourceFile();
+
+            builder.append(String.format(" (at %s:%d)", sourceFile, lineNumber));
+        }
+        catch (Exception ex)
+        {
+            // Leave the line number as 0 (aka "unknown").
+        }
+
+        return new StringLocation(builder.toString(), lineNumber);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImpl.java
new file mode 100644
index 0000000..48d5cfc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImpl.java
@@ -0,0 +1,309 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+import org.apache.tapestry.ioc.util.Stack;
+
+import java.io.*;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class ClassNameLocatorImpl implements ClassNameLocator
+{
+    private static final String CLASS_SUFFIX = ".class";
+
+    private final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+    static class Queued
+    {
+        final URL packageURL;
+
+        final String packagePath;
+
+        public Queued(final URL packageURL, final String packagePath)
+        {
+            this.packageURL = packageURL;
+            this.packagePath = packagePath;
+        }
+    }
+
+    /**
+     * Synchronization should not be necessary, but perhaps the underlying ClassLoader's are sensitive to threading.
+     */
+    public synchronized Collection<String> locateClassNames(String packageName)
+    {
+        String packagePath = packageName.replace('.', '/') + "/";
+
+        try
+        {
+
+            return findClassesWithinPath(packagePath);
+
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private Collection<String> findClassesWithinPath(String packagePath) throws IOException
+    {
+        Collection<String> result = CollectionFactory.newList();
+
+        Enumeration<URL> urls = contextClassLoader.getResources(packagePath);
+
+        while (urls.hasMoreElements())
+        {
+            URL url = urls.nextElement();
+
+            scanURL(packagePath, result, url);
+        }
+
+        return result;
+    }
+
+    private void scanURL(String packagePath, Collection<String> componentClassNames, URL url) throws IOException
+    {
+        URLConnection connection = url.openConnection();
+
+        JarFile jarFile;
+
+        if (connection instanceof JarURLConnection)
+        {
+            jarFile = ((JarURLConnection) connection).getJarFile();
+        }
+        else
+        {
+            jarFile = getAlternativeJarFile(url);
+        }
+
+        if (jarFile != null)
+        {
+            scanJarFile(packagePath, componentClassNames, jarFile);
+        }
+        else if (supportsDirStream(url))
+        {
+            Stack<Queued> queue = CollectionFactory.newStack();
+
+            queue.push(new Queued(url, packagePath));
+
+            while (!queue.isEmpty())
+            {
+                Queued queued = queue.pop();
+
+                scanDirStream(queued.packagePath, queued.packageURL, componentClassNames, queue);
+            }
+        }
+        else
+        {
+            // Try scanning file system.
+            String packageName = packagePath.replace("/", ".");
+            if (packageName.endsWith("."))
+            {
+                packageName = packageName.substring(0, packageName.length() - 1);
+            }
+            scanDir(packageName, new File(url.getFile()), componentClassNames);
+        }
+
+    }
+
+    /**
+     * Check whether container supports opening a stream on a dir/package to get a list of its contents.
+     *
+     * @param packageURL
+     * @return
+     */
+    private boolean supportsDirStream(URL packageURL)
+    {
+        InputStream is = null;
+        try
+        {
+            is = packageURL.openStream();
+            return true;
+        }
+        catch (FileNotFoundException ex)
+        {
+            return false;
+        }
+        catch (IOException e)
+        {
+            return false;
+        }
+        finally
+        {
+            InternalUtils.close(is);
+        }
+    }
+
+    private void scanDirStream(String packagePath, URL packageURL, Collection<String> componentClassNames,
+                               Stack<Queued> queue) throws IOException
+    {
+        InputStream is;
+
+        try
+        {
+            is = new BufferedInputStream(packageURL.openStream());
+        }
+        catch (FileNotFoundException ex)
+        {
+            // This can happen for certain application servers (JBoss 4.0.5 for example), that
+            // export part of the exploded WAR for deployment, but leave part (WEB-INF/classes)
+            // unexploded.
+
+            return;
+        }
+
+        Reader reader = new InputStreamReader(is);
+        LineNumberReader lineReader = new LineNumberReader(reader);
+
+        String packageName = null;
+
+        try
+        {
+            while (true)
+            {
+                String line = lineReader.readLine();
+
+                if (line == null) break;
+
+                if (line.contains("$")) continue;
+
+                if (line.endsWith(CLASS_SUFFIX))
+                {
+                    if (packageName == null) packageName = packagePath.replace('/', '.');
+
+                    // packagePath ends with '/', packageName ends with '.'
+
+                    String fullClassName = packageName + line.substring(0, line.length() - CLASS_SUFFIX.length());
+
+                    componentClassNames.add(fullClassName);
+
+                    continue;
+                }
+
+                // Either a file or a hidden directory (such as .svn)
+
+                if (line.contains(".")) continue;
+
+                // The name of a subdirectory.
+
+                URL newURL = new URL(packageURL.toExternalForm() + line + "/");
+                String newPackagePath = packagePath + line + "/";
+
+                queue.push(new Queued(newURL, newPackagePath));
+            }
+
+            lineReader.close();
+            lineReader = null;
+        }
+        finally
+        {
+            InternalUtils.close(lineReader);
+        }
+
+    }
+
+    private void scanJarFile(String packagePath, Collection<String> componentClassNames, JarFile jarFile)
+    {
+        Enumeration<JarEntry> e = jarFile.entries();
+
+        while (e.hasMoreElements())
+        {
+            String name = e.nextElement().getName();
+
+            if (!name.startsWith(packagePath)) continue;
+
+            if (!name.endsWith(CLASS_SUFFIX)) continue;
+
+            if (name.contains("$")) continue;
+
+            // Strip off .class and convert the slashes back to periods.
+
+            String className = name.substring(0, name.length() - CLASS_SUFFIX.length()).replace("/", ".");
+
+            componentClassNames.add(className);
+        }
+    }
+
+    /**
+     * Scan a dir for classes. Will recursively look in the supplied directory and all sub directories.
+     *
+     * @param packageName         Name of package that this directory corresponds to.
+     * @param dir                 Dir to scan for clases.
+     * @param componentClassNames List of class names that have been found.
+     */
+    private void scanDir(String packageName, File dir, Collection<String> componentClassNames)
+    {
+        if (dir.exists() && dir.isDirectory())
+        {
+            for (File file : dir.listFiles())
+            {
+                String fileName = file.getName();
+                if (file.isDirectory())
+                {
+                    scanDir(packageName + "." + fileName, file, componentClassNames);
+                }
+                else if (fileName.endsWith(CLASS_SUFFIX))
+                {
+                    String className = packageName + "." + fileName.substring(0,
+                                                                              fileName.length() - CLASS_SUFFIX.length());
+                    componentClassNames.add(className);
+                }
+            }
+        }
+    }
+
+    /**
+     * For URLs to JARs that do not use JarURLConnection - allowed by the servlet spec - attempt to produce a JarFile
+     * object all the same. Known servlet engines that function like this include Weblogic and OC4J. This is not a full
+     * solution, since an unpacked WAR or EAR will not have JAR "files" as such.
+     *
+     * @param url URL of jar
+     * @return JarFile or null
+     * @throws java.io.IOException If error occurs creating jar file
+     */
+    private JarFile getAlternativeJarFile(URL url) throws IOException
+    {
+        String urlFile = url.getFile();
+        // Trim off any suffix - which is prefixed by "!/" on Weblogic
+        int separatorIndex = urlFile.indexOf("!/");
+
+        // OK, didn't find that. Try the less safe "!", used on OC4J
+        if (separatorIndex == -1)
+        {
+            separatorIndex = urlFile.indexOf('!');
+        }
+        if (separatorIndex != -1)
+        {
+            String jarFileUrl = urlFile.substring(0, separatorIndex);
+            // And trim off any "file:" prefix.
+            if (jarFileUrl.startsWith("file:"))
+            {
+                jarFileUrl = jarFileUrl.substring("file:".length());
+            }
+            return new JarFile(jarFileUrl);
+        }
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java
new file mode 100644
index 0000000..cb7e493
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java
@@ -0,0 +1,98 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+import org.apache.tapestry.ioc.internal.util.GenericsUtils;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+public class ClassPropertyAdapterImpl implements ClassPropertyAdapter
+{
+    private final Map<String, PropertyAdapter> adapters = newCaseInsensitiveMap();
+
+    private final Class beanType;
+
+    public ClassPropertyAdapterImpl(Class beanType, List<PropertyDescriptor> descriptors)
+    {
+        this.beanType = beanType;
+
+        for (PropertyDescriptor pd : descriptors)
+        {
+            // Indexed properties will have a null propertyType (and a non-null
+            // indexedPropertyType). We ignore indexed properties.
+
+            if (pd.getPropertyType() == null) continue;
+
+            Method readMethod = pd.getReadMethod();
+
+            Class propertyType = readMethod == null ? pd.getPropertyType() : GenericsUtils.extractGenericReturnType(
+                    beanType, readMethod);
+
+            PropertyAdapter pa = new PropertyAdapterImpl(pd.getName(), propertyType, readMethod, pd.getWriteMethod());
+
+            adapters.put(pa.getName(), pa);
+        }
+    }
+
+    public Class getBeanType()
+    {
+        return beanType;
+    }
+
+    @Override
+    public String toString()
+    {
+        String names = InternalUtils.joinSorted(adapters.keySet());
+
+        return String.format("<ClassPropertyAdaptor %s : %s>", beanType.getName(), names);
+    }
+
+    public List<String> getPropertyNames()
+    {
+        return InternalUtils.sortedKeys(adapters);
+    }
+
+    public PropertyAdapter getPropertyAdapter(String name)
+    {
+        return adapters.get(name);
+    }
+
+    public Object get(Object instance, String propertyName)
+    {
+        return adaptorFor(propertyName).get(instance);
+    }
+
+    public void set(Object instance, String propertyName, Object value)
+    {
+        adaptorFor(propertyName).set(instance, value);
+    }
+
+    private PropertyAdapter adaptorFor(String name)
+    {
+        PropertyAdapter pa = adapters.get(name);
+
+        if (pa == null) throw new IllegalArgumentException(ServiceMessages.noSuchProperty(beanType, name));
+
+        return pa;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CompoundCoercion.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CompoundCoercion.java
new file mode 100644
index 0000000..0e9238a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CompoundCoercion.java
@@ -0,0 +1,53 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.Coercion;
+
+/**
+ * Combines two coercions to create a coercsion through an intermediate type.
+ *
+ * @param <S> The source (input) type
+ * @param <I> The intermediate type
+ * @param <T> The target (output) type
+ */
+public class CompoundCoercion<S, I, T> implements Coercion<S, T>
+{
+    private final Coercion<S, I> op1;
+
+    private final Coercion<I, T> op2;
+
+    public CompoundCoercion(Coercion<S, I> op1, Coercion<I, T> op2)
+    {
+        this.op1 = op1;
+        this.op2 = op2;
+    }
+
+    public T coerce(S input)
+    {
+        // Run the input through the first operation (S --> I), then run the result of that through
+        // the second operation (I --> T).
+
+        I intermediate = op1.coerce(input);
+
+        return op2.coerce(intermediate);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("%s, %s", op1, op2);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSource.java
new file mode 100644
index 0000000..efabdd5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSource.java
@@ -0,0 +1,50 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+
+/**
+ * Used when generating new classes on the fly.
+ *
+ * @see org.apache.tapestry.ioc.services.ClassFactory
+ */
+public interface CtClassSource
+{
+    /**
+     * Returns the number of classes created.
+     */
+    int getCreatedClassCount();
+
+    /**
+     * Converts an existing class to a CtClass instance.
+     */
+    CtClass toCtClass(Class searchClass);
+
+    /**
+     * Converts a class name to a CtClass instance.
+     */
+    CtClass toCtClass(String name);
+
+    /**
+     * Createa a new CtClass instance.
+     */
+    CtClass newClass(String name, Class superClass);
+
+    /**
+     * Used after constructing the CtClass fully, to convert it into a Class ready to be instantiated.
+     */
+    Class createClass(CtClass ctClass);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSourceImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSourceImpl.java
new file mode 100644
index 0000000..42fae15
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/CtClassSourceImpl.java
@@ -0,0 +1,121 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+import javassist.NotFoundException;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+import java.security.ProtectionDomain;
+
+/**
+ * Wrapper around Javassist's {@link javassist.ClassPool} that manages the creation of new instances of {@link
+ * javassist.CtClass} and converts finished CtClass's into instantiable Classes.
+ */
+public class CtClassSourceImpl implements CtClassSource
+{
+    private final ClassFactoryClassPool pool;
+
+    private final ClassLoader loader;
+
+    private final ProtectionDomain domain = getClass().getProtectionDomain();
+
+    private int createdClassCount = 0;
+
+    /**
+     * Returns the number of classes (and interfaces) created by this source.
+     */
+    public synchronized int getCreatedClassCount()
+    {
+        return createdClassCount;
+    }
+
+    public CtClassSourceImpl(ClassFactoryClassPool pool, ClassLoader loader)
+    {
+        this.pool = pool;
+        this.loader = loader;
+    }
+
+    public CtClass toCtClass(Class searchClass)
+    {
+        ClassLoader loader = searchClass.getClassLoader();
+
+        // Add the class loader for the searchClass to the class pool and
+        // delegating class loader if needed.
+
+        pool.addClassLoaderIfNeeded(loader);
+
+        String name = ClassFabUtils.toJavaClassName(searchClass);
+
+        return toCtClass(name);
+    }
+
+    public CtClass toCtClass(String name)
+    {
+        try
+        {
+            return pool.get(name);
+        }
+        catch (NotFoundException ex)
+        {
+            throw new RuntimeException(ServiceMessages.unableToLookupClass(name, ex), ex);
+        }
+    }
+
+    public synchronized CtClass newClass(String name, Class superClass)
+    {
+        CtClass ctSuperClass = toCtClass(superClass);
+
+        return pool.makeClass(name, ctSuperClass);
+    }
+
+    private static final String WRITE_DIR = System.getProperty("javassist-write-dir");
+
+    public synchronized Class createClass(CtClass ctClass)
+    {
+        if (WRITE_DIR != null) writeClass(ctClass);
+
+        try
+        {
+            Class result = pool.toClass(ctClass, loader, domain);
+
+            createdClassCount++;
+
+            return result;
+        }
+        catch (Throwable ex)
+        {
+            throw new RuntimeException(ServiceMessages.unableToWriteClass(ctClass, ex), ex);
+        }
+    }
+
+    private void writeClass(CtClass ctClass)
+    {
+        try
+        {
+            boolean pruning = ctClass.stopPruning(true);
+
+            ctClass.writeFile(WRITE_DIR);
+
+            ctClass.defrost();
+
+            ctClass.stopPruning(pruning);
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace(System.err);
+        }
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImpl.java
new file mode 100644
index 0000000..bd932e6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImpl.java
@@ -0,0 +1,94 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
+import org.apache.tapestry.ioc.services.*;
+
+import static java.lang.String.format;
+import java.util.Map;
+
+/**
+ *
+ */
+public class DefaultImplementationBuilderImpl implements DefaultImplementationBuilder
+{
+    private final Map<Class, Object> cache = newConcurrentMap();
+
+    private final ClassFactory classFactory;
+
+    public DefaultImplementationBuilderImpl(@Builtin ClassFactory classFactory)
+    {
+        this.classFactory = classFactory;
+    }
+
+    public <S> S createDefaultImplementation(Class<S> serviceInterface)
+    {
+        S instance = serviceInterface.cast(cache.get(serviceInterface));
+
+        if (instance == null)
+        {
+            instance = createInstance(serviceInterface);
+            cache.put(serviceInterface, instance);
+        }
+
+        return instance;
+    }
+
+    /**
+     * Creates a class and an instance of that class. Updates the cache and returns the instance.
+     */
+    private <S> S createInstance(Class<S> serviceInterface)
+    {
+        // In rare race conditions, we may end up creating two (or more)
+        // NOOP class/instance pairs for the same interface. You need multiple threads
+        // asking for a NOOP class for the same interface pretty much simulataneously.
+        // We just let this happen.
+
+        Class<S> noopClass = createClass(serviceInterface);
+
+        try
+        {
+            S instance = noopClass.newInstance();
+
+            cache.put(serviceInterface, instance);
+
+            return instance;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private <S> Class<S> createClass(Class<S> serviceInterface)
+    {
+        ClassFab cf = classFactory.newClass(serviceInterface);
+
+        MethodIterator mi = new MethodIterator(serviceInterface);
+
+        while (mi.hasNext())
+        {
+            MethodSignature sig = mi.next();
+
+            cf.addNoOpMethod(sig);
+        }
+
+        if (!mi.getToString()) cf.addToString(format("<NoOp %s>", serviceInterface.getName()));
+
+        return cf.createClass();
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java
new file mode 100644
index 0000000..60555c3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalysisImpl.java
@@ -0,0 +1,48 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.services;

+

+import org.apache.tapestry.ioc.services.ExceptionAnalysis;

+import org.apache.tapestry.ioc.services.ExceptionInfo;

+

+import static java.util.Collections.unmodifiableList;

+import java.util.List;

+

+/**

+ *

+ */

+public class ExceptionAnalysisImpl implements ExceptionAnalysis

+{

+    private final List<ExceptionInfo> infos;

+

+    public ExceptionAnalysisImpl(final List<ExceptionInfo> infos)

+    {

+        this.infos = unmodifiableList(infos);

+    }

+

+    public List<ExceptionInfo> getExceptionInfos()

+    {

+        return infos;

+    }

+

+    @Override

+    public String toString()

+    {

+        ExceptionInfo first = infos.get(0);

+

+        return String.format("ExceptionAnalysis[%s -- %s]", first.getClassName(), first

+                .getMessage());

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImpl.java
new file mode 100644
index 0000000..c1e85da
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImpl.java
@@ -0,0 +1,140 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import org.apache.tapestry.ioc.services.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
+{
+    private final PropertyAccess propertyAccess;
+
+    private final Set<String> throwableProperties;
+
+    public ExceptionAnalyzerImpl(PropertyAccess propertyAccess)
+    {
+        this.propertyAccess = propertyAccess;
+
+        throwableProperties = newSet(this.propertyAccess.getAdapter(Throwable.class)
+                .getPropertyNames());
+    }
+
+    public ExceptionAnalysis analyze(Throwable rootException)
+    {
+        List<ExceptionInfo> list = CollectionFactory.newList();
+
+        Throwable t = rootException;
+
+        ExceptionInfo previousInfo = null;
+
+        while (t != null)
+        {
+            ExceptionInfo info = extractInfo(t);
+
+            if (addsValue(previousInfo, info))
+            {
+                list.add(info);
+                previousInfo = info;
+            }
+
+            t = t.getCause();
+        }
+
+        return new ExceptionAnalysisImpl(list);
+    }
+
+    /**
+     * We want to filter out exceptions that do not provide any additional value. Additional value includes: an
+     * exception message not present in the containing exception or a property value not present in the containing
+     * exception. Also the first exception is always valued and the last exception (with the stack trace) is valued.
+     *
+     * @param previousInfo
+     * @param info
+     * @return
+     */
+    private boolean addsValue(ExceptionInfo previousInfo, ExceptionInfo info)
+    {
+        if (previousInfo == null) return true;
+
+        if (!info.getStackTrace().isEmpty()) return true;
+
+        if (!previousInfo.getMessage().contains(info.getMessage())) return true;
+
+        for (String name : info.getPropertyNames())
+        {
+            if (info.getProperty(name).equals(previousInfo.getProperty(name))) continue;
+
+            // Found something new and different at this level.
+
+            return true;
+        }
+
+        // This exception adds nothing that is not present at a higher level.
+
+        return false;
+    }
+
+    private ExceptionInfo extractInfo(Throwable t)
+    {
+        Map<String, Object> properties = newMap();
+
+        ClassPropertyAdapter adapter = propertyAccess.getAdapter(t);
+
+        for (String name : adapter.getPropertyNames())
+        {
+            if (throwableProperties.contains(name)) continue;
+
+            Object value = adapter.get(t, name);
+
+            if (value == null) continue;
+
+            // An interesting property, let's save it for the analysis.
+
+            properties.put(name, value);
+        }
+
+        List<StackTraceElement> stackTrace = Collections.emptyList();
+
+        // Usually, I'd use a terniary expression here, but Generics gets in
+        // the way here.
+
+        if (t.getCause() == null) stackTrace = extractStackTrace(t);
+
+        return new ExceptionInfoImpl(t, properties, stackTrace);
+    }
+
+    private List<StackTraceElement> extractStackTrace(Throwable t)
+    {
+        List<StackTraceElement> trace = newList();
+
+        for (StackTraceElement e : t.getStackTrace())
+        {
+            // Edit out IoC Proxy classes. They always start with a '$'
+            // and don't have any line number information.
+
+            if (e.getClassName().startsWith("$") && e.getLineNumber() < 0) continue;
+
+            trace.add(e);
+        }
+
+        return trace;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionInfoImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionInfoImpl.java
new file mode 100644
index 0000000..607fd5c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionInfoImpl.java
@@ -0,0 +1,68 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ExceptionInfo;
+
+import static java.util.Collections.unmodifiableList;
+import java.util.List;
+import java.util.Map;
+
+public class ExceptionInfoImpl implements ExceptionInfo
+{
+    private final String className;
+
+    private final String message;
+
+    private final Map<String, Object> properties;
+
+    private final List<StackTraceElement> stackTrace;
+
+    public ExceptionInfoImpl(Throwable t, Map<String, Object> properties, List<StackTraceElement> stackTrace)
+    {
+        className = t.getClass().getName();
+        message = t.getMessage() != null ? t.getMessage() : "";
+
+        this.properties = properties;
+        this.stackTrace = unmodifiableList(stackTrace);
+    }
+
+    public String getClassName()
+    {
+        return className;
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public Object getProperty(String name)
+    {
+        return properties.get(name);
+    }
+
+    public List<String> getPropertyNames()
+    {
+        return InternalUtils.sortedKeys(properties);
+    }
+
+    public List<StackTraceElement> getStackTrace()
+    {
+        return stackTrace;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImpl.java
new file mode 100644
index 0000000..3d29800
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImpl.java
@@ -0,0 +1,37 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ExceptionTracker;
+
+import java.util.Set;
+
+@Scope(PERTHREAD_SCOPE)
+public class ExceptionTrackerImpl implements ExceptionTracker
+{
+    private final Set<Throwable> exceptions = CollectionFactory.newSet();
+
+    public boolean exceptionLogged(Throwable exception)
+    {
+        boolean result = exceptions.contains(exception);
+
+        exceptions.add(exception);
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzer.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzer.java
new file mode 100644
index 0000000..60d3d8f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzer.java
@@ -0,0 +1,81 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.MethodSignature;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.PipelineBuilderImpl} to analyze service interface methods
+ * against filter interface methods to find the position of the extra service parameter (in the filter method).
+ */
+public class FilterMethodAnalyzer
+{
+    private final Class serviceInterface;
+
+    FilterMethodAnalyzer(Class serviceInterface)
+    {
+        this.serviceInterface = serviceInterface;
+    }
+
+    public int findServiceInterfacePosition(MethodSignature ms, MethodSignature fms)
+    {
+        if (ms.getReturnType() != fms.getReturnType()) return -1;
+
+        if (!ms.getName().equals(fms.getName())) return -1;
+
+        Class[] filterParameters = fms.getParameterTypes();
+        int filterParameterCount = filterParameters.length;
+        Class[] serviceParameters = ms.getParameterTypes();
+
+        if (filterParameterCount != (serviceParameters.length + 1)) return -1;
+
+        // TODO: check compatible exceptions!
+
+        // This needs work; it assumes the first occurance of the service interface
+        // in the filter interface method signature is the right match. That will suit
+        // most of the time.
+
+        boolean found = false;
+        int result = -1;
+
+        for (int i = 0; i < filterParameterCount; i++)
+        {
+            if (filterParameters[i] == serviceInterface)
+            {
+                result = i;
+                found = true;
+                break;
+            }
+        }
+
+        if (!found) return -1;
+
+        // Check that all the parameters before and after the service interface still
+        // match.
+
+        for (int i = 0; i < result; i++)
+        {
+            if (filterParameters[i] != serviceParameters[i]) return -1;
+        }
+
+        for (int i = result + 1; i < filterParameterCount; i++)
+        {
+            if (filterParameters[i] != serviceParameters[i - 1]) return -1;
+        }
+
+        return result;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java
new file mode 100644
index 0000000..e8b8935
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java
@@ -0,0 +1,102 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.internal.EagerLoadServiceProxy;
+import org.apache.tapestry.ioc.internal.ServiceActivityTracker;
+import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.apache.tapestry.ioc.services.Status;
+
+/**
+ * Invoked from a fabricated service delegate to get or realize (instantiate and configure) the service implementation.
+ * This includes synchronization logic, to prevent multiple threads from attempting to realize the same service at the
+ * same time (a service should be realized only once). The additional interfaces implemented by this class support eager
+ * loading of services (at application startup), and orderly shutdown of proxies.
+ */
+public class JustInTimeObjectCreator implements ObjectCreator, EagerLoadServiceProxy,
+        RegistryShutdownListener
+{
+    private final ServiceActivityTracker tracker;
+
+    private ObjectCreator creator;
+
+    private boolean shutdown;
+
+    private Object object;
+
+    private final String serviceId;
+
+    public JustInTimeObjectCreator(ServiceActivityTracker tracker, ObjectCreator creator,
+                                   String serviceId)
+    {
+        this.tracker = tracker;
+        this.creator = creator;
+        this.serviceId = serviceId;
+    }
+
+    /**
+     * Checks to see if the proxy has been shutdown, then invokes {@link ObjectCreator#createObject()} if it has not
+     * already done so.
+     *
+     * @throws IllegalStateException if the registry has been shutdown
+     */
+    public synchronized Object createObject()
+    {
+        if (shutdown)
+            throw new IllegalStateException(ServiceMessages.registryShutdown(serviceId));
+
+        if (object == null)
+        {
+            try
+            {
+                object = creator.createObject();
+
+                // And if that's successful ...
+
+                tracker.setStatus(serviceId, Status.REAL);
+
+                creator = null;
+            }
+            catch (RuntimeException ex)
+            {
+                throw new RuntimeException(ServiceMessages.serviceBuildFailure(serviceId, ex), ex);
+            }
+        }
+
+        return object;
+    }
+
+    /**
+     * Invokes {@link #createObject()} to force the creation of the underlying service.
+     */
+    public void eagerLoadService()
+    {
+        // Force object creation now
+
+        createObject();
+    }
+
+    /**
+     * Sets the shutdown flag and releases the object and the creator.
+     */
+    public synchronized void registryDidShutdown()
+    {
+        shutdown = true;
+        object = null;
+        creator = null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingAdvice.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingAdvice.java
new file mode 100644
index 0000000..096923d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingAdvice.java
@@ -0,0 +1,65 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.services.ExceptionTracker;
+import org.slf4j.Logger;
+
+public class LoggingAdvice implements MethodAdvice
+{
+    private final MethodLogger methodLogger;
+
+    public LoggingAdvice(Logger logger, ExceptionTracker exceptionTracker)
+    {
+        methodLogger = new MethodLogger(logger, exceptionTracker);
+    }
+
+    public void advise(Invocation invocation)
+    {
+        boolean debug = methodLogger.isDebugEnabled();
+
+        if (!debug)
+        {
+            invocation.proceed();
+            return;
+        }
+
+        methodLogger.entry(invocation);
+
+        try
+        {
+            invocation.proceed();
+        }
+        catch (RuntimeException ex)
+        {
+            methodLogger.fail(invocation, ex);
+
+            throw ex;
+        }
+
+        if (invocation.isFail())
+        {
+            Exception thrown = invocation.getThrown(Exception.class);
+
+            methodLogger.fail(invocation, thrown);
+
+            return;
+        }
+
+        methodLogger.exit(invocation);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImpl.java
new file mode 100644
index 0000000..a6c1ec4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImpl.java
@@ -0,0 +1,44 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.ioc.services.ExceptionTracker;
+import org.apache.tapestry.ioc.services.LoggingDecorator;
+import org.slf4j.Logger;
+
+public class LoggingDecoratorImpl implements LoggingDecorator
+{
+    private final AspectDecorator aspectDecorator;
+
+    private final ExceptionTracker exceptionTracker;
+
+    public LoggingDecoratorImpl(AspectDecorator aspectDecorator, ExceptionTracker exceptionTracker)
+    {
+        this.aspectDecorator = aspectDecorator;
+        this.exceptionTracker = exceptionTracker;
+    }
+
+    public <T> T build(Class<T> serviceInterface, T delegate, String serviceId, final Logger logger)
+    {
+        MethodAdvice advice = new LoggingAdvice(logger, exceptionTracker);
+
+        return aspectDecorator.build(serviceInterface, delegate, advice,
+                                     String.format("<Logging interceptor for %s(%s)>", serviceId,
+                                                   serviceInterface.getName()));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MapSymbolProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MapSymbolProvider.java
new file mode 100644
index 0000000..f76ac61
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MapSymbolProvider.java
@@ -0,0 +1,39 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.SymbolProvider;
+
+import java.util.Map;
+
+/**
+ * Provides symbol values from a Map of symbol names and symbol values (typically provided by a Tapestry IOC service
+ * configuration).
+ */
+public class MapSymbolProvider implements SymbolProvider
+{
+    private final Map<String, String> configuration;
+
+    public MapSymbolProvider(final Map<String, String> configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public String valueForSymbol(String symbolName)
+    {
+        return configuration.get(symbolName);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java
new file mode 100644
index 0000000..c155037
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImpl.java
@@ -0,0 +1,51 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.services.MasterObjectProvider;
+
+import java.util.List;
+
+public class MasterObjectProviderImpl implements MasterObjectProvider
+{
+    private final List<ObjectProvider> configuration;
+
+    public MasterObjectProviderImpl(List<ObjectProvider> configuration)
+    {
+        this.configuration = configuration;
+    }
+
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator,
+                         boolean required)
+    {
+        for (ObjectProvider provider : configuration)
+        {
+            T result = provider.provide(objectType, annotationProvider, locator);
+
+            if (result != null) return result;
+        }
+
+        // If required, then we must obtain it the hard way, by
+        // seeing if there's a single service that implements the interface.
+
+        if (required) return locator.getService(objectType);
+
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MethodLogger.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MethodLogger.java
new file mode 100644
index 0000000..7c80d3b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/MethodLogger.java
@@ -0,0 +1,170 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.services.ExceptionTracker;
+import org.slf4j.Logger;
+
+import static java.lang.String.format;
+import java.util.Iterator;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.LoggingDecoratorImpl} to delegate out logging behavior to a
+ * seperate object.
+ */
+public final class MethodLogger
+{
+    private static final int BUFFER_SIZE = 200;
+
+    private static final String ENTER = "ENTER";
+
+    private static final String EXIT = " EXIT";
+
+    private static final String FAIL = " FAIL";
+
+    private final Logger logger;
+
+    private final ExceptionTracker exceptionTracker;
+
+    public MethodLogger(Logger logger, ExceptionTracker exceptionTracker)
+    {
+        this.logger = logger;
+        this.exceptionTracker = exceptionTracker;
+    }
+
+    public boolean isDebugEnabled()
+    {
+        return logger.isDebugEnabled();
+    }
+
+    /**
+     * Invoked when a method is first entered
+     *
+     * @param invocation identifies method invoked as well as parameters passed to method
+     */
+    public void entry(Invocation invocation)
+    {
+        StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
+
+        buffer.append(format("[%s] %s(", ENTER, invocation.getMethodName()));
+
+        for (int i = 0; i < invocation.getParameterCount(); i++)
+        {
+            if (i > 0) buffer.append(", ");
+
+            convert(buffer, invocation.getParameter(i));
+        }
+
+        buffer.append(")");
+
+        logger.debug(buffer.toString());
+    }
+
+    private void convert(StringBuilder buffer, Object object)
+    {
+        if (object == null)
+        {
+            buffer.append("null");
+            return;
+        }
+
+        // Minimal, alas: Doesn't handle embedded quotes and other
+        // characters. Really want to convert the string back to what it
+        // would look like as source code.
+
+        if (object instanceof String)
+        {
+            buffer.append("\"");
+            buffer.append(object.toString());
+            buffer.append("\"");
+            return;
+        }
+
+        if (object instanceof Object[])
+        {
+            Object[] values = (Object[]) object;
+            buffer.append('{');
+
+            for (int i = 0; i < values.length; i++)
+            {
+                if (i > 0) buffer.append(", ");
+
+                convert(buffer, values[i]);
+            }
+
+            buffer.append('}');
+            return;
+        }
+
+        if (object instanceof Iterable)
+        {
+            Iterable itr = (Iterable) object;
+            boolean first = true;
+
+            buffer.append('[');
+            Iterator i = itr.iterator();
+            while (i.hasNext())
+            {
+                if (!first) buffer.append(", ");
+
+                convert(buffer, i.next());
+                first = false;
+            }
+            buffer.append(']');
+            return;
+        }
+
+        // Might need to add a few more, for things like character values ...
+
+        buffer.append(object.toString());
+    }
+
+    /**
+     * Invoked when a method exits (possibly returning a value).
+     *
+     * @param invocation identifies method invocation and  result value
+     */
+    public void exit(Invocation invocation)
+    {
+        StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
+
+        buffer.append(format("[%s] %s", EXIT, invocation.getMethodName()));
+
+        if (invocation.getResultType() != void.class)
+        {
+            buffer.append(" [");
+            convert(buffer, invocation.getResult());
+            buffer.append(']');
+        }
+
+        logger.debug(buffer.toString());
+    }
+
+    /**
+     * Invoked when method invocation instead throws an exception.
+     *
+     * @param invocation identifies method invocation which failed
+     * @param t          exception throws by method invocation
+     */
+    public void fail(Invocation invocation, Throwable t)
+    {
+        logger.debug(
+                format("[%s] %s -- %s", FAIL,
+                       invocation.getMethodName(),
+                       t.getClass().getName()),
+                exceptionTracker.exceptionLogged(t) ? null : t);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java
new file mode 100644
index 0000000..28e333f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceCreator.java
@@ -0,0 +1,57 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+/**

+ *

+ */

+package org.apache.tapestry.ioc.internal.services;

+

+import org.apache.tapestry.ioc.ObjectCreator;

+import org.apache.tapestry.ioc.services.PerthreadManager;

+

+/**

+ * Provides per-thread implementations of services.

+ */

+public class PerThreadServiceCreator implements ObjectCreator

+{

+    private final PerthreadManager perthreadManager;

+

+    private final ObjectCreator delegate;

+

+    public PerThreadServiceCreator(PerthreadManager perthreadManager, ObjectCreator delegate)

+    {

+        this.perthreadManager = perthreadManager;

+        this.delegate = delegate;

+    }

+

+    /**

+     * For each thread, the first call will use the delegate {@link org.apache.tapestry.ioc.ObjectCreator} to create an

+     * instance, and later calls will reuse the same per-thread instance. The instance is stored in the {@link

+     * org.apache.tapestry.ioc.services.PerthreadManager} and will be released at the end of the request.

+     */

+    public Object createObject()

+    {

+        // Use the ObjectCreator instance as the key.  it will be unique.

+

+        Object perthreadInstance = perthreadManager.get(delegate);

+

+        if (perthreadInstance == null)

+        {

+            perthreadInstance = delegate.createObject();

+            perthreadManager.put(delegate, perthreadInstance);

+        }

+

+        return perthreadInstance;

+    }

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceLifecycle.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceLifecycle.java
new file mode 100644
index 0000000..c81d022
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerThreadServiceLifecycle.java
@@ -0,0 +1,104 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.services.*;
+
+import static java.lang.String.format;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+
+/**
+ * Allows a service to exist "per thread" (in each thread). This involves an inner proxy, which caches an object derived
+ * from a {@link org.apache.tapestry.ioc.ObjectCreator} as a key in the {@link org.apache.tapestry.ioc.services.PerthreadManager}.
+ * Method invocations are delegated to the per-thread service instance.
+ * <p/>
+ * This scheme ensures that, although the service builder method will be invoked many times over the life of the
+ * application, the service decoration process occurs only once. The final calling chain is: Service Proxy --&gt;
+ * Decorator(s) --&gt; PerThread Proxy --&gt; (per thread) instance.
+ */
+public class PerThreadServiceLifecycle implements ServiceLifecycle
+{
+    private static final String PER_THREAD_METHOD_NAME = "_perThreadInstance";
+
+    private final PerthreadManager perthreadManager;
+
+    private final ClassFactory classFactory;
+
+    public PerThreadServiceLifecycle(PerthreadManager perthreadManager,
+
+                                     @Builtin
+                                     ClassFactory classFactory)
+    {
+        this.perthreadManager = perthreadManager;
+        this.classFactory = classFactory;
+    }
+
+    public Object createService(ServiceResources resources, ObjectCreator creator)
+    {
+        Class proxyClass = createProxyClass(resources);
+
+        ObjectCreator perThreadCreator = new PerThreadServiceCreator(perthreadManager, creator);
+
+        try
+        {
+            Constructor ctor = proxyClass.getConstructors()[0];
+
+            return ctor.newInstance(perThreadCreator);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new RuntimeException(ex.getCause());
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private Class createProxyClass(ServiceResources resources)
+    {
+        Class serviceInterface = resources.getServiceInterface();
+
+        ClassFab cf = classFactory.newClass(serviceInterface);
+
+        cf.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
+
+        // Constructor takes a ServiceCreator
+
+        cf.addConstructor(new Class[]
+                { ObjectCreator.class }, null, "_creator = $1;");
+
+        String body = format("return (%s) _creator.createObject();", serviceInterface.getName());
+
+        MethodSignature sig = new MethodSignature(serviceInterface, PER_THREAD_METHOD_NAME, null,
+                                                  null);
+
+        cf.addMethod(Modifier.PRIVATE, sig, body);
+
+        String toString = format(
+                "<PerThread Proxy for %s(%s)>",
+                resources.getServiceId(),
+                serviceInterface.getName());
+
+        cf.proxyMethodsToDelegate(serviceInterface, PER_THREAD_METHOD_NAME + "()", toString);
+
+        return cf.createClass();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImpl.java
new file mode 100644
index 0000000..bc0b5c7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImpl.java
@@ -0,0 +1,112 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.PerthreadManager;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Map;
+
+public class PerthreadManagerImpl implements PerthreadManager
+{
+    private static final String LISTENERS_KEY = "PerthreadManager.listenerList";
+
+    private static class MapHolder extends ThreadLocal<Map>
+    {
+        @Override
+        protected Map initialValue()
+        {
+            return CollectionFactory.newMap();
+        }
+    }
+
+    private final Logger logger;
+
+    private final MapHolder holder = new MapHolder();
+
+    public PerthreadManagerImpl(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+
+    private synchronized Map getPerthreadMap()
+    {
+        return holder.get();
+    }
+
+
+    private List<ThreadCleanupListener> getListeners()
+    {
+        List<ThreadCleanupListener> result = (List<ThreadCleanupListener>) get(LISTENERS_KEY);
+
+        if (result == null)
+        {
+            result = CollectionFactory.newList();
+            put(LISTENERS_KEY, result);
+        }
+
+        return result;
+    }
+
+
+    public void addThreadCleanupListener(ThreadCleanupListener listener)
+    {
+        getListeners().add(listener);
+    }
+
+    /**
+     * Instructs the hub to notify all its listeners (for the current thread). It also discards its list of listeners.
+     */
+    public void cleanup()
+    {
+        List<ThreadCleanupListener> listeners = getListeners();
+
+        put(LISTENERS_KEY, null);
+
+        for (ThreadCleanupListener listener : listeners)
+        {
+            try
+            {
+                listener.threadDidCleanup();
+            }
+            catch (Exception ex)
+            {
+                logger.warn(ServiceMessages.threadCleanupError(listener, ex), ex);
+            }
+        }
+
+        // Listeners should not re-add themselves or store any per-thread state here,
+        // it will be lost.
+
+        synchronized (this)
+        {
+            holder.remove();
+        }
+    }
+
+    public void put(Object key, Object value)
+    {
+        getPerthreadMap().put(key, value);
+    }
+
+    public Object get(Object key)
+    {
+        return getPerthreadMap().get(key);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImpl.java
new file mode 100644
index 0000000..a94a262
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImpl.java
@@ -0,0 +1,70 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.DefaultImplementationBuilder;
+import org.apache.tapestry.ioc.services.PipelineBuilder;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+public class PipelineBuilderImpl implements PipelineBuilder
+{
+    private final ClassFactory classFactory;
+
+    private final DefaultImplementationBuilder defaultImplementationBuilder;
+
+    public PipelineBuilderImpl(@Builtin ClassFactory classFactory,
+
+                               DefaultImplementationBuilder defaultImplementationBuilder)
+    {
+        this.classFactory = classFactory;
+        this.defaultImplementationBuilder = defaultImplementationBuilder;
+    }
+
+    public <S, F> S build(Logger logger, Class<S> serviceInterface, Class<F> filterInterface, List<F> filters)
+    {
+        S terminator = defaultImplementationBuilder.createDefaultImplementation(serviceInterface);
+
+        return build(logger, serviceInterface, filterInterface, filters, terminator);
+    }
+
+    public <S, F> S build(Logger logger, Class<S> serviceInterface, Class<F> filterInterface, List<F> filters,
+                          S terminator)
+    {
+        if (filters.isEmpty()) return terminator;
+
+        BridgeBuilder<S, F> bb = new BridgeBuilder<S, F>(logger, serviceInterface, filterInterface, classFactory);
+
+        // The first bridge will point to the terminator.
+        // Like service decorators, we work deepest (last)
+        // to shallowest (first)
+
+        S next = terminator;
+        int count = filters.size();
+
+        for (int i = count - 1; i >= 0; i--)
+        {
+            F filter = filters.get(i);
+
+            next = bb.instantiateBridge(next, filter);
+        }
+
+        return next;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java
new file mode 100644
index 0000000..a2d36c3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java
@@ -0,0 +1,124 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class PropertyAccessImpl implements PropertyAccess
+{
+    private final Map<Class, ClassPropertyAdapter> adapters = CollectionFactory.newConcurrentMap();
+
+    public Object get(Object instance, String propertyName)
+    {
+        return getAdapter(instance).get(instance, propertyName);
+    }
+
+    public void set(Object instance, String propertyName, Object value)
+    {
+        getAdapter(instance).set(instance, propertyName, value);
+    }
+
+    /**
+     * Clears the cache of adapters and asks the Introspector to clear its cache.
+     */
+    public synchronized void clearCache()
+    {
+        adapters.clear();
+
+        Introspector.flushCaches();
+    }
+
+    public ClassPropertyAdapter getAdapter(Object instance)
+    {
+        return getAdapter(instance.getClass());
+    }
+
+    public ClassPropertyAdapter getAdapter(Class forClass)
+    {
+        ClassPropertyAdapter result = adapters.get(forClass);
+
+        if (result == null)
+        {
+            result = buildAdapter(forClass);
+            adapters.put(forClass, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * Builds a new adapter and updates the _adapters cache. This not only guards access to the adapter cache, but also
+     * serializes access to the Java Beans Introspector, which is not thread safe. In addition, handles the case where
+     * the class in question is an interface, accumulating properties inherited from super-classes.
+     */
+    private synchronized ClassPropertyAdapter buildAdapter(Class forClass)
+    {
+        // In some race conditions, we may hit this method for the same class multiple times.
+        // We just let it happen, replacing the old ClassPropertyAdapter with a new one.
+
+        try
+        {
+            BeanInfo info = Introspector.getBeanInfo(forClass);
+
+            List<PropertyDescriptor> descriptors = CollectionFactory.newList();
+
+            addAll(descriptors, info.getPropertyDescriptors());
+
+            if (forClass.isInterface()) addPropertiesFromExtendedInterfaces(forClass, descriptors);
+
+            return new ClassPropertyAdapterImpl(forClass, descriptors);
+        }
+        catch (Throwable ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private <T> void addAll(List<T> list, T[] array)
+    {
+        list.addAll(Arrays.asList(array));
+    }
+
+    private void addPropertiesFromExtendedInterfaces(Class forClass, List<PropertyDescriptor> descriptors)
+            throws IntrospectionException
+    {
+        LinkedList<Class> queue = CollectionFactory.newLinkedList();
+
+        // Seed the queue
+        addAll(queue, forClass.getInterfaces());
+
+        while (!queue.isEmpty())
+        {
+            Class c = queue.removeFirst();
+
+            BeanInfo info = Introspector.getBeanInfo(c);
+
+            addAll(descriptors, info.getPropertyDescriptors());
+            addAll(queue, c.getInterfaces());
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAdapterImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAdapterImpl.java
new file mode 100644
index 0000000..7f3c5f8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAdapterImpl.java
@@ -0,0 +1,139 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class PropertyAdapterImpl implements PropertyAdapter
+{
+    private final String name;
+
+    private final Method readMethod;
+
+    private final Method writeMethod;
+
+    private final Class type;
+
+    private final boolean castRequired;
+
+    public PropertyAdapterImpl(String name, Class type, Method readMethod, Method writeMethod)
+    {
+        this.name = notBlank(name, "name");
+        this.type = notNull(type, "type");
+
+        this.readMethod = readMethod;
+        this.writeMethod = writeMethod;
+
+        castRequired = readMethod != null && readMethod.getReturnType() != type;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public Method getReadMethod()
+    {
+        return readMethod;
+    }
+
+    public Class getType()
+    {
+        return type;
+    }
+
+    public Method getWriteMethod()
+    {
+        return writeMethod;
+    }
+
+    public boolean isRead()
+    {
+        return readMethod != null;
+    }
+
+    public boolean isUpdate()
+    {
+        return writeMethod != null;
+    }
+
+    public Object get(Object instance)
+    {
+        if (readMethod == null)
+            throw new UnsupportedOperationException(ServiceMessages.readNotSupported(instance, name));
+
+        Throwable fail;
+
+        try
+        {
+            return readMethod.invoke(instance);
+        }
+        catch (InvocationTargetException ex)
+        {
+            fail = ex.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            fail = ex;
+        }
+
+        throw new RuntimeException(ServiceMessages.readFailure(name, instance, fail), fail);
+    }
+
+    public void set(Object instance, Object value)
+    {
+        if (writeMethod == null)
+            throw new UnsupportedOperationException(ServiceMessages.writeNotSupported(instance, name));
+
+        Throwable fail;
+
+        try
+        {
+            writeMethod.invoke(instance, value);
+
+            return;
+        }
+        catch (InvocationTargetException ex)
+        {
+            fail = ex.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            fail = ex;
+        }
+
+        throw new RuntimeException(ServiceMessages.writeFailure(name, instance, fail), fail);
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        T result = readMethod != null ? readMethod.getAnnotation(annotationClass) : null;
+
+        if (result == null && writeMethod != null) result = writeMethod.getAnnotation(annotationClass);
+
+        return result;
+    }
+
+    public boolean isCastRequired()
+    {
+        return castRequired;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyShadowBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyShadowBuilderImpl.java
new file mode 100644
index 0000000..ef62aee
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyShadowBuilderImpl.java
@@ -0,0 +1,93 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.*;
+
+import static java.lang.String.format;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+public class PropertyShadowBuilderImpl implements PropertyShadowBuilder
+{
+    private final ClassFactory classFactory;
+
+    private final PropertyAccess propertyAccess;
+
+    public PropertyShadowBuilderImpl(@Builtin
+    ClassFactory classFactory,
+
+                                     PropertyAccess propertyAccess)
+    {
+        this.classFactory = classFactory;
+        this.propertyAccess = propertyAccess;
+    }
+
+    public <T> T build(Object source, String propertyName, Class<T> propertyType)
+    {
+        Class sourceClass = source.getClass();
+        PropertyAdapter adapter = propertyAccess.getAdapter(sourceClass).getPropertyAdapter(
+                propertyName);
+
+        // TODO: Perhaps extend ClassPropertyAdapter to do these checks?
+
+        if (adapter == null)
+            throw new RuntimeException(ServiceMessages.noSuchProperty(sourceClass, propertyName));
+
+        if (!adapter.isRead())
+            throw new RuntimeException(ServiceMessages.readNotSupported(source, propertyName));
+
+        if (!propertyType.isAssignableFrom(adapter.getType()))
+            throw new RuntimeException(ServiceMessages.propertyTypeMismatch(
+                    propertyName,
+                    sourceClass,
+                    adapter.getType(),
+                    propertyType));
+
+        ClassFab cf = classFactory.newClass(propertyType);
+
+        cf.addField("_source", Modifier.PRIVATE | Modifier.FINAL, sourceClass);
+
+        cf.addConstructor(new Class[]
+                { sourceClass }, null, "_source = $1;");
+
+        String body = format("return _source.%s();", adapter.getReadMethod().getName());
+
+        MethodSignature sig = new MethodSignature(propertyType, "_delegate", null, null);
+        cf.addMethod(Modifier.PRIVATE, sig, body);
+
+        String toString = format("<Shadow: property %s of %s>", propertyName, source);
+
+        cf.proxyMethodsToDelegate(propertyType, "_delegate()", toString);
+
+        Class shadowClass = cf.createClass();
+
+        try
+        {
+            Constructor cc = shadowClass.getConstructors()[0];
+
+            Object instance = cc.newInstance(source);
+
+            return propertyType.cast(instance);
+        }
+        catch (Exception ex)
+        {
+            // Should not be reachable
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImpl.java
new file mode 100644
index 0000000..7e8f8ca
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImpl.java
@@ -0,0 +1,68 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newThreadSafeList;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.services.RegistryShutdownHub;
+import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+public class RegistryShutdownHubImpl implements RegistryShutdownHub
+{
+    private final OneShotLock lock = new OneShotLock();
+
+    private final Logger logger;
+
+    private final List<RegistryShutdownListener> listeners = newThreadSafeList();
+
+    public RegistryShutdownHubImpl(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    public void addRegistryShutdownListener(RegistryShutdownListener listener)
+    {
+        lock.check();
+
+        listeners.add(listener);
+    }
+
+    /**
+     * Fires the {@link RegistryShutdownListener#registryDidShutdown()} method on each listener. At the end, all the
+     * listeners are discarded.
+     */
+    public void fireRegistryDidShutdown()
+    {
+        lock.lock();
+
+        for (RegistryShutdownListener l : listeners)
+        {
+            try
+            {
+                l.registryDidShutdown();
+            }
+            catch (Exception ex)
+            {
+                logger.error(ServiceMessages.shutdownListenerError(l, ex), ex);
+            }
+        }
+
+        listeners.clear();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryStartup.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryStartup.java
new file mode 100644
index 0000000..f379b65
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/RegistryStartup.java
@@ -0,0 +1,69 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+/**
+ * Startup service for Tapestry IoC: automatically invoked at {@linkplain Registry#performRegistryStartup() registry
+ * startup} to execute a series of operations, via its ordered configuration of Runnable objects.
+ */
+public class RegistryStartup implements Runnable
+{
+    private final Logger logger;
+
+    private final List<Runnable> configuration;
+
+    private final OneShotLock lock = new OneShotLock();
+
+    public RegistryStartup(Logger logger, final List<Runnable> configuration)
+    {
+        this.logger = logger;
+        this.configuration = configuration;
+    }
+
+    /**
+     * Invokes run() on each contributed object. If the object throws a runtime exception, it is logged but startup
+     * continues anyway. This method may only be {@linkplain OneShotLock invoked once}.
+     */
+    public void run()
+    {
+        lock.lock();
+
+        // Do we want extra exception catching here?
+
+        for (Runnable r : configuration)
+        {
+            try
+            {
+                r.run();
+            }
+            catch (RuntimeException ex)
+            {
+                logger.error(ServiceMessages.startupFailure(ex));
+            }
+        }
+
+        // We don't need them any more since this method can only be run once. It's a insignificant
+        // savings, but still a nice thing to do.
+
+        configuration.clear();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ServiceMessages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ServiceMessages.java
new file mode 100644
index 0000000..86ccd4c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ServiceMessages.java
@@ -0,0 +1,193 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.Coercion;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+
+final class ServiceMessages
+{
+    private final static Messages MESSAGES = MessagesImpl.forClass(ServiceMessages.class);
+
+    private ServiceMessages()
+    {
+    }
+
+    static String unableToAddMethod(MethodSignature signature, CtClass ctClass, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-add-method", signature, ctClass.getName(), cause);
+    }
+
+    static String unableToAddConstructor(CtClass ctClass, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-add-constructor", ctClass.getName(), cause);
+    }
+
+    static String unableToAddField(String fieldName, CtClass ctClass, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-add-field", fieldName, ctClass.getName(), cause);
+    }
+
+    static String unableToCreateClass(String className, Class superClass, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-create-class", className, superClass.getName(), cause);
+    }
+
+    static String unableToLookupClass(String className, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-lookup-class", className, cause);
+    }
+
+    static String unableToWriteClass(CtClass ctClass, Throwable cause)
+    {
+        return MESSAGES.format("unable-to-write-class", ctClass.getName(), cause);
+    }
+
+    static String duplicateMethodInClass(MethodSignature ms, ClassFabImpl fab)
+    {
+        return MESSAGES.format("duplicate-method-in-class", ms, fab.getName());
+    }
+
+    static String loggingInterceptor(String serviceId, Class serviceInterface)
+    {
+        return MESSAGES.format("logging-interceptor", serviceId, serviceInterface.getName());
+    }
+
+    static String threadCleanupError(ThreadCleanupListener listener, Throwable cause)
+    {
+        return MESSAGES.format("thread-cleanup-error", listener, cause);
+    }
+
+    static String noSuchProperty(Class clazz, String propertyName)
+    {
+        return MESSAGES.format("no-such-property", clazz.getName(), propertyName);
+    }
+
+    static String readNotSupported(Object instance, String propertyName)
+    {
+        return MESSAGES.format("read-not-supported", instance.getClass().getName(), propertyName);
+    }
+
+    static String writeNotSupported(Object instance, String propertyName)
+    {
+        return MESSAGES.format("write-not-supported", instance.getClass().getName(), propertyName);
+    }
+
+    static String readFailure(String propertyName, Object instance, Throwable cause)
+    {
+        return MESSAGES.format("read-failure", propertyName, instance, cause);
+    }
+
+    static String writeFailure(String propertyName, Object instance, Throwable cause)
+    {
+        return MESSAGES.format("write-failure", propertyName, instance, cause);
+    }
+
+    static String propertyTypeMismatch(String propertyName, Class sourceClass, Class propertyType,
+                                       Class expectedType)
+    {
+        return MESSAGES.format(
+                "property-type-mismatch",
+                propertyName,
+                sourceClass.getName(),
+                propertyType.getName(),
+                expectedType.getName());
+    }
+
+    static String extraFilterMethod(MethodSignature sig, Class filterInterface,
+                                    Class serviceInterface)
+    {
+        return MESSAGES.format(
+                "extra-filter-method",
+                sig,
+                filterInterface.getName(),
+                serviceInterface.getName());
+    }
+
+    static String unmatchedServiceMethod(MethodSignature sig, Class filterInterface)
+    {
+        return MESSAGES.format("unmatched-service-method", sig, filterInterface.getName());
+    }
+
+    static String unknownObjectProvider(String prefix, String reference)
+    {
+        return MESSAGES.format("unknown-object-provider", prefix, reference);
+    }
+
+    static String shutdownListenerError(Object listener, Throwable cause)
+    {
+        return MESSAGES.format("shutdown-listener-error", listener, cause);
+    }
+
+    static String noCoercionFound(Class sourceType, Class targetType, String coercions)
+    {
+        return MESSAGES.format(
+                "no-coercion-found",
+                sourceType.getName(),
+                targetType.getName(),
+                coercions);
+    }
+
+    static String recursiveSymbol(String symbolName, String path)
+    {
+        return MESSAGES.format("recursive-symbol", symbolName, path);
+    }
+
+    static String symbolUndefined(String symbolName)
+    {
+        return MESSAGES.format("symbol-undefined", symbolName);
+    }
+
+    static String symbolUndefinedInPath(String symbolName, String path)
+    {
+        return MESSAGES.format("symbol-undefined-in-path", symbolName, path);
+    }
+
+    static String missingSymbolCloseBrace(String input)
+    {
+        return MESSAGES.format("missing-symbol-close-brace", input);
+    }
+
+    static String missingSymbolCloseBraceInPath(String input, String path)
+    {
+        return MESSAGES.format("missing-symbol-close-brace-in-path", input, path);
+    }
+
+    static String failedCoercion(Object input, Class targetType, Coercion coercion, Throwable cause)
+    {
+        return MESSAGES.format("failed-coercion", String.valueOf(input), ClassFabUtils
+                .toJavaClassName(targetType), coercion, cause);
+    }
+
+    static String registryShutdown(String serviceId)
+    {
+        return MESSAGES.format("registry-shutdown", serviceId);
+    }
+
+    static String serviceBuildFailure(String serviceId, Throwable cause)
+    {
+        return MESSAGES.format("service-build-failure", serviceId, cause);
+    }
+
+    static String startupFailure(Throwable cause)
+    {
+        return MESSAGES.format("startup-failure", cause);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImpl.java
new file mode 100644
index 0000000..5847adf
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImpl.java
@@ -0,0 +1,93 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.*;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+
+import java.lang.reflect.Modifier;
+
+public class StrategyBuilderImpl implements StrategyBuilder
+{
+    private final ClassFactory classFactory;
+
+    public StrategyBuilderImpl(@Builtin ClassFactory classFactory)
+    {
+        this.classFactory = classFactory;
+    }
+
+    public <S> S build(StrategyRegistry<S> registry)
+    {
+        Class<S> interfaceClass = registry.getAdapterType();
+
+        // TODO: Could cache the implClass by interfaceClass ...
+
+        Class implClass = createImplClass(interfaceClass);
+
+        try
+        {
+            Object raw = implClass.getConstructors()[0].newInstance(registry);
+
+            return interfaceClass.cast(raw);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private Class createImplClass(Class interfaceClass)
+    {
+        ClassFab cf = classFactory.newClass(interfaceClass);
+
+        String interfaceClassName = interfaceClass.getName();
+
+        cf.addField("_registry", Modifier.PRIVATE | Modifier.FINAL, StrategyRegistry.class);
+        cf.addConstructor(new Class[]
+                { StrategyRegistry.class }, null, "_registry = $1;");
+
+        BodyBuilder builder = new BodyBuilder();
+
+        MethodIterator mi = new MethodIterator(interfaceClass);
+
+        while (mi.hasNext())
+        {
+            MethodSignature sig = mi.next();
+
+            // TODO: Checks for methods that don't have at least one parameter, or don't have a
+            // compatible 1st parameter. Currently, we'll get a Javassist exception.
+
+            builder.clear();
+            builder.begin();
+
+            builder.addln("Object selector = $1;");
+            builder.addln(
+                    "%s adapter = (%<s) _registry.getByInstance(selector);",
+                    interfaceClassName);
+            builder.addln("return ($r) adapter.%s($$);", sig.getName());
+
+            builder.end();
+
+            cf.addMethod(Modifier.PUBLIC, sig, builder.toString());
+
+        }
+
+        if (!mi.getToString())
+            cf.addToString(String.format("<Strategy for %s>", interfaceClassName));
+
+        return cf.createClass();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StringLocation.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StringLocation.java
new file mode 100644
index 0000000..25204f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/StringLocation.java
@@ -0,0 +1,62 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+
+/**
+ * Implementation of {@link Location} used when the underlying resource isn't really known.
+ */
+public final class StringLocation implements Location
+{
+    private final String description;
+
+    private final int line;
+
+    public StringLocation(String description, int line)
+    {
+        this.description = description;
+        this.line = line;
+    }
+
+    @Override
+    public String toString()
+    {
+        return description;
+    }
+
+    /**
+     * Returns 0.
+     */
+    public int getColumn()
+    {
+        return 0;
+    }
+
+    public int getLine()
+    {
+        return line;
+    }
+
+    /**
+     * Returns null; we don't know where the file really is (it's probably a class on the class path).
+     */
+    public Resource getResource()
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProvider.java
new file mode 100644
index 0000000..818cf32
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProvider.java
@@ -0,0 +1,58 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+
+/**
+ * Performs an injection based on a {@link Symbol} annotation.
+ */
+public class SymbolObjectProvider implements ObjectProvider
+{
+    private final SymbolSource symbolSource;
+
+    private final TypeCoercer typeCoercer;
+
+    public SymbolObjectProvider(@Builtin SymbolSource symbolSource,
+
+                                @Builtin TypeCoercer typeCoercer)
+    {
+        this.symbolSource = symbolSource;
+        this.typeCoercer = typeCoercer;
+    }
+
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+    {
+        Symbol annotation = annotationProvider.getAnnotation(Symbol.class);
+
+        if (annotation == null) return null;
+
+        Object value = symbolSource.valueForSymbol(annotation.value());
+
+        IntermediateType it = annotationProvider.getAnnotation(IntermediateType.class);
+
+        if (it != null) value = typeCoercer.coerce(value, it.value());
+
+        return typeCoercer.coerce(value, objectType);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java
new file mode 100644
index 0000000..328ced8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImpl.java
@@ -0,0 +1,217 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.ioc.services.SymbolSource;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class SymbolSourceImpl implements SymbolSource
+{
+    private final List<SymbolProvider> providers;
+
+    /**
+     * Cache of symbol name to fully expanded symbol value.
+     */
+    private final Map<String, String> cache = CollectionFactory.newConcurrentMap();
+
+    /**
+     * Contains execution data needed when performing an expansion (largely, to check for endless recursion).
+     */
+    private class SymbolExpansion
+    {
+        private final LinkedList<String> expandingSymbols = newLinkedList();
+
+        String expandSymbols(String input)
+        {
+            StringBuilder builder = null;
+
+            int startx = 0;
+
+            while (true)
+            {
+                int symbolx = input.indexOf("${", startx);
+
+                // Special case: if the string contains no symbols then return it as is.
+
+                if (startx == 0 && symbolx < 0) return input;
+
+                // The string has at least one symbol, so its OK to create the StringBuilder
+
+                if (builder == null) builder = new StringBuilder();
+
+                // No more symbols found, so add in the rest of the string.
+
+                if (symbolx < 0)
+                {
+                    builder.append(input.substring(startx));
+                    break;
+                }
+
+                builder.append(input.substring(startx, symbolx));
+
+                int endx = input.indexOf("}", symbolx);
+
+                if (endx < 0)
+                {
+                    String message = expandingSymbols.isEmpty() ? ServiceMessages
+                            .missingSymbolCloseBrace(input) : ServiceMessages
+                            .missingSymbolCloseBraceInPath(input, path());
+
+                    throw new RuntimeException(message);
+                }
+
+                String symbolName = input.substring(symbolx + 2, endx);
+
+                builder.append(valueForSymbol(symbolName));
+
+                // Restart the search after the '}'
+
+                startx = endx + 1;
+            }
+
+            return builder.toString();
+        }
+
+        String valueForSymbol(String symbolName)
+        {
+            String value = cache.get(symbolName);
+
+            if (value == null)
+            {
+                value = expandSymbol(symbolName);
+
+                cache.put(symbolName, value);
+            }
+
+            return value;
+        }
+
+        String expandSymbol(String symbolName)
+        {
+            if (expandingSymbols.contains(symbolName))
+            {
+                expandingSymbols.add(symbolName);
+                throw new RuntimeException(ServiceMessages.recursiveSymbol(
+                        symbolName,
+                        pathFrom(symbolName)));
+            }
+
+            expandingSymbols.addLast(symbolName);
+
+            String value = null;
+
+            for (SymbolProvider provider : providers)
+            {
+                value = provider.valueForSymbol(symbolName);
+
+                if (value != null) break;
+            }
+
+            if (value == null)
+            {
+
+                String message = expandingSymbols.size() == 1 ? ServiceMessages
+                        .symbolUndefined(symbolName) : ServiceMessages.symbolUndefinedInPath(
+                        symbolName,
+                        path());
+
+                throw new RuntimeException(message);
+            }
+
+            // The value may have symbols that need expansion.
+
+            String result = expandSymbols(value);
+
+            // And we're done expanding this symbol
+
+            expandingSymbols.removeLast();
+
+            return result;
+
+        }
+
+        String path()
+        {
+            StringBuilder builder = new StringBuilder();
+
+            boolean first = true;
+
+            for (String symbolName : expandingSymbols)
+            {
+                if (!first) builder.append(" --> ");
+
+                builder.append(symbolName);
+
+                first = false;
+            }
+
+            return builder.toString();
+        }
+
+        String pathFrom(String startSymbolName)
+        {
+            StringBuilder builder = new StringBuilder();
+
+            boolean first = true;
+            boolean match = false;
+
+            for (String symbolName : expandingSymbols)
+            {
+                if (!match)
+                {
+                    if (symbolName.equals(startSymbolName))
+                        match = true;
+                    else
+                        continue;
+                }
+
+                if (!first) builder.append(" --> ");
+
+                builder.append(symbolName);
+
+                first = false;
+            }
+
+            return builder.toString();
+        }
+    }
+
+    public SymbolSourceImpl(final List<SymbolProvider> providers)
+    {
+        this.providers = providers;
+    }
+
+    public String expandSymbols(String input)
+    {
+        return new SymbolExpansion().expandSymbols(input);
+    }
+
+    public String valueForSymbol(String symbolName)
+    {
+        String value = cache.get(symbolName);
+
+        // If already in the cache, then return it. Otherwise, let the SE find the value and
+        // update the cache.
+
+        return value != null ? value : new SymbolExpansion().valueForSymbol(symbolName);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SystemPropertiesSymbolProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SystemPropertiesSymbolProvider.java
new file mode 100644
index 0000000..24886e9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/SystemPropertiesSymbolProvider.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.SymbolProvider;
+
+/**
+ * Obtains symbol values from JVM System properties. This implementation is usually ordered first,
+ * so that explicit overrides, provided as JVM system properties, can take effect.
+ */
+public class SystemPropertiesSymbolProvider implements SymbolProvider
+{
+    public String valueForSymbol(String symbolName)
+    {
+        return System.getProperty(symbolName);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImpl.java
new file mode 100644
index 0000000..b79e671
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImpl.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+
+import java.util.Locale;
+
+@Scope(PERTHREAD_SCOPE)
+public class ThreadLocaleImpl implements ThreadLocale
+{
+    private Locale locale = Locale.getDefault();
+
+    public Locale getLocale()
+    {
+        return locale;
+    }
+
+    public void setLocale(Locale locale)
+    {
+        notNull(locale, "locale");
+
+        this.locale = locale;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java
new file mode 100644
index 0000000..36e7466
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImpl.java
@@ -0,0 +1,382 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import org.apache.tapestry.ioc.internal.util.InheritanceSearch;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.Coercion;
+import org.apache.tapestry.ioc.services.CoercionTuple;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+
+import java.util.*;
+
+public class TypeCoercerImpl implements TypeCoercer
+{
+    // Read only after constructor
+
+    private final Map<Class, List<CoercionTuple>> sourceTypeToTuple = CollectionFactory.newMap();
+
+    // Access to the cache must be thread safe
+
+    private final Map<CacheKey, Coercion> cache = CollectionFactory.newConcurrentMap();
+
+    static class CacheKey
+    {
+        private final Class sourceClass;
+
+        private final Class targetClass;
+
+        CacheKey(final Class sourceClass, final Class targetClass)
+        {
+            this.sourceClass = sourceClass;
+            this.targetClass = targetClass;
+        }
+
+        @Override
+        public boolean equals(Object obj)
+        {
+            if (obj == null) return false;
+
+            if (!(obj instanceof CacheKey)) return false;
+
+            CacheKey other = (CacheKey) obj;
+
+            return sourceClass.equals(other.sourceClass)
+                    && targetClass.equals(other.targetClass);
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return sourceClass.hashCode() * 27 % targetClass.hashCode();
+        }
+
+        @Override
+        public String toString()
+        {
+            return String.format("CacheKey[%s --> %s]", sourceClass.getName(), targetClass
+                    .getName());
+        }
+    }
+
+    private static final Coercion COERCION_NULL_TO_OBJECT = new Coercion<Void, Object>()
+    {
+        public Object coerce(Void input)
+        {
+            return null;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "null --> null";
+        }
+    };
+
+    public TypeCoercerImpl(Collection<CoercionTuple> tuples)
+    {
+        for (CoercionTuple tuple : tuples)
+        {
+            Class key = tuple.getSourceType();
+
+            InternalUtils.addToMapList(sourceTypeToTuple, key, tuple);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object coerce(Object input, Class targetType)
+    {
+        notNull(targetType, "targetType");
+
+        // Treat null as void in terms of locating a coercion.
+
+        Class sourceType = input != null ? input.getClass() : void.class;
+
+        // The caller may ask for the value in a primitive type, but the best we can do is the
+        // equivalent wrapper type.
+
+        Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
+
+        // Is a coercion even necessary? Not if the target type is assignable from the
+        // input value.
+
+        if (effectiveTargetType.isAssignableFrom(sourceType)) return input;
+
+        Coercion coercion = findCoercion(sourceType, effectiveTargetType);
+
+        Object result;
+
+        try
+        {
+            result = coercion.coerce(input);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(ServiceMessages.failedCoercion(
+                    input,
+                    targetType,
+                    coercion,
+                    ex), ex);
+        }
+
+        // Double check that the coercer provided a result of the correct type
+
+        return effectiveTargetType.cast(result);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S, T> String explain(Class<S> inputType, Class<T> targetType)
+    {
+        notNull(inputType, "inputType");
+        notNull(targetType, "targetType");
+
+        Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
+
+        // Is a coercion even necessary? Not if the target type is assignable from the
+        // input value.
+
+        if (effectiveTargetType.isAssignableFrom(inputType)) return "";
+
+        Coercion coercion = findCoercion(inputType, effectiveTargetType);
+
+        return coercion.toString();
+    }
+
+    private Coercion findCoercion(Class sourceType, Class targetType)
+    {
+        CacheKey key = new CacheKey(sourceType, targetType);
+
+        Coercion result = cache.get(key);
+
+        if (result == null)
+        {
+            result = findOrCreateCoercion(sourceType, targetType);
+            cache.put(key, result);
+        }
+
+        return result;
+    }
+
+    public void clearCache()
+    {
+        cache.clear();
+    }
+
+    /**
+     * Here's the real meat; we do a search of the space to find coercions, or a system of coercions, that accomplish
+     * the desired coercion.
+     * <p/>
+     * There's <strong>TREMENDOUS</strong> room to improve this algorithm. For example, inheritance lists could be
+     * cached. Further, there's probably more ways to early prune the search. However, even with dozens or perhaps
+     * hundreds of tuples, I suspect the search will still grind to a conclusion quickly.
+     * <p/>
+     * The order of operations should help ensure that the most efficient tuple chain is located. If you think about how
+     * tuples are added to the queue, there are two factors: size (the number of steps in the coercion) and "class
+     * distance" (that is, number of steps up the inheritance hiearchy). All the appropriate 1 step coercions will be
+     * considered first, in class distance order. Along the way, we'll queue up all the 2 step coercions, again in class
+     * distance order. By the time we reach some of those, we'll have begun queing up the 3 step coercions, and so
+     * forth, until we run out of input tuples we can use to fabricate multi-step compound coercions, or reach a final
+     * response.
+     * <p/>
+     * This does create a good number of short lived temporary objects (the compound tuples), but that's what the GC is
+     * really good at.
+     *
+     * @param sourceType
+     * @param targetType
+     * @return coercer from sourceType to targetType
+     */
+    @SuppressWarnings("unchecked")
+    private Coercion findOrCreateCoercion(Class sourceType, Class targetType)
+    {
+        if (sourceType == void.class) return searchForNullCoercion(targetType);
+
+        // These are instance variables because this method may be called concurrently.
+        // On a true race, we may go to the work of seeking out and/or fabricating
+        // a tuple twice, but it's more likely that different threads are looking
+        // for different source/target coercions.
+
+        Set<CoercionTuple> consideredTuples = newSet();
+        LinkedList<CoercionTuple> queue = newLinkedList();
+
+        seedQueue(sourceType, consideredTuples, queue);
+
+        while (!queue.isEmpty())
+        {
+            CoercionTuple tuple = queue.removeFirst();
+
+            // If the tuple results in a value type that is assignable to the desired target type,
+            // we're done! Later, we may add a concept of "cost" (i.e. number of steps) or
+            // "quality" (how close is the tuple target type to the desired target type). Cost
+            // is currently implicit, as compound tuples are stored deeper in the queue,
+            // so simpler coercions will be located earlier.
+
+            Class tupleTargetType = tuple.getTargetType();
+
+            if (targetType.isAssignableFrom(tupleTargetType)) return tuple.getCoercion();
+
+            // So .. this tuple doesn't get us directly to the target type.
+            // However, it *may* get us part of the way. Each of these
+            // represents a coercion from the source type to an intermediate type.
+            // Now we're going to look for conversions from the intermediate type
+            // to some other type.
+
+            queueIntermediates(sourceType, tuple, consideredTuples, queue);
+        }
+
+        // Not found anywhere. Identify the source and target type and a (sorted) list of
+        // all the known coercions.
+
+        throw new IllegalArgumentException(ServiceMessages.noCoercionFound(
+                sourceType,
+                targetType,
+                buildCoercionCatalog()));
+    }
+
+    /**
+     * Coercion from null is special; we match based on the target type and its not a spanning search. In many cases, we
+     * return a pass-thru that leaves the value as null.
+     *
+     * @param targetType desired type
+     * @return the coercion
+     */
+    private Coercion searchForNullCoercion(Class targetType)
+    {
+        List<CoercionTuple> tuples = sourceTypeToTuple.get(void.class);
+
+        // We know it will never be null, because we make contributions
+        // to ensure this, but a little check doesn't hurt.
+
+        if (tuples != null)
+        {
+            for (CoercionTuple tuple : tuples)
+            {
+                Class tupleTargetType = tuple.getTargetType();
+
+                if (targetType.equals(tupleTargetType)) return tuple.getCoercion();
+            }
+        }
+
+        // Typical case: no match, this coercion passes the null through
+        // as null.
+
+        return COERCION_NULL_TO_OBJECT;
+    }
+
+    /**
+     * Builds a string listing all the coercions configured for the type coercer, sorted alphabetically.
+     */
+    private String buildCoercionCatalog()
+    {
+        List<String> descriptions = newList();
+
+        for (List<CoercionTuple> list : sourceTypeToTuple.values())
+        {
+            for (CoercionTuple tuple : list)
+                descriptions.add(tuple.toString());
+        }
+
+        return InternalUtils.joinSorted(descriptions);
+    }
+
+    /**
+     * Seeds the pool with the initial set of coercions for the given type.
+     */
+    private void seedQueue(Class sourceType, Set<CoercionTuple> consideredTuples,
+                           LinkedList<CoercionTuple> queue)
+    {
+        // Work from the source type up looking for tuples
+
+        for (Class c : new InheritanceSearch(sourceType))
+        {
+            List<CoercionTuple> tuples = sourceTypeToTuple.get(c);
+
+            if (tuples == null) continue;
+
+            for (CoercionTuple tuple : tuples)
+            {
+                queue.addLast(tuple);
+                consideredTuples.add(tuple);
+            }
+
+            // Don't pull in Object -> type coercions when doing
+            // a search from null.
+
+            if (sourceType == void.class) return;
+        }
+    }
+
+    /**
+     * Creates and adds to the pool a new set of coercions based on an intermediate tuple. Adds compound coercion tuples
+     * to the end of the queue.
+     *
+     * @param sourceType        the source type of the coercion
+     * @param intermediateTuple a tuple that converts from the source type to some intermediate type (that is not
+     *                          assignable to the target type)
+     * @param consideredTuples  set of tuples that have already been added to the pool (directly, or as a compound
+     *                          coercion)
+     * @param queue             the work queue of tuples
+     */
+    @SuppressWarnings("unchecked")
+    private void queueIntermediates(Class sourceType, CoercionTuple intermediateTuple,
+                                    Set<CoercionTuple> consideredTuples, LinkedList<CoercionTuple> queue)
+    {
+        Class intermediateType = intermediateTuple.getTargetType();
+
+        for (Class c : new InheritanceSearch(intermediateType))
+        {
+            List<CoercionTuple> tuples = sourceTypeToTuple.get(c);
+
+            if (tuples == null) continue;
+
+            for (CoercionTuple tuple : tuples)
+            {
+                if (consideredTuples.contains(tuple)) continue;
+
+                Class newIntermediateType = tuple.getTargetType();
+
+                // If this tuple is for coercing from an intermediate type back towards our
+                // initial source type, then ignore it. This should only be an optimization,
+                // as branches that loop back towards the source type will
+                // eventually be considered and discarded.
+
+                if (sourceType.isAssignableFrom(newIntermediateType)) continue;
+
+                // The intermediateTuple coercer gets from S --> I1 (an intermediate type).
+                // The current tuple's coercer gets us from I2 --> X. where I2 is assignable
+                // from I1 (i.e., I2 is a superclass/superinterface of I1) and X is a new
+                // intermediate type, hopefully closer to our eventual target type.
+
+                Coercion compoundCoercer = new CompoundCoercion(intermediateTuple.getCoercion(),
+                                                                tuple.getCoercion());
+
+                CoercionTuple compoundTuple = new CoercionTuple(sourceType, newIntermediateType,
+                                                                compoundCoercer, false);
+
+                // So, every tuple that is added to the queue can take as input the sourceType.
+                // The target type may be another intermdiate type, or may be something
+                // assignable to the target type, which will bring the search to a succesful
+                // conclusion.
+
+                queue.addLast(compoundTuple);
+                consideredTuples.add(tuple);
+            }
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java
new file mode 100644
index 0000000..35bb5cf
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/ValueObjectProvider.java
@@ -0,0 +1,60 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Value;
+import org.apache.tapestry.ioc.services.Builtin;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+
+/**
+ * Provides an object when the {@link Value} annotation is present. The string value has symbols expanded, and then is
+ * {@link TypeCoercer coerced} to the associated type.   The value may first be coerced to an intermediate type if the
+ * {@link IntermediateType} annotation is present.
+ */
+public class ValueObjectProvider implements ObjectProvider
+{
+    private final SymbolSource symbolSource;
+
+    private final TypeCoercer typeCoercer;
+
+    public ValueObjectProvider(@Builtin SymbolSource symbolSource,
+
+                               @Builtin TypeCoercer typeCoercer)
+    {
+        this.symbolSource = symbolSource;
+        this.typeCoercer = typeCoercer;
+    }
+
+    public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
+    {
+        Value annotation = annotationProvider.getAnnotation(Value.class);
+
+        if (annotation == null) return null;
+
+        String value = annotation.value();
+        Object expanded = symbolSource.expandSymbols(value);
+
+        IntermediateType intermediate = annotationProvider.getAnnotation(IntermediateType.class);
+
+        if (intermediate != null) expanded = typeCoercer.coerce(expanded, intermediate.value());
+
+        return typeCoercer.coerce(expanded, objectType);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/AbstractResource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/AbstractResource.java
new file mode 100644
index 0000000..441b42e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/AbstractResource.java
@@ -0,0 +1,156 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Resource;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Locale;
+
+/**
+ * Abstract implementation of {@link Resource}. Subclasses must implement the abstract methods {@link Resource#toURL()}
+ * and {@link #newResource(String)} as well as toString(), hashCode() and equals().
+ */
+public abstract class AbstractResource implements Resource
+{
+    private final String path;
+
+    protected AbstractResource(String path)
+    {
+        this.path = notNull(path, "path");
+    }
+
+    public final String getPath()
+    {
+        return path;
+    }
+
+    public final String getFile()
+    {
+        int slashx = path.lastIndexOf('/');
+
+        return path.substring(slashx + 1);
+    }
+
+    public final String getFolder()
+    {
+        int slashx = path.lastIndexOf('/');
+
+        return (slashx < 0) ? "" : path.substring(0, slashx);
+    }
+
+    public final Resource forFile(String relativePath)
+    {
+        Defense.notNull(relativePath, "relativePath");
+
+        StringBuilder builder = new StringBuilder(getFolder());
+
+        for (String term : relativePath.split("/"))
+        {
+            // This will occur if the relative path contains sequential slashes
+
+            if (term.equals("")) continue;
+
+            if (term.equals(".")) continue;
+
+            if (term.equals(".."))
+            {
+                int slashx = builder.lastIndexOf("/");
+
+                // TODO: slashx < 0 (i.e., no slash)
+
+                // Trim path to content before the slash
+
+                builder.setLength(slashx);
+                continue;
+            }
+
+            // TODO: term blank or otherwise invalid?
+            // TODO: final term should not be "." or "..", or for that matter, the
+            // name of a folder, since a Resource should be a file within
+            // a folder.
+
+            if (builder.length() > 0) builder.append("/");
+
+            builder.append(term);
+        }
+
+        return createResource(builder.toString());
+    }
+
+    public final Resource forLocale(Locale locale)
+    {
+        for (String path : new LocalizedNameGenerator(this.path, locale))
+        {
+            Resource potential = createResource(path);
+
+            if (potential.exists()) return potential;
+        }
+
+        return null;
+    }
+
+    public final Resource withExtension(String extension)
+    {
+        notBlank(extension, "extension");
+
+        int dotx = path.lastIndexOf('.');
+
+        if (dotx < 0) return createResource(path + "." + extension);
+
+        return createResource(path.substring(0, dotx + 1) + extension);
+    }
+
+    /**
+     * Creates a new resource, unless the path matches the current Resource's path (in which case, this resource is
+     * returned).
+     */
+    private Resource createResource(String path)
+    {
+        if (this.path.equals(path)) return this;
+
+        return newResource(path);
+    }
+
+    /**
+     * Simple check for whether {@link #toURL()} returns null or not.
+     */
+    public boolean exists()
+    {
+        return toURL() != null;
+    }
+
+    /**
+     * Obtains the URL for the Resource and opens the stream, wrapped by a BufferedInputStream.
+     */
+    public InputStream openStream() throws IOException
+    {
+        URL url = toURL();
+
+        if (url == null) return null;
+
+        return new BufferedInputStream(url.openStream());
+    }
+
+    /**
+     * Factory method provided by subclasses.
+     */
+    protected abstract Resource newResource(String path);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ClasspathResource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ClasspathResource.java
new file mode 100644
index 0000000..1dd0c53
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ClasspathResource.java
@@ -0,0 +1,92 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Resource;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
+import java.net.URL;
+
+/**
+ * Implementation of {@link Resource} for files on the classpath (as defined by a {@link ClassLoader}).
+ */
+public final class ClasspathResource extends AbstractResource
+{
+    private final ClassLoader classLoader;
+
+    // Guarded by this
+    private URL url;
+
+    // Guarded by this
+    private boolean urlResolved;
+
+    public ClasspathResource(String path)
+    {
+        this(Thread.currentThread().getContextClassLoader(), path);
+    }
+
+    public ClasspathResource(ClassLoader classLoader, String path)
+    {
+        super(path);
+
+        notNull(classLoader, "classLoader");
+
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    protected Resource newResource(String path)
+    {
+        return new ClasspathResource(classLoader, path);
+    }
+
+    public synchronized URL toURL()
+    {
+        if (!urlResolved)
+        {
+            url = classLoader.getResource(getPath());
+            urlResolved = true;
+        }
+
+        return url;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null) return false;
+
+        if (obj == this) return true;
+
+        if (obj.getClass() != getClass()) return false;
+
+        ClasspathResource other = (ClasspathResource) obj;
+
+        return other.classLoader == classLoader && other.getPath().equals(getPath());
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return 227 ^ getPath().hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "classpath:" + getPath();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/CollectionFactory.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/CollectionFactory.java
new file mode 100644
index 0000000..7bf3ab5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/CollectionFactory.java
@@ -0,0 +1,150 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.util.CaseInsensitiveMap;
+import org.apache.tapestry.ioc.util.Stack;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Static factory methods to ease the creation of new collection types (when using generics). Most of these method
+ * leverage the compiler's ability to match generic types by return value. Typical usage (with a static import):
+ * <p/>
+ * <pre>
+ * Map&lt;Foo, Bar&gt; map = newMap();
+ * </pre>
+ * <p/>
+ * <p/>
+ * This is a replacement for:
+ * <p/>
+ * <pre>
+ * Map&lt;Foo, Bar&gt; map = new HashMap&lt;Foo, Bar&gt;();
+ * </pre>
+ */
+public final class CollectionFactory
+{
+    private static final int INITIAL_HASHMAP_CAPACITY = 31;
+
+    /**
+     * Constructs and returns a generic {@link HashMap} instance.
+     */
+    public static <K, V> Map<K, V> newMap()
+    {
+        return new HashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+    }
+
+    /**
+     * Constructs and returns a generic {@link java.util.HashSet} instance.
+     */
+    public static <T> Set<T> newSet()
+    {
+        return new HashSet<T>();
+    }
+
+    /**
+     * Contructs a new {@link HashSet} and initializes it using the provided collection.
+     */
+    public static <T, V extends T> Set<T> newSet(Collection<V> values)
+    {
+        return new HashSet<T>(values);
+    }
+
+    public static <T, V extends T> Set<T> newSet(V... values)
+    {
+        // Was a call to newSet(), but Sun JDK can't handle that. Fucking generics.
+        return new HashSet<T>(Arrays.asList(values));
+    }
+
+    /**
+     * Constructs a new {@link java.util.HashMap} instance by copying an existing Map instance.
+     */
+    public static <K, V> Map<K, V> newMap(Map<? extends K, ? extends V> map)
+    {
+        return new HashMap<K, V>(map);
+    }
+
+    /**
+     * Constructs a new concurrent map, which is safe to access via multiple threads.
+     */
+    public static <K, V> ConcurrentMap<K, V> newConcurrentMap()
+    {
+        return new ConcurrentHashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+    }
+
+    /**
+     * Contructs and returns a new generic {@link java.util.ArrayList} instance.
+     */
+    public static <T> List<T> newList()
+    {
+        return new ArrayList<T>();
+    }
+
+    /**
+     * Creates a new, fully modifiable list from an initial set of elements.
+     */
+    public static <T, V extends T> List<T> newList(V... elements)
+    {
+        // Was call to newList(), but Sun JDK can't handle that.
+        return new ArrayList<T>(Arrays.asList(elements));
+    }
+
+    /**
+     * Useful for queues.
+     */
+    public static <T> LinkedList<T> newLinkedList()
+    {
+        return new LinkedList<T>();
+    }
+
+    /**
+     * Constructs and returns a new {@link java.util.ArrayList} as a copy of the provided collection.
+     */
+    public static <T, V extends T> List<T> newList(Collection<V> list)
+    {
+        return new ArrayList<T>(list);
+    }
+
+    /**
+     * Constructs and returns a new {@link java.util.concurrent.CopyOnWriteArrayList}.
+     */
+    public static <T> List<T> newThreadSafeList()
+    {
+        return new CopyOnWriteArrayList<T>();
+    }
+
+    public static <T> Stack<T> newStack()
+    {
+        return new Stack<T>();
+    }
+
+    public static <T> Stack<T> newStack(int initialSize)
+    {
+        return new Stack<T>(initialSize);
+    }
+
+    public static <V> Map<String, V> newCaseInsensitiveMap()
+    {
+        return new CaseInsensitiveMap<V>();
+    }
+
+    public static <V> Map<String, V> newCaseInsensitiveMap(Map<String, ? extends V> map)
+    {
+        return new CaseInsensitiveMap<V>(map);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java
new file mode 100644
index 0000000..541e437
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrier.java
@@ -0,0 +1,223 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * A barrier used to execute code in a context where it is guarded by read/write locks. In addition, handles upgrading
+ * read locks to write locks (and vice versa). Execution of code within a lock is in terms of a {@link Runnable} object
+ * (that returns no value), or a {@link Invokable} object (which does return a value).
+ */
+public class ConcurrentBarrier
+{
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+
+    /**
+     * This is, of course, a bit of a problem. We don't have an avenue for ensuring that this ThreadLocal is destroyed
+     * at the end of the request, and that means a thread can hold a reference to the class and the class loader which
+     * loaded it. This may cause redeployment problems (leaked classes and class loaders). Apparently JDK 1.6 provides
+     * the APIs to check to see if the current thread has a read lock. So, we tend to remove the TL, rather than set its
+     * value to false.
+     */
+    private static class ThreadBoolean extends ThreadLocal<Boolean>
+    {
+        @Override
+        protected Boolean initialValue()
+        {
+            return false;
+        }
+    }
+
+    private final ThreadBoolean threadHasReadLock = new ThreadBoolean();
+
+    /**
+     * Invokes the object after acquiring the read lock (if necessary). If invoked when the read lock has not yet been
+     * acquired, then the lock is acquired for the duration of the call. If the lock has already been acquired, then the
+     * status of the lock is not changed.
+     * <p/>
+     * TODO: Check to see if the write lock is acquired and <em>not</em> acquire the read lock in that situation.
+     * Currently this code is not re-entrant. If a write lock is already acquired and the thread attempts to get the
+     * read lock, then the thread will hang. For the moment, all the uses of ConcurrentBarrier are coded in such a way
+     * that reentrant locks are not a problem.
+     *
+     * @param <T>
+     * @param invokable
+     * @return the result of invoking the invokable
+     */
+    public <T> T withRead(Invokable<T> invokable)
+    {
+        boolean readLockedAtEntry = threadHasReadLock.get();
+
+        if (!readLockedAtEntry)
+        {
+            lock.readLock().lock();
+
+            threadHasReadLock.set(true);
+        }
+
+        try
+        {
+            return invokable.invoke();
+        }
+        finally
+        {
+            if (!readLockedAtEntry)
+            {
+                lock.readLock().unlock();
+
+                threadHasReadLock.remove();
+            }
+        }
+    }
+
+    /**
+     * As with {@link #withRead(Invokable)}, creating an {@link Invokable} wrapper around the runnable object.
+     */
+    public void withRead(final Runnable runnable)
+    {
+        Invokable<Void> invokable = new Invokable<Void>()
+        {
+            public Void invoke()
+            {
+                runnable.run();
+
+                return null;
+            }
+        };
+
+        withRead(invokable);
+    }
+
+    /**
+     * Acquires the exclusive write lock before invoking the Invokable. The code will be executed exclusively, no other
+     * reader or writer threads will exist (they will be blocked waiting for the lock). If the current thread has a read
+     * lock, it is released before attempting to acquire the write lock, and re-acquired after the write lock is
+     * released. Note that in that short window, between releasing the read lock and acquiring the write lock, it is
+     * entirely possible that some other thread will sneak in and do some work, so the {@link Invokable} object should
+     * be prepared for cases where the state has changed slightly, despite holding the read lock. This usually manifests
+     * as race conditions where either a) some parallel unrelated bit of work has occured or b) duplicate work has
+     * occured. The latter is only problematic if the operation is very expensive.
+     *
+     * @param <T>
+     * @param invokable
+     */
+    public <T> T withWrite(Invokable<T> invokable)
+    {
+        boolean readLockedAtEntry = releaseReadLock();
+
+        lock.writeLock().lock();
+
+        try
+        {
+            return invokable.invoke();
+        }
+        finally
+        {
+            lock.writeLock().unlock();
+            restoreReadLock(readLockedAtEntry);
+        }
+    }
+
+    private boolean releaseReadLock()
+    {
+        boolean readLockedAtEntry = threadHasReadLock.get();
+
+        if (readLockedAtEntry)
+        {
+            lock.readLock().unlock();
+
+            threadHasReadLock.set(false);
+        }
+        return readLockedAtEntry;
+    }
+
+    private void restoreReadLock(boolean readLockedAtEntry)
+    {
+        if (readLockedAtEntry)
+        {
+            lock.readLock().lock();
+
+            threadHasReadLock.set(true);
+        }
+        else
+        {
+            threadHasReadLock.remove();
+        }
+    }
+
+    /**
+     * As with {@link #withWrite(Invokable)}, creating an {@link Invokable} wrapper around the runnable object.
+     */
+    public void withWrite(final Runnable runnable)
+    {
+        Invokable<Void> invokable = new Invokable<Void>()
+        {
+            public Void invoke()
+            {
+                runnable.run();
+
+                return null;
+            }
+        };
+
+        withWrite(invokable);
+    }
+
+    /**
+     * Try to aquire the exclusive write lock and invoke the Runnable. If the write lock is obtained within the specfied
+     * timeout, then this method behaves as {@link #withWrite(Runnable)} and will return true. If the write lock is not
+     * obtained within the timeout then the runnable is never invoked and the method will return false.
+     *
+     * @param runnable    Runnable object to execute inside the write lock.
+     * @param timeout     Time to wait for write lock.
+     * @param timeoutUnit Units of timeout.
+     * @return true if lock was obtained & runnabled executed. False otherwise.
+     */
+    public boolean tryWithWrite(final Runnable runnable, long timeout, TimeUnit timeoutUnit)
+    {
+        boolean readLockedAtEntry = releaseReadLock();
+
+        boolean obtainedLock = false;
+
+        try
+        {
+            try
+            {
+                obtainedLock = lock.writeLock().tryLock(timeout, timeoutUnit);
+
+                if (obtainedLock) runnable.run();
+
+            }
+            catch (InterruptedException e)
+            {
+                obtainedLock = false;
+            }
+            finally
+            {
+                if (obtainedLock) lock.writeLock().unlock();
+            }
+        }
+        finally
+        {
+            restoreReadLock(readLockedAtEntry);
+        }
+
+        return obtainedLock;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Defense.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Defense.java
new file mode 100644
index 0000000..57f282b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Defense.java
@@ -0,0 +1,81 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+/**
+ * Static utility methods for defensive programming.
+ */
+public final class Defense
+{
+    private Defense()
+    {
+    }
+
+    /**
+     * Checks that a method parameter value is not null, and returns it.
+     *
+     * @param <T>           the value type
+     * @param value         the value (which is checked to ensure non-nullness)
+     * @param parameterName the name of the parameter, used for exception messages
+     * @return the value
+     * @throws IllegalArgumentException if the value is null
+     */
+    public static <T> T notNull(T value, String parameterName)
+    {
+        if (value == null) throw new IllegalArgumentException(UtilMessages.parameterWasNull(parameterName));
+
+        return value;
+    }
+
+    /**
+     * Checks that a parameter value is not null and not empty.
+     *
+     * @param value         value to check (which is returned)
+     * @param parameterName the name of the parameter, used for exception messages
+     * @return the value, trimmed, if non-blank
+     * @throws IllegalArgumentException if the value is null or empty
+     */
+    public static String notBlank(String value, String parameterName)
+    {
+        if (value != null)
+        {
+            String trimmedValue = value.trim();
+
+            if (!trimmedValue.equals("")) return trimmedValue;
+        }
+
+        throw new IllegalArgumentException(UtilMessages.parameterWasBlank(parameterName));
+    }
+
+    /**
+     * Checks that the provided value is not null, and may be cast to the desired type.
+     *
+     * @param <T>
+     * @param parameterValue
+     * @param type
+     * @param parameterName
+     * @return the casted value
+     * @throws IllegalArgumentException if the value is null, or is not assignable to the indicated type
+     */
+    public static <T> T cast(Object parameterValue, Class<T> type, String parameterName)
+    {
+        notNull(parameterValue, parameterName);
+
+        if (!type.isInstance(parameterValue))
+            throw new IllegalArgumentException(UtilMessages.badCast(parameterName, parameterValue, type));
+
+        return type.cast(parameterValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/DependencyNode.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/DependencyNode.java
new file mode 100644
index 0000000..b009684
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/DependencyNode.java
@@ -0,0 +1,137 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Orderable;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.util.Orderer} to establish backward dependencies for {@link
+ * org.apache.tapestry.ioc.Orderable} objects.
+ *
+ * @param <T>
+ */
+
+class DependencyNode<T>
+{
+    private final Logger logger;
+
+    private final Orderable<T> orderable;
+
+    private final List<DependencyNode<T>> dependencies = CollectionFactory.newList();
+
+    DependencyNode(Logger logger, Orderable<T> orderable)
+    {
+        this.logger = logger;
+        this.orderable = orderable;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder buffer = new StringBuilder(String.format("[%s", getId()));
+
+        boolean first = true;
+
+        for (DependencyNode<T> node : dependencies)
+        {
+
+            buffer.append(first ? ": " : ", ");
+
+            buffer.append(node.toString());
+
+            first = false;
+        }
+
+        buffer.append("]");
+
+        return buffer.toString();
+    }
+
+    /**
+     * Returns the underlying {@link Orderable}'s id.
+     */
+    public String getId()
+    {
+        return orderable.getId();
+    }
+
+    void addDependency(DependencyNode<T> node)
+    {
+        if (node.isReachable(this))
+        {
+            logger.warn(UtilMessages.dependencyCycle(node, this));
+            return;
+        }
+
+        // Make this node depend on the other node.
+        // That forces the other node's orderable
+        // to appear before this node's orderable.
+
+        dependencies.add(node);
+    }
+
+    boolean isReachable(DependencyNode<T> node)
+    {
+        if (this == node) return true;
+
+        // Quick fast pass for immediate dependencies
+
+        for (DependencyNode<T> d : dependencies)
+        {
+            if (d == node) return true;
+        }
+
+        // Slower second pass looks for
+        // indirect dependencies
+
+        for (DependencyNode<T> d : dependencies)
+        {
+            if (d.isReachable(node)) return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the {@link Orderable} objects for this node ordered based on dependencies.
+     */
+    List<Orderable<T>> getOrdered()
+    {
+        List<Orderable<T>> result = newList();
+
+        fillOrder(result);
+
+        return result;
+    }
+
+    private void fillOrder(List<Orderable<T>> list)
+    {
+        if (list.contains(orderable)) return;
+
+        // Recusively add dependencies
+
+        for (DependencyNode<T> node : dependencies)
+        {
+            node.fillOrder(list);
+        }
+
+        list.add(orderable);
+    }
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/GenericsUtils.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/GenericsUtils.java
new file mode 100644
index 0000000..cce8403
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/GenericsUtils.java
@@ -0,0 +1,91 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * Static methods related to the use of JDK 1.5 generics.
+ */
+public class GenericsUtils
+{
+    /**
+     * Analyzes the method (often defined in a base class) in the context of a particular concrete implementation of the
+     * class to establish the generic type of a property. This works when the property type is defined as a class
+     * generic parameter.
+     *
+     * @param type   base type for evaluation
+     * @param method method (possibly from a base class of type) to extract
+     * @return the generic type if it may be determined, or the raw type (that is, with type erasure, most often
+     *         Object)
+     */
+    public static Class extractGenericReturnType(Class type, Method method)
+    {
+        Class defaultType = method.getReturnType();
+
+        Type genericType = method.getGenericReturnType();
+
+        // We can only handle the case where you "lock down" a generic type to a specific type.
+
+        if (genericType instanceof TypeVariable)
+        {
+
+            // An odd name for the method that gives you access to the type parameters
+            // used when implementing this class.  When you say Bean<String>, the first
+            // type variable of the generic superclass is class String.
+
+            Type superType = type.getGenericSuperclass();
+
+            if (superType instanceof ParameterizedType)
+            {
+                ParameterizedType superPType = (ParameterizedType) superType;
+
+                TypeVariable tv = (TypeVariable) genericType;
+
+                String name = tv.getName();
+
+                TypeVariable[] typeVariables = tv.getGenericDeclaration().getTypeParameters();
+
+                for (int i = 0; i < typeVariables.length; i++)
+                {
+                    TypeVariable stv = typeVariables[i];
+
+                    // We're trying to match the name of the type variable that is used as the return type
+                    // of the method.  With that name, we find the corresponding index in the
+                    // type declarations.  With the index, we check superPType for the Class instance
+                    // that defines it. Generics has lots of other options that we simply can't handle.
+
+                    if (stv.getName().equals(name))
+                    {
+                        Type actualType = superPType.getActualTypeArguments()[i];
+
+                        if (actualType instanceof Class) return (Class) actualType;
+
+                        break;
+                    }
+                }
+
+            }
+        }
+
+
+        return defaultType;
+
+        // P.S. I wrote this and I barely understand it.  Fortunately, I have tests ...
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java
new file mode 100644
index 0000000..70280fc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/IdAllocator.java
@@ -0,0 +1,185 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.util;

+

+import java.util.HashMap;

+import java.util.IdentityHashMap;

+import java.util.List;

+import java.util.Map;

+

+

+/**

+ * Used to "uniquify" names within a given context. A base name is passed in, and the return value is the base name, or

+ * the base name extended with a suffix to make it unique.

+ * <p/>

+ * This class is not threadsafe.

+ */

+

+public final class IdAllocator

+{

+    private static final String SEPARATOR = "_";

+

+    /**

+     * Map from allocated id to a generator for names associated with the allocated id.

+     */

+    private final Map<String, NameGenerator> generatorMap;

+

+    private final String namespace;

+

+    /**

+     * Generates unique names with a particular prefix.

+     */

+    private static class NameGenerator implements Cloneable

+    {

+        private final String baseId;

+

+        private int index;

+

+        NameGenerator(String baseId)

+        {

+            this.baseId = baseId + SEPARATOR;

+        }

+

+        public String nextId()

+        {

+            return baseId + index++;

+        }

+

+        /**

+         * Clones this instance, returning an equivalent but seperate copy.

+         */

+        @SuppressWarnings({ "CloneDoesntDeclareCloneNotSupportedException" })

+        @Override

+        public NameGenerator clone()

+        {

+            try

+            {

+                return (NameGenerator) super.clone();

+            }

+            catch (CloneNotSupportedException ex)

+            {

+                // Unreachable!

+                throw new RuntimeException(ex);

+            }

+        }

+    }

+

+    /**

+     * Creates a new allocator with no namespace.

+     */

+    public IdAllocator()

+    {

+        this("");

+    }

+

+    /**

+     * Creates a new allocator with the provided namespace.

+     */

+    public IdAllocator(String namespace)

+    {

+        this(namespace, new HashMap<String, NameGenerator>());

+    }

+

+    private IdAllocator(String namespace, Map<String, NameGenerator> generatorMap)

+    {

+        this.namespace = namespace;

+        this.generatorMap = generatorMap;

+    }

+

+    /**

+     * Returns a list of all allocated ids, sorted alphabetically.

+     */

+    public List<String> getAllocatedIds()

+    {

+        return InternalUtils.sortedKeys(generatorMap);

+    }

+

+    /**

+     * Creates a clone of this IdAllocator instance, copying the allocator's namespace and key map.

+     */

+    @SuppressWarnings({ "CloneDoesntCallSuperClone" })

+    @Override

+    public IdAllocator clone()

+    {

+        // Copying the generatorMap is tricky; multiple keys will point to the same NameGenerator

+        // instance. We need to clone the NameGenerators, then build a new map around the clones.

+

+        IdentityHashMap<NameGenerator, NameGenerator> transformMap = new IdentityHashMap<NameGenerator, NameGenerator>();

+

+        for (NameGenerator original : generatorMap.values())

+        {

+            NameGenerator copy = original.clone();

+

+            transformMap.put(original, copy);

+        }

+

+        Map<String, NameGenerator> mapCopy = CollectionFactory.newMap();

+

+        for (String key : generatorMap.keySet())

+        {

+            NameGenerator original = generatorMap.get(key);

+            NameGenerator copy = transformMap.get(original);

+

+            mapCopy.put(key, copy);

+        }

+

+        return new IdAllocator(namespace, mapCopy);

+    }

+

+    /**

+     * Allocates the id. Repeated calls for the same name will return "name", "name_0", "name_1", etc.

+     */

+

+    public String allocateId(String name)

+    {

+        String key = name + namespace;

+

+        NameGenerator g = generatorMap.get(key);

+        String result;

+

+        if (g == null)

+        {

+            g = new NameGenerator(key);

+            result = key;

+        }

+        else result = g.nextId();

+

+        // Handle the degenerate case, where a base name of the form "foo_0" has been

+        // requested. Skip over any duplicates thus formed.

+

+        while (generatorMap.containsKey(result)) result = g.nextId();

+

+        generatorMap.put(result, g);

+

+        return result;

+    }

+

+    /**

+     * Checks to see if a given name has been allocated.

+     */

+    public boolean isAllocated(String name)

+    {

+        return generatorMap.containsKey(name);

+    }

+

+    /**

+     * Clears the allocator, resetting it to freshly allocated state.

+     */

+

+    public void clear()

+    {

+        generatorMap.clear();

+    }

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
new file mode 100644
index 0000000..3812e90
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
@@ -0,0 +1,154 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+/**
+ * Used to search from a particular class up the inheritance hierarchy of extended classes and implemented interfaces.
+ * <p/>
+ * The search starts with the initial class (provided in the constructor). It progresses up the inheritance chain, but
+ * skips java.lang.Object.
+ * <p/>
+ * Once classes are exhausted, the inheritance hiearchy is searched. This is a breadth-first search, rooted in the
+ * interfaces implemented by the initial class at its super classes.
+ * <p/>
+ * Once all interfaces are exhausted, java.lang.Object is returned (it is always returned last).
+ * <p/>
+ * Two minor tweak to normal inheritance rules: <ul> <li> Normally, the parent class of an <em>object</em> array is
+ * java.lang.Object, which is odd because Foo[] is assignable to Object[]. Thus, we tweak the search so that the
+ * effective super class of Foo[] is Object[]. <li> The "super class" of a primtive type is its <em>wrapper type</em>,
+ * with the exception of void, whose "super class" is left at its normal value (Object.class) </ul>
+ * <p/>
+ * This class implements the {@link Iterable} interface, so it can be used directly in a for loop: <code> for (Class
+ * search : new InheritanceSearch(startClass)) { ... } </code>
+ * <p/>
+ * This class is not threadsafe.
+ */
+public class InheritanceSearch implements Iterator<Class>, Iterable<Class>
+{
+    private Class searchClass;
+
+    private final Set<Class> addedInterfaces = CollectionFactory.newSet();
+
+    private final LinkedList<Class> interfaceQueue = CollectionFactory.newLinkedList();
+
+    private enum State
+    {
+        CLASS, INTERFACE, DONE
+    }
+
+    private State state;
+
+    public InheritanceSearch(Class searchClass)
+    {
+        this.searchClass = searchClass;
+
+        queueInterfaces(searchClass);
+
+        state = searchClass == Object.class ? State.INTERFACE : State.CLASS;
+    }
+
+    private void queueInterfaces(Class searchClass)
+    {
+        for (Class intf : searchClass.getInterfaces())
+        {
+            if (addedInterfaces.contains(intf)) continue;
+
+            interfaceQueue.addLast(intf);
+            addedInterfaces.add(intf);
+        }
+    }
+
+    public Iterator<Class> iterator()
+    {
+        return this;
+    }
+
+    public boolean hasNext()
+    {
+        return state != State.DONE;
+    }
+
+    public Class next()
+    {
+        switch (state)
+        {
+            case CLASS:
+
+                Class result = searchClass;
+
+                searchClass = parentOf(searchClass);
+
+                if (searchClass == null) state = State.INTERFACE;
+                else queueInterfaces(searchClass);
+
+                return result;
+
+            case INTERFACE:
+
+                if (interfaceQueue.isEmpty())
+                {
+                    state = State.DONE;
+                    return Object.class;
+                }
+
+                Class intf = interfaceQueue.removeFirst();
+
+                queueInterfaces(intf);
+
+                return intf;
+
+            default:
+                throw new IllegalStateException();
+        }
+
+    }
+
+    /**
+     * Returns the parent of the given class. Tweaks inheritance for object arrays. Returns null instead of
+     * Object.class.
+     */
+    private Class parentOf(Class clazz)
+    {
+        if (clazz != void.class && clazz.isPrimitive()) return ClassFabUtils.getWrapperType(clazz);
+
+        if (clazz.isArray() && clazz != Object[].class)
+        {
+            Class componentType = clazz.getComponentType();
+
+            while (componentType.isArray()) componentType = componentType.getComponentType();
+
+            if (!componentType.isPrimitive()) return Object[].class;
+        }
+
+        Class parent = clazz.getSuperclass();
+
+        return parent != Object.class ? parent : null;
+    }
+
+    /**
+     * @throws UnsupportedOperationException always
+     */
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
new file mode 100644
index 0000000..f5f51da
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
@@ -0,0 +1,565 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.InjectService;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Utilities used within various internal implemenations of Tapestry IOC and the rest of the tapestry-core framework.
+ */
+
+public class InternalUtils
+{
+    /**
+     * Leading punctiation on member names that is stripped off to form a property name or new member name.
+     */
+    private static final String NAME_PREFIX = "_$";
+
+    /**
+     * Converts a method to a user presentable string using a {@link ClassFactory} to obtain a {@link Location} (where
+     * possible). {@link #asString(Method)} is used under the covers, to present a detailed, but not excessive,
+     * description of the class, method and parameters.
+     *
+     * @param method       method to convert to a string
+     * @param classFactory used to obtain the {@link Location}
+     * @return the method formatted for presentation to the user
+     */
+    public static String asString(Method method, ClassFactory classFactory)
+    {
+        Location location = classFactory.getMethodLocation(method);
+
+        return location != null ? location.toString() : asString(method);
+    }
+
+    /**
+     * Converts a method to a user presentable string consisting of the containing class name, the method name, and the
+     * short form of the parameter list (the class name of each parameter type, shorn of the package name portion).
+     *
+     * @param method
+     * @return short string representation
+     */
+    public static String asString(Method method)
+    {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(method.getDeclaringClass().getName());
+        buffer.append(".");
+        buffer.append(method.getName());
+        buffer.append("(");
+
+        for (int i = 0; i < method.getParameterTypes().length; i++)
+        {
+            if (i > 0) buffer.append(", ");
+
+            String name = method.getParameterTypes()[i].getSimpleName();
+
+            buffer.append(name);
+        }
+
+        return buffer.append(")").toString();
+    }
+
+    /**
+     * Returns the size of an object array, or null if the array is empty.
+     */
+
+    public static int size(Object[] array)
+    {
+        return array == null ? 0 : array.length;
+    }
+
+    /**
+     * Strips leading punctuation ("_" and "$") from the provided name.
+     */
+    public static String stripMemberPrefix(String memberName)
+    {
+        StringBuilder builder = new StringBuilder(memberName);
+
+        // There may be other prefixes we want to strip off, at some point!
+
+        // Strip off leading characters defined by NAME_PREFIX
+
+        // This code is really ugly and needs to be fixed.
+
+        while (true)
+        {
+            char ch = builder.charAt(0);
+
+            if (InternalUtils.NAME_PREFIX.indexOf(ch) < 0) break;
+
+            builder.deleteCharAt(0);
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * Strips leading characters defined by {@link InternalUtils#NAME_PREFIX}, then adds the prefix back in.
+     */
+    public static String createMemberName(String memberName)
+    {
+        return NAME_PREFIX + stripMemberPrefix(memberName);
+    }
+
+    /**
+     * Converts an enumeration (of Strings) into a sorted list of Strings.
+     */
+    public static List<String> toList(Enumeration e)
+    {
+        List<String> result = newList();
+
+        while (e.hasMoreElements())
+        {
+            String name = (String) e.nextElement();
+
+            result.add(name);
+        }
+
+        Collections.sort(result);
+
+        return result;
+    }
+
+    /**
+     * Finds a specific annotation type within an array of annotations.
+     *
+     * @param <T>
+     * @param annotations     to search
+     * @param annotationClass to match
+     * @return the annotation instance, if found, or null otherwise
+     */
+    public static <T extends Annotation> T findAnnotation(Annotation[] annotations, Class<T> annotationClass)
+    {
+        for (Annotation a : annotations)
+        {
+            if (annotationClass.isInstance(a)) return annotationClass.cast(a);
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Object calculateParameterValue(Class parameterType, final Annotation[] parameterAnnotations,
+                                                  ObjectLocator locator, Map<Class, Object> parameterDefaults)
+    {
+        AnnotationProvider provider = new AnnotationProvider()
+        {
+            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+            {
+                return findAnnotation(parameterAnnotations, annotationClass);
+            }
+
+        };
+
+        // At some point, it would be nice to eliminate InjectService, and rely
+        // entirely on service interface type and point-of-injection markers.
+
+        InjectService is = provider.getAnnotation(InjectService.class);
+
+        if (is != null)
+        {
+            String serviceId = is.value();
+
+            return locator.getService(serviceId, parameterType);
+        }
+
+        // In the absence of @InjectService, try some autowiring. First, does the
+        // parameter type match on of the resources (the parameter defaults)?
+
+        if (provider.getAnnotation(Inject.class) == null)
+        {
+            Object result = parameterDefaults.get(parameterType);
+
+            if (result != null) return result;
+        }
+
+        // Otherwise, make use of the MasterObjectProvider service to resolve this type (plus
+        // any other information gleaned from additional annotation) into the correct object.
+
+        return locator.getObject(parameterType, provider);
+    }
+
+    public static Object[] calculateParametersForMethod(Method method, ObjectLocator locator,
+                                                        Map<Class, Object> parameterDefaults)
+    {
+        Class[] parameterTypes = method.getParameterTypes();
+        Annotation[][] annotations = method.getParameterAnnotations();
+
+        return calculateParameters(locator, parameterDefaults, parameterTypes, annotations);
+    }
+
+    public static Object[] calculateParametersForConstructor(Constructor constructor, ObjectLocator locator,
+                                                             Map<Class, Object> parameterDefaults)
+    {
+        Class[] parameterTypes = constructor.getParameterTypes();
+        Annotation[][] annotations = constructor.getParameterAnnotations();
+
+        return calculateParameters(locator, parameterDefaults, parameterTypes, annotations);
+    }
+
+    public static Object[] calculateParameters(ObjectLocator locator, Map<Class, Object> parameterDefaults,
+                                               Class[] parameterTypes, Annotation[][] parameterAnnotations)
+    {
+        int parameterCount = parameterTypes.length;
+
+        Object[] parameters = new Object[parameterCount];
+
+        for (int i = 0; i < parameterCount; i++)
+        {
+            parameters[i] = calculateParameterValue(parameterTypes[i], parameterAnnotations[i], locator,
+                                                    parameterDefaults);
+        }
+
+        return parameters;
+    }
+
+    /**
+     * Joins together some number of elements to form a comma separated list.
+     */
+    public static String join(List elements)
+    {
+        return join(elements, ", ");
+    }
+
+    /**
+     * Joins together some number of elements. If a value in the list is the empty string, it is replaced with the
+     * string "(blank)".
+     *
+     * @param elements  objects to be joined together
+     * @param separator used between elements when joining
+     */
+    public static String join(List elements, String separator)
+    {
+        switch (elements.size())
+        {
+            case 0:
+                return "";
+
+            case 1:
+                return elements.get(0).toString();
+
+            default:
+
+                StringBuilder buffer = new StringBuilder();
+                boolean first = true;
+
+                for (Object o : elements)
+                {
+                    if (!first) buffer.append(separator);
+
+                    String string = String.valueOf(o);
+
+                    if (string.equals("")) string = "(blank)";
+
+                    buffer.append(string);
+
+                    first = false;
+                }
+
+                return buffer.toString();
+        }
+    }
+
+    /**
+     * Creates a sorted copy of the provided elements, then turns that into a comma separated list.
+     *
+     * @return the elements converted to strings, sorted, joined with comma ... or "(none)" if the elements are null or
+     *         empty
+     */
+    public static String joinSorted(Collection elements)
+    {
+        if (elements == null || elements.isEmpty()) return "(none)";
+
+        List<String> list = newList();
+
+        for (Object o : elements)
+            list.add(String.valueOf(o));
+
+        Collections.sort(list);
+
+        return join(list);
+    }
+
+    /**
+     * Returns true if the input is null, or is a zero length string (excluding leading/trailing whitespace).
+     */
+
+    public static boolean isBlank(String input)
+    {
+        return input == null || input.length() == 0 || input.trim().length() == 0;
+    }
+
+    public static boolean isNonBlank(String input)
+    {
+        return !isBlank(input);
+    }
+
+    /**
+     * Capitalizes a string, converting the first character to uppercase.
+     */
+    public static String capitalize(String input)
+    {
+        if (input.length() == 0) return input;
+
+        return input.substring(0, 1).toUpperCase() + input.substring(1);
+    }
+
+    /**
+     * Sniffs the object to see if it is a {@link Location} or {@link Locatable}. Returns null if null or not
+     * convertable to a location.
+     */
+
+    public static Location locationOf(Object location)
+    {
+        if (location == null) return null;
+
+        if (location instanceof Location) return (Location) location;
+
+        if (location instanceof Locatable) return ((Locatable) location).getLocation();
+
+        return null;
+    }
+
+    /**
+     * Extracts the string keys from a map and returns them in sorted order. The keys are converted to strings.
+     *
+     * @param map the map to extract keys from (may be null)
+     * @return the sorted keys, or the empty set if map is null
+     */
+
+    public static List<String> sortedKeys(Map map)
+    {
+        if (map == null) return Collections.emptyList();
+
+        List<String> keys = newList();
+
+        for (Object o : map.keySet())
+            keys.add(String.valueOf(o));
+
+        Collections.sort(keys);
+
+        return keys;
+    }
+
+    /**
+     * Gets a value from a map (which may be null).
+     *
+     * @param <K>
+     * @param <V>
+     * @param map the map to extract from (may be null)
+     * @param key
+     * @return the value from the map, or null if the map is null
+     */
+
+    public static <K, V> V get(Map<K, V> map, K key)
+    {
+        if (map == null) return null;
+
+        return map.get(key);
+    }
+
+    /**
+     * Returns true if the method provided is a static method.
+     */
+    public static boolean isStatic(Method method)
+    {
+        return Modifier.isStatic(method.getModifiers());
+    }
+
+    public static <T> Iterator<T> reverseIterator(final List<T> list)
+    {
+        final ListIterator<T> normal = list.listIterator(list.size());
+
+        return new Iterator<T>()
+        {
+            public boolean hasNext()
+            {
+                return normal.hasPrevious();
+            }
+
+            public T next()
+            {
+                // TODO Auto-generated method stub
+                return normal.previous();
+            }
+
+            public void remove()
+            {
+                throw new UnsupportedOperationException();
+            }
+
+        };
+    }
+
+    /**
+     * Return true if the input string contains the marker for symbols that must be expanded.
+     */
+    public static boolean containsSymbols(String input)
+    {
+        return input.contains("${");
+    }
+
+    /**
+     * Searches the string for the final period ('.') character and returns everything after that. The input string is
+     * generally a fully qualified class name, though tapestry-core also uses this method for the occasional property
+     * expression (which is also dot separated). Returns the input string unchanged if it does not contain a period
+     * character.
+     */
+    public static String lastTerm(String input)
+    {
+        notBlank(input, "input");
+
+        int dotx = input.lastIndexOf('.');
+
+        if (dotx < 0) return input;
+
+        return input.substring(dotx + 1);
+    }
+
+    /**
+     * Searches a class for the "best" constructor, the public constructor with the most parameters. Returns null if
+     * there are no public constructors. If there is more than one constructor with the maximum number of parameters, it
+     * is not determined which will be returned (don't build a class like that!). In addition, if a constructor is
+     * annotated with {@link org.apache.tapestry.ioc.annotation.Inject}, it will be used (no check for multiple such
+     * constructors is made, only at most a single constructor should have the annotation).
+     *
+     * @param clazz to search for a constructor for
+     * @return the constructor to be used to instantiate the class, or null if no appropriate constructor was found
+     */
+    public static Constructor findAutobuildConstructor(Class clazz)
+    {
+        Constructor[] constructors = clazz.getConstructors();
+
+        switch (constructors.length)
+        {
+            case 1:
+
+                return constructors[0];
+
+            case 0:
+
+                return null;
+
+            default:
+                break;
+        }
+
+        for (Constructor c : constructors)
+        {
+            if (c.getAnnotation(Inject.class) != null) return c;
+        }
+
+        // Choose a constructor with the most parameters.
+
+        Comparator<Constructor> comparator = new Comparator<Constructor>()
+        {
+            public int compare(Constructor o1, Constructor o2)
+            {
+                return o2.getParameterTypes().length - o1.getParameterTypes().length;
+            }
+        };
+
+        Arrays.sort(constructors, comparator);
+
+        return constructors[0];
+    }
+
+    /**
+     * Adds a value to a specially organized map where the values are lists of objects. This somewhat simulates a map
+     * that allows mutiple values for the same key.
+     *
+     * @param map   to store value into
+     * @param key   for which a value is added
+     * @param value to add
+     * @param <K>   the type of key
+     * @param <V>   the type of the list
+     */
+    public static <K, V> void addToMapList(Map<K, List<V>> map, K key, V value)
+    {
+        List<V> list = map.get(key);
+
+        if (list == null)
+        {
+            list = newList();
+            map.put(key, list);
+        }
+
+        list.add(value);
+    }
+
+    /**
+     * Validates that the marker annotation class had a retention policy of runtime.
+     *
+     * @param markerClass the marker annotation class
+     */
+    public static void validateMarkerAnnotation(Class markerClass)
+    {
+        Retention policy = (Retention) markerClass.getAnnotation(Retention.class);
+
+        if (policy != null && policy.value() == RetentionPolicy.RUNTIME) return;
+
+        throw new IllegalArgumentException(UtilMessages.badMarkerAnnotation(markerClass));
+    }
+
+    public static void validateMarkerAnnotations(Class[] markerClasses)
+    {
+        for (Class markerClass : markerClasses) validateMarkerAnnotation(markerClass);
+    }
+
+    public static void close(Closeable stream)
+    {
+        if (stream != null) try
+        {
+            stream.close();
+        }
+        catch (IOException ex)
+        {
+            // Ignore.
+        }
+    }
+
+    /**
+     * Extracts the message from an exception.  If the exception's message is null, returns the exceptions class name.
+     *
+     * @param exception to extract message from
+     * @return message or class name
+     */
+    public static String toMessage(Throwable exception)
+    {
+        String message = exception.getMessage();
+
+        if (message != null) return message;
+
+        return exception.getClass().getName();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Invokable.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Invokable.java
new file mode 100644
index 0000000..8fc43cb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Invokable.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Similiar to {@link Runnable} execpt that it returns a value. Used by {@link ConcurrentBarrier} to

+ * identify the block of code to execute with read/write lock protection.

+ *

+ * @param <T>

+ * the return value type

+ */

+public interface Invokable<T>

+{

+    /**

+     * Called to produce a value.

+     */

+    T invoke();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGenerator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGenerator.java
new file mode 100644
index 0000000..d7f3a16
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGenerator.java
@@ -0,0 +1,230 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+/**
+ * Used in a wide variety of resource searches. Generates a series of name variations from a path (which must include a
+ * suffix) and locale.
+ * <p/>
+ * This class is not threadsafe.
+ */
+public class LocalizedNameGenerator implements Iterator<String>, Iterable<String>
+{
+    private final int baseNameLength;
+
+    private final String suffix;
+
+    private final StringBuilder builder;
+
+    private final String language;
+
+    private final String country;
+
+    private final String variant;
+
+    private int state;
+
+    private int prevState;
+
+    private static final int INITIAL = 0;
+
+    private static final int LCV = 1;
+
+    private static final int LC = 2;
+
+    private static final int LV = 3;
+
+    private static final int L = 4;
+
+    private static final int BARE = 5;
+
+    private static final int EXHAUSTED = 6;
+
+    public LocalizedNameGenerator(String path, Locale locale)
+    {
+        int dotx = path.lastIndexOf('.');
+
+        // When there is no dot in the name, pretend it exists after the
+        // end of the string. The locale extensions will be tacked on there.
+
+        if (dotx == -1) dotx = path.length();
+
+        // TODO: Case where there is no suffix
+
+        String baseName = path.substring(0, dotx);
+
+        suffix = path.substring(dotx);
+
+        baseNameLength = dotx;
+
+        language = locale.getLanguage();
+        country = locale.getCountry();
+        variant = locale.getVariant();
+
+        state = INITIAL;
+        prevState = INITIAL;
+
+        builder = new StringBuilder(baseName);
+
+        advance();
+    }
+
+    private void advance()
+    {
+        prevState = state;
+
+        while (state != EXHAUSTED)
+        {
+            state++;
+
+            switch (state)
+            {
+                case LCV:
+
+                    if (InternalUtils.isBlank(variant)) continue;
+
+                    return;
+
+                case LC:
+
+                    if (InternalUtils.isBlank(country)) continue;
+
+                    return;
+
+                case LV:
+
+                    // If country is null, then we've already generated this string
+                    // as state LCV and we can continue directly to state L
+
+                    if (InternalUtils.isBlank(variant) || InternalUtils.isBlank(country)) continue;
+
+                    return;
+
+                case L:
+
+                    if (InternalUtils.isBlank(language)) continue;
+
+                    return;
+
+                case BARE:
+                default:
+                    return;
+            }
+        }
+    }
+
+    /**
+     * Returns true if there are more name variants to be returned, false otherwise.
+     */
+
+    public boolean hasNext()
+    {
+        return state != EXHAUSTED;
+    }
+
+    /**
+     * Returns the next localized variant.
+     *
+     * @throws NoSuchElementException if all variants have been returned.
+     */
+
+    public String next()
+    {
+        if (state == EXHAUSTED) throw new NoSuchElementException();
+
+        String result = build();
+
+        advance();
+
+        return result;
+    }
+
+    private String build()
+    {
+        builder.setLength(baseNameLength);
+
+        if (state == LC || state == LCV || state == L)
+        {
+            builder.append('_');
+            builder.append(language);
+        }
+
+        // For LV, we want two underscores between language
+        // and variant.
+
+        if (state == LC || state == LCV || state == LV)
+        {
+            builder.append('_');
+
+            if (state != LV) builder.append(country);
+        }
+
+        if (state == LV || state == LCV)
+        {
+            builder.append('_');
+            builder.append(variant);
+        }
+
+        if (suffix != null) builder.append(suffix);
+
+        return builder.toString();
+    }
+
+    public Locale getCurrentLocale()
+    {
+        switch (prevState)
+        {
+            case LCV:
+
+                return new Locale(language, country, variant);
+
+            case LC:
+
+                return new Locale(language, country, "");
+
+            case LV:
+
+                return new Locale(language, "", variant);
+
+            case L:
+
+                return new Locale(language, "", "");
+
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * @throws UnsupportedOperationException
+     */
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * So that LNG may be used with the for loop.
+     */
+    public Iterator<String> iterator()
+    {
+        return this;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocationImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocationImpl.java
new file mode 100644
index 0000000..c0f1622
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/LocationImpl.java
@@ -0,0 +1,108 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+
+import java.util.Formatter;
+
+/**
+ * Implementation class for {@link org.apache.tapestry.ioc.Location}.
+ */
+public final class LocationImpl implements Location
+{
+    private final Resource resource;
+
+    private final int line;
+
+    private final int column;
+
+    private static final int UNKNOWN = -1;
+
+    public LocationImpl(Resource resource)
+    {
+        this(resource, UNKNOWN);
+    }
+
+    public LocationImpl(Resource resource, int line)
+    {
+        this(resource, line, UNKNOWN);
+    }
+
+    public LocationImpl(Resource resource, int line, int column)
+    {
+        this.resource = resource;
+        this.line = line;
+        this.column = column;
+    }
+
+    public Resource getResource()
+    {
+        return resource;
+    }
+
+    public int getLine()
+    {
+        return line;
+    }
+
+    public int getColumn()
+    {
+        return column;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder buffer = new StringBuilder(resource.toString());
+        Formatter formatter = new Formatter(buffer);
+
+        if (line != UNKNOWN) formatter.format(", line %d", line);
+
+        if (column != UNKNOWN) formatter.format(", column %d", column);
+
+        return buffer.toString();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int PRIME = 31;
+        int result = 1;
+        result = PRIME * result + column;
+        result = PRIME * result + line;
+        result = PRIME * result + ((resource == null) ? 0 : resource.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final LocationImpl other = (LocationImpl) obj;
+        if (column != other.column) return false;
+        if (line != other.line) return false;
+        if (resource == null)
+        {
+            if (other.resource != null) return false;
+        }
+        else if (!resource.equals(other.resource)) return false;
+        return true;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImpl.java
new file mode 100644
index 0000000..e9c1e92
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImpl.java
@@ -0,0 +1,52 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.util;

+

+import org.apache.tapestry.ioc.MessageFormatter;

+

+import java.util.Locale;

+

+

+public class MessageFormatterImpl implements MessageFormatter

+{

+    private final String format;

+

+    private final Locale locale;

+

+    public MessageFormatterImpl(String format, Locale locale)

+    {

+        this.format = format;

+        this.locale = locale;

+    }

+

+    public String format(Object... args)

+    {

+        for (int i = 0; i < args.length; i++)

+        {

+            Object arg = args[i];

+

+            if (Throwable.class.isInstance(arg))

+            {

+                args[i] = InternalUtils.toMessage((Throwable) arg);

+            }

+        }

+

+        // Might be tempting to create a Formatter object and just keep reusing it ... but

+        // Formatters are not threadsafe.

+

+        return String.format(locale, format, args);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessagesImpl.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessagesImpl.java
new file mode 100644
index 0000000..49413fb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/MessagesImpl.java
@@ -0,0 +1,72 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.util.AbstractMessages;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+/**
+ * Implementation of {@link org.apache.tapestry.ioc.Messages} based around a {@link java.util.ResourceBundle}.
+ */
+public class MessagesImpl extends AbstractMessages
+{
+    private final Map<String, String> properties = CollectionFactory.newCaseInsensitiveMap();
+
+    /**
+     * Finds the messages for a given Messages utility class. Strings the trailing "Messages" and replaces it with
+     * "Strings" to form the base path. Loads the bundle using the default locale, and the class' class loader.
+     *
+     * @param forClass
+     * @return Messages for the class
+     */
+    public static Messages forClass(Class forClass)
+    {
+        String className = forClass.getName();
+        String stringsClassName = className.replaceAll("Messages$", "Strings");
+
+        Locale locale = Locale.getDefault();
+
+        ResourceBundle bundle = ResourceBundle.getBundle(stringsClassName, locale, forClass.getClassLoader());
+
+        return new MessagesImpl(locale, bundle);
+    }
+
+    public MessagesImpl(Locale locale, ResourceBundle bundle)
+    {
+        super(locale);
+
+        // Our best (threadsafe) chance to determine all the available keys.
+        Enumeration<String> e = bundle.getKeys();
+        while (e.hasMoreElements())
+        {
+            String key = e.nextElement();
+            String value = bundle.getString(key);
+
+            properties.put(key, value);
+        }
+    }
+
+    @Override
+    protected String valueForKey(String key)
+    {
+        return properties.get(key);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/OneShotLock.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/OneShotLock.java
new file mode 100644
index 0000000..9948b61
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/OneShotLock.java
@@ -0,0 +1,66 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+/**
+ * Logic for handling one shot semantics for classes; classes that include a method (or methods) that "locks down" the
+ * instance, to prevent it from being used again in the future.
+ */
+public class OneShotLock
+{
+    private boolean lock;
+
+    /**
+     * Checks to see if the lock has been set (via {@link #lock()}).
+     *
+     * @throws IllegalStateException if the lock is set
+     */
+    public synchronized void check()
+    {
+        innerCheck();
+    }
+
+    private void innerCheck()
+    {
+        if (lock)
+        {
+            // This is how I would think it would be:
+
+            // [0] is getStackTrace()
+            // [1] is innerCheck()
+            // [2] is check() or lock()
+            // [3] is caller of check() or lock()
+
+            // ... so why do we get element 4?  Found this via trial and error.  Some extra stack frame
+            // gets in there somehow, as in, getStackTrace() must be calling something (probably native)
+            // that creates the actual array, and includes itself as [0], getStackTrace() as [1], etc.
+            // Maybe it's something to do with synchronized?
+
+            StackTraceElement element = Thread.currentThread().getStackTrace()[4];
+
+            throw new IllegalStateException(UtilMessages.oneShotLock(element));
+        }
+    }
+
+    /**
+     * Checks the lock, then sets it.
+     */
+    public synchronized void lock()
+    {
+        innerCheck();
+
+        lock = true;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Orderer.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Orderer.java
new file mode 100644
index 0000000..7bff8db
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/Orderer.java
@@ -0,0 +1,242 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.IdMatcher;
+import org.apache.tapestry.ioc.Orderable;
+import org.apache.tapestry.ioc.internal.IdMatcherImpl;
+import org.apache.tapestry.ioc.internal.OrIdMatcher;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Used to order objects into an "execution" order. Each object must have a unique id. It may specify a list of
+ * constraints which identify the ordering of the objects.
+ */
+public class Orderer<T>
+{
+    private final OneShotLock lock = new OneShotLock();
+
+    private final Logger logger;
+
+    private final List<Orderable> orderables = CollectionFactory.newList();
+
+    private final Map<String, Orderable<T>> idToOrderable = CollectionFactory.newCaseInsensitiveMap();
+
+    private final Map<String, DependencyNode<T>> dependencyNodesById = CollectionFactory.newCaseInsensitiveMap();
+
+    // Special node that is always dead last: all other nodes are a dependency
+    // of the trailer.
+
+    private DependencyNode<T> trailer;
+
+    interface DependencyLinker<T>
+    {
+        void link(DependencyNode<T> source, DependencyNode<T> target);
+    }
+
+    // before: source is added as a dependency of target, so source will
+    // appear before target.
+
+    final DependencyLinker<T> _before = new DependencyLinker<T>()
+    {
+        public void link(DependencyNode<T> source, DependencyNode<T> target)
+        {
+            target.addDependency(source);
+        }
+    };
+
+    // after: target is added as a dependency of source, so source will appear
+    // after target.
+
+    final DependencyLinker<T> _after = new DependencyLinker<T>()
+    {
+        public void link(DependencyNode<T> source, DependencyNode<T> target)
+        {
+            source.addDependency(target);
+        }
+    };
+
+    public Orderer(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    /**
+     * Adds an object to be ordered.
+     *
+     * @param orderable
+     */
+    public void add(Orderable<T> orderable)
+    {
+        lock.check();
+
+        String id = orderable.getId();
+
+        if (idToOrderable.containsKey(id))
+        {
+            logger.warn(UtilMessages.duplicateOrderer(id));
+            return;
+        }
+
+        orderables.add(orderable);
+
+        idToOrderable.put(id, orderable);
+    }
+
+    /**
+     * Adds an object to be ordered.
+     *
+     * @param id          unique, qualified id for the target
+     * @param target      the object to be ordered (or null as a placeholder)
+     * @param constraints optional, variable constraints
+     * @see #add(Orderable)
+     */
+
+    public void add(String id, T target, String... constraints)
+    {
+        lock.check();
+
+        add(new Orderable<T>(id, target, constraints));
+    }
+
+    public List<T> getOrdered()
+    {
+        lock.lock();
+
+        initializeGraph();
+
+        List<T> result = newList();
+
+        for (Orderable<T> orderable : trailer.getOrdered())
+        {
+            T target = orderable.getTarget();
+
+            // Nulls are placeholders that are skipped.
+
+            if (target != null) result.add(target);
+        }
+
+        return result;
+    }
+
+    private void initializeGraph()
+    {
+        trailer = new DependencyNode<T>(logger, new Orderable<T>("*-trailer-*", null));
+
+        addNodes();
+
+        addDependencies();
+    }
+
+    private void addNodes()
+    {
+        for (Orderable<T> orderable : orderables)
+        {
+            DependencyNode<T> node = new DependencyNode<T>(logger, orderable);
+
+            dependencyNodesById.put(orderable.getId(), node);
+
+            trailer.addDependency(node);
+        }
+    }
+
+    private void addDependencies()
+    {
+        for (Orderable<T> orderable : orderables)
+        {
+            addDependencies(orderable);
+        }
+    }
+
+    private void addDependencies(Orderable<T> orderable)
+    {
+        String sourceId = orderable.getId();
+
+        for (String constraint : orderable.getConstraints())
+        {
+            addDependencies(sourceId, constraint);
+        }
+    }
+
+    private void addDependencies(String sourceId, String constraint)
+    {
+        int colonx = constraint.indexOf(':');
+
+        String type = colonx > 0 ? constraint.substring(0, colonx) : null;
+
+        DependencyLinker<T> linker = null;
+
+        if ("after".equals(type))
+            linker = _after;
+        else if ("before".equals(type)) linker = _before;
+
+        if (linker == null)
+        {
+            logger.warn(UtilMessages.constraintFormat(constraint, sourceId));
+            return;
+        }
+
+        String patternList = constraint.substring(colonx + 1);
+
+        linkNodes(sourceId, patternList, linker);
+    }
+
+    private void linkNodes(String sourceId, String patternList, DependencyLinker<T> linker)
+    {
+        Collection<DependencyNode<T>> nodes = findDependencies(sourceId, patternList);
+
+        DependencyNode<T> source = dependencyNodesById.get(sourceId);
+
+        for (DependencyNode<T> target : nodes)
+        {
+            linker.link(source, target);
+        }
+    }
+
+    private Collection<DependencyNode<T>> findDependencies(String sourceId, String patternList)
+    {
+        IdMatcher matcher = buildMatcherForPattern(patternList);
+
+        Collection<DependencyNode<T>> result = newList();
+
+        for (String id : dependencyNodesById.keySet())
+        {
+            if (sourceId.equals(id)) continue;
+
+            if (matcher.matches(id)) result.add(dependencyNodesById.get(id));
+        }
+
+        return result;
+    }
+
+    private IdMatcher buildMatcherForPattern(String patternList)
+    {
+        List<IdMatcher> matchers = newList();
+
+        for (String pattern : patternList.split(","))
+        {
+            IdMatcher matcher = new IdMatcherImpl(pattern.trim());
+
+            matchers.add(matcher);
+        }
+
+        return matchers.size() == 1 ? matchers.get(0) : new OrIdMatcher(matchers);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/TapestryException.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/TapestryException.java
new file mode 100644
index 0000000..d2f61f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/TapestryException.java
@@ -0,0 +1,74 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.util;

+

+import org.apache.tapestry.ioc.Locatable;

+import org.apache.tapestry.ioc.Location;

+

+/**

+ * Exception class used as a replacement for {@link java.lang.RuntimeException} when the exception is related to a

+ * particular location.

+ */

+public class TapestryException extends RuntimeException implements Locatable

+{

+    private static final long serialVersionUID = 6396903640977182682L;

+

+    private transient final Location location;

+

+    /**

+     * @param message  a message (may be null)

+     * @param location implements {@link Location} or {@link Locatable}

+     * @param cause    if not null, the root cause of the exception

+     */

+    public TapestryException(String message, Object location, Throwable cause)

+    {

+        this(message, InternalUtils.locationOf(location), cause);

+    }

+

+    /**

+     * @param message a message (may be null)

+     * @param cause   if not null, the root cause of the exception, also used to set the location

+     */

+    public TapestryException(String message, Throwable cause)

+    {

+        this(message, cause, cause);

+    }

+

+    /**

+     * @param message  a message (may be null)

+     * @param location location to associated with the exception, or null if not known

+     * @param cause    if not null, the root cause of the exception

+     */

+    public TapestryException(String message, Location location, Throwable cause)

+    {

+        super(message, cause);

+

+        this.location = location;

+    }

+

+    public Location getLocation()

+    {

+        return location;

+    }

+

+    @Override

+    public String toString()

+    {

+        if (location == null) return super.toString();

+

+        return String.format("%s [at %s]", super.toString(), location);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/UtilMessages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/UtilMessages.java
new file mode 100644
index 0000000..5fae7a6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/UtilMessages.java
@@ -0,0 +1,66 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Messages;
+
+class UtilMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(UtilMessages.class);
+
+    private UtilMessages()
+    {
+    }
+
+    static String dependencyCycle(DependencyNode dependency, DependencyNode node)
+    {
+        return MESSAGES.format("dependency-cycle", dependency.getId(), node.getId());
+    }
+
+    static String duplicateOrderer(String id)
+    {
+        return MESSAGES.format("duplicate-orderer", id);
+    }
+
+    static String constraintFormat(String constraint, String id)
+    {
+        return MESSAGES.format("constraint-format", constraint, id);
+    }
+
+    static String oneShotLock(StackTraceElement element)
+    {
+        return MESSAGES.format("one-shot-lock", element);
+    }
+
+    static String parameterWasNull(String parameterName)
+    {
+        return MESSAGES.format("parameter-was-null", parameterName);
+    }
+
+    static String parameterWasBlank(String parameterName)
+    {
+        return MESSAGES.format("parameter-was-blank", parameterName);
+    }
+
+    static String badCast(String parameterName, Object parameterValue, Class type)
+    {
+        return MESSAGES.format("bad-cast", parameterName, parameterValue, type.getName());
+    }
+
+    static String badMarkerAnnotation(Class annotationClass)
+    {
+        return MESSAGES.format("bad-marker-annotation", annotationClass.getName());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/idToDependencyNode.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/idToDependencyNode.java
new file mode 100644
index 0000000..5c32aae
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/util/idToDependencyNode.java
@@ -0,0 +1,242 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.IdMatcher;
+import org.apache.tapestry.ioc.Orderable;
+import org.apache.tapestry.ioc.internal.IdMatcherImpl;
+import org.apache.tapestry.ioc.internal.OrIdMatcher;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Used to order objects into an "execution" order. Each object must have a unique id. It may specify a list of
+ * constraints which identify the ordering of the objects.
+ */
+public class idToDependencyNode<T>
+{
+    private final OneShotLock lock = new OneShotLock();
+
+    private final Logger logger;
+
+    private final List<Orderable> orderables = CollectionFactory.newList();
+
+    private final Map<String, Orderable<T>> idToOrderable = CollectionFactory.newCaseInsensitiveMap();
+
+    private final Map<String, DependencyNode<T>> idToDependencyNode = CollectionFactory.newCaseInsensitiveMap();
+
+    // Special node that is always dead last: all other nodes are a dependency
+    // of the trailer.
+
+    private DependencyNode<T> trailer;
+
+    interface DependencyLinker<T>
+    {
+        void link(DependencyNode<T> source, DependencyNode<T> target);
+    }
+
+    // before: source is added as a dependency of target, so source will
+    // appear before target.
+
+    final DependencyLinker<T> before = new DependencyLinker<T>()
+    {
+        public void link(DependencyNode<T> source, DependencyNode<T> target)
+        {
+            target.addDependency(source);
+        }
+    };
+
+    // after: target is added as a dependency of source, so source will appear
+    // after target.
+
+    final DependencyLinker<T> after = new DependencyLinker<T>()
+    {
+        public void link(DependencyNode<T> source, DependencyNode<T> target)
+        {
+            source.addDependency(target);
+        }
+    };
+
+    public idToDependencyNode(Logger logger)
+    {
+        this.logger = logger;
+    }
+
+    /**
+     * Adds an object to be ordered.
+     *
+     * @param orderable
+     */
+    public void add(Orderable<T> orderable)
+    {
+        lock.check();
+
+        String id = orderable.getId();
+
+        if (idToOrderable.containsKey(id))
+        {
+            logger.warn(UtilMessages.duplicateOrderer(id));
+            return;
+        }
+
+        orderables.add(orderable);
+
+        idToOrderable.put(id, orderable);
+    }
+
+    /**
+     * Adds an object to be ordered.
+     *
+     * @param id          unique, qualified id for the target
+     * @param target      the object to be ordered (or null as a placeholder)
+     * @param constraints optional, variable constraints
+     * @see #add(org.apache.tapestry.ioc.Orderable)
+     */
+
+    public void add(String id, T target, String... constraints)
+    {
+        lock.check();
+
+        add(new Orderable<T>(id, target, constraints));
+    }
+
+    public List<T> getOrdered()
+    {
+        lock.lock();
+
+        initializeGraph();
+
+        List<T> result = newList();
+
+        for (Orderable<T> orderable : trailer.getOrdered())
+        {
+            T target = orderable.getTarget();
+
+            // Nulls are placeholders that are skipped.
+
+            if (target != null) result.add(target);
+        }
+
+        return result;
+    }
+
+    private void initializeGraph()
+    {
+        trailer = new DependencyNode<T>(logger, new Orderable<T>("*-trailer-*", null));
+
+        addNodes();
+
+        addDependencies();
+    }
+
+    private void addNodes()
+    {
+        for (Orderable<T> orderable : orderables)
+        {
+            DependencyNode<T> node = new DependencyNode<T>(logger, orderable);
+
+            idToDependencyNode.put(orderable.getId(), node);
+
+            trailer.addDependency(node);
+        }
+    }
+
+    private void addDependencies()
+    {
+        for (Orderable<T> orderable : orderables)
+        {
+            addDependencies(orderable);
+        }
+    }
+
+    private void addDependencies(Orderable<T> orderable)
+    {
+        String sourceId = orderable.getId();
+
+        for (String constraint : orderable.getConstraints())
+        {
+            addDependencies(sourceId, constraint);
+        }
+    }
+
+    private void addDependencies(String sourceId, String constraint)
+    {
+        int colonx = constraint.indexOf(':');
+
+        String type = colonx > 0 ? constraint.substring(0, colonx) : null;
+
+        DependencyLinker<T> linker = null;
+
+        if ("after".equals(type))
+            linker = after;
+        else if ("before".equals(type)) linker = before;
+
+        if (linker == null)
+        {
+            logger.warn(UtilMessages.constraintFormat(constraint, sourceId));
+            return;
+        }
+
+        String patternList = constraint.substring(colonx + 1);
+
+        linkNodes(sourceId, patternList, linker);
+    }
+
+    private void linkNodes(String sourceId, String patternList, DependencyLinker<T> linker)
+    {
+        Collection<DependencyNode<T>> nodes = findDependencies(sourceId, patternList);
+
+        DependencyNode<T> source = idToDependencyNode.get(sourceId);
+
+        for (DependencyNode<T> target : nodes)
+        {
+            linker.link(source, target);
+        }
+    }
+
+    private Collection<DependencyNode<T>> findDependencies(String sourceId, String patternList)
+    {
+        IdMatcher matcher = buildMatcherForPattern(patternList);
+
+        Collection<DependencyNode<T>> result = newList();
+
+        for (String id : idToDependencyNode.keySet())
+        {
+            if (sourceId.equals(id)) continue;
+
+            if (matcher.matches(id)) result.add(idToDependencyNode.get(id));
+        }
+
+        return result;
+    }
+
+    private IdMatcher buildMatcherForPattern(String patternList)
+    {
+        List<IdMatcher> matchers = newList();
+
+        for (String pattern : patternList.split(","))
+        {
+            IdMatcher matcher = new IdMatcherImpl(pattern.trim());
+
+            matchers.add(matcher);
+        }
+
+        return matchers.size() == 1 ? matchers.get(0) : new OrIdMatcher(matchers);
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ApplicationDefaults.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ApplicationDefaults.java
new file mode 100644
index 0000000..028685d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ApplicationDefaults.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to disambiguate which version of {@link SymbolProvider} is being referenced. Contributions
+ * to the ApplicationDefaults symbol source are overridden by JVM System properties.
+ *
+ * @see FactoryDefaults
+ */
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface ApplicationDefaults
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectDecorator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectDecorator.java
new file mode 100644
index 0000000..6bbf24d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectDecorator.java
@@ -0,0 +1,51 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.MethodAdvice;
+
+
+/**
+ * A decorator used to create an interceptor that delegates each method's invocation to an {@link
+ * org.apache.tapestry.ioc.MethodAdvice} for advice.  Advice can inspect or change method parameters, inspect or change
+ * the method's return value, and inspect and change thrown exceptions (checked and unchecked).
+ */
+public interface AspectDecorator
+{
+    /**
+     * Intercepts method invocations on the delegate and passes them through the provided aspect. Note that the advice
+     * <em>must</em> be thread-safe.
+     *
+     * @param serviceInterface defines the interface of the interceptor and delegate
+     * @param delegate         the object on which methods will be invoked
+     * @param advice           intercepts the method invocations on the delegate
+     * @param description      used as the toString() of the returned interceptor, unless toString() is part of the
+     *                         service interface
+     * @return the interceptor, wrapping the delegate with all the advice
+     */
+    <T> T build(Class<T> serviceInterface, T delegate, MethodAdvice advice, String description);
+
+    /**
+     * Creates a builder that can be used to create the interceptor.  This is used when only some of the methods need to
+     * be advised, or when different methods need to recieve different advice.
+     *
+     * @param serviceInterface defines the interface of the interceptor and the delegate
+     * @param delegate         the object on which methods will be invokes
+     * @param description      used as the toString() of the interceptor unless toString() is part of the service
+     *                         interface
+     * @return a builder that can be used to generate the final interceptor
+     */
+    <T> AspectInterceptorBuilder<T> createBuilder(Class<T> serviceInterface, T delegate, String description);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectInterceptorBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectInterceptorBuilder.java
new file mode 100644
index 0000000..203fc07
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/AspectInterceptorBuilder.java
@@ -0,0 +1,42 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.MethodAdvice;
+
+import java.lang.reflect.Method;
+
+/**
+ * A builder may be obtained from the {@link org.apache.tapestry.ioc.services.AspectDecorator} and allows more
+ * controlled creation of the created interceptor; it allows different methods to be given different advice, and allows
+ * methods to be omitted (in which case the method invocation passes through without advice).
+ */
+public interface AspectInterceptorBuilder<T>
+{
+    /**
+     * Adds advice for a specific method of the aspect interceptor being constructed.
+     *
+     * @param method method (of the interface for which an interceptor is being constructed) to be adviced. A method may
+     *               only be advised <em>once</em> (for a single interceptor; it is valid to chain together a series of
+     *               interceptors).
+     * @param advice the advice for this particular method.   Advice must be threadsafe.
+     */
+    void adviseMethod(Method method, MethodAdvice advice);
+
+    /**
+     * Builds and returns the interceptor.  Any methods that have not been advised will become "pass thrus".
+     */
+    T build();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java
new file mode 100644
index 0000000..a4a17e1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Builtin.java
@@ -0,0 +1,37 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Marks services provided by this module that may need to be unambiguously referenced.
+ * Injecting with this marker annotation and the correct type ensure that the version defined in
+ * this module is used, even if another module provides a service with the same service
+ * interface.
+ */
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface Builtin
+{
+
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java
new file mode 100644
index 0000000..8876a37
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ChainBuilder.java
@@ -0,0 +1,43 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import java.util.List;

+

+/**

+ * A service which can assemble an implementation based on a command interface, and an ordered list

+ * of objects implementing that interface (the "commands"). This is an implementation of the Gang of

+ * Four Chain Of Command pattern.

+ * <p/>

+ * For each method in the interface, the chain implementation will call the corresponding method on

+ * each command object in turn (with the order defined by the list). If any of the command objects

+ * return true, then the chain of command stops and the initial method invocation returns true.

+ * Otherwise, the chain of command continues to the next command (and will return false if none of

+ * the commands returns true).

+ * <p/>

+ * For methods whose return type is not boolean, the chain stops with the first non-null (for object

+ * types), or non-zero (for numeric types). The chain returns the value that was returned by the

+ * command. If the method return type is void, all commands will be invoked.

+ * <p/>

+ * Method invocations will also be terminated if an exception is thrown.

+ */

+public interface ChainBuilder

+{

+    /**

+     * Creates a chain instance from a command interface and a list of commands (implementing the

+     * interface).

+     */

+    <T> T build(Class<T> commandInterface, List<T> commands);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java
new file mode 100644
index 0000000..7594791
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFab.java
@@ -0,0 +1,116 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+/**
+ * Used when fabricating a new class. Represents a wrapper around the Javassist library.
+ * <p/>
+ * The core concept of Javassist is how method bodies (as well as constructor bodies, etc.) are
+ * specified ... as a very Java-like scripting language. Details are available at the <a
+ * href="http://jboss.org/products/javassist">Javassist home page</a>.
+ * <p/>
+ * Method bodies look largely like Java. References to java classes must be fully qualified. Several
+ * special variables are used:
+ * <ul>
+ * <li><code>$0</code> first parameter, equivalent to <code>this</code> in Java code (and can't
+ * be used when creating a static method)
+ * <li><code>$1, $2, ...</code> actual parameters to the method
+ * <li><code>$args</code> all the parameters as an <code>Object[]</code>
+ * <li><code>$r</code> the return type of the method, typically used as
+ * <code>return ($r) ...</code>. <code>$r</code> is valid with method that return
+ * <code>void</code>. This also handles conversions between wrapper types and primitive types.
+ * <li><code>$w</code> conversion from primitive type to wrapper type, used as
+ * <code>($w) foo()</code> where <code>foo()</code> returns a primitive type and a wrapper type
+ * is needed
+ * <li>
+ * </ul>
+ * <p/>
+ * ClassFab instances are not thread safe.
+ * <p/>
+ * ClassFab instances are created by a {@link org.apache.tapestry.ioc.services.ClassFactory}.
+ */
+public interface ClassFab
+{
+    /**
+     * Adds the specified interface as an interface implemented by this class. It is not an error to
+     * invoke this method multiple times with the same interface class (and the interface is only
+     * added once).
+     */
+    void addInterface(Class interfaceClass);
+
+    /**
+     * Adds a new field with the given name and type. The field is added as a private field.
+     */
+    void addField(String name, Class type);
+
+    /**
+     * Adds a new field with the provided modifiers.
+     */
+    void addField(String name, int modifiers, Class Type);
+
+    /**
+     * Adds a method. The method is a public instance method.
+     *
+     * @param modifiers Modifiers for the method (see {@link java.lang.reflect.Modifier}).
+     * @param signature defines the name, return type, parameters and exceptions thrown
+     * @param body      The body of the method.
+     * @return a method fabricator, used to add catch handlers.
+     * @throws RuntimeException if a method with that signature has already been added, or if there is a
+     *                          Javassist compilation error
+     */
+    void addMethod(int modifiers, MethodSignature signature, String body);
+
+    /**
+     * Adds a constructor to the class. The constructor will be public.
+     *
+     * @param parameterTypes the type of each parameter, or null if the constructor takes no parameters.
+     * @param exceptions     the type of each exception, or null if the constructor throws no exceptions.
+     * @param body           The body of the constructor.
+     */
+    void addConstructor(Class[] parameterTypes, Class[] exceptions, String body);
+
+    /**
+     * Adds an implementation of toString, as a method that returns a fixed string.
+     */
+    void addToString(String toString);
+
+    /**
+     * Makes the fabricated class implement the provided service interface. The interface will be
+     * added, and all methods in the interface will be delegate wrappers. If toString() is not part
+     * of the delegate interface, then an implementation will be supplied that returns the provided
+     * string. This method is used when creating objects that proxy their behavior to some other
+     * object.
+     *
+     * @param serviceInterface   the interface to implement
+     * @param delegateExpression the expression used to find the delegate on which methods should be invoked.
+     *                           Typically a field name, such as "_delegate", or a method to invoke, such as
+     *                           "_service()".
+     * @param toString           fixed value to be returned as the description of the resultant object
+     */
+    void proxyMethodsToDelegate(Class serviceInterface, String delegateExpression, String toString);
+
+    /**
+     * Invoked last to create the class. This will enforce that all abstract methods have been
+     * implemented in the (concrete) class.
+     */
+    Class createClass();
+
+    /**
+     * Adds a public no-op method. The method will return null, false, or zero as per the return
+     * type (if not void).
+     */
+
+    void addNoOpMethod(MethodSignature signature);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFabUtils.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFabUtils.java
new file mode 100644
index 0000000..5d353bc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFabUtils.java
@@ -0,0 +1,271 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+
+import static java.lang.String.format;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Handy method useful when creating new classes using {@link org.apache.tapestry.ioc.services.ClassFab}.
+ */
+public final class ClassFabUtils
+{
+    private static final AtomicLong UID_GENERATOR = new AtomicLong(System.currentTimeMillis());
+
+    private static String nextUID()
+    {
+        return Long.toHexString(UID_GENERATOR.getAndIncrement());
+    }
+
+    /**
+     * Generates a unique class name, which will be in the default package.
+     */
+    public static synchronized String generateClassName(String baseName)
+    {
+        return "$" + baseName + "_" + nextUID();
+    }
+
+    /**
+     * Returns a class name derived from the provided interfaceClass. The package part of the interface name is stripped
+     * out, and the result passed to {@link #generateClassName(String)}.
+     */
+    public static String generateClassName(Class interfaceClass)
+    {
+        return generateClassName(interfaceClass.getSimpleName());
+    }
+
+    /**
+     * Javassist needs the class name to be as it appears in source code, even for arrays. Invoking getName() on a Class
+     * instance representing an array returns the internal format (i.e, "[...;" or something). This returns it as it
+     * would appear in Java code.
+     */
+    public static String toJavaClassName(Class inputClass)
+    {
+        if (inputClass.isArray()) return toJavaClassName(inputClass.getComponentType()) + "[]";
+
+        return inputClass.getName();
+    }
+
+    /**
+     * Returns true if the method is the standard toString() method. Very few interfaces will ever include this method
+     * as part of the interface, but we have to be sure.
+     */
+    public static boolean isToString(Method method)
+    {
+        if (!method.getName().equals("toString")) return false;
+
+        if (method.getParameterTypes().length > 0) return false;
+
+        return method.getReturnType().equals(String.class);
+    }
+
+    public static Class getPrimitiveType(String primitiveTypeName)
+    {
+        return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(primitiveTypeName).primitiveType;
+    }
+
+    private static class PrimitiveInfo
+    {
+        private final Class primitiveType;
+
+        private final String typeCode;
+
+        private final Class wrapperType;
+
+        private final String unwrapMethod;
+
+        public PrimitiveInfo(Class primitiveType, String typeCode, Class wrapperType, String unwrapMethod)
+        {
+            this.primitiveType = primitiveType;
+            this.typeCode = typeCode;
+            this.wrapperType = wrapperType;
+            this.unwrapMethod = unwrapMethod;
+        }
+    }
+
+    private static final Map<String, PrimitiveInfo> PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO = newMap();
+    private static final Map<Class, PrimitiveInfo> WRAPPER_TYPE_TO_PRIMITIVE_INFO = newMap();
+
+    static
+    {
+        add(boolean.class, "Z", Boolean.class, "booleanValue");
+        add(short.class, "S", Short.class, "shortValue");
+        add(int.class, "I", Integer.class, "intValue");
+        add(long.class, "J", Long.class, "longValue");
+        add(float.class, "F", Float.class, "floatValue");
+        add(double.class, "D", Double.class, "doubleValue");
+        add(char.class, "C", Character.class, "charValue");
+        add(byte.class, "B", Byte.class, "byteValue");
+    }
+
+    private static void add(Class primitiveType, String typeCode, Class wrapperType, String unwrapMethod)
+    {
+        PrimitiveInfo info = new PrimitiveInfo(primitiveType, typeCode, wrapperType, unwrapMethod);
+
+        PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.put(primitiveType.getName(), info);
+
+        WRAPPER_TYPE_TO_PRIMITIVE_INFO.put(wrapperType, info);
+    }
+
+    /**
+     * Translates types from standard Java format to Java VM format. For example, java.util.Locale remains
+     * java.util.Locale, but int[][] is translated to [[I and java.lang.Object[] to [Ljava.lang.Object;
+     */
+    public static String toJVMBinaryName(String type)
+    {
+        // if it is not an array, just return the type itself
+        if (!type.endsWith("[]")) return type;
+
+        // if it is an array, convert it to JavaVM-style format
+        StringBuilder buffer = new StringBuilder();
+
+        while (type.endsWith("[]"))
+        {
+            buffer.append("[");
+            type = type.substring(0, type.length() - 2);
+        }
+
+        PrimitiveInfo pi = PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(type);
+
+        if (pi != null)
+        {
+            buffer.append(pi.typeCode);
+        }
+        else
+        {
+            buffer.append("L");
+            buffer.append(type);
+            buffer.append(";");
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Given a wrapper type, determines the corresponding primitive type.
+     */
+    public static Class getPrimitiveType(Class wrapperType)
+    {
+        return WRAPPER_TYPE_TO_PRIMITIVE_INFO.get(wrapperType).primitiveType;
+    }
+
+    /**
+     * Returns the wrapper type for an input type; for most types, this is the type.  For primitive types, it is the
+     * corresponding wrapper type.
+     *
+     * @param type type to check
+     * @return type or corresponding wrapper type
+     */
+    public static Class getWrapperType(Class type)
+    {
+        PrimitiveInfo info = PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(type.getName());
+
+        return info == null ? type : info.wrapperType;
+    }
+
+    /**
+     * Takes a reference and casts it to the desired type.  If the desired type is a primitive type, then the reference
+     * is cast to the correct wrapper type and a call to the correct unwrapper method is added. The end result is code
+     * that can be assigned to a field or parameter of the desired type (even if desired type is a primitive).
+     *
+     * @param reference   to be cast
+     * @param desiredType desired object or primitive type
+     * @return Javassist code to peform the cast
+     */
+    public static String castReference(String reference, String desiredType)
+    {
+        if (isPrimitiveType(desiredType))
+        {
+            PrimitiveInfo info = PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(desiredType);
+
+            return String.format("((%s)%s).%s()",
+                                 info.wrapperType.getName(), reference,
+                                 info.unwrapMethod);
+        }
+
+        return String.format("(%s)%s", desiredType, reference);
+    }
+
+
+    /**
+     * Given a type name, determines if that is the name of a primitive type.
+     */
+    public static boolean isPrimitiveType(String typeName)
+    {
+        return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.containsKey(typeName);
+    }
+
+    /**
+     * Converts a Class to a JVM type code (the way class information is expressed in a class file).
+     */
+    public static String getTypeCode(Class type)
+    {
+        if (type.equals(void.class)) return "V";
+
+        if (type.isPrimitive()) return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(type.getName()).typeCode;
+
+        if (type.isArray()) return "[" + getTypeCode(type.getComponentType());
+
+        return "L" + type.getName().replace('.', '/') + ";";
+    }
+
+    /**
+     * Creates a proxy for a given service interface around an {@link org.apache.tapestry.ioc.ObjectCreator} that can
+     * provide (on demand) an object (implementing the service interface) to delegate to. The ObjectCreator will be
+     * invoked on every method invocation (if it is caching, that should be internal to its implementation).
+     *
+     * @param <T>
+     * @param classFab         used to create the new class
+     * @param serviceInterface the interface the proxy will implement
+     * @param creator          the createor which will provide an instance of the interface
+     * @param description      description to be returned from the proxy's toString() method
+     * @return the instantiated proxy object
+     */
+    public static <T> T createObjectCreatorProxy(ClassFab classFab, Class<T> serviceInterface, ObjectCreator creator,
+                                                 String description)
+    {
+        classFab.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
+
+        classFab.addConstructor(new Class[] { ObjectCreator.class }, null, "_creator = $1;");
+
+        String body = format("return (%s) _creator.createObject();", serviceInterface.getName());
+
+        MethodSignature sig = new MethodSignature(serviceInterface, "_delegate", null, null);
+
+        classFab.addMethod(Modifier.PRIVATE, sig, body);
+
+        classFab.proxyMethodsToDelegate(serviceInterface, "_delegate()", description);
+        Class proxyClass = classFab.createClass();
+
+        try
+        {
+            Object proxy = proxyClass.getConstructors()[0].newInstance(creator);
+
+            return serviceInterface.cast(proxy);
+        }
+        catch (Exception ex)
+        {
+            // This should never happen, so we won't go to a lot of trouble
+            // reporting it.
+            throw new RuntimeException(ex.getMessage(), ex);
+        }
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java
new file mode 100644
index 0000000..96ae66f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java
@@ -0,0 +1,86 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.Location;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * Service used when dynamically creating new classes.
+ */
+public interface ClassFactory
+{
+    /**
+     * Simplified version of {@link #newClass(String, Class)} that generates a name based on the
+     * service interface name, extends from java.lang.Object, and automatically adds the
+     * serviceInterface to the returned ClassFab. This is the most common use when creating the
+     * kinds of proxies used throughout Tapestry IoC.
+     *
+     * @param serviceInterface
+     */
+    ClassFab newClass(Class serviceInterface);
+
+    /**
+     * Creates a {@link ClassFab} object for the given name; the new class is a subclass of the
+     * indicated class. The new class is always public and concrete.
+     *
+     * @param name       the full qualified name of the class to create (note that it is common to place
+     *                   created classes in the default package)
+     * @param superClass the parent class, which is often java.lang.Object
+     */
+
+    ClassFab newClass(String name, Class superClass);
+
+    /**
+     * Imports the class to make it referenceable within the factory. The class loader for the class
+     * is added to the class path. The class itself is returned, if its bytecode is available. If
+     * not, a search up the inhertance occurs until a proper class (that can be referenced in
+     * generated bytecode) is found. This is necessary to handle cases where a class is generated at
+     * runtime, outside of the class factory, and bytecode is not available for it.
+     *
+     * @param clazz
+     * @return a referencable super-class
+     */
+    Class importClass(Class clazz);
+
+    /**
+     * Returns the number of classes (and interfaces) actually created.
+     */
+
+    int getCreatedClassCount();
+
+    /**
+     * Returns the class loader used when creating new classes; this is generally the same as the
+     * current thread's context class loader (except perhaps during testing).
+     */
+    ClassLoader getClassLoader();
+
+    /**
+     * Converts a method to a {@link Location}, which includes information about the source
+     * file name and line number.
+     *
+     * @param method to look up
+     * @return the location, or null if the necessary information is not available
+     */
+    Location getMethodLocation(Method method);
+
+    /**
+     * Return a string representation fo the constructor (including class and parameters) and (if
+     * available) file name and line number.
+     */
+    Location getConstructorLocation(Constructor constructor);
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassNameLocator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassNameLocator.java
new file mode 100644
index 0000000..e761fa9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassNameLocator.java
@@ -0,0 +1,33 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.util.Collection;
+
+/**
+ * Scans the classpath for top-level classes within particular packages.
+ */
+public interface ClassNameLocator
+{
+    /**
+     * Searches for all classes under the given package name. This consists of all top-level classes in the indicated
+     * package (or any sub-package), but excludes inner classes. No other filtering (beyond inner classes) occurs, so
+     * there's no guarantee that the class names returned are public (for example).
+     *
+     * @param packageName
+     * @return fully qualified class names
+     */
+    Collection<String> locateClassNames(String packageName);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassPropertyAdapter.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassPropertyAdapter.java
new file mode 100644
index 0000000..4ebc52c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ClassPropertyAdapter.java
@@ -0,0 +1,64 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.util.List;
+
+/**
+ * Organizes all {@link org.apache.tapestry.ioc.services.PropertyAdapter}s for a particular class.
+ * <p/>
+ * Only provides access to <em>simple</em> properties. Indexed properties are ignored.
+ * <p/>
+ * When accessing properties by name, the case of the name is ignored.
+ */
+public interface ClassPropertyAdapter
+{
+    /**
+     * Returns the names of all properties, sorted into alphabetic order.
+     */
+    List<String> getPropertyNames();
+
+    /**
+     * Returns the type of bean this adapter provides properties for.
+     */
+    Class getBeanType();
+
+    /**
+     * Returns the property adapter with the given name, or null if no such adapter exists.
+     *
+     * @param name of the property (case is ignored)
+     */
+    PropertyAdapter getPropertyAdapter(String name);
+
+    /**
+     * Reads the value of a property.
+     *
+     * @param instance     the object to read a value from
+     * @param propertyName the name of the property to read (case is ignored)
+     * @throws UnsupportedOperationException if the property is write only
+     * @throws IllegalArgumentException      if property does not exist
+     */
+    Object get(Object instance, String propertyName);
+
+    /**
+     * Updates the value of a property.
+     *
+     * @param instance     the object to update
+     * @param propertyName the name of the property to update (case is ignored)
+     * @throws UnsupportedOperationException if the property is read only
+     * @throws IllegalArgumentException      if property does not exist
+     */
+    void set(Object instance, String propertyName, Object value);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Coercion.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Coercion.java
new file mode 100644
index 0000000..35cb4dc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Coercion.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Responsible for converting from one type to another. This is used primarily around component

+ * parameters.

+ *

+ * @param <S>

+ * the source type (input)

+ * @param <T>

+ * the target type (output)

+ */

+public interface Coercion<S, T>

+{

+    /**

+     * Converts an input value.

+     *

+     * @param input the input value

+     */

+    T coerce(S input);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java
new file mode 100644
index 0000000..302d871
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/CoercionTuple.java
@@ -0,0 +1,126 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
+/**
+ * An immutable object that represents a mapping from one type to another. This is also the contribution type when
+ * building the {@link org.apache.tapestry.ioc.services.TypeCoercer} service. Wraps a {@link
+ * org.apache.tapestry.ioc.services.Coercion} object that performs the work with additional properties that describe the
+ * input and output types of the coercion, needed when searching for an appropriate coercion (or sequence of
+ * coercions).
+ *
+ * @param <S> source (input) type
+ * @param <T> target (output) type
+ */
+public final class CoercionTuple<S, T>
+{
+    private final Class<S> sourceType;
+
+    private final Class<T> targetType;
+
+    private final Coercion<S, T> coercion;
+
+    /**
+     * Wraps an arbitrary coercion with an implementation of toString() that identifies the source and target types.
+     */
+    private class CoercionWrapper<WS, WT> implements Coercion<WS, WT>
+    {
+        private final Coercion<WS, WT> coercion;
+
+        public CoercionWrapper(Coercion<WS, WT> coercion)
+        {
+            this.coercion = coercion;
+        }
+
+        public WT coerce(WS input)
+        {
+            return coercion.coerce(input);
+        }
+
+        @Override
+        public String toString()
+        {
+            return String.format("%s --> %s", convert(sourceType), convert(targetType));
+        }
+    }
+
+    private String convert(Class type)
+    {
+        if (void.class.equals(type)) return "null";
+
+        String name = ClassFabUtils.toJavaClassName(type);
+
+        int dotx = name.lastIndexOf('.');
+
+        // Strip off a package name of "java.lang"
+
+        if (dotx > 0 && name.substring(0, dotx).equals("java.lang"))
+            return name.substring(dotx + 1);
+
+        return name;
+    }
+
+    /**
+     * Standard constructor, which defaults wrap to true.
+     */
+    public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion)
+    {
+        this(sourceType, targetType, coercion, true);
+    }
+
+    /**
+     * Internal-use constructor.
+     *
+     * @param sourceType the source (or input) type of the coercion
+     * @param targetType the target (or output) type of the coercion
+     * @param coercion   the object that performs the coercion
+     * @param wrap       if true, the coercion is wrapped to provide a useful toString()
+     */
+    public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> coercion,
+                         boolean wrap)
+    {
+        notNull(sourceType, "sourceType");
+        notNull(targetType, "targetType");
+        notNull(coercion, "coercion");
+
+        this.sourceType = sourceType;
+        this.targetType = targetType;
+        this.coercion = wrap ? new CoercionWrapper<S, T>(coercion) : coercion;
+    }
+
+    @Override
+    public String toString()
+    {
+        return coercion.toString();
+    }
+
+    public Coercion<S, T> getCoercion()
+    {
+        return coercion;
+    }
+
+    public Class<S> getSourceType()
+    {
+        return sourceType;
+    }
+
+    public Class<T> getTargetType()
+    {
+        return targetType;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/DefaultImplementationBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/DefaultImplementationBuilder.java
new file mode 100644
index 0000000..7641efd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/DefaultImplementationBuilder.java
@@ -0,0 +1,34 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Creates default implementatons of a class.

+ *

+ * @see org.apache.tapestry.ioc.services.ClassFab#addNoOpMethod(MethodSignature)

+ */

+public interface DefaultImplementationBuilder

+{

+    /**

+     * Creates a new implementation of the provided interface. Each method in the interface will be

+     * implemented as a noop method. The method will ignore any parameters and return null, or 0, or

+     * false (or return nothing if the method is void).

+     *

+     * @param <S>

+     * @param serviceInterface

+     * @return

+     */

+    <S> S createDefaultImplementation(Class<S> serviceInterface);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java
new file mode 100644
index 0000000..e62764f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalysis.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import java.util.List;

+

+/**

+ * An analysis of an exception (including nested exceptions).

+ * <p/>

+ * TODO: Make serializable and/or convert to XML format.

+ */

+public interface ExceptionAnalysis

+{

+    /**

+     * Returns the analyzed exception info for each exception. The are ordered outermost exception

+     * to innermost.

+     */

+    List<ExceptionInfo> getExceptionInfos();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalyzer.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalyzer.java
new file mode 100644
index 0000000..762d962
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionAnalyzer.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Analyzes an exception, providing an analysis. The analysis easily exposes properties of the

+ * exception, the stack trace, and nested exceptions.

+ */

+public interface ExceptionAnalyzer

+{

+    ExceptionAnalysis analyze(Throwable rootException);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java
new file mode 100644
index 0000000..b9197c6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionInfo.java
@@ -0,0 +1,51 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.services;

+

+import java.util.List;

+

+/**

+ * Contains information about an analyzed exception.

+ *

+ * @see {@link org.apache.tapestry.ioc.services.ExceptionAnalysis}

+ */

+public interface ExceptionInfo

+{

+    /**

+     * The exception class name.

+     */

+    String getClassName();

+

+    /**

+     * The message associated with the exception, possibly null.

+     */

+    String getMessage();

+

+    /**

+     * Returns the names of the properties of the exception, sorted alphabetically.

+     */

+    List<String> getPropertyNames();

+

+    /**

+     * Returns a specific property of the exception by name.

+     */

+    Object getProperty(String name);

+

+    /**

+     * Returns the stack trace elements. Generally this is an empty list except for the deepest

+     * exception.

+     */

+    List<StackTraceElement> getStackTrace();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionTracker.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionTracker.java
new file mode 100644
index 0000000..db42c8c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ExceptionTracker.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.services.LoggingDecorator} to track which exceptions have

+ * been logged during the current request (the ExceptionTracker is perthread). This keeps redundant

+ * information from appearing in the console output.

+ */

+public interface ExceptionTracker

+{

+    /**

+     * Returns true if the indicated exception has already been logged (it is assumed that the

+     * exception will be logged if this method returns false). The exception is recorded for later

+     * checks.

+     *

+     * @param exception to check

+     * @return false if the exception has not been previously checked, true otherwise

+     */

+    boolean exceptionLogged(Throwable exception);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/FactoryDefaults.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/FactoryDefaults.java
new file mode 100644
index 0000000..9b63a15
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/FactoryDefaults.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Used to disambiguate which version of {@link SymbolProvider} is being referenced. Symbols defined
+ * by contributing to FactoryDefaults are overridden by contributions to {@link ApplicationDefaults}.
+ */
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface FactoryDefaults
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/LoggingDecorator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/LoggingDecorator.java
new file mode 100644
index 0000000..1b765f5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/LoggingDecorator.java
@@ -0,0 +1,38 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.slf4j.Logger;

+

+/**

+ * Service that can create a logging interceptor that wraps around a service implementation (or

+ * interceptor). The interceptor works with the service's log to log, at debug level, method entry

+ * (with arguments), method exit (with return value, if any) as well as any thrown exceptions.

+ */

+public interface LoggingDecorator

+{

+    /**

+     * Builds a logging interceptor instance.

+     *

+     * @param <T>

+     * @param serviceInterface interface implemented by the delegate

+     * @param delegate         existing object to be wrapped

+     * @param serviceId        id of service

+     * @param logger           log used for debug level logging messages by the interceptor

+     * @return a new object implementing the interface that can be used in place of the delegate,

+     *         providing logging behavior around each method call on the service interface

+     */

+    <T> T build(Class<T> serviceInterface, T delegate, String serviceId, Logger logger);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MasterObjectProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MasterObjectProvider.java
new file mode 100644
index 0000000..a04e9fa
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MasterObjectProvider.java
@@ -0,0 +1,51 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+
+/**
+ * Rolls up a number of {@link ObjectProvider}, but allows for the case where no object may be
+ * provided.
+ */
+public interface MasterObjectProvider
+{
+    /**
+     * Provides an object based on an expression. The process of providing objects occurs within a
+     * particular <em>context</em>, which will typically be a service builder method, service
+     * contributor method, or service decorator method. The locator parameter provides access to the
+     * services visible <em>to that context</em>.
+     * <p/>
+     * When the value is required and no {@link ObjectProvider} provided a non-null value, then
+     * {@link ObjectLocator#getService(Class)} is invoked, to provide a uniquely matching service,
+     * or throw a failure exception if no <em>single</em> service can be found.
+     *
+     * @param objectType         the expected object type
+     * @param annotationProvider provides access to annotations (typically, the field or parameter to which an
+     *                           injection-related annotation is attached); annotations on the field or parameter
+     *                           may also be used when resolving the desired object
+     * @param locator            locator for the <em>context</em> in which the provider is being used
+     * @param required           if true (normal case) a value must be provided; if false then it is allowed for no
+     *                           ObjectProvider to provide a value, and this method may return null to indicate the
+     *                           failure
+     * @param <T>
+     * @return the requested object, or null if this object provider can not supply an object
+     * @throws RuntimeException if the expression can not be evaluated, or the type of object identified is not
+     *                          assignable to the type specified by the objectType parameter
+     */
+    <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator, boolean required);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodIterator.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodIterator.java
new file mode 100644
index 0000000..b5baafa
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodIterator.java
@@ -0,0 +1,105 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Utility used to iterate over the publically visible methods of a class or interface. The MethodIterator understands
+ * some complications that can occur when a class inherits the same method from multiple interfaces and with slightly
+ * different signatures (due to the fact that declared thrown exceptions can vary slightly for the "same" method).
+ *
+ * @see org.apache.tapestry.ioc.services.MethodSignature#isOverridingSignatureOf(MethodSignature)
+ */
+public class MethodIterator
+{
+    private boolean toString;
+
+    private int index = 0;
+
+    private final int count;
+
+    private final List<MethodSignature> signatures;
+
+    private static final Comparator<MethodSignature> COMPARATOR = new Comparator<MethodSignature>()
+    {
+        public int compare(MethodSignature o1, MethodSignature o2)
+        {
+
+            return o1.getName().compareTo(o2.getName());
+        }
+    };
+
+
+    public MethodIterator(Class subjectClass)
+    {
+        Method[] methods = subjectClass.getMethods();
+
+        Map<String, MethodSignature> map = newMap();
+
+        for (int i = 0; i < methods.length; i++)
+            processMethod(methods[i], map);
+
+        signatures = newList(map.values());
+        count = signatures.size();
+
+
+        Collections.sort(signatures, COMPARATOR);
+    }
+
+    private void processMethod(Method m, Map<String, MethodSignature> map)
+    {
+        toString |= ClassFabUtils.isToString(m);
+
+        MethodSignature sig = new MethodSignature(m);
+        String uid = sig.getUniqueId();
+
+        MethodSignature existing = map.get(uid);
+
+        if (existing == null || sig.isOverridingSignatureOf(existing)) map.put(uid, sig);
+    }
+
+    public boolean hasNext()
+    {
+        return index < count;
+    }
+
+    /**
+     * Returns the next method (as a {@link MethodSignature}, returning null when all are exhausted. Each method
+     * signature is returned exactly once (even if the same method signature is defined in multiple inherited classes or
+     * interfaces). The method signatures returned in ascending order, according to the "natural ordering".
+     *
+     * @throws NoSuchElementException if there are no more signatures
+     */
+    public MethodSignature next()
+    {
+        if (index >= count) throw new NoSuchElementException();
+
+        return signatures.get(index++);
+    }
+
+    /**
+     * Returns true if the method <code>public String toString()</code> is part of the interface. This will be known
+     * immediately after iterator contruction (it is not necessary to iterate the methods first).
+     */
+    public boolean getToString()
+    {
+        return toString;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodSignature.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodSignature.java
new file mode 100644
index 0000000..614f1e6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/MethodSignature.java
@@ -0,0 +1,273 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+import static org.apache.tapestry.ioc.internal.util.InternalUtils.size;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * A representation of a {@link java.lang.reflect.Method}, identifying the name, return type, parameter types and
+ * exception types. Actual Method objects are tied to a particular class, and don't compare well with other otherwise
+ * identical Methods from other classes or interface; MethodSignatures are distinct from classes and compare well.
+ * <p/>
+ * Because the intended purpose is to compare methods from interfaces (which are always public and abstract) we don't
+ * bother to actually track the modifiers. In addition, at this time, MethodSignature <em>does not distinguish between
+ * instance and static methods</em>.
+ * <p/>
+ * This version of MethodSignature works with <em>loaded</em> classes, and it usually used in the context of {@link
+ * org.apache.tapestry.ioc.services.ClassFab} to create new classes and subclasses.
+ */
+public class MethodSignature
+{
+    private int hashCode = -1;
+
+    private final Class returnType;
+
+    private final String name;
+
+    private final Class[] parameterTypes;
+
+    private final Class[] exceptionTypes;
+
+    public MethodSignature(Class returnType, String name, Class[] parameterTypes, Class[] exceptionTypes)
+    {
+        this.returnType = notNull(returnType, "returnType");
+        this.name = notBlank(name, "name");
+
+        // Can be null!
+        this.parameterTypes = parameterTypes;
+        this.exceptionTypes = exceptionTypes;
+    }
+
+    public MethodSignature(Method m)
+    {
+        this(m.getReturnType(), m.getName(), m.getParameterTypes(), m.getExceptionTypes());
+    }
+
+    /**
+     * Returns the exceptions for this method. Caution: do not modify the returned array. May return null.
+     */
+    public Class[] getExceptionTypes()
+    {
+        return exceptionTypes;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Returns the parameter types for this method. May return null. Caution: do not modify the returned array.
+     */
+    public Class[] getParameterTypes()
+    {
+        return parameterTypes;
+    }
+
+    public Class getReturnType()
+    {
+        return returnType;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        if (hashCode == -1)
+        {
+
+            hashCode = returnType.hashCode();
+
+            hashCode = 31 * hashCode + name.hashCode();
+
+            int count = size(parameterTypes);
+
+            for (int i = 0; i < count; i++)
+                hashCode = 31 * hashCode + parameterTypes[i].hashCode();
+
+            count = size(exceptionTypes);
+
+            for (int i = 0; i < count; i++)
+                hashCode = 31 * hashCode + exceptionTypes[i].hashCode();
+        }
+
+        return hashCode;
+    }
+
+    /**
+     * Returns true if the other object is an instance of MethodSignature with <em>identical</em> values for return
+     * type, name, parameter types and exception types.
+     *
+     * @see #isOverridingSignatureOf(MethodSignature)
+     */
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o == null || !(o instanceof MethodSignature)) return false;
+
+        MethodSignature ms = (MethodSignature) o;
+
+        if (returnType != ms.returnType) return false;
+
+        if (!name.equals(ms.name)) return false;
+
+        if (mismatch(parameterTypes, ms.parameterTypes)) return false;
+
+        return !mismatch(exceptionTypes, ms.exceptionTypes);
+    }
+
+    private boolean mismatch(Class[] a1, Class[] a2)
+    {
+        int a1Count = size(a1);
+        int a2Count = size(a2);
+
+        if (a1Count != a2Count) return true;
+
+        // Hm. What if order is important (for exceptions)? We're really saying here that they
+        // were derived from the name Method.
+
+        for (int i = 0; i < a1Count; i++)
+        {
+            if (a1[i] != a2[i]) return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(ClassFabUtils.toJavaClassName(returnType));
+        buffer.append(" ");
+        buffer.append(name);
+        buffer.append("(");
+
+        for (int i = 0; i < size(parameterTypes); i++)
+        {
+            if (i > 0) buffer.append(", ");
+
+            buffer.append(ClassFabUtils.toJavaClassName(parameterTypes[i]));
+        }
+
+        buffer.append(")");
+
+        int _exceptionCount = size(exceptionTypes);
+        String _exceptionNames[] = new String[_exceptionCount];
+        for (int i = 0; i < _exceptionCount; i++)
+        {
+            _exceptionNames[i] = exceptionTypes[i].getName();
+        }
+
+        Arrays.sort(_exceptionNames);
+
+        for (int i = 0; i < _exceptionCount; i++)
+        {
+            if (i == 0) buffer.append(" throws ");
+            else buffer.append(", ");
+
+            buffer.append(_exceptionNames[i]);
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a string consisting of the name of the method and its parameter values. This is similar to {@link
+     * #toString()}, but omits the return type and information about thrown exceptions. A unique id is used by {@link
+     * MethodIterator} to identify overlapping methods (methods with the same name and parameter types but with
+     * different thrown exceptions).
+     *
+     * @see #isOverridingSignatureOf(MethodSignature)
+     */
+    public String getUniqueId()
+    {
+        StringBuilder buffer = new StringBuilder(name);
+        buffer.append("(");
+
+        for (int i = 0; i < size(parameterTypes); i++)
+        {
+            if (i > 0) buffer.append(",");
+
+            buffer.append(ClassFabUtils.toJavaClassName(parameterTypes[i]));
+        }
+
+        buffer.append(")");
+
+        return buffer.toString();
+    }
+
+    /**
+     * Returns true if this signature has the same return type, name and parameters types as the method signature passed
+     * in, and this signature's exceptions "trump" (are the same as, or super-implementations of, all exceptions thrown
+     * by the other method signature).
+     */
+
+    public boolean isOverridingSignatureOf(MethodSignature ms)
+    {
+        if (returnType != ms.returnType) return false;
+
+        if (!name.equals(ms.name)) return false;
+
+        if (mismatch(parameterTypes, ms.parameterTypes)) return false;
+
+        return exceptionsEncompass(ms.exceptionTypes);
+    }
+
+    /**
+     * The nuts and bolts of checking that another method signature's exceptions are a subset of this signature's.
+     */
+
+    @SuppressWarnings("unchecked")
+    private boolean exceptionsEncompass(Class[] otherExceptions)
+    {
+        int ourCount = size(exceptionTypes);
+        int otherCount = size(otherExceptions);
+
+        // If we have no exceptions, then ours encompass theirs only if they
+        // have no exceptions, either.
+
+        if (ourCount == 0) return otherCount == 0;
+
+        boolean[] matched = new boolean[otherCount];
+        int unmatched = otherCount;
+
+        for (int i = 0; i < ourCount && unmatched > 0; i++)
+        {
+            for (int j = 0; j < otherCount; j++)
+            {
+                // Ignore exceptions that have already been matched
+
+                if (matched[j]) continue;
+
+                // When one of our exceptions is a super-class of one of their exceptions,
+                // then their exceptions is matched.
+
+                if (exceptionTypes[i].isAssignableFrom(otherExceptions[j]))
+                {
+                    matched[j] = true;
+                    unmatched--;
+                }
+            }
+        }
+
+        return unmatched == 0;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PerthreadManager.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PerthreadManager.java
new file mode 100644
index 0000000..6978fe0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PerthreadManager.java
@@ -0,0 +1,58 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+/**
+ * Manages per-thread data, and provides a way for listeners to know when such data should be cleaned up.  Typically,
+ * data is cleaned up at the end of the request (in a web application).
+ * Tapestry IoC has any number of objects that need to know
+ * when this event occurs, so that they can clean up any per-thread/per-request state.
+ * <p/>
+ * Due to <a href="https://issues.apache.org/jira/browse/TAPESTRY-2141">TAPESTRY-2141<a> (and
+ * the underlying JDK 1.5 bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025230">5025230</a>),
+ * this service has expanded to manager per-thread data (not just end-of-request listeners).
+ */
+public interface PerthreadManager
+{
+    /**
+     * Adds a listener to the hub.  All listeners are discarded at the
+     * {@link #cleanup()}.
+     *
+     * @param listener to add
+     */
+    void addThreadCleanupListener(ThreadCleanupListener listener);
+
+    /**
+     * Immediately performs a cleanup of the thread, notifying all listeners then
+     * discarding the thread locale and the map it stores.
+     */
+    void cleanup();
+
+
+    /**
+     * Returns an object stored in the per-thread map.    When the object is a string,
+     * the expected name is <em>service id</em>.<em>subkey</em>.  Unlike most of Tapestry,
+     * such keys <em>will</em> be case sensitive.
+     *
+     * @param key key used to retrieve object
+     * @return corresponding per-thread object, or null
+     */
+    Object get(Object key);
+
+    /**
+     * Stores a value into the per-thread map.
+     */
+    void put(Object key, Object value);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PipelineBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PipelineBuilder.java
new file mode 100644
index 0000000..e4b4b98
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PipelineBuilder.java
@@ -0,0 +1,70 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.slf4j.Logger;

+

+import java.util.List;

+

+/**

+ * Creates a pipeline from a service inteface and an ordered list of filters. Each filter is defined

+ * in terms of a filter interface: the filter interface is a variant of the service interface, where

+ * each method has an additional parameter that is an instance of the service interface. Typically,

+ * this service parameter (often named "delegate") is either the first or the last parameter of each

+ * method.

+ * <p/>

+ * The implementation of a filter method is expected to pass all of its parameters to the service

+ * instance passed into it.

+ * <p/>

+ * The interesting thing is that there may be multiple filters in the pipeline. A fabricated

+ * "bridge" object (that implements the service interface) is created to let each filter invoke

+ * methods on the next filter down the pipeline. This simplifies the model for creating pipelines,

+ * as each filter is coded as if it was directly "in front of" the terminator. In fact, it may be

+ * indirectly invoking methods on the next filter in the pipeline via a bridge instance.

+ * <p/>

+ * The builder is fairly smart about matching up service interface methods to filter interface

+ * methods, but keeping it simple is also a good idea.

+ */

+public interface PipelineBuilder

+{

+    /**

+     * Creates a pipeline from the filters and a terminator.

+     *

+     * @param <S>              service type

+     * @param <F>              filter type

+     * @param logger           logs any warnings generated when constructing the pipeline

+     * @param serviceInterface

+     * @param filterInterface

+     * @param filters          sorted list of filters

+     * @param terminator       end of the pipeline

+     * @return an object that encapsulates the filters and the terminator

+     */

+    <S, F> S build(Logger logger, Class<S> serviceInterface, Class<F> filterInterface, List<F> filters, S terminator);

+

+    /**

+     * Creates a pipeline from just the filters. A

+     * {@link DefaultImplementationBuilder default implementation} is created as the terminator.

+     *

+     * @param <S>

+     * @param <F>

+     * @param logger

+     * @param serviceInterface

+     * @param filterInterface

+     * @param filters

+     * @return

+     */

+    <S, F> S build(Logger logger, Class<S> serviceInterface, Class<F> filterInterface, List<F> filters);

+

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java
new file mode 100644
index 0000000..3dee132
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAccess.java
@@ -0,0 +1,57 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+/**
+ * A wrapper around the JavaBean Introspector that allows more manageable access to JavaBean
+ * properties of objects.
+ * <p/>
+ * <p/>
+ * Only provides access to <em>simple</em> properties.  Indexed properties are ignored.
+ */
+public interface PropertyAccess
+{
+    /**
+     * Reads the value of a property.
+     *
+     * @throws UnsupportedOperationException if the property is write only
+     * @throws IllegalArgumentException      if property does not exist
+     */
+    Object get(Object instance, String propertyName);
+
+    /**
+     * Updates the value of a property.
+     *
+     * @throws UnsupportedOperationException if the property is read only
+     * @throws IllegalArgumentException      if property does not exist
+     */
+    void set(Object instance, String propertyName, Object value);
+
+    /**
+     * Returns the adapter for a particular object instance. A convienience over invoking
+     * {@link #getAdapter(Class)}.
+     */
+    ClassPropertyAdapter getAdapter(Object instance);
+
+    /**
+     * Returns the adapter used to access properties within the indicated class.
+     */
+    ClassPropertyAdapter getAdapter(Class forClass);
+
+    /**
+     * Discards all stored property access information, discarding all created class adapters.
+     */
+    void clearCache();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAdapter.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAdapter.java
new file mode 100644
index 0000000..c4608ef
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyAdapter.java
@@ -0,0 +1,83 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+
+import java.lang.reflect.Method;
+
+/**
+ * Provides access to a single property within a class. Acts as an {@link AnnotationProvider}; when searching for
+ * annotations, the read method (if present) is checked first, followed by the write method.
+ *
+ * @see org.apache.tapestry.ioc.services.ClassPropertyAdapter
+ */
+public interface PropertyAdapter extends AnnotationProvider
+{
+    /**
+     * Returns the name of the property.
+     */
+    String getName();
+
+    /**
+     * Returns true if the property is readable (i.e., has a getter method).
+     */
+    boolean isRead();
+
+    /**
+     * Returns the method used to read the property, or null if the property is not readable.
+     */
+    public Method getReadMethod();
+
+    /**
+     * Returns true if the property is writeable (i.e., has a setter method).
+     */
+    boolean isUpdate();
+
+    /**
+     * Returns the method used to update the property, or null if the property is not writeable.
+     */
+    public Method getWriteMethod();
+
+    /**
+     * Reads the property value.
+     *
+     * @param instance to read from
+     * @throws UnsupportedOperationException if the property is write only
+     */
+    Object get(Object instance);
+
+    /**
+     * Updates the property value. The provided value must not be null if the property type is primitive, and must
+     * otherwise be of the proper type.
+     *
+     * @param instance to update
+     * @param value    new value for the property
+     * @throws UnsupportedOperationException if the property is read only
+     */
+    void set(Object instance, Object value);
+
+    /**
+     * Returns the type of the property.
+     */
+    Class getType();
+
+    /**
+     * Returns true if the return type of the read method is not the same as the property type. This can occur when the
+     * property has been defined using generics, in which case, the method's type may be Object when the property type
+     * is something more specific. This method is primarily used when generating runtime code related to the property.
+     */
+    boolean isCastRequired();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyShadowBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyShadowBuilder.java
new file mode 100644
index 0000000..a553352
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/PropertyShadowBuilder.java
@@ -0,0 +1,38 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Creates a "shadow" of a property of an object. The shadow has the same type as the property, and

+ * delegates all method invocations to the property. Each method invocation on the shadow

+ * re-acquires the value of the property from the underlying object and delegates to the current

+ * value of the property.

+ * <p/>

+ * Typically, the object in question is another service, one with the "perthread" service lifecycle.

+ * This allows a global singleton to shadow a value that is specific to the current thread (and

+ * therefore, the current request).

+ */

+public interface PropertyShadowBuilder

+{

+    /**

+     * @param <T>

+     * @param source       the object from which a property will be extracted

+     * @param propertyName the name of a property of the object, which must be readable

+     * @param propertyType the expected type of the property, the actual property type must be assignable to

+     *                     this type

+     * @return the shadow

+     */

+    <T> T build(Object source, String propertyName, Class<T> propertyType);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownHub.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownHub.java
new file mode 100644
index 0000000..db6008e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownHub.java
@@ -0,0 +1,26 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+/**

+ * Event hub for notifications when the IOC {@link org.apache.tapestry.ioc.Registry} shuts down.

+ */

+public interface RegistryShutdownHub

+{

+    /**

+     * Adds a listener for eventual notification.

+     */

+    void addRegistryShutdownListener(RegistryShutdownListener listener);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java
new file mode 100644
index 0000000..68abb35
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/RegistryShutdownListener.java
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import java.util.EventListener;

+

+/**

+ * Event listener interfaces for objects that need to know when the Registry shutsdown.

+ */

+public interface RegistryShutdownListener extends EventListener

+{

+    /**

+     * Invoked when the registry shuts down, giving services a chance to perform any final

+     * operations. Service implementations should not attempt to invoke methods on other services

+     * (via proxies) as the service proxies may themselves be shutdown.

+     */

+    void registryDidShutdown();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java
new file mode 100644
index 0000000..1ac793c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java
@@ -0,0 +1,46 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * Provided by the {@link ServiceActivityScoreboard} to track a single service's state and activity.
+ *
+ * @see ServiceDef
+ */
+public interface ServiceActivity
+{
+    /**
+     * The unique id for the service.
+     */
+    String getServiceId();
+
+    /**
+     * The interface implemented by the service (this may occasionally be a class, for non-proxied
+     * services).
+     */
+    Class getServiceInterface();
+
+    /**
+     * The scope of the service (typically "singleton" or "perthread").
+     */
+    String getScope();
+
+    /**
+     * Indicates the lifecycle status of the service.
+     */
+    Status getStatus();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java
new file mode 100644
index 0000000..6bc3467
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import java.util.List;
+
+/**
+ * Provides access to the runtime details about services in the
+ * {@link org.apache.tapestry.ioc.Registry}.
+ */
+public interface ServiceActivityScoreboard
+{
+    /**
+     * Returns the status of all services, sorted alphabetically by service id.
+     */
+    List<ServiceActivity> getServiceActivity();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java
new file mode 100644
index 0000000..88223cb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceLifecycleSource.java
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.apache.tapestry.ioc.ServiceLifecycle;

+

+/**

+ * Provides access to user defined lifecycles (beyond the two built-in lifecycles: "singleton" and

+ * "primitive"). The user defined lifecycles are contributed into the service's configuration.

+ */

+public interface ServiceLifecycleSource

+{

+    /**

+     * Used to locate a configuration lifecycle, by name.

+     *

+     * @param lifecycleName

+     * @return the named lifecycle, or null if the name is not found

+     */

+    ServiceLifecycle get(String lifecycleName);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java
new file mode 100644
index 0000000..831c582
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.Registry;
+
+/**
+ * Used in {@link ServiceActivity} to identify the state of the service in terms of its overall
+ * lifecycle.
+ */
+public enum Status
+{
+    /**
+     * A builtin service that exists before the {@link Registry} is constructed.
+     */
+    BUILTIN,
+
+    /**
+     * The service is defined in a module, but has not yet been referenced.
+     */
+    DEFINED,
+
+    /**
+     * A proxy has been created for the service, but no methods of the proxy have been invoked.
+     */
+    VIRTUAL,
+
+    /**
+     * A service implementation for the service has been created.
+     */
+    REAL
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/StrategyBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/StrategyBuilder.java
new file mode 100644
index 0000000..e87dfda
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/StrategyBuilder.java
@@ -0,0 +1,42 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.apache.tapestry.ioc.util.StrategyRegistry;

+

+/**

+ * A service implementation builder that operates around a {@link StrategyRegistry}, implementing a

+ * version of the Gang of Four Strategy pattern.

+ * <p/>

+ * The constructed service is configured with a number of adapters (that implement the same service

+ * interface). Method invocations on the service are routed to one of the adapters.

+ * <p/>

+ * The first parameter of each method is used to select the appropriate adapter.

+ * <p/>

+ * The ideal interface for use with this builder has only one method.

+ */

+public interface StrategyBuilder

+{

+    /**

+     * Given a number of adapters implementing the service interface, builds a "dispatcher"

+     * implementations that delegates to the one of the adapters. It is an error if any of the

+     * methods takes no parameters.

+     *

+     * @param <S>      the service interface type

+     * @param registry defines the adapters based on parameter type (of the first parameter)

+     * @return a service implementation

+     */

+    <S> S build(StrategyRegistry<S> registry);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolProvider.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolProvider.java
new file mode 100644
index 0000000..b82c24a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolProvider.java
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+/**
+ * A provider of values for symbols.
+ */
+public interface SymbolProvider
+{
+    /**
+     * Returns the value for the symbol, or null if this provider can not provide a value. The value
+     * itself may contain symbols that will be recursively expanded.
+     *
+     * @param symbolName
+     * @return the value or null
+     */
+    String valueForSymbol(String symbolName);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolSource.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolSource.java
new file mode 100644
index 0000000..f36b16d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/SymbolSource.java
@@ -0,0 +1,45 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.annotation.Value;
+
+/**
+ * Used to manage <em>symbols</em>, configuration properties whose value is evaluated at runtime. Symbols use the Ant
+ * syntax: <code>${foo.bar.baz}</code> where <code>foo.bar.baz</code> is the name of the symbol. The symbol may appear
+ * inside annotation, such as {@link Value}. Values for symbols are provided by {@link SymbolProvider}.
+ */
+public interface SymbolSource
+{
+    /**
+     * Expands the value for a particular symbol. This may involve recursive expansion, if the immediate value for the
+     * symbol itself contains symbols.
+     *
+     * @param symbolName
+     * @return the expanded string
+     * @throws RuntimeException if the symbol name can not be expanded (no {@link SymbolProvider} can provide its
+     *                          value), or if an expansion is directly or indirectly recursive
+     */
+    String valueForSymbol(String symbolName);
+
+    /**
+     * Given an input string that <em>may</em> contain symbols, returns the string with any and all symbols fully
+     * expanded.
+     *
+     * @param input
+     * @return expanded input
+     */
+    String expandSymbols(String input);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
new file mode 100644
index 0000000..438be54
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
@@ -0,0 +1,340 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.*;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Marker;
+import org.apache.tapestry.ioc.annotation.Value;
+import org.apache.tapestry.ioc.internal.services.*;
+import org.apache.tapestry.ioc.util.TimeInterval;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * Defines the base set of services for the Tapestry IOC container.
+ */
+@Marker(Builtin.class)
+public final class TapestryIOCModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(LoggingDecorator.class, LoggingDecoratorImpl.class);
+        binder.bind(ChainBuilder.class, ChainBuilderImpl.class);
+        binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
+        binder.bind(StrategyBuilder.class, StrategyBuilderImpl.class);
+        binder.bind(PropertyShadowBuilder.class, PropertyShadowBuilderImpl.class);
+        binder.bind(PipelineBuilder.class, PipelineBuilderImpl.class);
+        binder.bind(DefaultImplementationBuilder.class, DefaultImplementationBuilderImpl.class);
+        binder.bind(ExceptionTracker.class, ExceptionTrackerImpl.class);
+        binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class);
+        binder.bind(TypeCoercer.class, TypeCoercerImpl.class);
+        binder.bind(ThreadLocale.class, ThreadLocaleImpl.class);
+        binder.bind(SymbolSource.class, SymbolSourceImpl.class);
+        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("ApplicationDefaults")
+                .withMarker(ApplicationDefaults.class);
+        binder.bind(SymbolProvider.class, MapSymbolProvider.class).withId("FactoryDefaults")
+                .withMarker(FactoryDefaults.class);
+        binder.bind(Runnable.class, RegistryStartup.class).withId("RegistryStartup");
+        binder.bind(MasterObjectProvider.class, MasterObjectProviderImpl.class);
+        binder.bind(ClassNameLocator.class, ClassNameLocatorImpl.class);
+        binder.bind(AspectDecorator.class, AspectDecoratorImpl.class);
+    }
+
+    /**
+     * Provides access to additional service lifecycles. One lifecycles is built in ("singleton") but additional ones
+     * are accessed via this service (and its mapped configuration). Only proxiable services (those with explicit
+     * service interfaces) can be managed in terms of a lifecycle.
+     */
+    public static ServiceLifecycleSource build(final Map<String, ServiceLifecycle> configuration)
+    {
+        return new ServiceLifecycleSource()
+        {
+            public ServiceLifecycle get(String lifecycleName)
+            {
+                return configuration.get(lifecycleName);
+            }
+        };
+    }
+
+    /**
+     * Contributes the "perthread" scope.
+     */
+    public void contributeServiceLifecycleSource(MappedConfiguration<String, ServiceLifecycle> configuration,
+                                                 ObjectLocator locator)
+    {
+        configuration.add(PERTHREAD_SCOPE, locator.autobuild(PerThreadServiceLifecycle.class));
+    }
+
+    /**
+     * Contributes "DefaultProvider", ordered last, that delegates to {@link ObjectLocator#getService(Class)}.
+     * <p/>
+     * Contributes "Value", which injects values (not services) triggered by the {@link Value} annotation.
+     */
+    public static void contributeMasterObjectProvider(OrderedConfiguration<ObjectProvider> configuration,
+
+                                                      ObjectLocator locator)
+    {
+        configuration.add("Value", locator.autobuild(ValueObjectProvider.class));
+        configuration.add("Symbol", locator.autobuild(SymbolObjectProvider.class));
+    }
+
+    /**
+     * Contributes a set of standard type coercions to the {@link TypeCoercer} service: <ul> <li>Object to String</li>
+     * <li>String to Double</li> <li>String to BigDecimal</li> <li>BigDecimal to Double</li> <li>Double to
+     * BigDecimal</li> <li>String to BigInteger</li> <li>BigInteger to Long</li> <li>String to Long</li> <li>Long to
+     * Byte</li> <li>Long to Short</li> <li>Long to Integer</li> <li>Double to Long</li> <li>Double to Float</li>
+     * <li>Float to Double</li> <li>Long to Double</li> <li>String to Boolean ("false" is always false, other non-blank
+     * strings are true)</li> <li>Long to Boolean (true if long value is non zero)</li> <li>Null to Boolean (always
+     * false)</li> <li>Collection to Boolean (false if empty)</li> <li>Object[] to List</li> <li>primitive[] to
+     * List</li> <li>Object to List (by wrapping as a singleton list)</li>  <li>String to File</li> <li>String to {@link
+     * org.apache.tapestry.ioc.util.TimeInterval}</li> <li>{@link org.apache.tapestry.ioc.util.TimeInterval} to
+     * Long</li> </ul>
+     */
+    @SuppressWarnings("unchecked")
+    public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
+    {
+        add(configuration, Object.class, String.class, new Coercion<Object, String>()
+        {
+            public String coerce(Object input)
+            {
+                return input.toString();
+            }
+        });
+
+        add(configuration, String.class, Double.class, new Coercion<String, Double>()
+        {
+            public Double coerce(String input)
+            {
+                return new Double(input);
+            }
+        });
+
+        // String to BigDecimal is important, as String->Double->BigDecimal would lose
+        // precision.
+
+        add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>()
+        {
+            public BigDecimal coerce(String input)
+            {
+                return new BigDecimal(input);
+            }
+        });
+
+        add(configuration, BigDecimal.class, Double.class, new Coercion<BigDecimal, Double>()
+        {
+            public Double coerce(BigDecimal input)
+            {
+                return input.doubleValue();
+            }
+        });
+
+        add(configuration, String.class, BigInteger.class, new Coercion<String, BigInteger>()
+        {
+            public BigInteger coerce(String input)
+            {
+                return new BigInteger(input);
+            }
+        });
+
+        add(configuration, String.class, Long.class, new Coercion<String, Long>()
+        {
+            public Long coerce(String input)
+            {
+                return new Long(input);
+            }
+        });
+
+        add(configuration, Long.class, Byte.class, new Coercion<Long, Byte>()
+        {
+            public Byte coerce(Long input)
+            {
+                return input.byteValue();
+            }
+        });
+
+        add(configuration, Long.class, Short.class, new Coercion<Long, Short>()
+        {
+            public Short coerce(Long input)
+            {
+                return input.shortValue();
+            }
+        });
+
+        add(configuration, Long.class, Integer.class, new Coercion<Long, Integer>()
+        {
+            public Integer coerce(Long input)
+            {
+                return input.intValue();
+            }
+        });
+
+        add(configuration, Number.class, Long.class, new Coercion<Number, Long>()
+        {
+            public Long coerce(Number input)
+            {
+                return input.longValue();
+            }
+        });
+
+        add(configuration, Double.class, Float.class, new Coercion<Double, Float>()
+        {
+            public Float coerce(Double input)
+            {
+                return input.floatValue();
+            }
+        });
+
+        add(configuration, Long.class, Double.class, new Coercion<Long, Double>()
+        {
+            public Double coerce(Long input)
+            {
+                return input.doubleValue();
+            }
+        });
+
+        add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>()
+        {
+            public Boolean coerce(String input)
+            {
+                String trimmed = input.trim();
+
+                if (trimmed.equalsIgnoreCase("false") || trimmed.length() == 0) return false;
+
+                // Any non-blank string but "false"
+
+                return true;
+            }
+        });
+
+        add(configuration, Long.class, Boolean.class, new Coercion<Long, Boolean>()
+        {
+            public Boolean coerce(Long input)
+            {
+                return input.longValue() != 0;
+            }
+        });
+
+        add(configuration, void.class, Boolean.class, new Coercion<Void, Boolean>()
+        {
+            public Boolean coerce(Void input)
+            {
+                return false;
+            }
+        });
+
+
+        add(configuration, Collection.class, Boolean.class, new Coercion<Collection, Boolean>()
+        {
+            public Boolean coerce(Collection input)
+            {
+                return !input.isEmpty();
+            }
+        });
+
+        add(configuration, Object.class, List.class, new Coercion<Object, List>()
+        {
+            public List coerce(Object input)
+            {
+                return Collections.singletonList(input);
+            }
+        });
+
+        add(configuration, Object[].class, List.class, new Coercion<Object[], List>()
+        {
+            public List coerce(Object[] input)
+            {
+                return Arrays.asList(input);
+            }
+        });
+
+        add(configuration, Float.class, Double.class, new Coercion<Float, Double>()
+        {
+            public Double coerce(Float input)
+            {
+                return input.doubleValue();
+            }
+        });
+
+        Coercion primitiveArrayCoercion = new Coercion<Object, List>()
+        {
+            public List<Object> coerce(Object input)
+            {
+                int length = Array.getLength(input);
+                Object[] array = new Object[length];
+                for (int i = 0; i < length; i++)
+                {
+                    array[i] = Array.get(input, i);
+                }
+                return Arrays.asList(array);
+            }
+        };
+
+        add(configuration, byte[].class, List.class, primitiveArrayCoercion);
+        add(configuration, short[].class, List.class, primitiveArrayCoercion);
+        add(configuration, int[].class, List.class, primitiveArrayCoercion);
+        add(configuration, long[].class, List.class, primitiveArrayCoercion);
+        add(configuration, float[].class, List.class, primitiveArrayCoercion);
+        add(configuration, double[].class, List.class, primitiveArrayCoercion);
+        add(configuration, char[].class, List.class, primitiveArrayCoercion);
+        add(configuration, boolean[].class, List.class, primitiveArrayCoercion);
+
+        add(configuration, String.class, File.class, new Coercion<String, File>()
+        {
+            public File coerce(String input)
+            {
+                return new File(input);
+            }
+        });
+
+        add(configuration, String.class, TimeInterval.class, new Coercion<String, TimeInterval>()
+        {
+            public TimeInterval coerce(String input)
+            {
+                return new TimeInterval(input);
+            }
+        });
+
+        add(configuration, TimeInterval.class, Long.class, new Coercion<TimeInterval, Long>()
+        {
+            public Long coerce(TimeInterval input)
+            {
+                return input.milliseconds();
+            }
+        });
+    }
+
+    private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType, Class<T> targetType,
+                                   Coercion<S, T> coercion)
+    {
+        CoercionTuple<S, T> tuple = new CoercionTuple<S, T>(sourceType, targetType, coercion);
+
+        configuration.add(tuple);
+    }
+
+    public static void contributeSymbolSource(OrderedConfiguration<SymbolProvider> configuration,
+                                              @ApplicationDefaults SymbolProvider applicationDefaults,
+
+                                              @FactoryDefaults SymbolProvider factoryDefaults)
+    {
+        configuration.add("SystemProperties", new SystemPropertiesSymbolProvider());
+        configuration.add("ApplicationDefaults", applicationDefaults, "after:SystemProperties");
+        configuration.add("FactoryDefaults", factoryDefaults, "after:ApplicationDefaults");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
new file mode 100644
index 0000000..788e2f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadCleanupListener.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.services;

+

+import java.util.EventListener;

+

+/**

+ * Listener interface for object that need to know about thread event cleanup.

+ * <p/>

+ * Note that registration with the {@link org.apache.tapestry.ioc.services.PerthreadManager} is a

+ * one-shot affair; it lasts no longer than the next cleanup.

+ */

+public interface ThreadCleanupListener extends EventListener

+{

+    /**

+     * Invoked by {@link org.apache.tapestry.ioc.services.PerthreadManager} service when a thread

+     * performs and end-of-request cleanup.

+     */

+    void threadDidCleanup();

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadLocale.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadLocale.java
new file mode 100644
index 0000000..4a1a6d9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ThreadLocale.java
@@ -0,0 +1,41 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.Registry;
+
+import java.util.Locale;
+
+/**
+ * Stores the locale <em>for the current thread</em>. This value persists until
+ * {@link Registry#cleanupThread()} is invoked.
+ */
+public interface ThreadLocale
+{
+    /**
+     * Updates the locale for the current thread.
+     *
+     * @param locale the new locale (may not be null)
+     */
+    void setLocale(Locale locale);
+
+    /**
+     * Returns the thread's locale, which will be the JVM's default locale, until
+     * {@link #setLocale(Locale)} is invoked.
+     *
+     * @return the thread's locale
+     */
+    Locale getLocale();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java
new file mode 100644
index 0000000..78fb711
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/TypeCoercer.java
@@ -0,0 +1,57 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+/**
+ * Makes use of {@link Coercion}s (via {@link CoercionTuple}s) to convert between an input value (of some specific type)
+ * and a desired output type. Smart about coercing, even if it requires multiple coercing steps (i.e., via an
+ * intermediate type, such as String).
+ */
+public interface TypeCoercer
+{
+    /**
+     * Performs a coercion from an input type to a desired output type. When the target type is a primitive, the actual
+     * conversion will be to the equivalent wrapper type. In some cases, the TypeCoercer will need to search for an
+     * appropriate coercion, and may even combine existing coercions to form new ones; in those cases, the results of
+     * the search are cached.
+     * <p/>
+     * <p/>
+     * The TypeCoercer also caches the results of a coercion search.
+     *
+     * @param <S>        source type (input)
+     * @param <T>        target type (output)
+     * @param input
+     * @param targetType defines the target type
+     * @return the coerced value
+     */
+    <S, T> T coerce(S input, Class<T> targetType);
+
+    /**
+     * Used primarily inside test suites, this method performs the same steps as {@link #coerce(Object, Class)}, but
+     * returns a string describing the series of coercision, such as "Object --&gt; String --&gt; Long --&gt; Integer".
+     *
+     * @param <S>        source type (input)
+     * @param <T>        target type (output)
+     * @param inputType  the source coercion type (use void.class for coercions from null)
+     * @param targetType defines the target type
+     * @return a string identifying the series of coercions, or the empty string if no coercion is necessary
+     */
+    <S, T> String explain(Class<S> inputType, Class<T> targetType);
+
+    /**
+     * Clears cached information stored by the TypeCoercer.
+     */
+    void clearCache();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
new file mode 100644
index 0000000..4080f42
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
@@ -0,0 +1,396 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.test;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.*;
+import static org.easymock.EasyMock.isA;
+import org.slf4j.Logger;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Locale;
+
+/**
+ * Add factory and trainer methods for the public interfaces of Tapestry IOC.
+ */
+public class IOCTestCase extends TestBase
+{
+
+    /**
+     * Builds a Registry for the provided modules; caller should shutdown the Registry when done.
+     */
+    protected final Registry buildRegistry(Class... moduleClasses)
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        builder.add(moduleClasses);
+
+        return builder.build();
+    }
+
+    protected final Method findMethod(Class clazz, String methodName)
+    {
+        for (Method method : clazz.getMethods())
+        {
+            if (method.getName().equals(methodName)) return method;
+        }
+
+        throw new IllegalArgumentException(
+                String.format("Class %s does not provide a method named '%s'.", clazz.getName(), methodName));
+    }
+
+    protected final Method findMethod(Object subject, String methodName)
+    {
+        return findMethod(subject.getClass(), methodName);
+    }
+
+    protected final Method findMethod(String methodName)
+    {
+        return findMethod(this, methodName);
+    }
+
+    /**
+     * Combines a series of lines by forming a string with a line separator after each line.
+     */
+    protected final String join(String... lines)
+    {
+        StringBuilder result = new StringBuilder();
+
+        for (String line : lines)
+        {
+            result.append(line);
+            result.append("\n");
+        }
+
+        return result.toString();
+    }
+
+    protected final AnnotationProvider mockAnnotationProvider()
+    {
+        return newMock(AnnotationProvider.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final <T> Configuration<T> mockConfiguration()
+    {
+        return newMock(Configuration.class);
+    }
+
+    protected final ContributionDef mockContributionDef()
+    {
+        return newMock(ContributionDef.class);
+    }
+
+    protected final DecoratorDef mockDecoratorDef()
+    {
+        return newMock(DecoratorDef.class);
+    }
+
+    protected final Location mockLocation()
+    {
+        return newMock(Location.class);
+    }
+
+    protected final Logger mockLogger()
+    {
+        return newMock(Logger.class);
+    }
+
+    protected final void stub_isDebugEnabled(Logger logger, boolean enabled)
+    {
+        expect(logger.isDebugEnabled()).andStubReturn(enabled);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final <K, V> MappedConfiguration<K, V> mockMappedConfiguration()
+    {
+        return newMock(MappedConfiguration.class);
+    }
+
+    protected final MessageFormatter mockMessageFormatter()
+    {
+        return newMock(MessageFormatter.class);
+    }
+
+    protected final Messages mockMessages()
+    {
+        return newMock(Messages.class);
+    }
+
+    protected final ModuleDef mockModuleDef()
+    {
+        return newMock(ModuleDef.class);
+    }
+
+    protected final ObjectCreator mockObjectCreator()
+    {
+        return newMock(ObjectCreator.class);
+    }
+
+    protected final ObjectProvider mockObjectProvider()
+    {
+        return newMock(ObjectProvider.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected final <T> OrderedConfiguration<T> mockOrderedConfiguration()
+    {
+        return newMock(OrderedConfiguration.class);
+    }
+
+    protected final Resource mockResource()
+    {
+        return newMock(Resource.class);
+    }
+
+    /**
+     * Frequently used as a placeholder for an arbitrary service (but its nice and simple).
+     */
+    protected final Runnable mockRunnable()
+    {
+        return newMock(Runnable.class);
+    }
+
+    protected final ServiceBuilderResources mockServiceBuilderResources()
+    {
+        return newMock(ServiceBuilderResources.class);
+    }
+
+    protected final ServiceDecorator mockServiceDecorator()
+    {
+        return newMock(ServiceDecorator.class);
+    }
+
+    protected final ServiceDef mockServiceDef()
+    {
+        return newMock(ServiceDef.class);
+    }
+
+    protected final ObjectLocator mockObjectLocator()
+    {
+        return newMock(ObjectLocator.class);
+    }
+
+    protected final ServiceResources mockServiceResources()
+    {
+        return newMock(ServiceResources.class);
+    }
+
+    protected final SymbolSource mockSymbolSource()
+    {
+        return newMock(SymbolSource.class);
+    }
+
+    protected final ThreadLocale mockThreadLocale()
+    {
+        return newMock(ThreadLocale.class);
+    }
+
+    protected final TypeCoercer mockTypeCoercer()
+    {
+        return newMock(TypeCoercer.class);
+    }
+
+    protected final void stub_contains(Messages messages, boolean contained)
+    {
+        expect(messages.contains(isA(String.class))).andStubReturn(contained);
+    }
+
+    protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType, T coercedValue)
+    {
+        expect(coercer.coerce(input, expectedType)).andReturn(coercedValue);
+    }
+
+    protected final void train_contains(Messages messages, String key, boolean result)
+    {
+        expect(messages.contains(key)).andReturn(result).atLeastOnce();
+    }
+
+    protected final void train_createInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor)
+    {
+        expect(decorator.createInterceptor(coreObject)).andReturn(interceptor);
+    }
+
+    protected final void train_createObject(ObjectCreator creator, Object service)
+    {
+        expect(creator.createObject()).andReturn(service);
+    }
+
+    protected final void train_expandSymbols(SymbolSource source, String input)
+    {
+        train_expandSymbols(source, input, input);
+
+    }
+
+    protected final void train_expandSymbols(SymbolSource source, String input, String expanded)
+    {
+        expect(source.expandSymbols(input)).andReturn(expanded);
+    }
+
+    protected final void train_forFile(Resource resource, String relativePath, Resource file)
+    {
+        expect(resource.forFile(relativePath)).andReturn(file);
+    }
+
+    protected final void train_forLocale(Resource base, Locale locale, Resource resource)
+    {
+        expect(base.forLocale(locale)).andReturn(resource);
+    }
+
+    /**
+     * Have to put the result before the varargs.
+     */
+    protected void train_format(MessageFormatter formatter, String result, Object... arguments)
+    {
+        expect(formatter.format(arguments)).andReturn(result);
+    }
+
+    protected final void train_get(Messages messages, String key, String message)
+    {
+        expect(messages.get(key)).andReturn(message).atLeastOnce();
+    }
+
+    protected final void train_getLocale(ThreadLocale threadLocale, Locale locale)
+    {
+        expect(threadLocale.getLocale()).andReturn(locale);
+    }
+
+    protected final void train_getLogger(LoggerSource source, String serviceId, Logger logger)
+    {
+        expect(source.getLogger(serviceId)).andReturn(logger).atLeastOnce();
+    }
+
+    protected final void train_getMessageFormatter(Messages messages, String key, MessageFormatter formatter)
+    {
+        expect(messages.getFormatter(key)).andReturn(formatter).atLeastOnce();
+    }
+
+    protected final void train_getPath(Resource r, String path)
+    {
+        expect(r.getPath()).andReturn(path).atLeastOnce();
+    }
+
+    protected final <T> void train_getService(ObjectLocator locator, Class<T> serviceInterface, T service)
+    {
+        expect(locator.getService(serviceInterface)).andReturn(service);
+    }
+
+    protected final <T> void train_getService(ObjectLocator locator, String serviceId, Class<T> serviceInterface,
+                                              T service)
+    {
+        expect(locator.getService(serviceId, serviceInterface)).andReturn(service);
+    }
+
+    protected final void train_getServiceId(ServiceDef def, String serviceId)
+    {
+        expect(def.getServiceId()).andReturn(serviceId).atLeastOnce();
+    }
+
+    protected final void train_getServiceId(ServiceResources resources, String serviceId)
+    {
+        expect(resources.getServiceId()).andReturn(serviceId).atLeastOnce();
+
+    }
+
+    protected final void train_getServiceInterface(ServiceDef def, Class serviceInterface)
+    {
+        expect(def.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
+    }
+
+    protected final void train_getServiceInterface(ServiceResources resources, Class serviceInterface)
+    {
+        expect(resources.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
+    }
+
+    protected final void train_getLogger(ServiceResources resources, Logger log)
+    {
+        expect(resources.getLogger()).andReturn(log).atLeastOnce();
+
+    }
+
+    protected final void train_isDebugEnabled(Logger log, boolean debugEnabled)
+    {
+        expect(log.isDebugEnabled()).andReturn(debugEnabled);
+    }
+
+    protected final void train_isTraceEnabled(Logger log, boolean traceEnabled)
+    {
+        expect(log.isTraceEnabled()).andReturn(traceEnabled);
+    }
+
+    protected final void train_matches(DecoratorDef decoratorDef, ServiceDef serviceDef, boolean matches)
+    {
+        expect(decoratorDef.matches(serviceDef)).andReturn(matches);
+    }
+
+    protected final <T> void train_provide(ObjectProvider provider, Class<T> objectType,
+                                           AnnotationProvider annotationProvider, ObjectLocator locator, T object)
+    {
+        expect(provider.provide(objectType, annotationProvider, locator)).andReturn(object);
+    }
+
+    protected final void train_toURL(Resource resource, URL url)
+    {
+        expect(resource.toURL()).andReturn(url).atLeastOnce();
+    }
+
+    protected final <T extends Annotation> void train_getAnnotation(AnnotationProvider annotationProvider,
+                                                                    Class<T> annotationClass, T annotation)
+    {
+        expect(annotationProvider.getAnnotation(annotationClass)).andReturn(annotation);
+    }
+
+    protected final MasterObjectProvider mockMasterObjectProvider()
+    {
+        return newMock(MasterObjectProvider.class);
+    }
+
+    protected final void train_value(IntermediateType it, Class value)
+    {
+        expect(it.value()).andReturn(value);
+    }
+
+    protected final IntermediateType newIntermediateType()
+    {
+        return newMock(IntermediateType.class);
+    }
+
+    protected final PropertyAdapter mockPropertyAdapter()
+    {
+        return newMock(PropertyAdapter.class);
+    }
+
+    protected final ClassPropertyAdapter mockClassPropertyAdapter()
+    {
+        return newMock(ClassPropertyAdapter.class);
+    }
+
+    protected final PropertyAccess mockPropertyAccess()
+    {
+        return newMock(PropertyAccess.class);
+    }
+
+    protected final <T> void train_autobuild(ObjectLocator locator, Class<T> beanClass, T instance)
+    {
+        expect(locator.autobuild(beanClass)).andReturn(instance);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/MockTester.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/MockTester.java
new file mode 100644
index 0000000..33cf125
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/MockTester.java
@@ -0,0 +1,85 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.test;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+/**
+ * Contains core logic used by {@link TestBase}, allowing for mock objects to be used outside of a TestNG-based test
+ * suite. A <em>single</em> standard mock control is used for all mock instances. The control does not care about
+ * execution order, but will balk at any unexpected method invocations. This class is thread safe (it used a thread
+ * local to store the mock control).
+ */
+public final class MockTester
+{
+    private static class ThreadLocalControl extends ThreadLocal<IMocksControl>
+    {
+        @Override
+        protected IMocksControl initialValue()
+        {
+            return EasyMock.createControl();
+        }
+    }
+
+    private final ThreadLocalControl localControl = new ThreadLocalControl();
+
+    /**
+     * Invoked after an individual unit test (i.e., a test method invocation) to discard the mock control.
+     */
+    public synchronized void cleanup()
+    {
+        localControl.remove();
+    }
+
+    public synchronized IMocksControl getMocksControl()
+    {
+        return localControl.get();
+    }
+
+    /**
+     * Creates a new mock object of the indicated type. The shared mock control does <strong>not</strong> check order,
+     * but does fail on any unexpected method invocations.
+     *
+     * @param <T>       the type of the mock object
+     * @param mockClass the class to mock
+     * @return the mock object, ready for training
+     */
+    public <T> T newMock(Class<T> mockClass)
+    {
+        return getMocksControl().createMock(mockClass.getSimpleName(), mockClass);
+    }
+
+    /**
+     * Switches each mock object created by {@link #newMock(Class)} into replay mode (out of the initial training
+     * mode).
+     */
+    public void replay()
+    {
+        getMocksControl().replay();
+    }
+
+    /**
+     * Verifies that all trained methods have been invoked on all mock objects (created by {@link #newMock(Class)}, then
+     * switches each mock object back to training mode.
+     */
+    public void verify()
+    {
+        IMocksControl control = getMocksControl();
+
+        control.verify();
+        control.reset();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/TestBase.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/TestBase.java
new file mode 100644
index 0000000..9d6027e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/TestBase.java
@@ -0,0 +1,201 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.test;
+
+import org.easymock.EasyMock;
+import org.easymock.IExpectationSetters;
+import org.easymock.IMocksControl;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Manages a set of EasyMock mock objects. Used as a base class for test cases.
+ * <p/>
+ * Extends from {@link org.testng.Assert} to bring in all the public static assert methods without requiring extra
+ * imports.
+ * <p/>
+ * Provides a common mock factory method, {@link #newMock(Class)}. A single <em>standard</em> mock control is used for
+ * all mock objects. Standard mocks do not care about the exact order in which methods are invoked, though they are as
+ * rigourous as strict mocks when checking that parameters are the correct values.
+ * <p/>
+ * This base class is created with the intention of use within a TestNG test suite; if using JUnit, you can get the same
+ * functionality using {@link MockTester}.
+ * <p/>
+ * This class is thread safe (it uses a thread local to store the mock control). In theory, this should allow TestNG to
+ * execute tests in parallel. Unfortunately, as of this writing (TestNG 5.1 and maven-surefire 2.8-SNAPSHOT) parallel
+ * execution does not always work fully and consistently, some tests are dropped, and so Tapestry does not make use of
+ * TestNG parallel execution.
+ *
+ * @see EasyMock#createControl()
+ * @see MockTester
+ */
+public class TestBase extends Assert
+{
+
+    private static class ThreadLocalControl extends ThreadLocal<IMocksControl>
+    {
+        @Override
+        protected IMocksControl initialValue()
+        {
+            return EasyMock.createControl();
+        }
+    }
+
+    private final MockTester tester = new MockTester();
+
+    /**
+     * Returns the {@link IMocksControl} for this thread.
+     */
+    protected final IMocksControl getMocksControl()
+    {
+        return tester.getMocksControl();
+    }
+
+    /**
+     * Discards any mock objects created during the test.
+     */
+    @AfterMethod(alwaysRun = true)
+    public final void discardMockControl()
+    {
+        tester.cleanup();
+    }
+
+    /**
+     * Creates a new mock object of the indicated type. The shared mock control does <strong>not</strong> check order,
+     * but does fail on any unexpected method invocations.
+     *
+     * @param <T>       the type of the mock object
+     * @param mockClass the class to mock
+     * @return the mock object, ready for training
+     */
+    protected final <T> T newMock(Class<T> mockClass)
+    {
+        return tester.newMock(mockClass);
+    }
+
+    /**
+     * Switches each mock object created by {@link #newMock(Class)} into replay mode (out of the initial training
+     * mode).
+     */
+    protected final void replay()
+    {
+        tester.replay();
+    }
+
+    /**
+     * Verifies that all trained methods have been invoked on all mock objects (created by {@link #newMock(Class)}, then
+     * switches each mock object back to training mode.
+     */
+    protected final void verify()
+    {
+        tester.verify();
+    }
+
+    /**
+     * Convienience for {@link EasyMock#expectLastCall()} with {@link IExpectationSetters#andThrow(Throwable)}.
+     *
+     * @param throwable the exception to be thrown by the most recent method call on any mock
+     */
+    protected final void setThrowable(Throwable throwable)
+    {
+        EasyMock.expectLastCall().andThrow(throwable);
+    }
+
+    /**
+     * Invoked from code that should not be reachable. For example, place a call to unreachable() after invoking a
+     * method that is expected to throw an exception.
+     */
+
+    protected final void unreachable()
+    {
+        fail("This code should not be reachable.");
+    }
+
+    /**
+     * Convienience for {@link EasyMock#expect(Object)}.
+     *
+     * @param <T>
+     * @param value
+     * @return expectation setter, for setting return value, etc.
+     */
+    @SuppressWarnings("unchecked")
+    protected final <T> IExpectationSetters<T> expect(T value)
+    {
+        return EasyMock.expect(value);
+    }
+
+    /**
+     * Asserts that the message property of the throwable contains each of the provided substrings.
+     *
+     * @param t          throwable to check
+     * @param substrings some number of expected substrings
+     */
+    protected final void assertMessageContains(Throwable t, String... substrings)
+    {
+        String message = t.getMessage();
+
+        for (String substring : substrings)
+            assertTrue(message.contains(substring),
+                       String.format("String '%s' not found in '%s'.", substring, message));
+    }
+
+    /**
+     * Compares two lists for equality; first all the elements are individually compared for equality (if the lists are
+     * of unequal length, only elements up to the shorter length are compared). Then the length of the lists are
+     * compared. This generally gives
+     *
+     * @param <T>      type of objects to compare
+     * @param actual   actual values to check
+     * @param expected expected values
+     */
+    protected final <T> void assertListsEquals(List<T> actual, List<T> expected)
+    {
+        int count = Math.min(actual.size(), expected.size());
+
+        for (int i = 0; i < count; i++)
+        {
+            assertEquals(actual.get(i), expected.get(i), String.format("Element #%d.", i));
+        }
+
+        assertEquals(actual.size(), expected.size(), "List size.");
+    }
+
+    /**
+     * Convenience for {@link #assertListsEquals(List, List)}.
+     *
+     * @param <T>      tyoe of objects to compare
+     * @param actual   actual values to check
+     * @param expected expected values
+     */
+    protected final <T> void assertListsEquals(List<T> actual, T... expected)
+    {
+        assertListsEquals(actual, Arrays.asList(expected));
+    }
+
+    /**
+     * Convenience for {@link #assertListsEquals(List, List)}.
+     *
+     * @param <T>      tyoe of objects to compare
+     * @param actual   actual values to check
+     * @param expected expected values
+     */
+    protected final <T> void assertArraysEqual(T[] actual, T... expected)
+    {
+        assertListsEquals(Arrays.asList(actual), expected);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/AbstractMessages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/AbstractMessages.java
new file mode 100644
index 0000000..8b1e5f8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/AbstractMessages.java
@@ -0,0 +1,106 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+import org.apache.tapestry.ioc.internal.util.ConcurrentBarrier;
+import org.apache.tapestry.ioc.internal.util.Invokable;
+import org.apache.tapestry.ioc.internal.util.MessageFormatterImpl;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Abstract implementation of {@link Messages} that doesn't know where values come from (that information is supplied in
+ * a subclass, via the {@link #valueForKey(String)} method).
+ */
+public abstract class AbstractMessages implements Messages
+{
+    private final ConcurrentBarrier barrier = new ConcurrentBarrier();
+
+    /**
+     * String key to MF instance.
+     */
+    private final Map<String, MessageFormatter> cache = newCaseInsensitiveMap();
+
+    private final Locale locale;
+
+    protected AbstractMessages(Locale locale)
+    {
+        this.locale = locale;
+    }
+
+    /**
+     * Invoked to provide the value for a particular key. This may be invoked multiple times even for the same key. The
+     * implementation should <em>ignore the case of the key</em>.
+     *
+     * @param key the key to obtain a value for (case insensitive)
+     * @return the value for the key, or null if this instance can not provide the value
+     */
+    protected abstract String valueForKey(String key);
+
+
+    public boolean contains(String key)
+    {
+        return valueForKey(key) != null;
+    }
+
+    public String get(String key)
+    {
+        if (contains(key)) return valueForKey(key);
+
+        return String.format("[[missing key: %s]]", key);
+    }
+
+    public MessageFormatter getFormatter(final String key)
+    {
+        MessageFormatter result = barrier.withRead(new Invokable<MessageFormatter>()
+        {
+            public MessageFormatter invoke()
+            {
+                return cache.get(key);
+            }
+        });
+
+        if (result != null) return result;
+
+        final MessageFormatter newFormatter = buildMessageFormatter(key);
+
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                cache.put(key, newFormatter);
+            }
+        });
+
+        return newFormatter;
+    }
+
+    private MessageFormatter buildMessageFormatter(String key)
+    {
+        String format = get(key);
+
+        return new MessageFormatterImpl(format, locale);
+    }
+
+    public String format(String key, Object... args)
+    {
+        return getFormatter(key).format(args);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java
new file mode 100644
index 0000000..a4cc84f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/BodyBuilder.java
@@ -0,0 +1,165 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.services.MethodSignature;
+
+import java.util.Formatter;
+
+/**
+ * Utility class for assembling the <em>body</em> used with Javassist when defining a method or constructor. Basically,
+ * assists with formatting and with indentation. This makes the code that assembles a method body much simpler ... and
+ * it makes the result neater, which will be easier to debug (debugging dynamically generated code is hard enough that
+ * it should be easy to read the input code before worrying about why it doesn't compile or execute properly).
+ * <p/>
+ * This class is not threadsafe.
+ * <p/>
+ * Most of the methods return the BodyBuilder, to form a fluent interface.
+ */
+public final class BodyBuilder
+{
+    /**
+     * Feels right for the size of a typical body.
+     */
+    private static final int DEFAULT_LENGTH = 200;
+
+    private static final String INDENT = "  ";
+
+    private final StringBuilder buffer = new StringBuilder(DEFAULT_LENGTH);
+
+    private final Formatter formatter = new Formatter(buffer);
+
+    // Per level of nesting depth (two spaces).
+
+    private int nestingDepth = 0;
+
+    private boolean atNewLine = true;
+
+    /**
+     * Clears the builder, returning it to its initial, empty state.
+     */
+    public BodyBuilder clear()
+    {
+        nestingDepth = 0;
+        atNewLine = true;
+        buffer.setLength(0);
+
+        return this;
+    }
+
+    /**
+     * Adds text to the current line, without ending the line.
+     *
+     * @param format string format, as per {@link java.util.Formatter}
+     * @param args   arguments referenced by format specifiers
+     */
+    public BodyBuilder add(String format, Object... args)
+    {
+        add(format, args, false);
+
+        return this;
+    }
+
+    /**
+     * Adds text to the current line and ends the line.
+     *
+     * @param format string format, as per {@link java.util.Formatter}
+     * @param args   arguments referenced by format specifiers
+     */
+    public BodyBuilder addln(String format, Object... args)
+    {
+        add(format, args, true);
+
+        return this;
+    }
+
+    private BodyBuilder add(String format, Object[] args, boolean newLine)
+    {
+        indent();
+
+        // Format output, send to buffer
+
+        formatter.format(format, args);
+
+        if (newLine) newline();
+
+        return this;
+    }
+
+    private void newline()
+    {
+        buffer.append("\n");
+        atNewLine = true;
+    }
+
+    /**
+     * Begins a new block. Emits a "{", properly indented, on a new line.
+     */
+    public BodyBuilder begin()
+    {
+        if (!atNewLine) newline();
+
+        indent();
+        buffer.append("{");
+        newline();
+
+        nestingDepth++;
+
+        return this;
+    }
+
+    /**
+     * Ends the current block. Emits a "}", propertly indented, on a new line.
+     */
+    public BodyBuilder end()
+    {
+        if (!atNewLine) newline();
+
+        // TODO: Could check here if nesting depth goes below zero.
+
+        nestingDepth--;
+
+        indent();
+        buffer.append("}");
+
+        newline();
+
+        return this;
+    }
+
+    private void indent()
+    {
+        if (atNewLine)
+        {
+            for (int i = 0; i < nestingDepth; i++)
+                buffer.append(INDENT);
+
+            atNewLine = false;
+        }
+    }
+
+    /**
+     * Returns the current contents of the buffer. This value is often passed to methods such as {@link
+     * org.apache.tapestry.ioc.services.ClassFab#addConstructor(Class[], Class[], String)} or {@link
+     * org.apache.tapestry.ioc.services.ClassFab#addMethod(int, MethodSignature, String)}.
+     * <p/>
+     * A BodyBuilder can be used again after invoking toString(), typically by invoking {@link #clear()}.
+     */
+    @Override
+    public String toString()
+    {
+        return buffer.toString();
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/CaseInsensitiveMap.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/CaseInsensitiveMap.java
new file mode 100644
index 0000000..acf7228
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/CaseInsensitiveMap.java
@@ -0,0 +1,493 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * An mapped collection where the keys are always strings and access to values is case-insensitive. The case of keys in
+ * the map is <em>maintained</em>, but on any access to a key (directly or indirectly), all key comparisons are
+ * performed in a case-insensitive manner. The map implementation is intended to support a reasonably finite number
+ * (dozens or hundreds, not thousands or millions of key/value pairs. Unlike HashMap, it is based on a sorted list of
+ * entries rather than hash bucket. It is also geared towards a largely static map, one that is created and then used
+ * without modification.
+ *
+ * @param <V> the type of value stored
+ */
+public class CaseInsensitiveMap<V> extends AbstractMap<String, V> implements Serializable
+{
+    private static final long serialVersionUID = 3362718337611953298L;
+
+    private static final int NULL_HASH = Integer.MIN_VALUE;
+
+    private static final int DEFAULT_SIZE = 20;
+
+    private static class CIMEntry<V> implements Map.Entry<String, V>, Serializable
+    {
+        private static final long serialVersionUID = 6713986085221148350L;
+
+        private String key;
+
+        private final int hashCode;
+
+        V value;
+
+        public CIMEntry(final String key, final int hashCode, V value)
+        {
+            this.key = key;
+            this.hashCode = hashCode;
+            this.value = value;
+        }
+
+        public String getKey()
+        {
+            return key;
+        }
+
+        public V getValue()
+        {
+            return value;
+        }
+
+        public V setValue(V value)
+        {
+            V result = this.value;
+
+            this.value = value;
+
+            return result;
+        }
+
+        /**
+         * Returns true if both keys are null, or if the provided key is the same as, or case-insensitively equal to,
+         * the entrie's key.
+         *
+         * @param key to compare against
+         * @return true if equal
+         */
+        @SuppressWarnings({ "StringEquality" })
+        boolean matches(String key)
+        {
+            return key == this.key || (key != null && key.equalsIgnoreCase(this.key));
+        }
+
+        boolean valueMatches(Object value)
+        {
+            return value == this.value || (value != null && value.equals(this.value));
+        }
+    }
+
+    private class EntrySetIterator implements Iterator
+    {
+        int expectedModCount = modCount;
+
+        int index;
+
+        int current = -1;
+
+        public boolean hasNext()
+        {
+            return index < size;
+        }
+
+        public Object next()
+        {
+            check();
+
+            if (index >= size) throw new NoSuchElementException();
+
+            current = index++;
+
+            return entries[current];
+        }
+
+        public void remove()
+        {
+            check();
+
+            if (current < 0) throw new NoSuchElementException();
+
+            new Position(current, true).remove();
+
+            expectedModCount = modCount;
+        }
+
+        private void check()
+        {
+            if (expectedModCount != modCount) throw new ConcurrentModificationException();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private class EntrySet extends AbstractSet
+    {
+        @Override
+        public Iterator iterator()
+        {
+            return new EntrySetIterator();
+        }
+
+        @Override
+        public int size()
+        {
+            return size;
+        }
+
+        @Override
+        public void clear()
+        {
+            CaseInsensitiveMap.this.clear();
+        }
+
+        @Override
+        public boolean contains(Object o)
+        {
+            if (!(o instanceof Map.Entry)) return false;
+
+            Map.Entry e = (Map.Entry) o;
+
+            Position position = select(e.getKey());
+
+            return position.isFound() && position.entry().valueMatches(e.getValue());
+        }
+
+        @Override
+        public boolean remove(Object o)
+        {
+            if (!(o instanceof Map.Entry)) return false;
+
+            Map.Entry e = (Map.Entry) o;
+
+            Position position = select(e.getKey());
+
+            if (position.isFound() && position.entry().valueMatches(e.getValue()))
+            {
+                position.remove();
+                return true;
+            }
+
+            return false;
+        }
+
+    }
+
+    private class Position
+    {
+        private final int cursor;
+
+        private final boolean found;
+
+        Position(int cursor, boolean found)
+        {
+            this.cursor = cursor;
+            this.found = found;
+        }
+
+        boolean isFound()
+        {
+            return found;
+        }
+
+        CIMEntry<V> entry()
+        {
+            return entries[cursor];
+        }
+
+        V get()
+        {
+            return found ? entries[cursor].value : null;
+        }
+
+        V remove()
+        {
+            if (!found) return null;
+
+            V result = entries[cursor].value;
+
+            // Remove the entry by shifting everything else down.
+
+            System.arraycopy(entries, cursor + 1, entries, cursor, size - cursor - 1);
+
+            // We shifted down, leaving one (now duplicate) entry behind.
+
+            entries[--size] = null;
+
+            // A structural change for sure
+
+            modCount++;
+
+            return result;
+        }
+
+        @SuppressWarnings("unchecked")
+        V put(String key, int hashCode, V newValue)
+        {
+            if (found)
+            {
+                CIMEntry<V> e = entries[cursor];
+
+                V result = e.value;
+
+                // Not a structural change, so no change to modCount
+
+                // Update the key (to maintain case). By definition, the hash code
+                // will not change.
+
+                e.key = key;
+                e.value = newValue;
+
+                return result;
+            }
+
+            // Not found, we're going to add it.
+
+            int newSize = size + 1;
+
+            if (newSize == entries.length)
+            {
+                // Time to expand!
+
+                int newCapacity = (size * 3) / 2 + 1;
+
+                CIMEntry<V>[] newEntries = new CIMEntry[newCapacity];
+
+                System.arraycopy(entries, 0, newEntries, 0, cursor);
+
+                System.arraycopy(entries, cursor, newEntries, cursor + 1, size - cursor);
+
+                entries = newEntries;
+            }
+            else
+            {
+                // Open up a space for the new entry
+
+                System.arraycopy(entries, cursor, entries, cursor + 1, size - cursor);
+            }
+
+            CIMEntry<V> newEntry = new CIMEntry<V>(key, hashCode, newValue);
+            entries[cursor] = newEntry;
+
+            size++;
+
+            // This is definately a structural change
+
+            modCount++;
+
+            return null;
+        }
+
+    }
+
+    // The list of entries. This is kept sorted by hash code. In some cases, there may be different
+    // keys with the same hash code in adjacent indexes.
+    private CIMEntry<V>[] entries;
+
+    private int size = 0;
+
+    // Used by iterators to check for concurrent modifications
+
+    private transient int modCount = 0;
+
+    private transient Set<Map.Entry<String, V>> entrySet;
+
+    public CaseInsensitiveMap()
+    {
+        this(DEFAULT_SIZE);
+    }
+
+    @SuppressWarnings("unchecked")
+    public CaseInsensitiveMap(int size)
+    {
+        entries = new CIMEntry[Math.max(size, 3)];
+    }
+
+    public CaseInsensitiveMap(Map<String, ? extends V> map)
+    {
+        this(map.size());
+
+        for (Map.Entry<String, ? extends V> entry : map.entrySet())
+        {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    public void clear()
+    {
+        for (int i = 0; i < size; i++)
+            entries[i] = null;
+
+        size = 0;
+        modCount++;
+    }
+
+    @Override
+    public boolean isEmpty()
+    {
+        return size == 0;
+    }
+
+    @Override
+    public int size()
+    {
+        return size;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public V put(String key, V value)
+    {
+        int hashCode = caseInsenitiveHashCode(key);
+
+        return select(key, hashCode).put(key, hashCode, value);
+    }
+
+    @Override
+    public boolean containsKey(Object key)
+    {
+        return select(key).isFound();
+    }
+
+    @Override
+    public V get(Object key)
+    {
+        return select(key).get();
+    }
+
+    @Override
+    public V remove(Object key)
+    {
+        return select(key).remove();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Set<Map.Entry<String, V>> entrySet()
+    {
+        if (entrySet == null) entrySet = new EntrySet();
+
+        return entrySet;
+    }
+
+    private Position select(Object key)
+    {
+        if (key == null || key instanceof String)
+        {
+            String keyString = (String) key;
+            return select(keyString, caseInsenitiveHashCode(keyString));
+        }
+
+        return new Position(0, false);
+    }
+
+    /**
+     * Searches the elements for the index of the indicated key and (case insensitive) hash code. Sets the _cursor and
+     * _found attributes.
+     */
+    private Position select(String key, int hashCode)
+    {
+        if (size == 0) return new Position(0, false);
+
+        int low = 0;
+        int high = size - 1;
+
+        int cursor;
+
+        while (low <= high)
+        {
+            cursor = (low + high) >> 1;
+
+            CIMEntry e = entries[cursor];
+
+            if (e.hashCode < hashCode)
+            {
+                low = cursor + 1;
+                continue;
+            }
+
+            if (e.hashCode > hashCode)
+            {
+                high = cursor - 1;
+                continue;
+            }
+
+            return tunePosition(key, hashCode, cursor);
+        }
+
+        return new Position(low, false);
+    }
+
+    /**
+     * select() has located a matching hashCode, but there's an outlying possibility that multiple keys share the same
+     * hashCode. Backup the cursor until we get to locate the initial hashCode match, then march forward until the key
+     * is located, or the hashCode stops matching.
+     *
+     * @param key
+     * @param hashCode
+     */
+    private Position tunePosition(String key, int hashCode, int cursor)
+    {
+        boolean found = false;
+
+        while (cursor > 0)
+        {
+            if (entries[cursor - 1].hashCode != hashCode) break;
+
+            cursor--;
+        }
+
+        while (true)
+        {
+            if (entries[cursor].matches(key))
+            {
+                found = true;
+                break;
+            }
+
+            // Advance to the next entry.
+
+            cursor++;
+
+            // If out of entries,
+            if (cursor >= size || entries[cursor].hashCode != hashCode) break;
+        }
+
+        return new Position(cursor, found);
+    }
+
+    static int caseInsenitiveHashCode(String input)
+    {
+        if (input == null) return NULL_HASH;
+
+        int length = input.length();
+        int hash = 0;
+
+        // This should end up more or less equal to input.toLowerCase().hashCode(), unless String
+        // changes its implementation. Let's hope this is reasonably fast.
+
+        for (int i = 0; i < length; i++)
+        {
+            int ch = input.charAt(i);
+
+            int caselessCh = Character.toLowerCase(ch);
+
+            hash = 31 * hash + caselessCh;
+        }
+
+        return hash;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/ExceptionUtils.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/ExceptionUtils.java
new file mode 100644
index 0000000..21b9005
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/ExceptionUtils.java
@@ -0,0 +1,45 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+/**
+ * Contains static methods useful for manipulating exceptions.
+ */
+public class ExceptionUtils
+{
+    /**
+     * Locates a particular type of exception, working its way via the cause property of each exception in the exception
+     * stack.
+     *
+     * @param t    the outermost exception
+     * @param type the type of exception to search for
+     * @return the first exception of the given type, if found, or null
+     */
+    public static <T extends Throwable> T findCause(Throwable t, Class<T> type)
+    {
+        Throwable current = t;
+
+        while (current != null)
+        {
+            if (type.isInstance(current)) return type.cast(current);
+
+            // Not a match, work down.
+
+            current = current.getCause();
+        }
+
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java
new file mode 100644
index 0000000..4762f79
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/Stack.java
@@ -0,0 +1,165 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+/**
+ * A simple, streamlined implementation of {@link java.util.Stack}. The implementation is <em>not</em> threadsafe.
+ *
+ * @param <E> the type of elements stored in the map
+ * @see CollectionFactory#newStack()
+ */
+public class Stack<E>
+{
+    private static final int MINIMUM_SIZE = 3;
+
+    private static final int DEFAULT_ARRAY_SIZE = 20;
+
+    private Object[] items;
+
+    private int index = -1;
+
+    /**
+     * Normal constructor supporting an initial size of 20.
+     */
+    public Stack()
+    {
+        this(DEFAULT_ARRAY_SIZE);
+    }
+
+    /**
+     * @param initialSize the initial size of the internal array (which will be expanded as necessary). For best
+     *                    efficiency, set this to the maximum depth of the stack.
+     */
+    public Stack(int initialSize)
+    {
+        items = new Object[Math.max(initialSize, MINIMUM_SIZE)];
+    }
+
+    /**
+     * Returns true if the stack is empty.
+     */
+    public boolean isEmpty()
+    {
+        return index < 0;
+    }
+
+    /**
+     * Clears the stack, the same as popping off all elements.
+     */
+    public void clear()
+    {
+        for (int i = 0; i <= index; i++) items[i] = null;
+
+        index = -1;
+    }
+
+    /**
+     * Pushes a new item onto the stack.
+     */
+    public void push(E item)
+    {
+        index++;
+
+        if (index == items.length)
+        {
+            int newCapacity = (items.length * 3) / 2 + 1;
+            Object[] newItems = new Object[newCapacity];
+            System.arraycopy(items, 0, newItems, 0, items.length);
+
+            items = newItems;
+        }
+
+        items[index] = item;
+    }
+
+    /**
+     * Pops the top element off the stack and returns it.
+     *
+     * @return the top element of the stack
+     * @throws IllegalStateException if the stack is empty
+     */
+    @SuppressWarnings("unchecked")
+    public E pop()
+    {
+        checkIfEmpty();
+
+        Object result = items[index];
+
+        items[index] = null;
+
+        index--;
+
+        return (E) result;
+    }
+
+    private void checkIfEmpty()
+    {
+        if (index < 0) throw new IllegalStateException(UtilMessages.stackIsEmpty());
+    }
+
+    /**
+     * Returns the top element of the stack without affecting the stack.
+     *
+     * @return top element on the stack
+     * @throws IllegalStateException if the stack is empty
+     */
+    @SuppressWarnings("unchecked")
+    public E peek()
+    {
+        checkIfEmpty();
+
+        return (E) items[index];
+    }
+
+    /**
+     * Describes the stack, listing the element in order of depth (top element first).
+     *
+     * @return string description of the stack
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder("Stack[");
+
+        for (int i = index; i >= 0; i--)
+        {
+            if (i != index) builder.append(", ");
+
+            builder.append(String.valueOf(items[i]));
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+
+    /**
+     * Returns a snapshot of the current state of the stack as an array of objects. The first object is the deepest in
+     * the stack, the last object is the most shallowest (most recently pushed onto the stack).  The returned array may
+     * be manipulated (it is a copy).
+     *
+     * @return the stack as an object array
+     */
+    public Object[] getSnapshot()
+    {
+        Object[] result = new Object[index + 1];
+
+        System.arraycopy(items, 0, result, 0, index + 1);
+
+        return result;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java
new file mode 100644
index 0000000..2a2a3bf
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java
@@ -0,0 +1,173 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InheritanceSearch;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A key component in implementing the "Gang of Four" Strategy pattern. A StrategyRegistry will match up a given input
+ * type with a registered strategy for that type.
+ *
+ * @param <A> the type of the strategy adapter
+ */
+public final class StrategyRegistry<A>
+{
+    private final Class<A> adapterType;
+
+    private final boolean allowNonMatch;
+
+    private final Map<Class, A> registrations = CollectionFactory.newMap();
+
+    private final Map<Class, A> cache = CollectionFactory.newConcurrentMap();
+
+    /**
+     * Used to identify types for which there is no matching adapter; we're using it as if it were a ConcurrentSet.
+     */
+    private final Map<Class, Boolean> unmatched = CollectionFactory.newConcurrentMap();
+
+    private StrategyRegistry(Class<A> adapterType, Map<Class, A> registrations, boolean allowNonMatch)
+    {
+        this.adapterType = adapterType;
+        this.allowNonMatch = allowNonMatch;
+
+        this.registrations.putAll(registrations);
+    }
+
+    /**
+     * Creates a strategy registry for the given adapter type. The registry will be configured to require matches.
+     *
+     * @param adapterType   the type of adapter retrieved from the registry
+     * @param registrations map of registrations (the contents of the map are copied)
+     */
+    public static <A> StrategyRegistry<A> newInstance(Class<A> adapterType,
+                                                      Map<Class, A> registrations)
+    {
+        return newInstance(adapterType, registrations, false);
+    }
+
+    /**
+     * Creates a strategy registry for the given adapter type.
+     *
+     * @param adapterType   the type of adapter retrieved from the registry
+     * @param registrations map of registrations (the contents of the map are copied)
+     * @param allowNonMatch if true, then the registry supports non-matches when retrieving an adapter
+     */
+    public static <A> StrategyRegistry<A> newInstance(
+            Class<A> adapterType,
+            Map<Class, A> registrations, boolean allowNonMatch)
+    {
+        return new StrategyRegistry<A>(adapterType, registrations, allowNonMatch);
+    }
+
+    public void clearCache()
+    {
+        cache.clear();
+        unmatched.clear();
+    }
+
+    public Class<A> getAdapterType()
+    {
+        return adapterType;
+    }
+
+    /**
+     * Gets an adapter for an object. Searches based on the value's class, unless the value is null, in which case, a
+     * search on class void is used.
+     *
+     * @param value for which an adapter is needed
+     * @return the adapter for the value or null if not found (and allowNonMatch is true)
+     * @throws IllegalArgumentException if no matching adapter may be found and allowNonMatch is false
+     */
+
+    public A getByInstance(Object value)
+    {
+        return get(value == null ? void.class : value.getClass());
+    }
+
+    /**
+     * Searches for an adapter corresponding to the given input type.
+     *
+     * @param type the type to search
+     * @return the adapter for the type or null if not found (and allowNonMatch is true)
+     * @throws IllegalArgumentException if no matching adapter may be found   and allowNonMatch is false
+     */
+    public A get(Class type)
+    {
+
+        A result = cache.get(type);
+
+        if (result != null) return result;
+
+        if (unmatched.containsKey(type)) return null;
+
+
+        result = findMatch(type);
+
+        // This may be null in the case that there is no match and we're allowing that to not
+        // be an error.  That's why we check via containsKey.
+
+        if (result != null)
+        {
+            cache.put(type, result);
+        }
+        else
+        {
+            unmatched.put(type, true);
+        }
+
+        return result;
+    }
+
+    private A findMatch(Class type)
+    {
+        for (Class t : new InheritanceSearch(type))
+        {
+            A result = registrations.get(t);
+
+            if (result != null) return result;
+        }
+
+        if (allowNonMatch) return null;
+
+        // Report the error. These things really confused the hell out of people in Tap4, so we're
+        // going the extra mile on the exception message.
+
+        List<String> names = CollectionFactory.newList();
+        for (Class t : registrations.keySet())
+            names.add(t.getName());
+
+        throw new IllegalArgumentException(UtilMessages
+                .noStrategyAdapter(type, adapterType, names));
+    }
+
+    /**
+     * Returns the registered types for which adapters are available.
+     */
+    public Collection<Class> getTypes()
+    {
+        return CollectionFactory.newList(registrations.keySet());
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("StrategyRegistry[%s]", adapterType.getName());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/TimeInterval.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/TimeInterval.java
new file mode 100644
index 0000000..29b1dcc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/TimeInterval.java
@@ -0,0 +1,144 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Used to represent a period of time, specifically as a configuration value. This is often used to specify timeouts.
+ * <p/>
+ * TimePeriods are parsed from strings.
+ * <p/>
+ * The string specifys a number of terms. The values of all the terms are summed together to form the total time period.
+ * Each term consists of a number followed by a unit. Units (from largest to smallest) are: <dl> <dt>y <dd>year <dt>d
+ * <dd>day <dt>h <dd>hour <dt>m <dd>minute <dt>s <dd>second <dt>ms <dd>millisecond </dl> <p>  Example: "2 h 30 m". By
+ * convention, terms are specified largest to smallest.  A term without a unit is assumed to be milliseconds.  Units are
+ * case insensitive ("h" or "H" are treated the same).
+ */
+public class TimeInterval
+{
+    private static final Map<String, Long> UNITS = CollectionFactory.newCaseInsensitiveMap();
+
+    private static final long MILLISECOND = 1000l;
+
+    static
+    {
+        UNITS.put("ms", 1l);
+        UNITS.put("s", MILLISECOND);
+        UNITS.put("m", 60 * MILLISECOND);
+        UNITS.put("h", 60 * UNITS.get("m"));
+        UNITS.put("d", 24 * UNITS.get("h"));
+        UNITS.put("y", 365 * UNITS.get("d"));
+    }
+
+    private static final Pattern PATTERN = Pattern.compile("\\s*(\\d+)\\s*([a-z]*)", Pattern.CASE_INSENSITIVE);
+
+    private final long milliseconds;
+
+    /**
+     * Creates a TimeInterval for a string.
+     *
+     * @param input the string specifying the amount of time in the period
+     */
+    public TimeInterval(String input)
+    {
+        milliseconds = parseMilliseconds(input);
+    }
+
+    public long milliseconds()
+    {
+        return milliseconds;
+    }
+
+    public long seconds()
+    {
+        return milliseconds / MILLISECOND;
+    }
+
+    static long parseMilliseconds(String input)
+    {
+        long milliseconds = 0l;
+
+        Matcher matcher = PATTERN.matcher(input);
+
+        matcher.useAnchoringBounds(true);
+
+        // TODO: Notice non matching characters and reject input, including at end
+
+        int lastMatchEnd = -1;
+
+        while (matcher.find())
+        {
+            int start = matcher.start();
+
+            if (lastMatchEnd + 1 < start)
+            {
+                String invalid = input.substring(lastMatchEnd + 1, start);
+                throw new RuntimeException(UtilMessages.invalidTimeIntervalInput(invalid, input));
+            }
+
+            lastMatchEnd = matcher.end();
+
+            long count = Long.parseLong(matcher.group(1));
+            String units = matcher.group(2);
+
+            if (units.length() == 0)
+            {
+                milliseconds += count;
+                continue;
+            }
+
+            Long unitValue = UNITS.get(units);
+
+            if (unitValue == null)
+                throw new RuntimeException(UtilMessages.invalidTimeIntervalUnit(units, input, UNITS.keySet()));
+
+            milliseconds += count * unitValue;
+        }
+
+        if (lastMatchEnd + 1 < input.length())
+        {
+            String invalid = input.substring(lastMatchEnd + 1);
+            throw new RuntimeException(UtilMessages.invalidTimeIntervalInput(invalid, input));
+        }
+
+        return milliseconds;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("TimeInterval[%d ms]", milliseconds);
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null) return false;
+
+        if (obj instanceof TimeInterval)
+        {
+            TimeInterval tp = (TimeInterval) obj;
+
+            return milliseconds == tp.milliseconds;
+        }
+
+        return false;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/UtilMessages.java b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/UtilMessages.java
new file mode 100644
index 0000000..c21903a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/UtilMessages.java
@@ -0,0 +1,54 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+
+import java.util.Collection;
+
+/**
+ * Static messages
+ */
+class UtilMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(UtilMessages.class);
+
+    private UtilMessages()
+    {
+    }
+
+    static String noStrategyAdapter(Class inputType, Class adapterType, Collection<String> catalog)
+    {
+        return MESSAGES.format("no-strategy-adapter", inputType.getName(), adapterType.getName(),
+                               InternalUtils.joinSorted(catalog));
+    }
+
+    static String stackIsEmpty()
+    {
+        return MESSAGES.get("stack-is-empty");
+    }
+
+    static String invalidTimeIntervalUnit(String unit, String input, Collection<String> units)
+    {
+        return MESSAGES.format("invalid-time-interval-unit", unit, input, InternalUtils.joinSorted(units));
+    }
+
+    static String invalidTimeIntervalInput(String invalid, String input)
+    {
+        return MESSAGES.format("invalid-time-interval-input", invalid, input);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties
new file mode 100644
index 0000000..99056cd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties
@@ -0,0 +1,89 @@
+# Copyright 2006, 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+build-method-conflict=Service building method %s conflicts with (has the same name as, but different parameters than) \
+  previously seen method %s and has been ignored.
+build-method-wrong-return-type=Method %s is named like a service builder method, \
+ but the return type (%s) is not acceptable (try an interface). \
+ The method has been ignored.
+decorator-method-wrong-return-type=Method %s is named like a service decorator method, \
+  but the return type (%s) is not acceptable (try Object). The method has been ignored.
+builder-locked=The Registry Builder has created the Registry, further operations are not allowed.
+service-wrong-interface=Service '%s' implements interface %s, which is not compatible with the requested type %s.
+instantiate-builder-error=Unable to instantiate class %s as a module builder: %s
+builder-method-error=Error invoking service builder method %s (for service '%s'): %s
+constructor-error=Error invoking constructor %s (for service '%s'): %s
+decorator-method-error=Error invoking service decorator method %s (for service '%s'): %s
+builder-method-returned-null=Builder method %s (for service '%s') returned null.
+no-service-matches-type=No service implements the interface %s.
+many-service-matches=Service interface %s is matched by %d services: %s.  \
+  Automatic dependency resolution requires that exactly one service implement the interface.
+no-services-match-marker=Unable to locate any service assignable to type %s with marker annotation %s.
+many-services-match-marker=Unable to locate a single service assignable to type %s with marker annotation %s.  \
+ All of the following services match: %s.
+unknown-scope=Unknown service scope '%s'.
+decorator-method-needs-delegate-parameter=Decorator methods must a parameter for the service delegate \
+ (i.e., the object the created interceptor will delegate to). \
+ Method %s does not include such a parameter, and has been ignored.
+decorator-returned-wrong-type=Decorator method %s (invoked for service '%s') returned %s, \
+  which is not assignable to the %s service interface.
+creating-service=Creating service '%s'.
+invoking-method=Invoking method %s.
+invoking-constructor=Invoking constructor %s.
+recursive-service-build=Construction of service '%s' has failed due to recursion: \
+  the service depends on itself in some way. \
+  Please check %s for references to another service that is itself dependent on service '%1$s'.
+contribution-wrong-return-type=Method %s is named like a service contributor method, \
+  but the return type (%s) is not appropriate (try void). The return value will be ignored.
+too-many-contribution-parameters=Service contribution method %s contains more than one parameter of type Configuration, \
+  OrderedConfiguration, or MappedConfiguration. Exactly one such parameter is required for a service contribution method. \
+  The method has been ignored.
+too-many-configuration-parameters=Service builder method %s contains more than one parameter of type \
+  Collection, List, or Map. Parameters of this type are the way in which service configuration values, \
+  collected from service contributor methods, are provided to the service builder. \
+  Services are only allowed a single configuration. Unexpected results or failures may occur.
+no-contribution-parameter=Service contribution method %s does not contain a parameter of type \
+  Configuration, OrderedConfiguration or MappedConfiguration. This parameter is how the method \
+  make contributions into the service's configuration. The method has been ignored.
+contribution-method-error=Error invoking service contribution method %s: %s
+contribution-was-null=Service contribution (to service '%s', by %s) was null and has been ignored.
+contribution-key-was-null=Key for service contribution (to service '%s', by %s) was null and has been ignored.
+contribution-wrong-value-type=Service contribution (to service '%s', by %s) was an instance of %s, \
+  but %s was expected. The contribution has been ignored.
+contribution-wrong-key-type=Key for service contribution (to service '%s', by %s) was an instance of %s, \
+  but %s was expected. The contribution has been ignored.
+contribution-duplicate-key=Service contribution (to service '%s', by %s) conflicts with \
+  existing contribution (by %s) and has been ignored.
+generic-type-not-supported=Generic type '%s' is not supported. Only simple parameterized lists are \
+  supported.
+error-building-service=Error building service proxy for service '%s' (at %s): %s
+no-public-constructors=Module builder class %s does not contain any public constructors.
+too-many-public-constructors=Module bulider class %s contains more than one public constructor. \
+  The first constructor, %s, is being used. \
+  You should change the class to have only a single public constructor.
+recursive-module-constructor=The constructor for module class %s is recursive: it depends on itself in some way. \
+  The constructor, %s, is in some way is triggering a service builder, decorator or contribution method within the class.
+constructed-configuration=Constructed configuration: %s
+service-construction-failed=Construction of service %s failed: %s
+no-such-service=Service id '%s' is not defined by any module.  Defined services: %s.
+service-id-conflict=Service id '%s' has already been defined by %s and may not be redefined by %s. \
+ You should rename one of the service builder methods.
+ no-constructor=Class %s (implementation of service '%s') does not contain any public constructors.
+ bind-method-must-be-static=Method %s appears to be a service binder method, but is an instance method, not a static method.
+ error-in-bind-method=Error invoking service binder method %s: %s
+no-autobuild-constructor=Class %s does not contain a public constructor needed to autobuild.
+autobuild-constructor-error=Error invoking constructor %s: %s
+overlapping-service-proxy-providers=Setting a new service proxy provider when there's already an existing provider. This may indicate that you have multiple IoC Registries.
+unexpected-service-proxy-provider=Unexpected service proxy provider when clearing the provider. This may indicate that you have multiple IoC Registries.
+no-proxy-provider=Service token for service '%s' can not be converted back into a proxy because no proxy provider has been registered. This may indicate that an IoC Registry has not been started yet.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties
new file mode 100644
index 0000000..082b045
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties
@@ -0,0 +1,43 @@
+# Copyright 2006, 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+unable-to-add-method=Unable to add method %s to class %s: %s
+unable-to-add-field=Unable to add field %s to class %s: %s
+unable-to-add-constructor=Unable to add constructor to class %s: %s
+unable-to-create-class=Unable to create class %s as subclass of %s: %s
+unable-to-lookup-class=Unable to lookup class %s: %s
+unable-to-write-class=Unable to create class %s: %s
+duplicate-method-in-class=Attempt to redefine method %s of class %s.
+logging-interceptor=<Logging interceptor for %s(%s)>
+thread-cleanup-error=Error invoking listener %s: %s
+no-such-property=Class %s does not contain a property named '%s'.
+read-not-supported=Class %s does not provide an accessor ('getter') method for property '%s'.
+write-not-supported=Class %s does not provide an mutator ('setter') method for property '%s'.
+read-failure=Error reading property '%s' of %s: %s
+write-failure=Error updating property '%s' of %s: %s
+property-type-mismatch=Property '%s' of class %s is of type %s, which is not assignable to type %s.
+extra-filter-method=Method %s of filter interface %s does not have a matching method in %s.
+unmatched-service-method=Method %s has no match in filter interface %s.
+unknown-object-proxyProvider=Object proxyProvider '%s' does not exist (in object reference '%s').
+shutdown-listener-error=Error notifying %s of registry shutdown: %s
+no-coercion-found=Could not find a coercion from type %s to type %s.  Available coercions: %s.
+recursive-symbol=Symbol '%s' is defined in terms of itself (%s).
+symbol-undefined=Symbol '%s' is not defined.
+symbol-undefined-in-path=Symbol '%s' is not defined (in %s). 
+missing-symbol-close-brace=Input string '%s' is missing a symbol closing brace.
+missing-symbol-close-brace-in-path=Input string '%s' is missing a symbol closing brace (in %s).
+failed-coercion=Coercion of %s to type %s (via %s) failed: %s
+registry-shutdown=Proxy for service %s is no longer active because the IOC Registry has been shut down.
+service-build-failure=Exception constructing service '%s': %s
+startup-failure=An exception occurred during startup: %s
diff --git a/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/util/UtilStrings.properties b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/util/UtilStrings.properties
new file mode 100644
index 0000000..5620897
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/util/UtilStrings.properties
@@ -0,0 +1,22 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+dependency-cycle=Unable to add '%s' as a dependency of '%s', as that forms a dependency cycle ('%<s' depends on itself via '%1$s'). The dependency has been ignored.

+duplicate-orderer=Could not add object with duplicate id '%s'.  The duplicate object has been ignored.

+constraint-format=Could not parse ordering constraint '%s' (for '%s'). The constraint has been ignored.

+one-shot-lock=Method %s may no longer be invoked.

+parameter-was-null=Parameter %s was null.

+parameter-was-blank=Parameter %s was null or contained only whitespace.

+bad-cast=Parameter %s (%s) is not assignable to type %s.

+bad-marker-annotation=Marker annotation class %s is not valid because it is not visible at runtime. Add a @RetentionPolicy(RUNTIME) to the class.

diff --git a/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/util/UtilStrings.properties b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/util/UtilStrings.properties
new file mode 100644
index 0000000..1624cc0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/util/UtilStrings.properties
@@ -0,0 +1,18 @@
+# Copyright 2006 The Apache Software Foundation

+#

+# Licensed under the Apache License, Version 2.0 (the "License");

+# you may not use this file except in compliance with the License.

+# You may obtain a copy of the License at

+#

+#     http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing, software

+# distributed under the License is distributed on an "AS IS" BASIS,

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

+# See the License for the specific language governing permissions and

+# limitations under the License.

+

+no-strategy-adapter=No adapter from type %s to type %s is available (registered types are %s).

+stack-is-empty=Stack is empty.

+invalid-time-interval-unit=Unknown time interval unit '%s' (in '%s').  Defined units: %s.

+invalid-time-interval-input=Unexpected string '%s' (in time interval '%s').
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/case.apt b/hlship-20080520/tapestry-ioc/src/site/apt/case.apt
new file mode 100644
index 0000000..ae8acd8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/case.apt
@@ -0,0 +1,25 @@
+ ----
+ Case Insensitivity
+ ----
+ 
+Case Insensitivity
+
+  Ever get frustrated because you typed the right thing with the wrong case and your system blew up?  We do.
+  
+  Tapestry IOC attempts to be case insensitive for all the main constructs:
+   
+  * Service ids.
+  
+  * Object provider prefixes.
+  
+  * Message keys.
+  
+  []
+  
+  Thus, <<<getService("Baz", Baz.class)>>> is preferred, but <<<getService("BAZ", Baz.class)>>> (or any variation thereof) will work just exactly as well.  This also extends to other naming conventions,
+  such as <<<contributeFoo>>> methods. It also applies to values inside annotations.
+  
+  Just case is ignored --
+  other punctuation, as well as whitespace, must exactly match.
+  
+  Under the covers, this is supported by the {{{../apidocs/org/apache/tapestry/ioc/CaseInsensitiveMap.html}CaseInsensitiveMap}} class.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/coerce.apt b/hlship-20080520/tapestry-ioc/src/site/apt/coerce.apt
new file mode 100644
index 0000000..0546ea5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/coerce.apt
@@ -0,0 +1,81 @@
+ ----
+ Type Coercion
+ ----
+ 
+Type Coercion
+
+  Tapestry frequently must coerce objects from one type to another. By coercion, we mean to convert an object of some type into a new object
+  of a different type with similar content: a common example is coercing a string into an integer or a double.
+  
+  Although these types of coercions happens more inside
+  tapestry-core (inlcuding coercions of {{{http://tapestry.apache.org/tapestry5/tapestry-core/guide/coercion.html}component parameters}}), this
+  may also happen inside tapestry-ioc, such as when injecting a value, rather than a service, into a builder method.
+  
+  Like everything else in Tapestry, type coercions are extensible.  At the root is the
+  {{{../apidocs/org/apache/tapestry/ioc/services/TypeCoercer.html}TypeCoercer}} service. Its configuration consists
+  of a number of 
+  {{{../apidocs/org/apache/tapestry/ioc/services/CoercionTuple.html}CoercionTuple}}s.  Each tuple defines how to coerce from one type to another.
+  The initial set of coercions is focused primarily on coercions between different numeric types:
+  
+[images/type-coercer.png] Default Type Coercions  
+
+  There's a few special coercions related to null there; Object --\> List wraps a lone object as a singleton list, we then need
+  null --\> List to ensure that null stays null (rather than a singleton list whose lone element is a null). 
+  
+  Tapestry can <interpolate> necessary coercions.  For example, say it is necessary to coerce a StringBuffer to an Integer; the
+  TypeCoercer will chain together a series of coercions:
+  
+   * Object --\> String
+   
+   * String --\> Long
+   
+   * Long --\> Integer
+   
+   []
+
+Coercing from null
+
+  Coercing from null is special; it is not a spanning search as with the other types.
+  Either there is a specific coercion from null to the desired type, or no coercion
+  takes places (and the coerced value is null).
+
+  The only built-in null coercion is from null to boolean (which is always false).
+   
+Contributing new Coercions
+
+  TypeCoercer is extensible, you may add new coercions as desired.  For example, let's say you have a Money type that represents
+  an amount of some currency, and you want to be able to convert from  BigDecimal to Money.  Further, let's assume that
+  Money has a constructor that accepts a BigDecimal as its parameter.  We'll use a little Tapestry IOC configuration jujitsu to
+  inform the TypeCoercer about this coercion.
+  
++---+    
+   public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
+   {
+     Coercion<BigDecimal, Money> coercion = new Coercion<BigDecimal, Money>()
+     {
+       public Money coerce(BigDecimal input)
+       {
+         return new Money(input);
+       }
+     };
+     
+     configuration.add(new CoercionTuple<BigDecimal, Money>(BigDecimal.class, Money.class, coercion));     
+   }
++---+  
+
+  Further, since TypeCoercer knows how to convert Double to BigDecimal, or even Integer (to Long to Double) to BigDecimal, all of those coercions would
+  work as well.
+  
+  When creating a coercion from null, use Void.class as the source type.  For example, the builtin coercion from null to Boolean is implemented as:
+  
++----+
+  configuration.add(new CoercionTuple(void.class, Boolean.class,
+        new Coercion<Void, Boolean>()
+        {
+            public Boolean coerce(Void input)
+            {
+                return false;
+            }
+        }));
++---+          
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/command.apt b/hlship-20080520/tapestry-ioc/src/site/apt/command.apt
new file mode 100644
index 0000000..570c7ce
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/command.apt
@@ -0,0 +1,74 @@
+ ----

+ Chain of Command

+ ----

+ 

+Chain of Command

+ 

+  One of the most useful of the Gang Of Four Design Patterns is the <<command>> pattern.

+

+  With the command pattern, a complex process is broken down into many individual steps.  The

+  steps are the <commands> in the command pattern.  A key part of this is that the commands

+  are expected to implement some common interface. The commands are carefully arrainged into

+  a specific order.

+

+  The process operates by working down the list of commands. Each command is given a chance

+  to operate. A command can terminate the process either by throwing an exception, or by

+  returning true.

+  

+  The return type of the command method does not have to be boolean:  For object types,

+  any non-null value short-circuits the process. For numeric type, any non-zero value.

+  For void methods, only throwing an exception will short circuit the process.

+  

+  Often, the command interface consists of a single method. When the command interface

+  has multiple methods, each can be thought of as its own chain.

+  

+  This is a useful pattern because it makes it very easy to <extend> a given process,

+  simply by providing new commands and specifying where they fit into the overall

+  process. Most often chain of command is combined with an ordered 

+  {{{configuration.html}configuration}} to define what the list of commands are (and in what

+  order they should execute).

+  

+ChainBuilder Service

+

+  Because this pattern is used so often inside Tapestry, a built-in service exists

+  to create implementations of the pattern as needed.  The

+  {{{../apidocs/org/apache/tapestry/ioc/services/ChainBuilder.html}ChainBuilder}}

+  service takes care of all the work:

+  

++----+

+public interface ChainBuilder

+{

+  <T> T build(Class<T> commandInterface, List<T> commands);

+}

++----+

+

+  All that generics parameterization just ensures that the command interface matches

+  the items in the list, and confirms that a single instance of the command interface

+  will be returned.

+

+  Invoking this method returns an object that encapsulates the chain of command for a

+  particular interface and a particular list of commands implementing that interface.  

+  

+  This can be used inside a service builder method.  Nothing says a service builder method

+  just has to  instantiate a class; it is only required to return an appropriate object.

+  We can just let the ChainBuilder service create that object.

+  

++----+

+  public static MyChainService build(List<MyChainService> commands,

+    @InjectService("ChainBuilder")

+    ChainBuilder chainBuilder)

+  {

+     return chainBuilder.build(MyChainService.class, commands);

+  }

++----+

+

+  Here, the behavior of the MyChainService is defined by its configuration: an ordered

+  list of MyChainService commands that are contributed by one or more modules.

+  

+  Internally, the ChainBuilder creates a new class that implements the service interface.

+  The list of commands is converted into an array, which is used inside the service implementation

+  (for maximum efficiency).  Therefore, changing the list after creating the chain

+  instance will not affect the chain instance's behavior.

+  

+  ChainBuilder will reuse the fabricated class for any number of chains of the same

+  command interface.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/configuration.apt b/hlship-20080520/tapestry-ioc/src/site/apt/configuration.apt
new file mode 100644
index 0000000..aab48d5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/configuration.apt
@@ -0,0 +1,244 @@
+ ----

+ Tapestry IoC Configurations

+ ----

+ 

+Tapestry IoC Configurations

+

+  One of the key concepts on Tapestry IoC is <distributed configuration>. This is a

+  concept borrowed from the Eclipse Plugin API and evidenced in 

+  HiveMind prior to Tapestry 5 IoC.

+  

+  So ... nice term, what does it mean?

+  

+  Distributed configuration is the key feature of Tapestry IoC that supports <extensibility>.

+  

+  The distributed part refers to the fact that <any module> may make <contributions> to 

+  any service's configuration (subject to the normal visibility rules for private services).

+  

+  This seems esoteric, but is quite handy, and is best explained by example.

+  

+  Say you are building a service that, say, maps a file extension

+  to an interface called FileServicer. There's a bunch of different services, all implementing the

+  FileServicer interface, across many different modules, each doing something specific for a

+  particular type of file (identified by the file's extension).  

+  

+  A central service uses this configuration to select a particular FileService interface:

+  

++------+

+  public static FileServicer buildFileServicerDispatcher(Map<String,FileServicer> contributions)

+  {

+    return new FileServiceDispatcherImpl(contributions);

+  } 

++------+

+

+  In order to provide a value for the contribution parameter, Tapestry will <collect> contributions

+  from service contribution methods. It will ensure that the keys and values match the generic

+  types shown (String for the key, FileServicer for the value). The map will be assembled and passed into

+  the service builder method, and from there, into the FileServiceDispatcherImpl contructor.

+  

+  So where do the values come from?  Service contributor methods, methods that start with

+  "contribute":

+  

++------+

+  public static void contributeFileServicerDispatcher(MappedConfiguration<String,FileServicer> configuration)

+  {

+    configuration.add("txt", new TextFileServicer());

+    configuration.add("pdf", new PDFFileServicer());

+  }  

++------+

+

+  Like service builder and service decorator methods, we can inject services if we like:

+  

++------+

+  public static void contributFileServicerDispatcher(MappedConfiguration<String,FileServicer> configuration,

+  

+    @InjectService("TextFileServicer") FileServicer textFileServicer,

+    

+    @InjectService("PDFFileServicer") FileServicer pdfFileServicer,

+  {

+    configuration.add("txt", textFileServicer);

+    configuration.add("pdf", pdfFileServicer);

+  }  

++------+  

+   

+  The <<extensibility>> comes from the fact multiple modules may all contribute to the same

+  service configuration:

+  

++------+

+   public static void contributeFileServicerDispatcher(MappedConfiguration<String,FileServicer> configuration)

+  {

+    configuration.add("doc", new WordFileServicer());

+    configuration.add("ppt", new PowerPointFileServicer());

+  }  

++------+

+

+  Now the FileServicerDispatcher builder method gets a Map with at least four entries in it.

+

+  Because Tapestry IoC is highly dynamic (it scans the visible JAR manifest files to identify

+  module builder classes), the FileServicerDispatcher service may be in one module, and the

+  other contributing modules (such as the one that contributes the Office file services) may be written at 

+  a much later date. With no change to the FileServicerDispatcher service or its module builder class,

+  the new services "plug into" the overall solution, simply by having their JAR's on runtime classpath. 

+  

+Configuration Types

+

+  There are three different styles of configurations (with matching contributions):

+  

+  * Unordered Collection. Contributions are simply added in and order is not important.

+  

+  * Ordered List.  Contributions are provided as an ordered list. Contributions must

+    establish the order by giving each contributed object a unique id,

+    by establishing forward and backward dependencies between the values.

+    

+  * Map. Contributions provide unique keys and corresponding values.

+  

+  []

+  

+* Unordered Collection

+

+  A service builder method can collect an unordered list of values by defining

+  a parameter of type java.util.Collection.  Further, you should parameterize

+  the type of collection.  Tapestry will identify the parameterized type

+  and ensure that all contributions match.

+  

+  One thing to remember is that the order in which contributions occur

+  is unspecified. There will be a possibly large number modules, each having

+  zero or more methods that contribute into the service.  The order in which these

+  methods are invoked is unknown.

+  

+  For example, here's a kind of Startup service that needs some Runnable

+  objects.  It doesn't care what order the Runnable objects are executed in.

+  

++------+

+  public static Runnable buildStartup(final Collection<Runnable> configuration)

+  {

+    return new Runnable()

+    {

+      public void run()

+      {

+        for (Runnable contribution : configuration)

+          contribution.run();

+      }

+    };

+  }  

++------+

+

+  Here we don't even need a separate class for the implementation,

+  we use a inner class for the implementation. The point is, the configuration

+  is provided to the builder method, which passes it along to the implementation

+  of the service.  

+  

+  On the contribution side, a service contribution method sees a 

+  {{{apidocs/org/apache/tapestry/ioc/Configuration.html}Configuration}} object:

+  

++------+

+  public static void contributeStartup(Configuration<Runnable> configuration)

+  {

+    configuration.add(new JMSStartup());

+    configuration.add(new FileSystemStartup());

+  }    

++------+

+   

+  The Configuration interface defines just a single method:  add().  This is very

+  intentional: the only thing you can do is add new items. If we passed in a Collection,

+  you might be tempted to check it for values, or remove them ... but that flys in the face

+  of the fact that the order of execution of these service contribution methods is 

+  entirely unknown.

+  

+  For readability (if Java any longer supports that concept), we've parameterized the

+  configuration parameter of the method, constraining it to instances of java.lang.Runnable,

+  so as to match the corresponding parameter.  This is optional, but often very helpful.  In any case,

+  attempting to contribute an object that doesn't extend or implement the type (Runnable) will result

+  in a runtime warning (and the value will be ignored).

+  

+  Tapestry supports only this simple form of parameterized types.  Java generics supports a wider

+  form, "wildcards", that Tapestry doesn't understand.

+  

+

+* {Ordered List}

+

+  Ordered lists are much more common. With an ordered list, the contributions are sorted into a

+  proper order before being provided to the service builder method.

+  

+  Again, the order in which service contribution methods are invoked is unknown. Therefore, the order in

+  which objects are added to the configuration is not known. Instead, we enforce an order on the items

+  <after> all the contributions have been added.  As with {{{decorator.html}service decorators}}, we

+  set the order by giving each contributed object a unique id, and identifying (by id) which items

+  must preceded it in the list, and which must follow.

+  

+  So, if we changed our Startup service to require a specific order for startup:

+  

++------+

+  public static Runnable buildStartup(final List<Runnable> configuration)

+  {

+    return new Runnable()

+    {

+      public void run()

+      {

+        for (Runnable contribution : configuration)

+          contribution.run();

+      }

+    };

+  }  

++------+  

+

+  Notice that the service builder method is shielded from the details of how the items are

+  ordered. It doesn't have to know about ids and pre- and post-requisites.  By using

+  a parameter type of List, we've triggered Tapestry to collected all the ordering information.

+  

+  For our service contribution methods, we must provide a parameter

+  of type 

+  {{{apidocs/org/apache/tapestry/ioc/OrderedConfiguration.html}OrderedConfiguration}}:

+ 

++------+

+  public static void contributeStartup(OrderedConfiguration<Runnable> configuration)

+  {

+    configuration.add("JMS", new JMSStartup());

+    configuration.add("FileSystem", new FileSystemStartup(), "after:CacheSetup");

+  }    

++------+

+  

+  Often, you don't care about ordering, the first form of the add method is used then.   The ordering algorithm will find a spot for the

+  object (here the JMSStartup instance) based on the constraints of other contributed objects.

+  

+  For the "FileSystem" contribution, a constraint has been specified, indicating

+  that FileSystem should be ordered after some other contribution named "CacheSetup". Any number of such

+  {{{order.html}ordering constraints}} may be specified (the add() method accepts

+  a variable number of arguments).

+  

+  The object passed in may be null; this is valid, and is considered a "join point": points of reference in the

+  list that don't actually have any meaning of their own, but can be used when ordering other elements.

+  <TODO: Show example for chain of command, once that's put together.> 

+  

+  Null values, once ordered,

+  are editted out (the List passed to the service builder method does not include any nulls). Again, they are

+  allowed as placeholders, for the actual contributed objects to organize themselves around.

+  

+  

+* Mapped Configurations

+

+  As discussed in the earlier examples, mapped configurations are also supported.  The keys passed in must

+  be unique.  When conflicts occur, Tapestry will log warnings (identifying the source, in terms of invoked methods, of

+  the conflict), and ignore the conflicting value.

+  

+  The value may not be null.

+  

+  For mapped configurations where the key type is String, a 

+  {{{apidocs/org/apache/tapestry/ioc/util/CaseInsensitiveMap.html}CaseInsensitiveMap}}

+  will be  automatically used (and passed to the service builder method), to help ensure that {{{case.html}case insensitivity}} 

+  is automatic and pervasive.

+  

+Injecting Resources

+

+  In addition to injecting services into a contributor method (via

+  the @InjectService and @Inject annotations), 

+  Tapestry will key off of the parameter type to allow

+  other things to be injected.

+  

+  

+  * {{{apidocs/org/apache/tapestry/ioc/ObjectLocator.html}ObjectLocator}}:  access to other services visible

+  to the contributing module

+  

+  []

+  

+  No annotation is needed for these cases.

diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/basics.apt b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/basics.apt
new file mode 100644
index 0000000..52916e0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/basics.apt
@@ -0,0 +1,145 @@
+ ----
+ Basic Services and Injection
+ ----
+
+Basic Services and Injection
+
+  A good part of the basics is convention: what to name your classes, what packages to put them in and so forth.
+
+  In many cases, these conventions are just a little stronger: you may have to do some amount of
+  extra configuration if you choose to go your own way.
+
+Getting Started
+
+  Like anything else, you want to choose a package for your application, such as org.example.myapp.
+  
+  By convention, services go in a package named "services".
+
+  Module classes are suffixed with "Module".
+
+  Thus, you might start with a module class org.example.myapp.services.MyAppModule.
+
+Simple Services
+
+  The simplest services don't have any special configuration or dependencies.  They are defined as services so that
+  they can be shared.
+
+  For example, the {{{../../apidocs/org/apache/tapestry/ioc/services/PropertyAccess.html}PropertyAccess}} service 
+  is used in multiple places around the framework to access properties of objects (its a wrapper around
+  the Java Beans Introspector and a bit of reflection).  This is defined in the
+  {{{../../apidocs/org/apache/tapestry/ioc/services/TapestryIOCModule.html}TapestryIOCModule}}.
+
+  It's useful to share PropertyAccess, because it does a lot of useful caching internally.
+
+  The PropertyAccess service is defined inside TapestryIOCModule's bind() method:
+
++----+
+  public static void bind(ServiceBinder binder)
+  {
+    . . .
+    binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
+    binder.bind(ExceptionAnalyzer.class, ExceptionAnalyzerImpl.class);
+    . . .
+  }
++----+
+  
+  This example includes {{{../../apidocs/org/apache/tapestry/ioc/services/ExceptionAnalyzer.html}ExceptionAnalyzer}}, 
+  because it has a dependency on PropertyAccess:
+
++----+
+public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
+{
+    private final PropertyAccess propertyAccess;
+
+    public ExceptionAnalyzerImpl(PropertyAccess propertyAccess)
+    {
+        this.propertyAccess = propertyAccess;
+    }
+
+    . . .
+}
++----+
+
+  And that's the essence of Tapestry IoC right there; the bind() plus the constructor is <all> that's necessary.
+
+Service Disambiguation
+
+  In the previous example, we relied on the fact that only a single service implements the PropertyAccess interface.
+  Had more than one done so, Tapestry would have thrown an exception when the ExceptionAnalyzer service was realized (it isn't
+  until a service is realized that dependencies are resolved).
+
+  That's normally ok; in many situations, it makes sense that only a single service implement a particular interface.
+
+  But there are often exceptions to the rule, and in those cases, we must provide more information to 
+  Tapestry when a service is defined, and when it is injected, in order to disambiguate -- to inform Tapestry which
+  particular version of service to inject.
+
+  This example demonstrates a number of ideas that we haven't discussed so far, so try not to get
+  too distracted by some of the details.  One of the main concepts introduced here is <service builder methods>.  
+  These are methods, of a Tapestry IoC Module class, that act as an alternate way
+  to define a service.  You often used a service builder method if you are doing more than simply instantiating a class.
+
+  A service builder method is a method of a Module, prefixed with the word "build".  This defines a service, and
+  dependency injection occurs on the parameters of the service builder method.
+
+  The Tapestry web framework includes the concept of an "asset": a resource that may be inside a web application, or packaged
+  inside a JAR.  Assets are represented as the type {{{../../apidcos/org/apache/tapestry/Asset.html}Asset}}.
+
+  In fact, there are different implementations of this class: one for context resources (part of the web application), the other
+  for classpath resources (packaged inside a JAR).  The Asset instances are created via
+  {{{../../apidocs/org/apache/tapesty/services/AssetFactory.html}AssetFactory}} services.
+
+  Tapestry defines two such services, in the
+  {{{../../apidocs/org/apache/tapestry/services/TapestryModule.html}TapestryModule}}.
+
++---+
+  @Marker(ClasspathProvider.class)
+  public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache,
+
+  ClasspathAssetAliasManager aliasManager)
+  {
+    ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceCache, aliasManager);
+
+    resourceCache.addInvalidationListener(factory);
+
+    return factory;
+  }
+
+  @Marker(ContextProvider.class)
+  public AssetFactory buildContextAssetFactory(ApplicationGlobals globals)
+  {
+    return new ContextAssetFactory(request, globals.getContext());
+  }
++---+
+
+  Service builder methods are used here for two purposes:  For the ClasspathAssetFactory, we are registering the new service as a
+  listener of events from another service.  For the ContextAssetFactory, we are extracting a value from an injected service and passing
+  <that> to the constructor.
+
+  What's important is that the services are differentiated not just in terms of their id (which is defined by the name of the method,
+  after stripping off "build"), but in terms of their <marker annotation>.
+
+  The {{{../../apidocs/org/apache/tapestry/ioc/annotations/Marker.html}Marker}} annotation provides the discriminator.  When
+  the service type is supplemented with the ClasspathProvider annotation, the ClasspathAssetFactory is injected.  When the
+  service type is supplemented with the ContextProvider annotation, the ContextAssetFactory is injected.
+
+  Here's an example.  Again, we've jumped the gun with this <service contributor method> (we'll get into the why and how of these later), but
+  you can see how Tapestry is figuring out which service to inject based on the presence of those annotations:
+
++----+
+  public void contributeAssetSource(MappedConfiguration<String, AssetFactory> configuration,
+      @ContextProvider
+      AssetFactory contextAssetFactory,
+
+      @ClasspathProvider
+      AssetFactory classpathAssetFactory)
+  {
+    configuration.add("context", contextAssetFactory);
+    configuration.add("classpath", classpathAssetFactory);
+  }
++---+
+
+  This is far from the final word on injection and disambiguation; we'll be coming back to this concept repeatedly.  And in later chapters
+  of the cookbook, we'll also go into more detail about the many other concepts present in this example.  The important part is
+  that Tapestry <primarily> works off the parameter type (at the point of injection), but when that is insufficient (you'll know ... there will be an error) you
+  can provide additional information, in the form of annotations, to straighten things out.
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/index.apt b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/index.apt
new file mode 100644
index 0000000..094cf72
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/index.apt
@@ -0,0 +1,20 @@
+ ----
+ Tapestry IoC Cookbook
+ ----
+
+Tapestry IoC Cookbook
+
+  Tapestry IoC, though designed specifically for the needs of the Tapestry web framework,  may also be employed as a stand-alone IoC container, separate
+  from the rest of Tapestry.
+
+  Tapestry IoC is a sophisticated tool that takes some experience to use properly.
+
+  The existing documentation is factually correct, but is designed more as a reference, rather than giving the big picture.  In the Cookbook,
+  we'll try to show how Tapestry IoC is really used, and build up towards that big picture.
+
+  The cookbook will show a bit more about how to use Tapestry IoC, using real examples from the Tapestry code base (both the tapestry-ioc
+  and tapestry-core modules).
+
+  A word of caution: several of the examples have been taken from Tapestry's <internal> code base.  Tapestry internals are
+  private, subject to change at any time, so be aware that if you go peeking at the internal source code, it may have
+  changed since the corresponding documentation was written.  
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/patterns.apt b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/patterns.apt
new file mode 100644
index 0000000..33b84b1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/patterns.apt
@@ -0,0 +1,140 @@
+ ----
+ Using Patterns
+ ----
+
+Using Patterns
+
+  Tapestry IoC has support for implementing several of the
+  {{{http://en.wikipedia.org/wiki/Design_pattern_(computer_science)}Gang Of Four Design Patterns}}.
+  In fact, the IoC container itself is a pumped up version of the Factory pattern.
+
+  The basis for these patterns is often the use of <service builder methods>, where
+  a {{{servconf.html}configuration}} for the service is combined with a factory to produce
+  the service implementation on the fly.
+  
+Chain of Command Pattern
+
+  Let's look at another example, again from the Tapestry code base.  The
+  {{{../../apidocs/org/apache/tapestry/services/InjectionProvider.html}InjectProvider}} interface
+  is used to process the @Inject annotation on the fields of a Tapestry page or component.
+  Many different instances are combined together to form a
+  {{{../command.html}chain of command}}.
+
+  The interface has only a single method (this is far from uncommon):
+
++---+
+public interface InjectionProvider
+{
+  boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
+      ClassTransformation transformation, MutableComponentModel componentModel);
+}
++---+
+
+  The return type indicates whether the provider was able to do something.  For example,
+  the AssetInjectionProvider checks to see if there's an @Path annotation on the field, and
+  if so, converts the path to an asset, works with the ClassTransformation object to 
+  implement injection, and returns true to indicate success.  Returns true terminates
+  the chain early, and that true value is ultimately returned to the caller.
+
+  In other cases, it returns false and the chain of command continues down to the
+  next provider.  If no provider is capable of 
+  handling the injection, then the value false is ultimately returned.
+
+  The InjectionProvider service is built up via contributions.  These are the contributions
+  from the TapestryModule:
+
++---+
+public static void contributeInjectionProvider(
+    OrderedConfiguration<InjectionProvider> configuration,
+    MasterObjectProvider masterObjectProvider,
+    ObjectLocator locator,
+    SymbolSource symbolSource,
+    AssetSource assetSource)
+{
+  configuration.add("Default", new DefaultInjectionProvider(masterObjectProvider, locator));
+
+  configuration.add("ComponentResources", new ComponentResourcesInjectionProvider());
+
+  configuration.add(
+      "CommonResources",
+      new CommonResourcesInjectionProvider(),
+      "after:Default");
+
+  configuration.add(
+      "Asset",
+      new AssetInjectionProvider(symbolSource, assetSource),
+      "before:Default");
+
+  configuration.add("Block", new BlockInjectionProvider(), "before:Default");
+  configuration.add("Service", new ServiceInjectionProvider(locator), "after:*");
+}
++---+
+
+  And, of course, other contributions could be made in other modules ... if you wanted to
+  add in your own form of injection.
+
+  The configuration is converted into a service via a service builder method:
+
++----+
+  public InjectionProvider build(List<InjectionProvider> configuration, ChainBuilder chainBuilder)
+  {
+    return chainBuilder.build(InjectionProvider.class, configuration);
+  }
++---+
+
+  Now, let's see how this is used.  The InjectWorker class looks for fields with
+  the InjectAnnotation, and uses the chain of command to inject the appropriate value.  However,
+  to InjectWorker, there is no chain ... just a <single> object that implements the InjectionProvider interface.
+
++----+
+public class InjectWorker implements ComponentClassTransformWorker
+{
+  private final ObjectLocator locator;
+
+  // Really, a chain of command
+
+  private final InjectionProvider injectionProvider;
+
+  public InjectWorker(ObjectLocator locator, InjectionProvider injectionProvider)
+  {
+    this.locator = locator;
+    this.injectionProvider = injectionProvider;
+  }
+
+  public final void transform(ClassTransformation transformation, MutableComponentModel model)
+  {
+    for (String fieldName : transformation.findFieldsWithAnnotation(Inject.class))
+    {
+      Inject annotation = transformation.getFieldAnnotation(fieldName, Inject.class);
+
+      try
+      {
+        String fieldType = transformation.getFieldType(fieldName);
+
+        Class type = transformation.toClass(fieldType);
+
+        boolean success = injectionProvider.provideInjection(
+            fieldName,
+            type,
+            locator,
+            transformation,
+            model);
+
+        if (success) transformation.claimField(fieldName, annotation);
+      }
+      catch (RuntimeException ex)
+      {
+        throw new RuntimeException(ServicesMessages.fieldInjectionError(transformation
+            .getClassName(), fieldName, ex), ex);
+      }
+
+    }
+  }
+}
++----+
+
+  Reducing the chain to a single object vastly simplifies the code: we've <factored out> the loop implicit in the chain of command.
+  That eliminates a lot of code, and that's less code to test, and fewer paths through InjectWorker, which lowers its complexity further.  
+  We don't have to test the cases where the list of injection providers is empty, or consists of only a single object, or where it's the third
+  object in that returns true: it looks like a single object, it acts like a single object ... but its implementation uses many objects.
+
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/servconf.apt b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/servconf.apt
new file mode 100644
index 0000000..63fb00f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/cookbook/servconf.apt
@@ -0,0 +1,205 @@
+ ----
+ Service Configurations
+ ----
+
+Service Configurations
+
+  This is an area of Tapestry IoC that is often least well understood.  Tapestry services often must have some configuration to fine tune
+  exactly what they do.  One of the interactions between modules is that these service configurations are shared: they may
+  be contributed into by any module.
+
+  Let's start with the most basic kind, the unordered configuration.
+
+Unordered Service Configurations
+
+  One of Tapestry's features is the ability to package assets (images, style sheets, javascript libraries, etc.) inside JAR files
+  and expose those to the client.  For example, an application URL /assets/org/example/mylib/mylib.js would refer to
+  a file, myllib.js, stored on the classpath in the /org/example/mylib folder.
+
+  That's fine for most cases, but for certain file extensions, we don't want to allow a client browser to "troll" for the files, as the
+  contents could compromise security.  For example, downloading a .class file is bad: a clever client might download one that contains
+  a hardcoded user name or password.
+
+  Thus, for certain file extensions, Tapestry guards the resource by attaching an MD5 digest for the resource to the URL. 
+  The checksum is derived from the file contents; thus it can't be spoofed from the client unless the client already has the file contents.
+
+  This is controlled by the 
+  {{{../../apidocs/org/apache/tapestry/services/ResourceDigestGenerator.html}ResourceDigestGenerator}} service, which uses its
+  configuration to determine which file extensions require an MD5 digest.
+
+* Contributing to a Service
+
+  The Tapestry module makes a contribution into the service configuration:
+
++-----+
+  public static void contributeResourceDigestGenerator(Configuration<String> configuration)
+  {
+    configuration.add("class");
+    configuration.add("tml");
+  }
++----+
+
+  This is a <service contribution method>, a method that is invoked to provide values for a configuration.  We'll see how the
+  service receives these contributions shortly.  The 
+  {{{../../apidocs/org/apache/tapestry/ioc/Configuration.html}Configuration}} object is how
+  values are added to the service's configuration. Other parameters to a service configuration method are injected
+  much as with a service's constructor, or a service builder method.
+
+  How does Tapestry know which service configuration to update?  It's from the name of the method, anything
+  after the "contribute" prefix is the id of the service to contribute to (the match against service id is  
+  case insensitive).
+
+  Here, the configuration receives two values:  "class" (a compiled Java class) and "tml" (a Tapestry component template).
+
+  Say your application stored a file on the classpath needed by your application; for illustrative purposes, perhaps it
+  is a PGP private key.  You don't want any client to able to download a .pgp file, no matter how unlikely that
+  would be.  Thus:
+
++----+
+public class MyAppModule
+{
+ public static void contributeResourceDigestGenerator(Configuration<String> configuration)
+ {
+   configuration.add("pgp");
+ }
+}
++----+
+
+  The contribution in MyAppModule doesn't <replace> the normal contribution, it is <combined>.  The end result is that
+  .class, .tml and .pgp files would <all> be protected.
+
+* Receiving the Configuration
+
+  A service receives the configuration as an injected parameter ... not of type Configuration (that's used for <making> contributions), but
+  instead is  of type Collection:
+
++----+
+public class ResourceDigestGeneratorImpl implements ResourceDigestGenerator
+{
+  private final Set<String> digestExtensions;
+
+  public ResourceDigestGeneratorImpl(Collection<String> configuration)
+  {
+      digestExtensions = new HashSet<String>(configuration);
+  }
+
+  . . .
+}
++---+
+
+  In many cases, the configuration is simply stored into an instance variable; in this example, the value is transformed
+  from a Collection to a Set.
+
+  These kinds of unordered configurations are surprisingly rare in Tapestry (the only other notable one is for the
+  {{{../coerce.html}TypeCoercer}} service).  However, as you can see, setting up such a configuration is quite easy.
+
+Ordered Configurations
+
+  Ordered configurations are very similar to unordered configurations ... the difference is that the configuration
+  is provided to the service as a parameter of type List.  This is used when the order of operations counts.  Often
+  these configurations are related to a design pattern such as
+  {{{../command.html}Chain of Command}} or
+  {{{../pipeline.html}Pipeline}}.
+
+  Here, the example is the
+  {{{../../apidocs/org/apache/tapestry/services/Dispatcher.html}Dispatcher}} interface; a Dispatcher inside Tapestry
+  is roughly equivalent to a servlet, though a touch more active.  It is passed a Request and decides if the URL
+  for the Request is something it can handle; if so it will process the request, send a response, and return true.
+
+  Alternately, if the Request can't be handled, the Dispatcher returns false.
+
++----+
+public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration, . . .)
+{
+  // Looks for the root path and renders the start page
+
+  configuration.add("RootPath", new RootPathDispatcher(. . .), "before:Asset");
+
+  // This goes first because an asset to be streamed may have an file extension, such as
+  // ".html", that will confuse the later dispatchers.
+
+  configuration.add(
+          "Asset",
+          new AssetDispatcher(. . .),
+          "before:PageRender");
+
+  configuration.add("PageRender", new PageRenderDispatcher(. . .));
+
+  configuration.add("ComponentAction", new ComponentActionDispatcher(. . .), "after:PageRender");
+}
++---+
+
+  With an {{{../../apidcos/org/apache/tapestry/ioc/OrderedConfiguration.html}OrderedConfiguration}}, 
+  each contribution gets a name, which must be unique.  Here the names are RootPath, Asset, PageRender and ComponentAction.
+
+  The add() method takes a name, the contributed object for that name, and then zero or more optional constraints.
+  The constraints control the ordering.  The "after:" constraint ensures that the contribution is ordered after
+  the other named contribution, the "before:" contribution is the opposite.
+
+  The ordering occurs on the complete set of contributions, from all modules. 
+
+  Here, we need a specific order, used to make sure that the Dispatchers don't get confused about which URLs
+  are appropriate ... for example, an asset URL might be /assets/tapestry/tapestry.js.  This looks just like
+  a component action URL (for page "assets/tapestry/tapestry" and component "js"). Given that software is totally lacking
+  in basic common-sense, we instead use careful ordering of the Dipstachers to ensure that AssetDispatcher is checked <before> 
+  the ComponentAction dispatcher.
+
+* Receiving the Configuration
+
+  The configuration, once assembled and ordered, is provided as a List.
+
+  The MasterDispatcher service configuration defines a {{{../command.apt}Chain of Command}} and we can
+  provide the implementation using virtually no code:
+
++----+
+  public static Dispatcher buildMasterDispatcher(List<Dispatcher> configuration, ChainBuilder chainBuilder)
+  {
+    return chainBuilder.build(Dispatcher.class, configuration);
+  }
++----+
+
+  {{{../../apidocs/org/apache/tapestry/ioc/services/ChainBuilder.html}ChainBuilder}} is a service that
+  <builds other services>.  Here it creates an object of type Dispatcher in terms of the list of Dispatchers.
+  This is one of the most common uses of service builder methods ... for when the service implementation
+  doesn't exist, but can be constructed at runtime.
+
+Mapped Configurations
+
+  The last type of service configuration is
+  the mapped service configuration.  Here we relate a key, often a string, to some value.  The contributions
+  are ultimately combined to form a Map.
+
+  Tapestry IoC's {{{../symbols.html}symbols}} mechanism allows configuration values to be defined and perhaps overridden, then
+  provided to services via injection, using
+  the  {{{../../apidocs/org/apache/tapestry/ioc/annotations/Value.html}Value}} annotation.
+
+  The first step is to contribute values.
+
++----+
+  public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
+  {
+    configuration.add("tapestry.file-check-interval", "1000"); // 1 second
+    configuration.add("tapestry.file-check-update-timeout", "50"); // 50 milliseconds
+    configuration.add("tapestry.supported-locales", "en");
+    configuration.add("tapestry.default-cookie-max-age", "604800"); // One week
+    configuration.add("tapestry.start-page-name", "start");
+    configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
+    configuration.add(
+            "tapestry.scriptaculous.path",
+            "org/apache/tapestry/scriptaculous_1_7_1_beta_3");
+    configuration.add("tapestry.jscalendar.path", "org/apache/tapestry/jscalendar-1.0");
+    configuration.add("tapestry.jscalendar", "classpath:${tapestry.jscalendar.path}");
+  }
++---+
+
+  These contribution set up a number of defaults used to configure various Tapestry services. As you can see, you
+  can even define symbol values in terms of other symbol values.
+
+  Mapped configurations don't have to be keyed on Strings (enums or Class are other common key types).  When a mapped
+  configuration <is> keyed on String, then a case-insensitive map is used.
+
+
+
+
+
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/decorator.apt b/hlship-20080520/tapestry-ioc/src/site/apt/decorator.apt
new file mode 100644
index 0000000..48a7fff
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/decorator.apt
@@ -0,0 +1,316 @@
+ ----

+ Tapestry IoC Decorators

+ ----

+ 

+Tapestry IoC Decorators

+

+  <Decoration> is the name of a popular design pattern.  Using decoration,

+  an existing object's behavior can be extended without changing the implementation

+  of the object.

+  

+  Instead, a new object is placed <around> the existing object.  The rest of the world

+  sees this new object, termed an <<interceptor>>.  The interceptor implements the

+  same  interface as the underlying object being decorated.

+  

+  A common example for this is the Java I/O library.  The abstract InputStream

+  base class has a very simple API for reading bytes from a stream (and a few

+  other things).  Subclasses of InputStream provide a wide array of other options

+  such as buffering, encryption or decryption, as well as control over the source

+  of data read by the stream.  All of these <concerns> are encapsulated in different

+  implementations of InputStream, and all can be connected together in a kind of

+  pipline, using the common InputStream API.

+  

+  Tapestry IoC uses a similar approach, where a one or more of interceptor objects,

+  all implementing the service interface, are strung together.  The service's

+  proxy (responsible for just-in-time instantiation of the service implementation)

+  is at one end of this pipeline, the core service implementation is at the other.

+  

+  For each method in the service interface, the interceptor object can perform

+  some operations before and after re-invoking the same method on the

+  core service implementation.  This is another design pattern: <delegation>.  An interceptor

+  can even catch exceptions thrown by the underlying implementation and react to them.

+  A sufficiently clever interceptor could retry a method if an exception is thrown, or

+  could "soften" a checked exception by wrapping it in a RuntimeException.

+  

+  Decorators often are used in the context of <cross-cutting concerns>, such as logging or

+  transaction management. This approach is a kind of <aspect oriented design>.

+  

+  One such cross cutting concern is lazy initialization of services.  In HiveMind, services

+  are created only as needed, when a method of a service interface is first invoked.

+  This concern is supplied by the Tapestry IoC framework itself, but similar

+  concerns are easily implemented as decorations.

+  

+  Whereas the popular AspectJ framework changes the compiled bytecode of your

+  classes (it calls the process "weaving"),

+  with Tapestry IoC, the approach is to wrap your existing classes in new objects. These

+  wrapper objects are often dynamically created at runtime.

+  

+  It is also common to have <multiple> decorations on a single service. In this case,

+  a whole stack of interceptor objects will be created, each delegating to the next.

+  Tapestry IoC provides control over the order in which such decorations occur.

+  

+  Decorations are driven by service decoration methods. Often, a reusable service

+  exists to do the grunt work of creating and instantiating a new class.

+  

+Service Decoration Methods

+

++---------------------+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.services.LoggingDecorator;

+import org.slf4j.Logger;

+

+public class MyAppModule

+{

+  public static Indexer build()

+  {

+    return new IndexerImpl();

+  }

+  

+  public static <T> T decorateIndexer(Class<T> serviceInterface, T delegate, 

+    String serviceId, Logger logger,

+    

+    LoggingDecorator decorator)

+  {

+    return decorator.build(serviceInterface, delegate, serviceId, logger);

+  } 

+}

++---------------------+

+

+   The method decorateIndexer() is a service decorator method because it starts with the

+   word "decorate".  In this simple case, only the myapp.Indexer service will be decorated,

+   even if there are other services in this module or others ... this is because

+   of the name match ("decorateIndexer" and "buildIndexer"), but we'll shortly see how

+   annotations can be used to target many services for decoration.

+   

+   We are using the parameterized types here (the \<T\>), to reinforce the fact that the delegate object

+   passed in (which will be the core service implementation, or some other interceptor)

+   must implement the service interface, and that the decorator method must return an

+   instance of the service interface.

+   

+   The values that may be provided to a decorator method are exactly the same as for a builder

+   method, with one addition:  The underlying service will be passed in

+   as a parameter of type java.lang.Object (after type erasure, the <<<T delegate>>> parameter

+   becomes <<<Object delegate>>>).  A decorator method must have one

+   parameter for this purpose.

+   

+   In the above example, the decorator method recieves the core service implementation,

+   the service interface for the Indexer service, the Log for the Indexer service,

+   and an interceptor factory that generates logging interceptors.

+   

+   The "heavy lifting" is provided by the factory, which will create a new interceptor

+   that logs method entry before delegating to the core service implementation. The interceptor

+   will also log method parameters, return values, and even log exceptions.

+   

+   The return value of the method is the new interceptor. You may return null if your

+   decorator method decides not to decorate the supplied service.

+   

+   Of course, nothing stops you from combining building with decorating inside

+   the service builder method:

+   

+   

++---------------------+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.services.LoggingDecorator;

+import org.slf4j.Logger;

+

+public class MyAppModule

+{

+  public static Indexer build(Class serviceInterface, Logger logger,

+    LoggingDecorator decorator)

+  {

+    return decorator.build(serviceInterface, logger,  new IndexerImpl());

+  } 

+}

++---------------------+   

+

+  But as we'll see, its possible to have a single decorator method work on many different

+  services by using annotations.

+  

+Targetting Multiple Services

+

+  By using the

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/Match.html}@Match annnotation}},

+  you may identify which services are to be decorated.

+  

+  The value specified in the Match annotation is one or more patterns. These patterns

+  are used to match services. In a pattern, a "*" at the start or end of a string

+  match zero or more characters.

+  

+  For example, to target all the services in your module:

+  

++---------------------+    

+  @Match("*")

+  public static <T> T decorateLogging(Class<T> serviceInterface, T delegate, 

+    String serviceId, Logger logger,

+    LoggingDecorator decorator)

+  {

+    return decorator.build(serviceInterface, delegate, serviceId, logger);

+  }   

++---------------------+  

+

+  You can use multiple patterns with @Match, in which case, the decorator will be applied

+  to a service that matches <any> of the patterns. For instance, if you only wanted

+  logging for your data access and business logic services, you might end up with

+  <<<@Match("Data*", "*Logic")>>> (based, of course, on how you name your services). 

+  

+  As the precending example showed, a simple "glob" matching is supported, where a asterisk ('*')

+  may be used at the start or end of the match string to match any number of characters.

+  As elsewhere, matching is case insensitive.

+

+

+  Thus, <<<@Match("*")>>> is dangerous, because it will match every service in every

+  module.  

+  

+  <Note: It is not possible to decorate the services of the TapestryIOCModule.>

+  

+  <Note: Another idea will be other ways of matching services: base on inheritance of the

+  service interface and/or based on the presence of particular class annotations on the

+  service interface. None of this has been implemented yet, and can readily be accompllished

+  inside the decorator method (which will return null if it decides the service doesn't

+  need decoration).>

+  

+    

+Ordering of Decorators

+

+   In cases where multiple decorators will apply to a single service, you can control

+   the order in which decorators are applied using  an additional annotation:

+   {{{../apidocs/org/apache/tapestry/ioc/annotations/Order.html}@Order}}.

+   

+   This annotation allows any number of {{{order.html}ordering constraints}}

+   to be specified for the decorator, to order it relative to

+   any other decorators.

+   

+   For example, you almost always want logging decorators to come first, so:

+   

++---------------------+    

+  @Match("*")

+  @Order("before:*")

+  public static <T> T decorateLogging(Class<T> serviceInterface, T delegate, 

+    String serviceId, Logger logger,

+    LoggingDecorator decorator)

+  {

+    return decorator.build(serviceInterface, delegate, serviceId, logger);

+  }   

++---------------------+     

+   

+   

+   "before:*" indicates that this decorator should come before any decorator in <any> module.

+   

+   <<Note:>> the ordering of decorators is in terms of the <effect> desired.

+   Internally, the decorators are invoked

+   last to first (since each once receives the "next" interceptor as its delegate).

+   So the core service implementation is created (via a service builder method)

+   and that is passed to the last decorator method. The interceptor created there

+   is passed to the the next-to-last decorator method, and so forth.

+

+Creating your own Decorators

+

+  Decorators are a limited form of Aspect Oriented Programming, so we have

+  borrowed some of that terminology here.

+

+  A decorator exists to create an <interceptor>.  The interceptor wraps around

+  the service (because these interceptors can get chained, we talk about the "delegate" and not the "service").

+

+  Each method of the interceptor will take <advice>.  Advice

+  is provided by a {{{../apidocs/org/apache/tapestry/ioc/MethodAdvice.html}MethodAdvice}} instance.

+  The sole method, <<<advise()>>>, recieves an

+   {{{../apidocs/org/apache/tapestry/ioc/Invocation.html}Invocation}}.

+  MethodAdvice gives you a chance to see what the method invocation <is>; you can query

+  the name of the method, and the types and values of the parameters.

+

+  The MethodAdvice can override the parameters if necessary, then invoke <<<proceed()>>>.  This

+  call invokes the corresponding method on the original object, the delegate.

+

+  If the method call throws a runtime exception, that exception is not caught.  Your method advice can

+  put a try ... catch block around the call to proceed() if interested in catching runtime exception.

+

+  Checked exceptions are not thrown (since they are not part of the proceed() method's signature).  Instead

+  the invocation's <<<isFail()>>> method will return true.  You can then retrieve the exception or override it.

+

+  In the normal success case, you can ask for the return value and even override it before

+  returning from the advise() method.

+

+  In other words, you have total control.  Your MethodAdvise can query or change parameters, decide whether

+  it proceed into the original code, it can intercept exceptions that are thrown and replace them, and can

+  query or even replace the return value.

+

+  The

+  {{{../apidocs/org/apache/tapestry/ioc/services/AspectDecorator.html}AspectDecorator}} service

+  is how you put your MethodAdvise into action.

+

+  By way of an example, we'll show an implementation of the LoggingDecorator service:

+

++----+

+public class LoggingDecoratorImpl implements LoggingDecorator

+{

+    private final AspectDecorator aspectDecorator;

+

+    private final ExceptionTracker exceptionTracker;

+

+    public LoggingDecoratorImpl(AspectDecorator aspectDecorator, ExceptionTracker exceptionTracker)

+    {

+        this.aspectDecorator = aspectDecorator;

+        this.exceptionTracker = exceptionTracker;

+    }

+

+    public <T> T build(Class<T> serviceInterface, T delegate, String serviceId, final Logger logger)

+    {

+        final ServiceLogger serviceLogger = new ServiceLogger(logger, exceptionTracker);

+

+        MethodAdvice advice = new MethodAdvice()

+        {

+            public void advise(Invocation invocation)

+            {

+                boolean debug = logger.isDebugEnabled();

+

+                if (debug) serviceLogger.entry(invocation);

+

+                try

+                {

+                    invocation.proceed();

+                }

+                catch (RuntimeException ex)

+                {

+                    if (debug) serviceLogger.fail(invocation, ex);

+

+                    throw ex;

+                }

+

+                if (!debug) return;

+

+                if (invocation.isFail())

+                {

+                    Exception thrown = invocation.getThrown(Exception.class);

+

+                    serviceLogger.fail(invocation, thrown);

+

+                    return;

+                }

+

+                serviceLogger.exit(invocation);

+            }

+        };

+

+        return aspectDecorator.build(serviceInterface, delegate, advice,

+                                      String.format("<Logging interceptor for %s(%s)>", serviceId,

+                                                    serviceInterface.getName()));

+    }

+}

++---+

+

+  <The actual code has been refactored slightly since this documentation was written.> 

+

+  Most of the logging logic occurs inside the ServiceLogger object, the MethodAdvice exists to call the right methods at

+  the right time.  A Logger doesn't <change> parameter values (or thrown exceptions, or the result), it just

+  captures and logs the data.

+

+  Notice that for runtime exceptions, we catch the exception, log it, and rethrow it.

+

+  For checked exceptions, we use isFail() and getThrown().

+

+  The AspectDecorator service can also be used in more complicated ways: it is possible to

+  only advise some of the methods and not others, or use different advice for different methods.  Check the

+  JavaDoc for more details.

+

diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/index.apt b/hlship-20080520/tapestry-ioc/src/site/apt/index.apt
new file mode 100644
index 0000000..4a702b4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/index.apt
@@ -0,0 +1,213 @@
+ ----

+ Tapestry IoC Introduction

+ ----

+ 

+Tapestry Inversion of Control Container

+

+  The inner construction of the Tapestry framework is based on {{{http://www.martinfowler.com/articles/injection.html}inversion of control}},

+  a design approach that allows a working system to be fabricated from many small, easily testable pieces.

+  

+  An additional benefit of using IoC (Inversion of Control) is that, by breaking a complex system into small pieces, it becomes easier to

+  modify and extend the system, by overriding or replacing selected parts of the system.

+  

+  The use of IoC in Tapestry represents an evolution from Tapestry 3 to Tapestry 4 to Tapestry 5.  Tapestry 3 did not use IoC, though it included

+  some weaker mechanisms, such as extensions, that served a similar purpose.  To make large scale changes to the behavior of Tapestry 3 required

+  subclassing key classes and overriding methods.

+  

+  Tapestry 4 introduced the use of the {{{http://hivemind.apache.org/}HiveMind}} IoC container.  In fact, the HiveMind project was created 

+  specifically for use as the IoC container for Tapestry 4.  Tapestry 4 has met its goals for extensibility and configurability, largely

+  because of HiveMind's flexibility.

+  

+  Tapestry 5 extends on this, replacing HiveMind with a new container specifically build for Tapestry 5,

+  designed for greater ease of use, expressiveness and performance.  And it can be used separately from the rest of Tapestry!

+  

+* Why Not Spring?

+

+  {{{http://www.springframework.org}Spring}} is the most successful IoC container project. The Spring project combines a very good IoC container,

+  integrated {{{http://aspectj.org}AspectJ}} support, and a large number of libraries built on top of the container. Spring is an excellent

+  <application> container, but lacks a number of features necessary for a <framework> container:

+  

+  * Spring beans can be wired together by name (or id), but it is not possible to introduce additional naming abstractions. Tapestry 4's 

+    "infrastructure:" abstraction was the key to allowing easy spot overrides of internal Tapestry services without having to

+    duplicate the large web of interrelated services (nearly 200 in Tapestry 4.0).

+        

+  * Although Spring allows beans to be intercepted, it does so in the form of a new bean, leaving the un-intercepted bean visible

+    (and subject to misuse).  HiveMind and Tapestry IoC "wrap" the service inside interceptors, preventing unintercepted access

+    to the core service implementation.

+  

+  * Spring's XML configuration files are quite verbose, often more so than equivalent HiveMind XML files. This has improved with

+    Spring 2.0.

+    

+  * Spring has a simple map/list/value configuration scheme, but it is not distributed; it is part of a single bean definition. 

+    HiveMind and Tapestry 5 IoC allow service configuration to be assembled from multiple modules. This is very important

+    for seamless extensibility of the framework, with zero configuration (just drop the module into the classpath and 

+    everything hooks together).

+  

+* Why Not HiveMind?

+

+  The difficulty of managing the release schedules of two complex frameworks has proven to be an issue. HiveMind's 2.0 release will

+  incorporate ideas similar to those present in Tapestry 5 IoC, 

+  but will also maintain legacy support for the existing XML-driven approach.

+  

+  The use of HiveMind is also related to one of the common criticisms of Tapestry 4: startup time. The time it takes to parse and

+  organize all that XML shows up as several seconds of startup time. It is <hoped> that creating a streamlined IoC container that is not

+  driven by XML will alleviate those issues.

+  

+  With the advent of new technologies (in particular, 

+  {{{http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html}JDK 1.5 Annotations}}, 

+  and runtime class generation via 

+  {{{http://www.jboss.org/products/javassist}Javassist}})

+  some of the precepts of HiveMind have been undermined.  That is to say, in HiveMind (and Spring), all that XML is an awkward

+  way to describe a few basic Java operations: instantiating classes and invoking methods on those classes (to inject

+  dependencies into the instantiated instances).  The central concept in Tapestry IoC is to eliminate XML and build an equivalent

+  system around simple objects and methods.

+  

+  Tapestry IoC also represents many simplifications of HiveMind, representing lessons learned while creating both

+  HiveMind and Tapestry 4.

+

+* Why not Guice?

+

+  {{{http://code.google.com/p/google-guice/}Google Guice}} is a newcomer to the IoC landscape.  Guice and T5 IoC are very close and, in fact,

+  T5 IoC expressly borrows many great and innovative ideas from Guice. Guice abandons not only XML but even any concept of a service id ...

+  for injection, services are matched by type and perhaps filtered based on annotations.

+

+  Guice is still missing some core ideas needed in T5 IoC.  There's no concept of configurations or anything similar.

+  And there are limitations on injection based on scope (a request scoped value can't be injected into a global scope service; in T5 IoC, scope

+  is internal to the proxy and never an issue).

+  

+Goals

+

+  As with Tapestry 5 in general, the goal of Tapestry IoC is greater simplicity, greater power, and an avoidance of XML.

+  

+  Existing IoC containers such as HiveMind and Spring contain large amounts of XML configuration that exists to

+  describe how and when to instantiate a particular JavaBean, and how to provide that bean with its dependencies (either

+  by constructor injection, or by property injection).  Other XML is used to hook objects into some form of lifecycle ... 

+  typically callback methods invoked when the object is instantiated and configured, or when it is being discarded.

+

+  The core concept of Tapestry IoC is that

+  the Java language itself 

+  is the easiest and most succinct way to describe object creation and method invocation. Any approximation in

+  XML is ultimately more verbose and unwieldy.  As the {{{service.html#injection} examples}} show, a small amount of Java code and a

+  handful of naming conventions and annotations is far simpler

+  and easier than a big chunk of XML.

+

+  In addition, moving from XML to Java code encourages testing; you can unit test the 

+  service builder methods of your

+  module builder class, but you can't realistically unit test an XML descriptor.

+  

+  Tapestry IoC modules are easily packaged into JAR files, supporting 

+  zero-configuration usage: just drop the JAR onto the classpath.

+  

+  Another goal is "developer friendliness". This is a true cross-cutting concern, and one not likely to be packaged

+  into an aspect any time soon. The Tapestry IoC framework is designed to be easy to use and easy to understand.

+  Further, when things go wrong, it actively attempts to help you by 

+	comprehensive checks and carefully composed error messages. Further,

+  all user-visible objects implement

+  {{{http://howardlewisship.com/blog/2003/08/importance-of-tostring.html}a reasonable toString() method}},

+  to help you understand what's going when you inevitably try to figure things out in the debugger. 

+  

+  In terms of building services using Tapestry IoC ... the objective here is "lightness", a term borrowed from the board

+  game {{{http://boardgamegeek.com/game/188}Go}}. In Go, two players place stones on an initially empty board, 

+  creating walls to enclose territory or eliminate the encroaching stones played by the opponent. The winner at the

+  end of the game controls the most territory, and it is the constant tension between taking territory and defending

+  existing territory that drives the game.   In Go, groups of playing stones are "light" (or have "good shape")

+  when the minimum number of them control the maximum area on the board.  Playing "heavy" just gives your opponent a free

+  chance to take control of another section of the board.

+  

+  In software development, we are also attempting to create complex systems

+  from simple pieces, but our tension is derived from the need to add functionality balanced against the need

+  to test and maintain existing code.  Too often in the world of software development, the need to add functionality

+  trumps all, and testing and maintenance is deferred ... until too late.

+  

+  IoC containers is general, and Tapestry IoC very specifically, exist to address this issue, to provide the foundations

+  for balancing the need to quickly add functionality against the need to test new functionality and maintain

+  existing functionality.  IoC containers provide the means to break large, complex, monolithic blocks into light, small, testable

+  pieces.   

+  

+  When building a registry of services, lightness refers to the proper division of responsibility, the seperation of

+  concerns, and the limiting of dependencies between different parts of the system. This style is often

+  called {{{http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html}Law of Demeter}}.

+  Using an IoC container makes it easier to embrace this approach, since one critical concern, which objects are responsible for 

+  instantiating which others, is entirely managed by the container. With this lifecycle concern removed, it becomes very

+  easy to reduce complex chunks of code into small, testable, reusable services.

+  

+  "Light" means:

+  

+  * Small interfaces of two or three methods.

+  

+  * Small methods, with two or three parameters (because dependencies are injected in behind the scenes, rather than

+    passed into the method).

+    

+  * Anonymous communication via events, rather than explicit method invocations. The service implementation can

+    implement an event listener interface.

+  

+  []

+  

+  See {{{http://www.pragmaticprogrammer.com/ppbook/index.shtml}The Pragmatic Programmer}} for more insights into

+  building solid code.

+  

+Overview

+

+  The Tapestry IoC container takes over all the plumbing necessary for a highly scalable, extensible, thread-safe, testable

+  application.  Please see the {{{overview.html}overview}} for more details.  

+  

+Terminology

+

+  The basic unit in Tapestry IoC is a <<service>>.  A service consists of a <<service interface>> and a <<service implementation>>.

+  The service interface is an ordinary Java interface.  The service implementation is a Java object that implements the 

+  service interface.  Often there will

+  only be a single service per service interface, but in some situations, there may be many different services and service implementations

+  all sharing the same service interface.

+  

+  

+  Services are identified by a unique id.  Typically, a service id matches the unqualified name of the service interface, but

+  this is simply a convention.

+  

+  Services are aggregated into <<modules>>:

+      

+  * A module is defined by a <<module builder>>, a specific class containing a mix of static or instance methods, used to define

+    services, decorate them (see below), or contribute to service configurations (again, more below).

+  

+  * Methods of the module builder class define the services provided by the module, 

+    and the same methods are responsible

+    for instantiating the service implementation.

+    

+  []

+  

+  The methods which define and construct services are called <<service builder methods>>.

+  

+  The <<registry>> is the outside world's view of the modules and services. From the registry, it is possible to obtain

+  a service, via its unique id or by its service interface.  Access by unique id is <caseless> (meaning, a match will be found

+  even the case of the search key doesn't match the case of the service id itself). 

+    

+    

+  Services may be <<decorated>> by <<service decorator methods>>.  These methods create

+  <<interceptor>> objects that wrap around core service implementations, adding behavior such

+  as logging, security access, or transaction management.  Interceptors implement the same

+  service interface as the service.

+  Control is given over the order in which decorators are applied to a service.

+  

+  A service may have a <<configuration>>. The configuration is either a map, a collection, or an ordered list. The service defines the type

+  of object allowed to be contributed into the configuration. The configuration is constructed

+  from <<contributions>> provided by one or more modules.   <<Service contributor methods>> are invoked to contribute objects into

+  configurations.

+  

+  <Note: In HiveMind, services and configurations were separate, which often lead

+  to linked pairs of similarly named services and configurations. For Tapestry IoC, each service is allowed to have a single configuration,

+  which is normally sufficient.>

+  

+  Services are instantiated as needed. In this case, "need" translates to "when a method of the service is invoked".

+  A service is represented (to the outside world, or to other services) as a <<proxy>> that implements

+  the service interface. The first time a method is invoked on the proxy, the full service (consisting of the core service implementation wrapped with any interceptors) is

+  constructed. This occurs in a completely <<thread-safe>> manner. Just-in-time instantiation allows for more complex, more finely grained networks of services, and improves

+  startup time.

+  

+  Services define a <<scope>> that controls when the service is constructed, as well as its visibility.  The default scope is <<singleton>>, meaning a single

+  global instance created as needed.  Other scopes allow service implementations to be bound to the current thread (i.e., the current

+  request in a servlet application).

+  

+  <<Dependencies>> are other services (or other objects) that are needed by a service implementation. These 

+  dependencies can be <<injected>> into a service builder method and provided, from there, to a service implementation via

+  its constructor, or via methods on the service implementation. These may also be referred to as <<collaborators>>, especially

+  in the context of writing unit tests.

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/logging.apt b/hlship-20080520/tapestry-ioc/src/site/apt/logging.apt
new file mode 100644
index 0000000..891b748
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/logging.apt
@@ -0,0 +1,79 @@
+ ----
+ Logging
+ ----
+ 
+Logging in Tapestry
+
+	Logging in Tapestry is based on the
+	{{{http://www.slf4j.org/}Simple Logging Facade for Java (SLF4J)}}.  You can think of SLF4J as a leaner, meaner replacement
+	for {{{http://commons.apache.org/logging/}commons-logging}}.
+	
+	In theory, SLF4J is a wrapper around any of a number of logging systems, including 
+	{{{http://logging.apache.org/log4j/docs/}Log4J}}
+	or the built-in JDK logging.  In practice, it is almost always used with Log4J and no additional build configuration is needed. 
+	
+	Your application <will> need to provide a <<log4j.properties>> file (or its XML equivalent).  See 
+	{{{http://logging.apache.org/log4j/docs/manual.html}the Log4J manual}} for more information.
+
+Accessing Loggers
+
+  Loggers are a special kind of resource that is injected into a service.  In Tapestry IoC, Loggers an be injected into
+  service constructors, or into service builder methods.
+  
+  In Tapestry Core (the web framework), Loggers for components can be injected into component fields.
+  
+  This often confuses people, because the standard idiom is to create a Logger based on the class name and inject it into a static field.  In Tapestry, the Logger
+  is created on your code's behalf and provided to you, and stored into a final private field. 
+  
+  In terms of seperation of concerns, Tapestry's approach is superior ... the concern of creating loggers is offloaded
+  into the framework, and you code retains the concern of actually logging useful information.  However this is largely theoretical.
+  
+  For a pragamatic standpoint, injecting Loggers makes it easier to test <logging> code using the same techniques used to test other code: via the injection
+  of Mock Object implementations of the Logger interface.  This is something to consider when writing your own services, components and test.
+  
+Configuring Tapestry for other Logging Toolkits
+
+  The default configuration uses Log4J.
+  
+  If you need to use another logging system, that can be accomplished using Maven dependency control.
+  
+  You can exclude some of the dependencies that Tapestry introduces, and replace them with your own.  For example, to switch over to JDK logging, update your pom as follows:
+  
+----
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tapestry</groupId>
+      <artifactId>tapestry-ioc</artifactId>
+      <version>5.0.x</version>
+      <exclusions>
+      
+        <exclusion>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-log4j12</artifactId>
+        </exclusion>
+      
+        <exclusion>
+          <groupId>log4j</groupId>
+          <artifactId>log4j</groupId>
+        </exclusion>
+
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+	  <artifactId>slf4j-jdk14</artifactId>
+	  <version>1.4.3</version>
+    </dependency>
+  </dependencies>
+----
+
+  This pulls out the log4j support normally included with Tapestry, and replaces it with the SLF4J library that wraps around JDK 1.4 logging.  
+
+  In all likelyhood, you'll replace <tapestry-ioc> with <tapestry-core> (assuming you are building a web application using Tapestry, rather than using Tapestry IoC as part of some other
+  application).  And, of course, version numbers change all the time!
+      
+  
+  
+	
+	
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/module.apt b/hlship-20080520/tapestry-ioc/src/site/apt/module.apt
new file mode 100644
index 0000000..146a3ca
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/module.apt
@@ -0,0 +1,301 @@
+ ---

+ Tapestry IoC Modules

+ ---

+ 

+Tapestry IoC Modules

+ 

+  You inform Tapestry about your services and contributions by providing a module builder class.

+

+  The module builder is a plain Java class.  A system of annotations and naming conventions allow

+  Tapestry to determine what services are provided by the module.

+

+  A module class exists for the following reasons:

+

+  * To <bind> service interfaces to service implementations

+

+  * To contribute configuration data <into> services

+

+  * To <decorate> services by providing <interceptors> around them

+

+  * To provide explicit code for building a service

+  

+  * To set a default <marker> for all services defined in the module

+

+  []

+

+  A module builder defines builder methods, one for each service provided by the module.

+

+  <<This page needs to be rewritten or reorganized; using the bind() method is the preferred way to define services,

+  service builder methods are now used in very limited circumstances.>>

+

+  Service builder methods are public methods. They are often static. Here's a trivial example:

+

++-----------------------------------------------------------------------------------+

+package org.example.myapp.services;

+

+public class MyAppModule

+{

+  public static Indexer build()

+  {

+    return new IndexerImpl();

+  }

+}

++-----------------------------------------------------------------------------------+

+

+  Any public method (static or instance) whose name starts with "build" is a service builder method, implicitly

+  defining a service within the module. 

+  

+  

+  Here we're defining a service around

+  the Indexer service interface (presumably also in the org.example.myapp.services

+  package).

+  

+  

+  Every service has a unique id, used to identify it throughout the Registry of services (the Registry

+  is the combined sum of all services from all modules). If you don't provide an explicit service id,

+  as in this example, the service id  is drawn from the return type; this service has an id of "Indexer".

+  

+  

+  You can give a service an explicit id by adding it to the method name:  buildIndexer().  This is useful

+  when you do not want the service id to match the service interface name (for example, when you have different

+  services that implement the same interface), or when you need to avoid name collisions on the 

+  method name (Java allows only a single method with a given name and set of parameters, even if the return

+  types are differenty, so if you have two different service builder methods that take the same parameters,

+  you should give them explicit service ids in the method name).

+  

+  

+  Tapestry IoC is {{{case.html}case insensitive}}; later we can

+  refer to this service as "indexer" or "INDEXER" or any variation thereof, and connect to

+  this service.

+  

+  Service ids must be unique; if another module contributes a service with the id "Indexer" 

+  (or any case variation thereof) a runtime exception will occur when the Registry is created.

+

+  We could extend this example by adding additional service builder methods, or by showing

+  how to inject dependencies. See {{{service.html#Injecting Dependencies}the service documentation}} 

+  for more details.

+  

+Autobuilding Services

+

+  An alternate, and usually preferred, way to define a service is via a module's bind() method.  The previous

+  example can be rewritten as:

+  

++---+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.ServiceBinder;

+

+public class MyAppModule

+{

+  public static void bind(ServiceBinder binder)

+  {

+     binder.bind(Indexer.class, IndexerImpl.class);

+  }

+}

++----+  

+

+  The {{{service.html}service}} documentation goes into much greater detail about autobuilding of services. In most cases,

+  autobuilding is the <preferred> approach.

+

+  Generally speaking, you should always bind and autobuild your services. The only exceptions are when:

+

+  * You wish to do more than just instantiate a class; for example, to register the class as an event listener with some other service.

+

+  * There is <no implementation class>; in some cases, you can create your implementation on the fly using JDK dynamic proxies or bytecode generation.

+  

+{Cacheing Services}

+

+  You will occasionally find yourself in the position of injecting the same services

+  into your service builder or service decorator methods repeatedly (this occurs much less often since the introduction of

+  service autobuilding). This can result in quite

+  a bit of redundant typing.  Less code is better code, so as an alternative, you may define a <constructor> for your

+  module that accepts annotated parameters (as with 

+  {{{service.html#Injecting Dependencies}service builder injection}}).

+  

+  This gives you a chance to store common services in instance variables for later use inside 

+  service builder methods.

+  

++-----------------------------------------------------------------------------------+

+

+public class MyModule

+{   

+  private final JobScheduler scheduler;

+  private final FileSystem fileSystem;

+  

+  public MyModule(JobScheduler scheduler, FileSystem fileSystem)

+  {

+    this.scheduler = scheduler;

+    this.fileSystem = fileSystem;

+  }

+  

+  public Indexer build()

+  {

+    IndexerImpl indexer = new IndexerImpl(fileSystem);

+      

+    scheduler.scheduleDailyJob(indexer);

+      

+    return indexer;

+  }

+}

++-----------------------------------------------------------------------------------+

+

+  Notice that we've switched from <static> methods to <instance> methods.  Since the builder

+  methods are not static, the MyModule class will be instantiated so that the methods may be

+  invoked. The constructor receives two common dependencies, which are stored into instance

+  fields that may later be used inside service builder methods such as buildIndexer().

+  

+  This approach is far from required; all the builder methods of your module can be static if you wish.

+  It is used when you have many common dependencies and wish to avoid defining those

+  dependencies as parameters to multiple methods.

+

+  Tapestry IoC automatically resolves the parameter type (JobScheduler and FileSystem, in the example)

+  to the corresponding services that implement that type. When there's more than one

+  service that implements the service interface, you'll get an error (but additional annotations

+  and configuration can be used to ensure the correct service injected).

+ 

+  For modules, there are two additional parameter types that are used to refer to <resources> that

+  can be provided to the module instance (rather than <services> which may be injected).    

+      

+  * {{{http://www.slf4j.org/api/org/slf4j/Logger.html}org.slf4j.Logger}}: logger for the module (derived from the module's class name)

+   

+  * {{{../apidocs/org/apache/tapestry/ioc/ObjectLocator.html}ObjectLocator}}:  access to other services

+  

+  []

+  

+  Note that the fields are final: this is important. Tapestry IoC is thread-safe and you largely

+  never have to think about concurrency issues. But in a busy application, different services may be

+  built by different threads simultaneously. Each module builder class is instantiated at most once, and

+  making these fields final ensures that the values are available across multiple threads.

+  Refer to Brian Goetz's {{{http://www.javaconcurrencyinpractice.com/}Java Concurrency in Practice}}

+  for a more complete explanation of the relationship between final fields, constructors, and threads ...

+  or just trust us!

+  

+  Care should be taken with this approach: in some circumstances, you may force a situation in which

+  the module constructor is dependent on itself. For example, if you invoke a method on any injected services

+  defined within the same module from the module builder's constructor,

+  then the service implementation will be needed. Creating service implementations

+  requires the module builder instance ... that's a recursive reference. 

+    

+  Tapestry detects these scenarios and throws a runtime exception to prevent an endless loop.

+    

+{Autoloading modules}

+

+  When setting up the registry, Tapestry can automatically locate modules packaged into JARs.

+  It does this by searching for a particular global manifest entry. 

+  

+  The manifest entry name is "Tapestry-Module-Classes".  The value is a comma-separated list

+  of fully qualified class names of module builder classes (this allows a single

+  JAR to contain multiple, related modules).  Whitespace is ignored.

+  

+  Example:

+  

++-----------------------------------------------------------------------------------+

+Manifest-Version: 1.0

+Tapestry-Module-Classes: org.example.mylib.LibModule, org.example.mylib.internal.InternalModule

++-----------------------------------------------------------------------------------+

+

+  If you are using Maven 2, then getting these entries into your JAR's manifest

+  is as simple as some configuration in your pom.xml:

+  

++-----------------------------------------------------------------------------------+

+<project>

+  . . .

+  <build>

+    <plugins>

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-jar-plugin</artifactId>

+        <configuration>

+          <archive>

+            <manifestEntries>

+              <Tapestry-Module-Classes>org.example.mylib.LibModule, 

+                org.example.mylib.internal.InternalModule</Tapestry-Module-Classes>

+            </manifestEntries>

+          </archive>

+        </configuration>

+      </plugin>

+    </plugins>

+  </build>

+  . . .

+</project>

++-----------------------------------------------------------------------------------+

+  

+  

+  More details are provided in the 

+  {{{http://maven.apache.org/guides/mini/guide-manifest.html}Maven Manifest Guide}}.

+  

+SubModule Annotation

+

+  Often, you will have several different modules working together that should all be loaded

+  as a unit. 

+  

+  One approach is to update the module ids into the manifest, as shown in the previous extension.

+  

+  This can become tedious, and somewhat brittle in the face of refactorings (such as renaming of classes

+  or packages).

+  

+  A better alternative is the 

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/SubModule.html}@SubModule annotation}}.

+  

+  The value for this annotation is a list of <additional> classes to be treated as module builder classes,

+  exactly as if they were identified in the manifest.  For example:

+  

++----+

+@SubModule(

+{ InternalTransformModule.class })

+public final class InternalModule

+{

+  . . .

++----+

+

+  In general, your should only need to identify a single module in the JAR manifest, and make use of

+  @SubModule to pull in any additional module builder classes.

+

+Module Builder Implementation Notes

+

+  Module builder classes are designed to be very, very simple to implement.

+    

+  Again, keep the methods very simple. Use {{{service.html#Injecting Dependencies}parameter injection}}

+  to gain access to the dependencies you need.

+  

+  Be careful about inheritance. Tapestry will see all <public> methods,

+  even those inherited from base classes.  Tapestry <only> sees public methods.  

+  

+  By convention, module builder class names end in Module and are final classes.

+  

+  You don't <have> to define your methods as static. The use of static methods is only absolutely

+  necessary in a few cases, where the constructor for a module is dependent on contributions

+  from the same module (this creates a chicken-and-the-egg situation that is resolved through

+  static methods).

+  

+Default Marker

+

+  Services are often referenced by a particular marker interface on the method or contructor parameter. Tapestry

+  will use the intersection of services with that exact marker and assignable by type to find a unique service

+  to inject.  

+  

+  Often, all services in a module should share a marker, this can be specified with a @Marker annotation

+  on the module class.  For example, the TapestryIOCModule:

+  

++---+

+@Marker(Builtin.class)

+public final class TapestryIOCModule

+{

+  . . .

++---+

+

+  This references a particular annotation class, Builtin:

+  

++---+

+@Target(

+{ PARAMETER, FIELD })

+@Retention(RUNTIME)

+@Documented

+public @interface Builtin

+{

+

+}

++----+

+

+  The annotation can be applied to method and constructor parameters, for use within the IoC container.  It can also be applied

+  to fields, though this is specific to the Tapestry web framework.

diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/order.apt b/hlship-20080520/tapestry-ioc/src/site/apt/order.apt
new file mode 100644
index 0000000..29c5b88
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/order.apt
@@ -0,0 +1,59 @@
+ ----

+ Ordering by Constraints

+ ----

+ 

+Ordering by Constraints

+

+  Tapestry IoC has two specific areas where it must put some form of contribution into

+  a specific order:

+  

+  * {{{configuration.html#Ordered List}Ordered Configurations}}, where different modules

+    may contribute into a service's configuration

+    

+  * {{{decorator.html}Service Decorators}} which must be applied to services from 

+    a number of modules.

+    

+  []

+  

+  In both these cases, objects (either contributions to a configuration, or decorators)

+  are assigning qualified ids, simple ids qualified with the containing/contributing

+  module's id.

+  

+  Because the contributions can come from different modules, and there isn't a specific

+  order in which the service contribution methods are invoked, there is no

+  natural ordering of the contributed objects.

+  

+  Instead, <constraints> are applied to each contribution.  These constraints

+  control what other objects must come before a contribution, or come after.

+  

+  The constraints are specified using the

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/Order.html}Order}} annotation (for

+  service decorator methods), or as variable arguments at the end of the add() method

+  for ordered configurations.

+  

+  Often a single contribution will have more than one constraint.

+  

+Constraint Types

+  

+  Each constraint string begins with a prefix, "before:" or "after:", used to

+  identify  the type of constraint.

+  

+  The remainder of the constraint string is a comma-separated list of <patterns>. The

+  contributed object will be ordered before or after the contributions identified by

+  the patterns.

+  

+Constraint {Match Patterns}

+

+  A constraint match pattern is used to select one or more objects by their id.

+  

+  Match patterns support a very simple kind of wildcard matching.  A "*" may

+  appear at the start, or end, or both of the pattern, and will match zero or more

+  characters there.  Thus you can have patterns such as "Data*" or "*Logic" or even "*User*".

+

+  Matching is case insensitive.

+

+  

+  

+  

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/overview.apt b/hlship-20080520/tapestry-ioc/src/site/apt/overview.apt
new file mode 100644
index 0000000..a374fbb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/overview.apt
@@ -0,0 +1,397 @@
+ ----
+ Tapestry IoC Overview
+ ----
+ 
+Tapestry IoC Overview
+
+  Even today, with the overwhelming success of {{{http://www.springframework.org}Spring}} and the rise of 
+  smaller, simpler approaches to building application that stand in sharp contrast to the ultra-heavyweight
+  EJB approach, many people still have trouble wrapping their heads around Inversion of Control.
+  
+  Really understanding IoC is a new step for many developers.  If you can remember back to when you made the transition
+  from procedural programming (in C, or BASIC) to object oriented programming, you might remember the point where you "got it". The point
+  where it made sense to have methods on objects, and data inside objects.  
+  
+  Inversion of Control builds upon those ideas.  The goal is to make coding more robust (that is, with fewer errors), more reusable and
+  to make code much easier to test.
+  
+  Most developers are used to a more <monolithic> design, they have a few core objects and a <<<main()>>> method somewhere
+  that starts the ball rolling.  <<<main()>>> instantiates the first couple of classes, and those classes
+  end up instantiating and using all the other classes in the system.
+  
+  That's an <unmanaged> system.  Most desktop applications are unmanaged, so it's a very familiar pattern, and easy to get your head around.
+
+  By contrast, web applications are a <managed> environment.  You don't write a main(), you don't control startup.  You <configure>
+  the Servlet API to tell it about your servlet classes to be instantiated, and their lifecycle is totally controlled by
+  the servlet container. 
+
+  Inversion of Control is just a more general application of this approach. The container is ultimately responsible for
+  instantiating and configuring the objects you tell it about, and running their entire lifecycle of those objects.
+
+  Building web applications are more complicated than monolithic applications, largely because of <multithreading>.
+  Your code will be servicing many different users simultaneously across many different threads.  This tends to complicate the
+  code you write, since some fundamental aspects of object oriented development get called into question: in particular, the use
+  of <internal state>, values stored inside instance variables, since in a multi-threaded environment, that's no longer the safe
+  place it is in traditional development.  Shared objects plus internal state plus multiple threads equals an broken, unpredictable application.
+  
+  Frameworks such as Tapestry -- both the IoC container, and the web framework itself -- exist to help.
+  
+  When thinking in terms of IoC, <<small is beautiful>>.  What does that mean?  It means small classes and small methods
+  are easier to code than large ones.  At one extreme, we have servlets circa 1997 (and Visual Basic before that) with methods a thousand lines long,
+  and no distinction between business logic and view logic.  Everything mixed together into an untestable jumble.
+  
+  At the other extreme is IoC: small objects, each with a specific purpose, collaborating with other small objects. 
+  
+  Using unit tests, in collaboration with tools such as {{{http://easymock.org/}EasyMock}}, you can have a code base that is easy to maintain,
+  easy to extend, and easy to test. And by factoring out a lot of <plumbing> code, your code base will not only be easier to work with, it will be smaller.
+  
+Living on the Frontier
+
+  Coding applications the traditional way is like being a homesteader on the American frontier in the 1800's.  You're responsible for
+  every aspect of your house: every board, every nail, every stick of furniture is something you personally created. There <is> a great
+  comfort in total self reliance. Even if your house is small, the windows are a bit drafty or the floorboards creak a little, you know exactly <why> 
+  things are not-quite perfect.
+  
+  Flash forward to modern cities or modern suburbia and it's a whole different story.  Houses are built to specification from design plans, made
+  from common materials, by many specializing tradespeople. Construction codes dictate how plumbing, wiring and framing should be performed.   
+  A home-owner may not even know how to drive a nail, but can still take comfort
+  in draft-free windows, solid floors and working plumbing.
+  
+  To extend the metaphor, a  house in a town is not alone and self-reliant the way a frontier house is.  The town house
+  is situated on a street, in a neighborhood, within a town. The town provides services
+  (utilities, police, fire control, streets and sewers) to houses in a uniform way. Each house just needs to connect up to those services.
+  
+The World of the Container
+
+  So the IoC container is the "town" and in the world of the IoC container, everything has a name, a place, and a relationship
+  to everything else in the container.  Tapestry calls this world "The Registry".
+  
+[images/ioc-overview.png] IoC Overview
+
+  Here we're seeing a few services from the built-in Tapestry IoC module, and a few of the services from the Tapestry web framework module.
+  In fact, there are over 100 services, all interrelated, in the Registry ... and that's before you add your own to the mix.  The IoC Registry
+  treats all the services uniformly, regardless of whether they are part of Tapestry, or part of your application, or part of an add-on library.
+  
+  Tapestry IoC's job is to make all of these services available to each other, and to the outside world.  The outside world could
+  be a standalone application, or it could be an application built on top of the Tapestry web framework.
+  
+Service Lifecycle
+
+  
+  Tapestry services are <lazy>, which means they are not fully instantiated until they are absolutely needed.  Often, what looks like a service
+  is really a proxy object ... the first time any method of the proxy is invoked, 
+  the actual service is instantiated and initialized (Tapestry uses the term <realized> for this process).  Of course, this is all absolutely
+  thread-safe.
+  
+  Initially a service is <defined>, meaning some module has defined the service. Later, the service will be <virtual>, meaning a proxy
+  has been created.  This occurs most often because some other service <depends> on it, but hasn't gotten around to invoking methods on it.  Finally, a service
+  that is ready to use is <realized>.  What's nice is that your code neither knows nor cares about the lifecycle of the service, because of the magic of the proxy.
+
+  In fact, when a  Tapestry web application starts up, before it services its first request, only about 20% of the services have been realized; the remainder
+  are defined or virtual.
+  
+Class vs. Service
+
+  A Tapestry service is more than just a class.  First of all, it is a combination of an <interface> that defines the operations of the service,
+  and an <implementation class> that implements the interface. 
+  
+  Why this extra division?  Having a service interface is what lets Tapestry create proxies and perform other operations.  It's also a very good practice to
+  code to an interface, rather than a specific implementation.  You'll often be surprised at the kinds of things you can accomplish by substituting
+  one implementation for another.
+  
+  Tapestry is also very aware that a service will have dependencies on other services.  It may also have other needs ... for example, in Tapestry IoC, the 
+  container provides services with access to Loggers.
+  
+  Tapestry IoC also has support for other configuration that may be provided to services when they are realized.
+
+Dependency Injection
+
+  Inversion of Control refers to the fact that the container, here Tapestry IoC's Registry, instantiates your classes.  It decides on when the classes
+  get instantiated.
+  
+  Dependency Injection is a key part of <realization>: this is how a service is provided with the other services it needs to operate.  For example,
+  a Data Access Object service may be injected with a ConnectionPool service.
+  
+  In Tapestry, injection occurs exclusively through constructors.  Other frameworks support a mix of constructor injection, property injection (i.e., invoking setter methods)
+  and method injection (invoking arbitrary methods to pass in dependencies).  Tapestry focuses exclusively on constructor injection, and emphasizes
+  that dependencies should be stored in <<final>> variables.  This is the best approach towards ensuring thread safety.
+  
+  In any case, injection "just happens".  Tapestry finds the constructor of your class and analyzes the parameters to determine what to pass in.  In some cases,
+  it uses just the parameter type to find a match, in other cases, annotations on the parameters may also be used.
+  
+Why can't I just use <<<new>>>?
+
+  I've had this question asked me many a time.  All these new concepts seem alien.  All that XML (in the Spring or HiveMind IoC containers; Tapestry IoC uses no XML) is a burden.
+  What's wrong with <<<new>>>?
+
+  The problem with new is that it rigidly connects one implementation to another implementation.  Let's follow a progression that reflects how a lot of projects
+  get written.  It will show that in the real world, <<<new>>> is not as simple as it first seems.
+
+  This example is built around some work I've done recently involving a Java Messaging Service queue, part of an application performance monitoring
+  subsystem for a large application.  Code inside each server collects performance data of various types and sends it, via a shared JMS queue,
+  to a central server for collection and reporting.
+
+  This code is for a metric that periodically counts the number of rows in a key database table. Other implementations of MetricProducer
+  will be responsible for measuring CPU utilization, available disk space, number of requests per second, and so forth.
+
++----+
+public class TableMetricProducer implements MetricProducer
+{
+  . . . 
+
+  public void execute() 
+  {
+
+    int rowCount = . . .;
+    Metric metric = new Metric("app/clients", System.currentTimeMillis(), rowCount);
+
+    new QueueWriter().sendMetric(metric);
+  }
+}
++----+
+ 
+  I've elided some of the details (this code will need a database URL or a connection pool to operate), 
+  so as to focus on the one method and it's relationship to the QueueWriter class.
+ 
+  Obviously, this code has a problem ... we're creating a new QueueWriter for each metric we write into the queue, and the QueueWriter presumably is going to
+  open the JMS queue fresh each time, an expensive operation.  Thus:
+
++----+
+public class TableMetricProducer implements MetricProducer
+{
+  . . . 
+
+  private final QueueWriter queueWriter = new QueueWriter();
+
+  public void execute() 
+  {
+    int rowCount = . . .;
+    Metric metric = new Metric("app/clients", System.currentTimeMillis(), rowCount);
+
+   queueWriter.sendMetric(metric);
+  }
++-----+
+
+  That's better.  It's not perfect ... a proper system might know when the application was being shutdown and would shut down the JMS Connection
+  inside the QueueWriter as well.
+
+  Here's a more immediate problem:  JMS connections are really meant to be shared, and we'll have lots of little classes collecting different metrics.  So we need
+  to make the QueueWriter shareable:
+
++----+
+  private final QueueWriter queueWriter = QueueWriter.getInstance();
++----+
+
+  ... and inside class QueueWriter:
+
++----+
+public class QueueWriter
+{
+  private static QueueWriter instance;
+
+  private QueueWriter()
+  {
+    ...
+  }
+
+  public static getInstance()
+  {
+    if (instance == null)
+      instance = new QueueWriter();
+
+    return instance;
+  }
+}
++-----+
+
+  Much better!  Now all the metric producers running inside all the threads can share a single QueueWriter.  Oh wait ...
+
++-----+
+  public synchronized static getInstance()
+  {
+    if (instance == null)
+      instance = new QueueWriter();
+
+    return instance;
+  }
++----+
+
+  Is that necessary?  Yes.  Will the code work without it? Yes -- <<99.9% of the time>>.  In fact, this is a very common error
+  in systems that manually code a lot of these construction patterns: forgetting to properly synchronize access.  These things often work in development and testing,
+  but fail (with infuriating infrequency) in production, as it takes two or more threads running simultaneously to reveal the
+  coding error.
+
+  Wow, we're a long way from a simple <<<new>>> already, and we're talking about just one service. But let's detour into <testing>.
+
+  How would you test TableMetricProducer?  One way would be to let it run and try to find the message or messages it writes
+  in the queue, but that seems fraught with difficulties.  It's more of an integration test, and is certainly something
+  that you'd want to execute at some stage of your development, but not as part of a quick-running unit test suite.
+
+  Instead, let's split QueueWriter in two:  a QueueWriter interface, and a QueueWriterImpl implementation class. This will allow
+  us to run TableMetricProducer against a <mock implementation> of QueueWriter, rather than the real thing.  This is one
+  of the immediate benefits of <coding to an interface> rather than <coding to an implementation>.
+
+  We'll need to change
+  TableMetricProducer to take the QueueWriter as a constructor parameter.
+
++----+
+public class TableMetricProducer implements MetricProducer
+{
+  private final QueueWriter queueWriter;
+
+  /**
+   * The normal constructor.
+   *
+   */
+  public TableMetricProducer(. . .)
+  {
+    this(QueueWriterImpl.getInstance(), . . .);
+  }
+
+  /**
+   * Constructor used for testing.
+   *
+   */
+  TableMetricProducer(QueueWriter queueWriter, . . .)
+  {
+    queueWriter = queueWriter;
+    . . . 
+  }
+
+  public void execute() 
+  {
+    int rowCount = . . .;
+    Metric metric = new Metric("app/clients", System.currentTimeMillis(), rowCount);
+
+   queueWriter.sendMetric(metric);
+  }
+}
++----+
+
+  This still isn't ideal, as we still have an explicit linkage between TableMetricProducer and QueueWriterImpl.
+
+  What we're seeing here is that there are multple <concerns> inside the little bit of code in this example.  TableMetricProducer has an unwanted
+  <construction concern> about which implementation of QueueWriter to instantiate (this shows up as two constructors,
+  rather than just one).  QueueWriterImpl has an additional <lifecycle concern>, in terms
+  of managing the singleton.
+
+  These extra concerns, combined with the use of static variables and methods, are a <bad design smell>.  It's not yet very stinky, because
+  this example is so small, but these problems tend to multiply as an application grows larger and more complex, especially as services
+  start to truly collaborate in earnest.
+
+  For comparison, lets see what the Tapestry IoC implementation would look like:
+
++----+
+public class MonitorModule
+{
+  public static void bind(ServiceBinder binder)
+  {
+    binder.bind(QueueWriter.class, QueueWriterImpl.class);
+    binder.bind(MetricScheduler.class, MetricSchedulerImpl.class);
+  }
+
+  public void contributeMetricScheduler(Configuration<MetricProducer> configuration, QueueWriter queueWriter, . . .)
+  {
+    configuration.add(new TableMetricProducer(queueWriter, . . .))
+  }
+}
++----+
+
+  Again, I've elided out a few details related to the database the TableMetricProducer will point at (in fact, Tapestry IoC
+  provides a lot of support for configuration of this type as well, which is yet another concern).
+
+  The MonitorModule class is a Tapestry IoC module: a class that defines and configures services.
+
+  The bind() method is the principle way that services are made known to the Registry:  here we're binding
+  a service interface to a service implementation.  QueueWriter we've discussed already,
+  and MetricScheduler is a service that is responsible for determining when MetricProducer instances
+  run.
+
+  The contributeMetricScheduler() method allows the module to <contribute> into the MetricProducer service's <configuration>. More testability:
+  the MetricProducer isn't tied to a pre-set list of producers, instead it will have a Collection\<MetricProducer\> injected into its
+  constructor.  Thus, when we're coding the MetricProducerImpl class, we can test it against mock implementations of MetricProducer.
+
+  The QueueWriter service in injected into the contributeMetricScheduler() method.   Since there's only one QueueWriter service,
+  Tapestry IoC is able to "find" the correct service based entirely on type.  If, eventually, there's more than one QueueWriter service
+  (perhaps pointing at different JMS queues), you would use an annotation on the parameter to help Tapestry connect the parameter to the appropriate service.
+
+  Presumably, there'd be a couple of other parameters to the contributeMetricScheduler() method, to inject in a database URL or connection pool
+  (that would, in turn, be passed to TableMetricProducer).
+
+  A new TableMetricProducer instance is created and contributed in.  We could contribute as many producers as we like here.  Other modules could also
+  define a contributeMetricScheduler() method and contribute their own MetricProducer instances.
+
+  Meanwhile, the QueueWriterImpl class no longer needs the _instance variable or getInstance() method, and the TableMetricProducer
+  only needs a single constructor.
+
+Advantages of IoC: Summary
+
+  It would be ludicrous for us to claim that applications built without an IoC container are doomed to failure. There is overwhelming evidence
+  that applications have been built without containers and have been perfectly successful.
+
+  What we are saying is that IoC techniques and discipline will lead to applications that are:
+
+  * More testable -- smaller, simpler classes; coding to interfaces allows use of mock implementations
+
+  * More robust -- smaller, simpler classes; use of final variables; thread safety baked in
+
+  * More scalable -- thread safety baked in
+
+  * Easier to maintain -- less code, simpler classes
+
+  * Easier to extend -- new features are often additions (new services, new contributions) rather than changes to existing classes
+
+  []
+
+  What we're saying is that an IoC container allows you to work faster and smarter.
+
+
+  Many of these traits work together; for example, a more testable application is inherently more robust. Having a test suite
+  makes it easier to maintain and extend your code, because its much easier to see if new features break existing ones. 
+  Simpler code plus tests also lowers the cost of entry for new developers
+  coming on board, which allows for more developers to work efficiently on the same code base.  The clean separation between
+  interface and implementation also allows multiple developers to work on different aspects of the same code
+  base with a lowered risk of interference and conflict.
+
+  By contrast, traditional applications, which we term <monolithic> applications, are often very difficult to test, because 
+  there are fewer classes, and each class has multiple concerns. A lack of tests makes it more difficult to
+  add new features without breaking existing features. Further, the monolithic approach 
+  more often leads to implementations being linked to other implementations, yet another hurdle standing in the  way of testing.
+
+  Let's end with a metaphor.
+
+  Over a decade ago, when Java first came on the scene, it was the first mainstream language to support garbage collection.
+  This was very controversial: the garbage collector was seen as unnecessary, and a waste of resources.  Among
+  C and C++ developers, the attitude was "Why do I need a garbage collector?  If I call malloc() I can call free()."
+
+  I don't know about you, but I don't think I could ever go back to a non-garbage collected environment. Having the GC
+  around makes it much easier to code in a way I find natural: many small related objects working together. It turns out
+  that knowing when to call free() is more difficult than it sounds.  The Objective-C language tried to solve this with retain
+  counts on objects and that still lead to memory leaks when it was applied to object <graphs> rather than object <trees>.  
+
+  Roll the clock forward a decade and the common consensus has shifted considerably. Objective-C 2.0 features
+  true garbage collection and GC libraries are available for C and C++.  All scripting languages, including Ruby and Python, feature
+  garbage collection as well.  A new language <without> garbage collection is now considered an anomaly.
+
+  The point is, the lifecycle of objects turns out to be far more complicated than it looks at first glance. We've come to accept that our
+  own applications lack the ability to police their objects as they are no longer needed (they literally lack the ability to determine
+  <when> an object is no longer needed) and the garbage collector, a kind of higher authority, takes over that job very effetively.  The end result?
+  Less code and fewer bugs.  And a careful study shows that the Java memory allocator and garbage collector (the two are
+  quite intimately tied together) is actually
+  <<more>> efficient that malloc() and free().
+
+  So we've come to accept that the <death concern> is better handled outside of our own code.  The use of Inversion of Control
+  is simply the flip side of that: the <lifecycle and construction concerns> are also better handled by an outside authority as well: the IoC container. 
+  These concerns govern when a service is <realized> and how its dependencies and configuration are injected.  As with
+  the garbage collector, ceding these chores to the container
+  results in less code and fewer bugs, and lets you concentrate on the things that should matter to you: your business logic, your application -- and not
+  a whole bunch of boilerplate plumbing!
+
+
+  
+
+
+  
+  
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/pipeline.apt b/hlship-20080520/tapestry-ioc/src/site/apt/pipeline.apt
new file mode 100644
index 0000000..f8e8d28
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/pipeline.apt
@@ -0,0 +1,102 @@
+ ----

+ Building Pipelines

+ ----

+ 

+Building Pipelines

+

+  A common pattern within Tapestry is the use of filtering pipelines.   Another name

+  for a pipeline is a <filter chain>; an example of this is the Filter and FilterChain

+  interfaces inside the Servlet API.

+

+  In this pattern, an existing service is decorated with a filter.

+  The filter will delegate to the service, but has the chance to

+  alter or replace parameters before invoking the method, and

+  can perform operations before returning.  This is

+  similar to {{{command.html}chain of command}}, but differs in that

+  there are two interfaces (the service interface and the filter interface)

+  and that each filter invokes the next filter via the service interface.

+  In chain of command, the chain invokes each method, which must return 

+  before the next command in the chain is invoked.

+  

+  The service interface and the filter interface are closely related:

+  the filter interface must match the service interface method for method,

+  but each method of the filter interface must have an additional parameter

+  whose type is the service interface. For example, a pipeline

+  that performed string transformations might use the following interfaces:

+  

++------+

+public interface StringTransformService

+{

+  String transform(String input);

+}

+

+public interface StringTransformFilter

+{

+  String transform(String input, StringTransformService delegate);

+}

++-----+

+

+  An implementation of the filter might look like:

+  

++-----+

+public class UpcasePreFilter implements StringTransformFilter

+{

+  public String transform(String input, StringTransformService delegate)

+  {

+    return delegate.transform(input.toUpperCase());

+  }

+}

++-----+

+

+  Alternately, the filter could pass input to delegate unchanged, but invoke

+  toUpperCase() on the result:

+  

++-----+

+public class UpcasePostFilter implements StringTransformFilter

+{

+  public String transform(String input, StringTransformService delegate)

+  {

+    return delegate.transform(input).toUpperCase();

+  }

+}

++-----+  

+

+  The

+  {{{../apidocs/org/apache/tapestry/ioc/services/PipelineBuilder.html}PipelineBuilder}}

+  service is useful for constructing pipelines. The service is often injected

+  into a service builder method, along with an ordered configuration of services.

+  

+  What the builder accomplishes is to represent each <filter> in the pipeline as

+  an instance of the <service> interface.

+  

+[images/PipelineCallingSequence.png] Pipeline Calling Sequence

+  

+  The bridges are created by the PipelineBuilder service.  The terminator

+  must be provided.  The bridges and the terminator implement the service interface.

+  

++-----+

+  public static StringTransformService build(

+    @InjectService("PipelineBuilder")

+    PipelineBuilder builder,

+    List<StringTransformFilter> configuration,

+    Log serviceLog)

+    {

+      

+      StringTransformService terminator = new StringTransformService()

+      {

+        public String transform(String input)

+        {

+          return input;

+        }

+      };

+      

+      return builder.build(log,

+        StringTransformService.class, StringTransformFilter.class,

+        configuration,

+        terminator);

+    }    

++-----+

+

+  Here, we create the terminator for the pipeline as an inner class instance,

+  and feed that into the builder. The result is a new service that encapsulates

+  the entire pipeline.  When there are no filters, this is just the terminator.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/provider.apt b/hlship-20080520/tapestry-ioc/src/site/apt/provider.apt
new file mode 100644
index 0000000..5991ed6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/provider.apt
@@ -0,0 +1,88 @@
+ ----

+ Object Providers

+ ----

+

+Object Providers

+

+  When you don't provide the {{{../apidocs/org/apache/tapestry/ioc/annotations/InjectService.html}InjectService}} annotation

+  on a parameter (to a service builder method or constructor), Tapestry will

+  resolve the parameter automatically.

+  

+  This is called <object injection>, rather than <service injection>, because the value that will ultimately

+  be injected is not necessarily a service; it may be some arbitrary object.

+  

+  If this sounds vague, its because there is not just one

+  {{{../apidocs/org/apache/tapestry/ioc/ObjectProvider.html}ObjectProvider}}; there's a whole set of them,

+  forming a {{{command.html}chain of command}}.  The commands in the chain may provide an object

+  based on the parameter type, or based on additional annotations on the parameter.

+  

+  There are two built-in object providers:

+  

+  * Check for {{{../apidocs/org/apache/tapestry/ioc/annotations/Value.html}Value}} annotation

+  

+  * Check for a <unique> service in the Registry whose service interface matches the parameter type

+  

+  []

+  

+  Usually, the @Inject annotation is supplemented by an additional annotation which

+  triggers a specific  ObjectProvider to provide the value.

+  

+@Value Annotation Provider

+

+  The Value annotation

+  allows a literal value to be injected.  When combined with 

+  {{{symbols.html}symbols}}, they represent a way for parts of the overall service

+  network to be spot-configured.  For example:

+  

++----+

+  public MyService build(@Value("${max-seconds}") long maxSeconds)

+  {

+    return new MyServiceImpl(maxSeconds);

+  }

++----+

+

+  Here, the MyService service requires a configuration of a number of seconds.

+  The value is supplied as a symbol, with a factory default that may be overwritten

+  with an application default. 

+  

+Service Provider

+

+  This is always that last object provider checked.

+  

+  A <single> service must exist whose service interface matches the parameter type.  This is <not> an exact match: a search is made for any and all

+  services whose service interface is a super class of the parameter type.  

+  

+  An exception is thrown if there are no matches, or if there are multiple matches.

+

+  

+Alias Object Provider

+

+  The {{{http://tapestry.apache.org/tapestry5/tapestry-core/}tapestry-core}} module

+  defines the 

+  {{{http://tapestry.apache.org/tapestry5/tapestry-core/guide/alias.html}Alias object provider}},

+   which is used as a way to override services or

+  disambiguate services (when multiple services implement the same interface).  

+    

+Defining New Providers

+

+  New providers can be specified by contributing to the

+  MasterObjectProvider service's configuration.  The configuration

+  is mapped, with the keys being the provider prefix, and the values

+  being the object provider implementation.

+  

+  Example:

+  

++-----+

+  public void contributeMasterObjectProvider(OrderedConfiguration<ObjectProvider> configuration)

+  {

+    configuration.add("MyObject", new MyObjectProvider());

+  }

++-----+

+

+  This establishes a name for the object provider (useful if the exact order of execution of the

+  provider, relative to other providers, is relevant). 

+

+  Of course, this is a simplified example. In a real scenario, the provider is most likely

+  a service with its own dependencies.      

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/run.apt b/hlship-20080520/tapestry-ioc/src/site/apt/run.apt
new file mode 100644
index 0000000..06bcbb0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/run.apt
@@ -0,0 +1,67 @@
+ ----

+ Starting the Tapestry IoC Registry

+ ----

+ 

+Starting the Tapestry IoC Registry

+

+ Primarily, you will use the IoC Registry as part of a Tapestry application.

+ In those situations, the 

+ {{{../apidocs/org/apache/tapestry/TapestryFilter.html}TapestryFilter}} will

+ be responsible for starting and stopping the registry.

+ 

+ However, you may want to do some integration testing using the Registry

+ from within a test case, or you may even use Tapestry IoC separately from

+ Tapestry.

+ 

+Building the Registry

+

+  The class

+  {{{../apidocs/org/apache/tapestry/ioc/RegistryBuilder.html}RegistryBuilder}}

+  is used to create a Registry.

+  

++---+

+RegistryBuilder builder = new RegistryBuilder();

+

+builder.add(AppModule.class, UtilModule.class);

+

+Registry registry = builder.build();

+

+registry.performRegistryStartup();

++---+

+

+  You may invoke add() as many times as you wish, or pass as many module classes

+  as you wish.

+  

+  Using this approach, you will form a Registry containing

+  the builtin services from the

+  {{{../apidocs/org/apache/tapestry/ioc/services/TapestryIoCModule.html}Tapestry IoC module}}, plus

+  the modules you explicitly list.

+  

+  The call to performRegistryStartup() is necessary to ensure that any services marked with the

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/EagerLoad.html}EagerLoad}} annotation are, in fact,

+  loaded.

+  

+Building the Default Registry

+

+  The default registry is available by invoking the static method

+  {{{../apidocs/org/apache/tapestry/ioc/IOCUtilities.html#buildDefaultRegistry()}IOCUtilities.buildDefaultRegistry()}}.

+  This method builds a Registry using

+  {{{module.html#Autoloading modules}autoloading logic}}, where modules to load

+  are identified via a JAR Manifest entry.

+  

+  In addition, the JVM system property <<<tapestry.modules>>> (if specified) is a list of additional

+  module classes to load.  This is often used in development, where tests may be executed against

+  the local classes, not JARs, and so there no manifest to read.

+  

+  

+Shutting down the Registry

+

+  The method

+  {{{../apidocs/org/apache/tapestry/ioc/Registry.html#shutdown()}Registry.shutdown()}}

+  will shutdown the Registry. This immediately invalidates all service proxies.

+  Some services may have chosen to register for shutdown notification (for example,

+  to do cleanup work such as closing a database connection).

+  

+  Once the Registry is shutdown, it may not be used again: it will not be possible to

+  access services within the Registry, or invoke methods on services previously

+  acquired.  All you can do is release the Registry to the garbage collector.

diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/serialization.apt b/hlship-20080520/tapestry-ioc/src/site/apt/serialization.apt
new file mode 100644
index 0000000..b188f6f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/serialization.apt
@@ -0,0 +1,51 @@
+ ----
+ Service Serialization
+ ----
+
+Service Serialization
+
+  Every once in a while you may need to serialize a service.  For example, you may store an object into
+  the HttpSession that holds a reference to a service.  In a clustered environment, that object will
+  be serialized and broadcast to other servers in the cluster.
+
+  Services in Tapestry are serializable.  Specifically, service <proxies> are serializable.
+
+  Your service implementations <do not> have to be serializable.
+
+  Serialization works as follows:
+
+  * When a proxy is serialized, it instead serializes a <token> object.
+
+  * The token object is what's stored in the output stream.
+
+  * When the token is de-serialized, it locates the service proxy in the current Registry and returns that.
+
+  []
+
+  The end result is very efficient: just the tiny tokens are serialized, not the services with their
+  proxies, configurations, implementations, dependencies, internal state and so forth.
+
+  Again, note that the actual service implementation is not serialized.  Due to Tapestry's lazy  creation policy,
+  the service implementation may not even exist.  Since outside code only sees the proxy, there's no
+  difference.
+
+Registry Resolution
+
+  The one trick here is locating the service proxy.  Tapestry uses a <weak reference> to the Registry to do this.
+  When a Registry starts up, it is stored in the reference, so that de-serialization can work.
+
+  The reference is cleared when you shut down the Registry.  If you stop using the Registry, but fail to
+  shut it down, the weak reference ensures that it will be released to the garbage collector anyway.  Stil, you
+  should shutdown a Registry when done with it.
+
+  This all makes one BIG assumption: that there's just one Registry.  That's normal for a web application, especially
+  when the tapestry-ioc JAR is included as part of the web application's WAR.
+
+  If you are running multiple Registries you will likely see errors in your console:
+
++---+
+[ERROR] SerializationSupport Setting a new service proxy provider when there's already an existing provider. This may indicate that you have multiple IoC Registries.
++---+
+
+
+
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/service.apt b/hlship-20080520/tapestry-ioc/src/site/apt/service.apt
new file mode 100644
index 0000000..bcb134a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/service.apt
@@ -0,0 +1,640 @@
+ ----

+ Tapestry IoC Services

+ ----

+ 

+Tapestry IoC Services

+

+  Services consist of two main parts: a service interface and a service implementation.

+  

+  The service interface is how the service will be represented throughout the rest of the

+  registry. Since what gets passed around is normally a proxy, you can't expect to cast a service

+  object down to the implementation class (you'll see a ClassCastException instead). In other

+  words, you should be careful to ensure that your service interface is complete, since

+  Tapestry IoC effectively walls you off from backdoors such as casts.

+  

+Service Life-cycle

+

+  Every service has a very specific life-cycle.

+

+  * Defined: The service has a definition (from some module) but has not yet been referenced.

+

+  * Virtual: The service has been referenced, so a proxy for the class has been created.

+

+  * Realized: A method on the proxy has been invoked, so the service implementation has 

+    been instantiated, and any decorators applied.

+

+  * Shutdown: The entire Registry has been shut down and with it, all the proxies have been disabled.

+

+  []

+

+  When the Registry is first created, all modules are scanned and the definitions for all services

+  are created.  

+

+  Services will be referenced by either accessing them using the Registry, or as dependencies

+  of other realized services.  

+

+  Tapestry IoC waits until the last possible moment to <realize> the service: that's defined

+  as when a method of the service is invoked. Tapestry is <thread-safe>, so even in a heavily

+  contested, highly threaded envrionment (such as a servlet container or application server) 

+  things <Just Work>.

+

+Service Builder Methods

+

+  Tapestry doesn't know how to instantiate and configure your service; instead it relies

+  on you to provide the code to do so, in a service builder method:

+  

++-----------------------------------------------------------------------------------+

+package org.example.myapp.services;

+

+public class MyAppModule

+{

+  public static Indexer build()

+  {

+    return new IndexerImpl();

+  }

+}

++-----------------------------------------------------------------------------------+

+

+  Here the service interface is Indexer (presumably inside the org.example.myapp.services package,

+  since there isn't an import).  Tapestry IoC doesn't know about the IndexerImpl class (the

+  service implementation of the Indexer service), but it does know 

+  about the build() method.

+  

+  That's one of the great innovations of Tapestry IoC: we don't try to encapsulate in XML or annotations

+  all the different ways possible to create a service; those things are best expressed in Java code.

+  For a simple case (as here), it would be hard for external configuration (again, in XML or Java annotations)

+  to be shorter than "new IndexerImpl()".

+

+  <The above paragraph was written before Binding and Autobuilding were introduced.>

+  

+  For more complex and realistic scenarios, such as injecting dependencies via the constructor, or

+  doing more interest work (such as registering the newly created service for events published by some other service),

+  the Java code is simply the most direct, flexible, extensible and readable approach.

+  

+Binding and Autobuilding

+

+  Tapestry IoC can also <autobuild> your service. Autobuilding is the <preferred> way to 

+  instantiate your services.

+

+  Every module may have an optional, static bind() method which is passed a

+  {{{../apidocs/org/apache/tapestry/ioc/ServiceBinder.html}ServiceBinder}}.  Services may be registered with

+  the container by "binding" a service interface to a service implementation:

+  

++------+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.ServiceBinder;

+

+public class MyAppModule

+{

+  public static void bind(ServiceBinder binder)

+  {

+    binder.bind(Indexer.class, IndexerImpl.class);

+  }

+}

++----+

+

+  You can make repeated calls to ServiceBinder.bind(), to bind additional services.

+

+

+  You might ask, "which is better, a builder method for each service, or a bind() method for the module?"  For simple services,

+  those that are just an instantiated instance with simple dependencies, binding is better than building. That covers

+  at least 90% of all services, so bind away!

+  

+  There are many cases, however, where constructing a service is more than just instantiating a class. Often the new service

+  will (for example) be registered as a listener with some other service. In other cases, the implementation of the

+  service is generated at runtime. These are where the service builder methods are most useful.

+

+  In terms of the evolution of the framework, service builder methods came first, and autobuilding was a later

+  addition, inspired by the terseness of the {{{http://code.google.com/p/google-guice/}Guice}} IoC container.

+    

+Service Ids

+

+  Every service will have a unique service id. 

+  

+  When using a service builder method, the service id is the <simple name> of the service interface.

+  

+  This can be overridden by adding the service id to the method name, after "build", for example:

+  

++---+

+  public static Indexer buildFileSystemIndexer(@InjectService("FileSystem") FileSystem fileSystem)

+  {

+     . . .

+  }

++----+

+

+  Here, the service id is "FileSystemIndexer" not "Indexer".

+  

+  For autobuilt services, the service id can be specified when the service is bound:

+  

++---+

+  binder.bind(Indexer.class, IndexerImpl.class).withId("FileSystemIndexer");

++---+

+  

+{Injecting Dependencies}

+

+  It's pretty unlikely  that your service will be able to operate in a total vacuum. It will

+  have other dependencies.  

+  

+  Dependencies are provided to a service in one of three ways:

+  

+  * As parameters to the service builder method

+  

+  * As parameters to the service implementation class' constructor (for autobuilt services)

+  

+  * As parameters passed to the constructor of the service's module builder (cached inside instance variables)

+  

+  []

+   

+  

+  For example, let's say the Indexer needs a JobScheduler to control

+  when it executes, and a FileSystem to access files and store indexes.

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(JobScheduler scheduler, FileSystem fileSystem)

+  {

+    IndexerImpl indexer = new IndexerImpl(fileSystem);

+      

+    scheduler.scheduleDailyJob(indexer);

+      

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+

+

+  Here we've annotated the parameters of the service builder method to identify what

+  service to inject for that parameter.  

+  

+  This is an example of when you would want to use the service builder method, rather than

+  just binding the service interface to the implementation class: because we want to do something extra,

+  in this case, register the new indexer service with the scheduler.

+  

+  Note that we don't invoke those service builder methods ... we just "advertise" that we need

+  the named services.  Tapestry IoC will provide the necessary proxies and, when we start to

+  invoke methods on those proxies, will ensure that the full service, including its

+  interceptors and its dependencies, are ready to go. Again, this is done in a 

+  thread-safe manner.   

+

+  What happens if there is more than one service that implements the JobScheduler interface, or

+  the FileSystem interface?  You'll see a runtime exception, because Tapestry is unable to resolve

+  it down to a <single> service. At this point, it is necessary to <disambiguate> the link between

+  the service interface and <one> service.  One approach is to use

+  the 

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/InjectService.html}InjectService}} annotation:

+  

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(@InjectService("JobScheduler")

+    JobScheduler scheduler, 

+    

+    @InjectService("FileSystem")

+    FileSystem fileSystem)

+  {

+    IndexerImpl indexer = new IndexerImpl(fileSystem);

+      

+    scheduler.scheduleDailyJob(indexer);

+      

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+  

+  

+  If you find yourself injecting the same dependencies into multiple service builder 

+  (or service decorator) methods, you can 

+  {{{module.html#Caching Services}cache dependency injections}} in your module, by defining

+  a constructor.  This reduces duplication in your module.

+ 

+Disambiguation with Marker Annotations

+

+  In the previous example we were faced with a problem: multiple versions of the JobScheduler

+  service.  They had the same service interface but unique service ids.  If you try to inject

+  based on type, the service to inject will be ambiguous.  Tapestry will throw an exception (identifying

+  the parameter type and the matching services that implement that type).

+

+  The problem is that when injecting a JobScheduler into some other service we need to know 

+  which <one> to inject. Rather than using the service id, another approach is to

+  use a <marker annotation>.

+

+  You may optionally link a service implementation with a marker annotation.

+

+  For example, maybe you have one JobScheduler implementation where the jobs are spread across

+  a number of nodes in a cluster, and you have another JobScheduler where the jobs are all executed exclusively

+  in the current process.

+

+  We can associate those two JobSchedulers with two annotations.

+

++----+

+@Target(

+{ PARAMETER, FIELD })

+@Retention(RUNTIME)

+@Documented

+public @interface Clustered

+{

+

+}

+

+@Target(

+{ PARAMETER, FIELD })

+@Retention(RUNTIME)

+@Documented

+public @interface InProcess

+{

+

+}

+

+

+public class MyModule

+{

+  public static void bind(ServiceBinder binder)

+  {

+    binder.bind(JobScheduler.class, ClusteredJobSchedulerImpl.class).withId("ClusteredJobScheduler").withMarker(Clustered.class);

+    binder.bind(JobScheduler.class, SimpleJobSchedulerImpl.class).withId("InProcessJobScheduler").withMarker(InProcess.class);

+  }

+}

++---+

+

+  Notice that the marker annotations have no attributes.  Further, we support markers on fields

+  (for use in Tapestry components) as well as parameters.

+

+  To get the right version of the service, you use one of the annotations:

+

++---+

+public class MyServiceImpl implements MyService

+{

+  private final JobScheduler jobScheduler;

+

+  public MyServiceImpl(@Clustered JobScheduler jobScheduler)

+  {

+    this.jobScheduler = jobScheduler;

+  }

+

+  . . .

+}  

++---+

+

+  The @Clustered annotation on the parameter is combined with the parameter type (JobScheduler) to find the exact

+  service implementation.

+

+  Why is this better than using the service id?  It's more refactoring-safe.  Service ids can change, which can break

+  your services.  However, using an IDE to rename or move an annotation class or service interface

+  will be able to update all the uses of the annotation or interface.

+

+  With a service builder method, you use the

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/Marker.html}@Marker}} annotation:

+

++---+

+  @Marker(Clustered.class)

+  public JobScheduler buildClusteredJobScheduler()

+  {

+    return . . .;

+  }

++---+

+

+  The @Marker annotation may also be placed on an implementation class, which means that you may omit

+  the call to withMarker() inside the bind() method.

+

+Injecting Dependencies for Autobuilt Services

+

+  With autobuilt services, there's no service builder method in which to specify injections.

+  

+  Instead, the injections occur on <constructor> for the implementation class:

+  

++---+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.annotation.InjectService;

+

+public class IndexerImpl implements Indexer

+{

+  private final FileSystem fileSystem;

+  

+  public IndexerImpl(@InjectService("FileSystem") FileSystem fileSystem)

+  {

+    this.fileSystem = fileSystem;

+  }

+

+  . . .

+}

++---+  

+

+  If the class has multiple constructors, the constructor with the <most> parameters will be invoked.

+  Alternately, you may mark a single constructor with the Inject annotation, and Tapestry will use

+  <that> constructor specifically, ignoring all other constructors.

+  

+  Note how we are using final fields for our dependencies; this is generally a Good Idea.

+  These services will often execute inside a multi-threaded environment, such as a web application,

+  and the use of final fields inside a constructor ensures that the fields will be properly published

+  (meaning, "visible to other threads") in accordance with the Java Memory Model.

+  

+  Once thing that is not a good idea is to pass in another service, such as JobScheduler in the previous

+  example, and pass <<<this>>> from a constructor:

+  

++---+

+package org.example.myapp.services;

+

+import org.apache.tapestry.ioc.annotation.InjectService;

+

+public class IndexerImpl implements Indexer

+{

+  private final FileSystem fileSystem;

+  

+  public IndexerImpl(@InjectService("FileSystem") FileSystem fileSystem,

+  

+  @InjectService("JobScheduler") JobScheduler scheduler)

+  {

+    this.fileSystem = fileSystem;

+    

+    scheduler.scheduleDailyJob(this); // Bad Idea

+  }

+

+  . . .

+}

++---+

+ 

+  Understanding why this is a bad idea involves a long detour into inner details of the Java Memory Model.

+  The short form is that other threads may end up invoking methods on the IndexerImpl instance, and its fields

+  (even though they are final, even though they appear to already have been set) may be uninitialized.

+    

+Defining Service Scope

+

+  Each service has a <lifecycle> that controls when the service implementation is instantiated.

+  There are two built in lifecycles: "singleton" and "perthread", but

+  more can be added.

+  

+  Service lifecycle is specified using the 

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/Scope.html}@Scope annotation}},

+  which is attached to a builder method.  When this annotation is not present, the

+  default scope, "singleton" is used.

+    

+* singleton

+  

+  Most services use the default scope, "singleton".  With this scope a <proxy>

+  is created when the service is first referenced.  By reference, we mean any situation in which

+  the service is requested by name, such as using the @InjectService annotation on a

+  service builder method, or by using the

+  {{{../apidocs/org/apache/tapestry/ioc/Registry.html}Registry}} API from outside the

+  container.

+  

+  In any case, the service proxy will only create the service implementation when a method

+  on the service interface is invoked. Until then, the service can be thought of as "virtual".

+  As the first method is invoked, the service builder method is invoked, then any service

+  decorations occur.  This construction process, called "realization", occurs only once.

+  

+  You should be aware when writing services that your code must be thread safe; any service

+  you define could be invoked simulataneously by multiple threads. This is rarely an issue

+  in practice, since most services take input, use local variables, and invoke methods on other services,

+  without making use of non-final instance variables.  The few instance variables

+  in a service implementation are usually references to other Tapestry IoC services.

+  

+* perthread

+

+  The perthread service scope exists primarily to help multi-threaded servlet applications,

+  though it has other applications.

+  

+  With perthread, the service proxy will delegate to a local service instance that is associated

+  with the current thread. Two different threads, invoking methods on the same proxy, will

+  ultimately be invoking methods on two different service instances, each reserved to their own thread.

+  

+  This is useful when a service needs to keep request specific state, such as information extracted

+  from the HttpServletRequest (in a web application). The default singleton model would not work

+  in such a multi threaded environment.  Using perthread on select services allows state to be isolated

+  to those services.  Because the dispatch occurs <inside> the proxy, you can treat the service

+  as a global, like any other.

+  

+  You will see that your service builder method is invoked more than once.  It is invoked in each

+  thread where the perthread service is used.

+  

+  At the end of the request, the  Registry's cleanupThread() method is invoked; it will discard

+  any perthread service implementations for the current thread.

+  

+  <<Caution:>> A common technique in Tapestry IoC is to have a service builder method

+  register a core service implementation as an event listener with some event hub service.

+  With non-singleton objects, this can cause a number of problems; the event hub will

+  hold a reference to the per-thread instance, even after that per-thread instance has been

+  cleaned up (discarded by the inner proxy). Simply put, this is a pattern to avoid. For

+  the most part, perthread services should be simple holders of data specific to a thread or

+  a request, and should not have overly complex relationships with the other services

+  in the registry.

+  

+Defining the scope of Autobuilt Services

+

+  There are two options for defining the scope for an autobuilt service.

+  

+   The service implementation class may include the @Scope annotation. This is generally the preferred way

+   to specify scope.

+  

+  In addition, it is possible to specify the scope when binding the service:

+  

++----+

+  bind(MyServiceInterface.class, MyServiceImpl.class).scope("perthread");

++----+

+

+    

+  

+Eager Loading Services

+

+  Services are normally created only as needed (per the scope discussion above).

+  

+  This can be tweaked slightly; by adding the 

+  {{{../apidocs/org/apache/tapestry/ioc/annotations/EagerLoad.html}EagerLoad}} annotation to

+  the service builder method, Tapestry will instantiate the service when the Registry is first created.

+  

+  This will cause the service builder method to be invoked, as well as any service decorator methods.

+  

+  This feature is used when a service manages a resource, such as a thread, that needs to be created

+  as soon as the application starts up.  Another common example is a service that listens for events produced

+  by a second service; the first service may need to be created, and start listening, before any of its

+  service methods are invoked (which would normally trigger the instantiation of the service).

+  

+  Many services may be annotated with @EagerLoad; the order in which services are created is not defined. 

+  

+  With the perthread lifecycle, the service builder method will not be invoked (this won't happen until

+  a service method is invoked), but the decorators for

+  the service will be created. 

+  

+Eager Loading Autobuilt Services

+

+  As with service scope, there are two options for indicating that an autobuilt service should be

+  eagerly loaded.

+  

+  The service implementation class may include the @EagerLoad annotation.

+  

+  You may also specify eager loading explicitly when binding the service:

+

++----+

+  bind(MyServiceInterface.class, MyServiceImpl.class).eagerLoad();

++----+

+  

+     

+Injecting Resources

+

+  In addition to injecting services, Tapestry will key off of the parameter type to allow

+  other things to be injected.

+  

+  * java.lang.String: unique id for the service

+    

+  * {{{http://www.slf4j.org/api/org/slf4j/Logger.html}org.slf4j.Logger}}: logger for the service

+  

+  * java.lang.Class: service interface implemented by the service to be constructed

+  

+  * {{{../apidocs/org/apache/tapestry/ioc/ServiceResources.html}ServiceResources}}:  access to other services

+  

+  []

+  

+  No annotation is needed for these cases.

+  

+  See also {{{configuration.html}service configuration}} for additional special cases

+  of resources that can be injected.

+  

+  Example:

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(String serviceId, Log serviceLog,  

+     JobScheduler scheduler, FileSystem fileSystem)

+  {

+    IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem);

+      

+    scheduler.scheduleDailyJob(serviceId, indexer);

+

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+  

+  

+  The order of parameters is completely irrelevant. They can come first or last or be

+  interspersed however you like.

+  

+  Injecting in the ServiceResources can be handy when you want to calculate the name

+  of a service dependency on the fly.  However, in the general case (where the

+  id of service dependencies is known at build time), it is easier

+  to use the @InjectService annotation.

+      

+  The Log's name (used when configuring logging settings for the service) consists of

+  the module class name and the service id seperated by a period, i.e. "org.example.myapp.MyModule.Indexer". 

+  

+  Further, ServiceResources includes an autobuild() method that allows you to easily trigger

+  the construction of a class, including dependencies.  Thus the previos example could be rewritten as:

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(ServiceResources resources, JobScheduler jobScheduler)

+  {

+    IndexerImpl indexer = resources.autobuild(IndexerImpl.class);

+      

+    scheduler.scheduleDailyJob(resources.getServiceId(), indexer);

+

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+  

+  

+  This works the exact same way with autobuilt services, except that the parameters of the service

+  implementation constructor are considered, rather than the parameters of the service

+  builder method.

+

+  The @InjectService annotation takes precendence over these resources.

+  

+  If the @InjectService annotation is not present, and the parameter type does not exactly match

+  a resource type, then {{{provider.html}object injection}} occurs.   Object injection will find the correct

+  object to inject based on a number of (extensible) factors, including the parameter type and any additional annotations

+  on the parameter.

+  

+  Every once and a while, you'll have a conflict between a resource type and an object injection.  For example,

+  the following does not work as expected:

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(String serviceId, Log serviceLog,  

+     JobScheduler scheduler, FileSystem fileSystem,

+     @Value("${index-alerts-email}")

+     String alertEmail)

+  {

+    IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem, alertEmail);

+      

+    scheduler.scheduleDailyJob(serviceId, indexer);

+

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+    

+

+  It doesn't work because type String always gets the service id, as a resource (as with the serviceId parameter).

+  In order to get this to work, we need to turn off the resource injection for the alertEmail parameter.

+  That's what the {{{../apidocs/org/apache/tapestry/ioc/annotations/Inject.html}Inject}} annotation does:

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(String serviceId, Log serviceLog,  

+     JobScheduler scheduler, FileSystem fileSystem,

+     @Inject @Value("${index-alerts-email}")

+     String alertEmail)

+  {

+    IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem, alertEmail);

+      

+    scheduler.scheduleDailyJob(serviceId, indexer);

+

+    return indexer;

+  }

++-----------------------------------------------------------------------------------+      

+  

+  Here, the alertEmail parameter will recieve the configured alerts email (see

+  {{{symbols.html}the symbols documentation}} for more about this syntax) rather than the service id.

+  

+Builtin Services

+

+  A few services within the Tapestry IOC Module are "builtin"; there is no 

+  service builder method

+  in the

+  {{{../apidocs/org/apache/tapestry/ioc/services/TapestryIOCModule.html}TapestryIOCModule}} class.

+  

+*---------------------+-----------------------------------------------------------------------------------------+

+| <<Service Id>>      | <<Service Interface>>                                                                   |

+*---------------------+-----------------------------------------------------------------------------------------+

+| ClassFactory        | {{{../apidocs/org/apache/tapestry/ioc/services/ClassFactory.html}ClassFactory}}         |

+*---------------------+-----------------------------------------------------------------------------------------+

+| LoggerSource        | {{{../apidocs/org/apache/tapestry/ioc/LoggerSource.html}LoggerSource}}                  |

+*---------------------+-----------------------------------------------------------------------------------------+

+| RegistryShutdownHub | {{{../apidocs/org/apache/tapestry/ioc/RegistryShutdownHub.html}RegistryShutdownHub}}    |

+*---------------------+-----------------------------------------------------------------------------------------+

+| PerthreadManager    | {{{../apidocs/org/apache/tapestry/ioc/services/PerthreadManager.html}PerthreadManager}} |

+*---------------------+-----------------------------------------------------------------------------------------+

+

+  Consult the JavaDoc for each of these services to identify under what circumstances you'll need to use them.

+  

+Mutually Dependant Services

+

+  One of the benefits of Tapestry IoC's proxy-based approach to just-in-time instantiation 

+  is the automatic support for mutually dependent services.  For example, suppose that

+  the Indexer and the FileSystem needed to talk directly to each other.  Normally, this

+  would cause a "chicken-and-the-egg" problem: which one to create first?

+

+  With Tapestry IoC, this is not even considered a special case:

+  

++-----------------------------------------------------------------------------------+

+  public static Indexer build(JobScheduler scheduler, FileSystem fileSystem)

+  {

+    IndexerImpl indexer = new IndexerImpl(fileSystem);

+  

+    scheduler.scheduleDailyJob(indexer);

+  

+    return indexer;

+  }

+    

+  public static Indexed build(Indexer indexer)

+  {

+    return new FileSystemImpl(indexer);

+  }  

++-----------------------------------------------------------------------------------+   

+  

+   Here, Indexer and FileSystem are mutually dependent. Eventually, one or the other

+   of them will be created ... let's say its FileSystem. The buildFileSystem() builder

+   method will be invoked, and a proxy to Indexer will be passed in.  Inside the

+   FileSystemImpl constructor (or at some later date), a method of the Indexer service

+   will be invoked, at which point, the builderIndexer() method is invoked. It still receives

+   the proxy to the FileSystem service.

+   

+   If the order is reversed, such that Indexer is built before FileSystem, everything still

+   works the same.

+   

+   This approach can be very powerful: I've (HLS) used it to break apart untestable

+   monolithic code into two mutually dependent halves, each of which can be unit tested.

+    

+   The exception to this rule is a service that depends on itself <during construction>.

+   This can occur when (indirectly, through other services) building the service

+   tries to invoke a method on the service being built. This can happen when the service

+   implemention's constructor invoke methods on service dependencies passed into it,

+   or when the service builder method itself does the same. This is actually a very rare

+   case and difficult to illustrate.

+        
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/shadow.apt b/hlship-20080520/tapestry-ioc/src/site/apt/shadow.apt
new file mode 100644
index 0000000..4a8a674
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/shadow.apt
@@ -0,0 +1,61 @@
+ ----

+ Shadow Services

+ ----

+ 

+Shadow Services

+

+  The 

+  {{{../apidocs/org/apache/tapestry/ioc/services/PropertyShadowBuilder.html}PropertyShadowBuilder}}

+  service is used to build a special, delegating kind of service implementation.

+  

+  Effectively, it is used to allow a property of another service to be exposed as its own service.

+  

+  For example, the tapestry-core module provides a Request property as a shadow of the RequestGlobals

+  service's request property:

+  

++----+

+public Request build()

+{

+  return _shadowBuilder.build(_requestGlobals, "request", Request.class);

+}

++----+

+

+  This can be thought of as similar to:

+  

++----+

+public Request build()

+{

+  return _requestGlobals.getRequest();

+}

++----+

+    

+  However there is a <critical> difference between the two:  a shadow property is <re-evaluated on each method invocation>.

+  In the former case, the Request service will always obtain the current value of the request property from the

+  per-thread RequestGlobals service. The second example is more than likely broken, since it will expose whatever

+  value is in the request property of the RequestGlobals <at the time the Request service implementation is created>.

+  

+  Notice that in this example, the Request service is a normal singleton. This service can be freely injected

+  into any service throughout the framework or application. Invoking methods on this service will always delegate

+  to the current thread's request. Callers don't have to be aware of this internal delegation; it just happens.    

+  

+Non-Reflective

+

+  When the shadow is created, reflection is used to translate the property name to a method name.

+  This information is used to build a new class (at runtime) that is instantiated as the service implementation.

+  

+  A typical method is implemented as (approximately):

+  

++----+

+private RequestGlobals _source;

+

+public String getParameter(String name)

+{

+  return _source.getRequest().getParameter(name);

+}

++----+

+

+  That is, the shadow implementation holds onto the target object (in the above example,

+  the RequestGlobals service) and invokes a method on it directly, not using reflection, no differently

+  than you would if you wrote the code yourself.

+  

+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/startup.apt b/hlship-20080520/tapestry-ioc/src/site/apt/startup.apt
new file mode 100644
index 0000000..ef61f2d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/startup.apt
@@ -0,0 +1,28 @@
+ ----
+ Registry Startup
+ ----
+ 
+Registry Startup
+
+  It is possible to provide extra logic to be executed at Registry startup, by making contributions to the 
+  RegistryStartup service configuration.
+  
+  The values contributed are Runnable objects.  The configuration is ordered, so it is possible to control
+  in what order the objects are executed.
+  
+  RegistryStartup occurs after eager loaded services are instantiated.
+  
+  Here's an example of a module that makes a contribution.
+  
+----
+
+public class MyModule
+{
+  public static void contributeRegistryStartup(OrderedConfiguration<Runnable> configuration)
+  {
+    configuration.add("MyContributionName", new Runnable() { ... });
+  }
+}
+----
+
+  Generally, these contributions are in the form of inner classes; if they were services, they could just be eagerly loaded.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/strategy.apt b/hlship-20080520/tapestry-ioc/src/site/apt/strategy.apt
new file mode 100644
index 0000000..2f6396a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/strategy.apt
@@ -0,0 +1,53 @@
+ ----
+  Strategy Pattern
+ ----
+ 
+Strategy Pattern
+ 
+  Another of the Gang Of Four patterns, the strategy pattern as implemented in Tapestry IoC is a kind of late binding.
+  
+  The idea is that <adapters> for objects are accessed based on the <actual type> of an object.  These adapters supply additional functionality.  The adapters
+  are located using an {{{../apidocs/org/apache/tapestry/util/StrategyRegistry.html}StrategyRegistry}}.
+  
+  The lookup of adapters is based on an inheritance search; thus providing an adapter for type java.util.Map will match any object that implements the Map interface.
+  The inheritance search works its way up the class hierarchy looking for a matching registration. If nothing is found, then all the interfaces directly or indirectly
+  implemented by the selector class are checked. java.lang.Object is always the final match.
+  
+  A runtime exception is thrown if no match can be found.
+  
+  As a special case, the value null is search for as if it was an instance of the class void.
+    
+  The {{{../apidocs/org/apache/tapestry/ioc/services/StrategyBuilder.html}StrategyBuilder}} service creates a service implementation around a strategy registry.
+  
++---+
+public interface StrategyBuilder
+{
+    <S> S build(StrategyRegistry<S> registry);
+}
++---+  
+  
+  For a given interface (and matching   StrategyRegistry), a service implementation is created.  The service interface is determined from the
+  strategy registry.
+  
+  The first parameter of each method is the <selector>.  Its type is used to locate an adapter.
+  
+  The corresponding method of the adapter is then invoked, passing all parameters.
+  
+  Every method of the service interface should take at least one parameter.  Generally, such interfaces have only one or two methods.
+  
+Example
+
+  You will usually have a service configuration for defining the adapter registry.
+  
+  You convert the configuration into a StrategyRegistry, and use that to build the final service:
+  
++---+
+  public static MyStrategyService build(Map<Class, MyStrategyService> configuration,
+    @InjectService("StrategyBuilder")
+    StrategyBuilder builder)
+  {
+     StategyRegistry<MyStrategyService> registry = StrategyRegistry.newInstance(MyStrategyService.class, configuration);
+  
+     return builder.build(registry);
+  }
++---+
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/symbols.apt b/hlship-20080520/tapestry-ioc/src/site/apt/symbols.apt
new file mode 100644
index 0000000..fc3ae38
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/symbols.apt
@@ -0,0 +1,106 @@
+ ----
+ Symbols
+ ----
+ 
+Symbols
+
+  Tapestry IOC makes use of runtime-evaluated <symbols> to handle certains types of configuration tasks.
+  
+  The syntax of symbols is based on Ant expression, that is, a leading <<<$\{>>> before the symbol name,
+  and a trailing <<<\}>>> after.  The value on the inside is the <symbol name>.  By convention, the symbol
+  name is segmented with periods.
+  
+  These symbols are used inside the 
+  {{{../apidocs/org/apache/tapestry/ioc/annoations/Value.html}Value}} and
+  {{{../apidocs/org/apache/tapestry/ioc/annoations/InjectService.html}InjectService}}
+  annotations.
+  
+  For example:
+  
++----+
+  public static MyService build(
+      @InjectService("${some-service-id}") Collaborator collab)
+  {
+    return . . . ;
+  }
++---+
+
+  Here, the symbol,
+  <<<some-service-id>>> is  a service id, such as <<<WackyCollaborator>>>.
+     
+  Although not shown here, it is possible to use multple symbols inside the string, or mix literal text with
+  symbols.
+  
+Symbol Resolution
+
+  Symbols are resolved by the
+  {{{../apidocs/org/apache/tapestry/ioc/services/SymbolSource.html}SymbolSource}} service.  The SymbolSource
+  checks against an ordered list of
+  {{{../apidocs/org/apache/tapestry/ioc/services/SymbolProvider.html}SymbolProvider}} objects.
+
+  Additional symbol providers may be employed by contributing to the tapestry.ioc.SymbolSource service configuration,
+  which is an ordered list of SymbolProviders.
+  
+  By default, there are three providers:
+  
+* SystemProperties
+
+  The first provider allows JVM System Properties to provide symbol values.  This allows the use
+  of the <<java>> command's <<-D>> option to provide runtime overrides.  This is most often used
+  when testing code, rather than in production.
+  
+* ApplicationDefaults
+
+  Values not found as System Properties are searched for in the ApplicationDefaults.  This
+  service, ApplicationDefaults, may be configured using a mapped configuration to provide values.
+  
+  From the previous example:
+  
++----+
+  public void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+  {
+    configuration.add("some-service-id", "WackyCollaborator");
+  }
++----+
+  
+* FactoryDefaults
+
+  The same as ApplicationDefaults, but checked only if a value is not satisfied by SystemProperties
+  or ApplicationDefaults.
+  
+  Libraries will typically set reasonable defaults as contributions to the FactoryDefaults service configuration.
+  Individual applications may hard code overrides of those defaults using ApplicationDefaults.  Individual developers
+  may override even those defaults by setting JVM System Properties.
+  
+Recursive Symbols
+
+  It is possible and valid to define one symbol in terms of one ore more other symbols.
+  
+  
++----+
+  public void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
+  {
+      configuration.add("report.url", "http://${report.host}:${report.port}/${report.path}");
+      configuration.add("report.host", "www.myreportsite.com");
+      configuration.add("report.port", "80");
+      configuration.add("report.path", "/report.cgi");
+  }
++----+
+  
+  The ordinary default for <<<report.url>>> will be <<<http://www.myreportsite.com:80/report.cgi>>>.
+  
+  However, this can be changed by making an overriding contribution to the ApplicationDefaults service
+  configuration.  
+  
+  Tapestry checks that no symbol is directly or indirectly dependent on itself.  For example, the following contribution is
+  illegal:
+  
++----+
+  public void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+  {
+      configuration.add("report.path", "${report.url}/report.cgi");
+  }
++----+  
+  
+  When the <<<report.url>>> is referenced, an exception will be thrown with the message: <<
+  Symbol 'report.path' is defined in terms of itself (report.path --> report.url --> report.path).>>
diff --git a/hlship-20080520/tapestry-ioc/src/site/apt/upgrade.apt b/hlship-20080520/tapestry-ioc/src/site/apt/upgrade.apt
new file mode 100644
index 0000000..e89406f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/apt/upgrade.apt
@@ -0,0 +1,24 @@
+ ----
+ Upgrade Notes
+ ----
+
+Upgrade Notes
+
+  This is a quick guide to changes between releases of Tapestry.  This is meant to provide information
+  on any additions or changes that developers will face after upgrading to the latest version of Tapestry.
+
+  It is always advised to perform a full and complete build after upgrading.
+
+  You should also check the {{{../release-notes.html}project-wide release notes}} for information
+  about bugs fixes and other improvements.
+
+Release 5.0.12
+
+  Several methods of {{{../apidocs/org/apache/tapestry/ioc/services/ClassFabUtils.html}ClassFabUtils}}
+  have been removed.  The new method {{{castReference()}}} is an improved replacement for the removed
+  methods. These methods were largely used when decorating services, and the new 
+  {{{../apidocs/org/apache/tapestry/ioc/services/AspectDecorator.html}AspectDecorator}} is even easier.
+
+  For {{{https://issues.apache.org/jira/browse/TAPESTRY-2421}TAPESTRY-2421}} (compatibility between
+  Tapestry 4 and Tapestry 5), the org.apache.tapestry.ioc.annotations package was renamed
+  to org.apache.tapestry.ioc.annotation.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/site/resources/images/PipelineCallingSequence.png b/hlship-20080520/tapestry-ioc/src/site/resources/images/PipelineCallingSequence.png
new file mode 100644
index 0000000..96b5ed2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/resources/images/PipelineCallingSequence.png
Binary files differ
diff --git a/hlship-20080520/tapestry-ioc/src/site/resources/images/ioc-overview.png b/hlship-20080520/tapestry-ioc/src/site/resources/images/ioc-overview.png
new file mode 100644
index 0000000..c317c34
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/resources/images/ioc-overview.png
Binary files differ
diff --git a/hlship-20080520/tapestry-ioc/src/site/resources/images/type-coercer.png b/hlship-20080520/tapestry-ioc/src/site/resources/images/type-coercer.png
new file mode 100644
index 0000000..cfb43d5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/resources/images/type-coercer.png
Binary files differ
diff --git a/hlship-20080520/tapestry-ioc/src/site/site.xml b/hlship-20080520/tapestry-ioc/src/site/site.xml
new file mode 100644
index 0000000..ce78858
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/site/site.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2006 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry IoC">
+    <bannerLeft>
+        <name>Tapestry 5</name>
+        <href>http://tapestry.apache.org/tapestry5/</href>
+        <src>images/tapestry_banner.gif</src>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache</name>
+        <href>http://www.apache.org</href>
+        <src>images/asf_logo_wide.gif</src>
+    </bannerRight>
+    <skin>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>maven-skin</artifactId>
+        <version>1.1</version>
+    </skin>
+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+        <head>
+            <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
+            <script type="text/javascript">_uacct = "UA-400821-1"; urchinTracker();</script>
+        </head>
+
+        <menu name="Quick Links">
+            <item name="Download" href="http://tapestry.apache.org/download.html"/>
+            <item name="Upgrade Notes" href="upgrade.html"/>
+        </menu>
+
+        <menu name="Tapestry IoC Container">
+            <item name="Introduction" href="index.html"/>
+            <item name="Overview of Tapestry IoC" href="overview.html"/>
+            <item name="Modules" href="module.html"/>
+            <item name="Services" href="service.html"/>
+            <item name="Decorators" href="decorator.html"/>
+            <item name="Configuration" href="configuration.html"/>
+            <item name="Type Coercion" href="coerce.html"/>
+            <item name="Serialization" href="serialization.html"/>
+            <item name="Case Insensitivity" href="case.html"/>
+            <item name="Symbols" href="symbols.html"/>
+            <item name="Starting the Registry" href="run.html"/>
+            <item name="Object Providers" href="provider.html"/>
+            <item name="Ordering" href="order.html"/>
+            <item name="Logging" href="logging.html"/>
+            <item name="Startup" href="startup.html"/>
+        </menu>
+
+
+        <menu name="Service Builders">
+            <item name="Chain Of Command" href="command.html"/>
+            <item name="Strategy" href="strategy.html"/>
+            <item name="Pipeline" href="pipeline.html"/>
+            <item name="Shadow Services" href="shadow.html"/>
+        </menu>
+
+        <menu name="Tapestry IoC Cookbook">
+            <item name="Introduction" href="cookbook/index.html"/>
+            <item name="Basics" href="cookbook/basics.html"/>
+            <item name="Service Configurations" href="cookbook/servconf.html"/>
+            <item name="Using Patterns" href="cookbook/patterns.html"/>
+        </menu>
+
+
+        <menu ref="reports"/>
+
+    </body>
+</project>
diff --git a/hlship-20080520/tapestry-ioc/src/test/conf/testng.xml b/hlship-20080520/tapestry-ioc/src/test/conf/testng.xml
new file mode 100644
index 0000000..1f786b9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/conf/testng.xml
@@ -0,0 +1,33 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2007, 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry IOC" thread-count="10" annotations="1.5" verbose="2" parallel="tests">
+    <test name="Public APIs">
+        <packages>
+            <package name="org.apache.tapestry.ioc"/>
+            <package name="org.apache.tapestry.ioc.services"/>
+            <package name="org.apache.tapestry.ioc.util"/>
+        </packages>
+    </test>
+    <test name="Internals">
+        <packages>
+            <package name="org.apache.tapestry.ioc.internal"/>
+            <package name="org.apache.tapestry.ioc.internal.services"/>
+            <package name="org.apache.tapestry.ioc.internal.util"/>
+        </packages>
+    </test>
+</suite>
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/AutobuildModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/AutobuildModule.java
new file mode 100644
index 0000000..805fb93
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/AutobuildModule.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class AutobuildModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(StringHolder.class, StringHolderImpl.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BarneyModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BarneyModule.java
new file mode 100644
index 0000000..3378bb9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BarneyModule.java
@@ -0,0 +1,115 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Match;
+import org.apache.tapestry.ioc.annotation.Order;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Module used to demonstrate decorator ordering.
+ */
+
+public class BarneyModule
+{
+    @Match(
+            { "UnorderedNames", "Fred", "PrivateFredAlias" })
+    @Order("after:Beta")
+    public Object decorateGamma(Object delegate, DecoratorList list)
+    {
+        list.add("gamma");
+
+        return null;
+    }
+
+    public Sizer buildSizer(final Map<Class, Sizer> configuration)
+    {
+        return new Sizer()
+        {
+            public int size(Object object)
+            {
+                if (object == null) return 0;
+
+                Sizer sizer = configuration.get(object.getClass());
+
+                if (sizer != null) return sizer.size(object);
+
+                return 1;
+            }
+
+        };
+    }
+
+    public void contributeSizer(MappedConfiguration<Class, Sizer> configuration)
+    {
+        Sizer listSizer = new Sizer()
+        {
+            public int size(Object object)
+            {
+                List list = (List) object;
+
+                return list.size();
+            }
+        };
+
+        Sizer mapSizer = new Sizer()
+        {
+            public int size(Object object)
+            {
+                Map map = (Map) object;
+
+                return map.size();
+            }
+        };
+
+        // Have to work on concrete class, rather than type, until we move the StrategyFactory
+        // over from HiveMind.
+
+        configuration.add(ArrayList.class, listSizer);
+        configuration.add(HashMap.class, mapSizer);
+    }
+
+    /**
+     * Put DecoratorList in module barney, where so it won't accidentally be decorated (which recusively builds the
+     * service, and is caught as a failure).
+     */
+    public DecoratorList buildDecoratorList()
+    {
+        return new DecoratorList()
+        {
+            private List<String> names = CollectionFactory.newList();
+
+            public void add(String name)
+            {
+                names.add(name);
+            }
+
+            public List<String> getNames()
+            {
+                return names;
+            }
+        };
+    }
+
+    public void contributeUnorderedNames(Configuration<String> configuration)
+    {
+        configuration.add("Gamma");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BaseLocatableTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BaseLocatableTest.java
new file mode 100644
index 0000000..977f61d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BaseLocatableTest.java
@@ -0,0 +1,52 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+public class BaseLocatableTest extends IOCTestCase
+{
+
+    static class LocatableFixture extends BaseLocatable
+    {
+        LocatableFixture(Location location)
+        {
+            super(location);
+        }
+    }
+
+    @Test
+    public void location_property_is_readable()
+    {
+        Location location = newMock(Location.class);
+
+        replay();
+
+        Locatable locatable = new LocatableFixture(location);
+
+        verify();
+
+        assertSame(locatable.getLocation(), location);
+    }
+
+    @Test
+    public void null_is_allowed_for_location()
+    {
+        Locatable locatable = new LocatableFixture(null);
+
+        assertNull(locatable.getLocation());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java
new file mode 100644
index 0000000..6f09c71
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/BlueMarker.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface BlueMarker
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ConcreteServiceBuilderModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ConcreteServiceBuilderModule.java
new file mode 100644
index 0000000..61b6a43
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ConcreteServiceBuilderModule.java
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class ConcreteServiceBuilderModule
+{
+    /**
+     * Of course, this is silly to do now that there is {@link ServiceBinder}.
+     */
+    public StringHolderImpl buildStringHolder()
+    {
+        return new StringHolderImpl();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/CountingGreeterImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/CountingGreeterImpl.java
new file mode 100644
index 0000000..839bf66
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/CountingGreeterImpl.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class CountingGreeterImpl implements Greeter
+{
+    public static int instantiationCount;
+
+    public CountingGreeterImpl()
+    {
+        instantiationCount++;
+    }
+
+    public String getGreeting()
+    {
+        return "Hello";
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java
new file mode 100644
index 0000000..7d9acb8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DecoratorList.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+import java.util.List;

+

+/**

+ * Used to track the order in which decorators are invoked.

+ */

+public interface DecoratorList

+{

+    void add(String name);

+

+    List<String> getNames();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateFredModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateFredModule.java
new file mode 100644
index 0000000..5ad184a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateFredModule.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class DuplicateFredModule
+{
+    public Runnable buildFred()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateServiceTypeModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateServiceTypeModule.java
new file mode 100644
index 0000000..f8a70a9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/DuplicateServiceTypeModule.java
@@ -0,0 +1,29 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class DuplicateServiceTypeModule
+{
+    public Pingable buildFred()
+    {
+        return null;
+    }
+
+    public Pingable buildBarney()
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/EagerLoadModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/EagerLoadModule.java
new file mode 100644
index 0000000..dd5b8f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/EagerLoadModule.java
@@ -0,0 +1,33 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+
+/**
+ * Used to test service eager loading.
+ */
+public class EagerLoadModule
+{
+    public static boolean _eagerLoadDidHappen = false;
+
+    @EagerLoad
+    public StringHolder buildStringHolder()
+    {
+        _eagerLoadDidHappen = true;
+
+        return new StringHolderImpl();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FailInConstructorRunnable.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FailInConstructorRunnable.java
new file mode 100644
index 0000000..3d915e8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FailInConstructorRunnable.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class FailInConstructorRunnable implements Runnable
+{
+    public FailInConstructorRunnable()
+    {
+        throw new RuntimeException("Failure in Runnable constructor.");
+    }
+
+    public void run()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FredModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FredModule.java
new file mode 100644
index 0000000..6947d26
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/FredModule.java
@@ -0,0 +1,107 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Match;
+import org.apache.tapestry.ioc.annotation.Order;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Module used to demonstrate decorator ordering.
+ */
+public class FredModule
+{
+
+    /**
+     * Doesn't matter what the service does, we just want to verify that the decorators are invoked in the order we
+     * expect.
+     */
+    public Runnable buildFred()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+            }
+        };
+    }
+
+    @Match(
+            { "UnorderedNames", "Fred" })
+    @Order("before:Beta")
+    public Object decorateAlpha(Object delegate, DecoratorList list)
+    {
+        list.add("alpha");
+
+        return null;
+    }
+
+    @Match(
+            { "UnorderedNames", "Fred" })
+    public Object decorateBeta(Object delegate, DecoratorList list)
+    {
+        list.add("beta");
+
+        return null;
+    }
+
+    public NameListHolder buildUnorderedNames(Collection<String> configuration)
+    {
+        final List<String> sorted = CollectionFactory.newList(configuration);
+
+        Collections.sort(sorted);
+
+        return new NameListHolder()
+        {
+
+            public List<String> getNames()
+            {
+                return sorted;
+            }
+
+        };
+    }
+
+    public NameListHolder buildOrderedNames(final List<String> configuration)
+    {
+        return new NameListHolder()
+        {
+
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+
+        };
+    }
+
+    public void contributeOrderedNames(OrderedConfiguration<String> configuration)
+    {
+        // Order "FRED" after "BARNEY"
+
+        configuration.add("fred", "FRED", "after:barney");
+        configuration.add("barney", "BARNEY");
+    }
+
+    public void contributeUnorderedNames(Configuration<String> configuration)
+    {
+        configuration.add("UnorderedNames");
+        configuration.add("Beta");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Greeter.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Greeter.java
new file mode 100644
index 0000000..276a5f7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Greeter.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public interface Greeter
+{
+    String getGreeting();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java
new file mode 100644
index 0000000..e33a2fd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/GreeterModule.java
@@ -0,0 +1,102 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.InjectService;
+import org.apache.tapestry.ioc.annotation.Marker;
+
+public class GreeterModule
+{
+    @Marker(YellowMarker.class)
+    public NameListHolder buildYellowThing()
+    {
+        return null;
+    }
+
+    public Greeter buildHelloGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+            {
+                return "Hello";
+            }
+        };
+    }
+
+    public Greeter buildGoodbyeGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+            {
+                return "Goodbye";
+            }
+        };
+    }
+
+    @Marker(BlueMarker.class)
+    public Greeter buildBlueGreeter()
+    {
+        return new Greeter()
+        {
+            public String getGreeting()
+            {
+                return "Blue";
+            }
+        };
+    }
+
+    @Marker(RedMarker.class)
+    public Greeter buildRedGreeter1()
+    {
+        return null;
+    }
+
+    @Marker(RedMarker.class)
+    public Greeter buildRedGreeter2()
+    {
+        return null;
+    }
+
+    public Greeter buildInjectedBlueGreeter(@BlueMarker
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public Greeter buildInjectedRedGreeter(@RedMarker
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public Greeter buildInjectedYellowGreeter(@YellowMarker
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public Greeter buildGreeter(@InjectService("${greeter}")
+    Greeter greeter)
+    {
+        return greeter;
+    }
+
+    public void contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add("greeter", "HelloGreeter");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/HelterModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/HelterModule.java
new file mode 100644
index 0000000..d0b3f2d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/HelterModule.java
@@ -0,0 +1,27 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.SubModule;
+
+
+@SubModule(SkelterModule.class)
+public class HelterModule
+{
+    public Runnable buildHelter()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Indirection.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Indirection.java
new file mode 100644
index 0000000..13bce89
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Indirection.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Used to demonstrate indirection via symbols.
+ */
+public interface Indirection
+{
+    String getName();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolder.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolder.java
new file mode 100644
index 0000000..d714fb7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolder.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public interface IntHolder
+{
+    int getValue();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolderImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolderImpl.java
new file mode 100644
index 0000000..22d45d3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntHolderImpl.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class IntHolderImpl implements IntHolder
+{
+    private final int value;
+
+    public IntHolderImpl(final int value)
+    {
+        this.value = value;
+    }
+
+    public int getValue()
+    {
+        return value;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
new file mode 100644
index 0000000..508aa9f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
@@ -0,0 +1,784 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.internal.ExceptionInConstructorModule;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.*;
+import org.easymock.EasyMock;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.sql.PreparedStatement;
+import java.util.*;
+
+/**
+ * A few tests that are easiest (or even just possible) by building a Registry and trying out a few things.
+ */
+public class IntegrationTest extends IOCInternalTestCase
+{
+    private Registry buildRegistry()
+    {
+        return buildRegistry(FredModule.class, BarneyModule.class);
+    }
+
+    @Test
+    public void duplicate_service_names_are_failure()
+    {
+        try
+        {
+            buildRegistry(FredModule.class, DuplicateFredModule.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertTrue(ex.getMessage().startsWith("Service id 'Fred' has already been defined by"));
+
+            // Can't check the entire message, because we can't guarantee what order the modules
+            // will be processed in.
+        }
+    }
+
+    @Test
+    public void static_builder_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+        StaticModule.setFredRan(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        Runnable fred = r.getService("Fred", Runnable.class);
+
+        fred.run();
+
+        assertFalse(StaticModule.isInstantiated());
+        assertTrue(StaticModule.getFredRan());
+
+        r.shutdown();
+    }
+
+    @Test
+    public void static_decorator_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+        StaticModule.setDecoratorRan(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        Runnable fred = r.getService("Barney", Runnable.class);
+
+        fred.run();
+
+        assertFalse(StaticModule.isInstantiated());
+        assertTrue(StaticModule.getDecoratorRan());
+
+        r.shutdown();
+    }
+
+    @Test
+    public void static_contributor_method_does_not_instantiate_builder()
+    {
+        StaticModule.setInstantiated(false);
+
+        Registry r = buildRegistry(StaticModule.class);
+
+        NameListHolder holder = r.getService("Names", NameListHolder.class);
+
+        List<String> names = holder.getNames();
+
+        assertEquals(names, Arrays.asList("Fred"));
+
+        assertFalse(StaticModule.isInstantiated());
+
+        r.shutdown();
+    }
+
+    @Test
+    public void shutdown_deactivates_proxies()
+    {
+        Registry r = buildRegistry();
+
+        Runnable service = r.getService("Fred", Runnable.class);
+
+        service.run();
+
+        r.shutdown();
+
+        try
+        {
+            service.run();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Proxy for service Fred is no longer active because the IOC Registry has been shut down.");
+        }
+
+        // Show that toString() still works, even for a shutdown proxy.
+
+        assertEquals(service.toString(), "<Proxy for Fred(java.lang.Runnable)>");
+    }
+
+    /**
+     * Along the way, we also test a few other things, such as decorator matching and automatic dependency resolution.
+     */
+    @Test
+    public void public_service_decorator_order()
+    {
+        Registry r = buildRegistry();
+
+        Runnable service = r.getService("Fred", Runnable.class);
+
+        // Force creation
+
+        service.run();
+
+        List<String> names = r.getService(DecoratorList.class).getNames();
+
+        // Note that the order of invocation appears backwards, since we build back-to-front
+
+        assertEquals(names, Arrays.asList("gamma", "beta", "alpha"));
+    }
+
+    @Test
+    public void public_service_unordered_configuration()
+    {
+        Registry r = buildRegistry();
+
+        NameListHolder service = r.getService("UnorderedNames", NameListHolder.class);
+
+        List<String> names = service.getNames();
+
+        assertEquals(names, Arrays.asList("Beta", "Gamma", "UnorderedNames"));
+    }
+
+    /**
+     * We don't have to do as many public/private etc. tests for the other types of configuration, because the code
+     * paths are so similar.
+     */
+
+    @Test
+    public void service_ordered_configuration()
+    {
+        Registry r = buildRegistry();
+
+        NameListHolder service = r.getService("OrderedNames", NameListHolder.class);
+
+        List<String> names = service.getNames();
+
+        assertEquals(names, Arrays.asList("BARNEY", "FRED"));
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void service_mapped_configuration()
+    {
+        Registry r = buildRegistry();
+
+        Sizer sizer = r.getService("Sizer", Sizer.class);
+
+        assertEquals(sizer.size(null), 0);
+
+        // Have to be exact on type here.
+
+        List list = new ArrayList();
+        list.add(1);
+        list.add(2);
+        list.add(3);
+
+        assertEquals(sizer.size(list), 3);
+
+        Map map = new HashMap();
+        map.put("fred", "flinstone");
+        map.put("barney", "rubble");
+
+        assertEquals(sizer.size(map), 2);
+
+        // Random objects are size 1
+
+        assertEquals(sizer.size(this), 1);
+
+        r.shutdown();
+    }
+
+    @Test
+    public void unknown_scope()
+    {
+        Registry r = buildRegistry(UnknownScopeModule.class);
+
+        try
+        {
+            Runnable runnable = r.getService("UnknownScope", Runnable.class);
+
+            runnable.run();
+
+            unreachable();
+        }
+        catch (Exception ex)
+        {
+            assertMessageContains(ex, "Exception constructing service 'UnknownScope'", "Unknown service scope 'magic'");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void simple_perthread() throws Exception
+    {
+        final Registry r = buildRegistry(PerThreadModule.class);
+
+        final StringHolder holder = r.getService(StringHolder.class);
+
+        // Something about some of the other tests causes this one to fail
+        // unless we start with cleanupThread(), there must be a loose ThreadLocal
+        // hanging around causing problems.
+
+        r.cleanupThread();
+
+        holder.setValue("fred");
+        assertEquals(holder.getValue(), "fred", holder.toString());
+
+        Runnable runnable = new Runnable()
+        {
+            public void run()
+            {
+                Assert.assertNull(holder.getValue());
+
+                holder.setValue("barney");
+                assertEquals(holder.getValue(), "barney");
+
+                r.cleanupThread();
+            }
+        };
+
+        Thread t = new Thread(runnable);
+
+        t.start();
+        t.join();
+
+        assertEquals(holder.getValue(), "fred");
+
+        r.cleanupThread();
+
+        r.shutdown();
+    }
+
+    /**
+     * This test fails at times and I'm not sure why. It's some kind of interaction with other tests but hard to figure
+     * out. Damn ThreadLocals!
+     */
+    @Test
+    public void registry_thread_cleanup()
+    {
+        Registry r = buildRegistry(PerThreadModule.class);
+
+        r.cleanupThread();
+
+        StringHolder holder = r.getService(StringHolder.class);
+
+        assertNull(holder.getValue());
+
+        holder.setValue("fred");
+        assertEquals(holder.getValue(), "fred");
+
+        r.cleanupThread();
+
+        assertNull(holder.getValue());
+    }
+
+    @Test
+    public void recursive_module_construction_is_caught()
+    {
+        Registry r = buildRegistry(RecursiveConstructorModule.class);
+
+        try
+        {
+            Runnable runnable = r.getService("Runnable", Runnable.class);
+
+            // We can get the proxy, but invoking a method causes
+            // the module to be instantiated ... but that also invokes a method on
+            // the proxy.
+
+            runnable.run();
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertTrue(ex.getMessage().contains("has failed due to recursion"));
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void eager_service_loading()
+    {
+        Registry r = buildRegistry(EagerLoadModule.class);
+
+        assertFalse(EagerLoadModule._eagerLoadDidHappen, "EagerLoadModule is not in correct initial state.");
+
+        r.performRegistryStartup();
+
+        assertTrue(EagerLoadModule._eagerLoadDidHappen);
+
+        r.shutdown();
+    }
+
+    @Test
+    public void access_to_services_ignores_case()
+    {
+        Registry r = buildRegistry(FredModule.class);
+
+        Runnable fred = r.getService("Fred", Runnable.class);
+
+        assertSame(r.getService("FRED", Runnable.class), fred);
+
+        r.shutdown();
+    }
+
+    @Test
+    public void simple_autobuild()
+    {
+        Registry r = buildRegistry(AutobuildModule.class);
+
+        StringHolder sh = r.getService(StringHolder.class);
+
+        sh.setValue("Foo");
+
+        assertEquals(sh.getValue(), "Foo");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void exception_in_autobuild_service_constructor()
+    {
+        Registry r = buildRegistry(ExceptionInConstructorModule.class);
+
+        Pingable pingable = r.getService(Pingable.class);
+
+        try
+        {
+            pingable.ping();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Error invoking constructor",
+                                  "ExceptionInConstructorServiceImpl() (at ExceptionInConstructorServiceImpl.java",
+                                  "for service 'Pingable'", "Yes, we have no tomatoes.");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void non_proxied_service()
+    {
+        Registry r = buildRegistry(NonProxiedServiceModule.class);
+
+        // Note: obtained via the (or an) interface implemented by
+        // the service implementation.
+
+        StringHolder holder = r.getService(StringHolder.class);
+
+        assertTrue(holder instanceof StringHolderImpl);
+
+        r.shutdown();
+    }
+
+    @Test
+    public void service_builder_method_uses_autobuild()
+    {
+        Registry r = buildRegistry(ServiceBuilderAutobuilderModule.class);
+
+        StringHolder holder = r.getService(StringHolder.class);
+
+        // Check that it works.
+
+        holder.setValue("Foo");
+
+        assertEquals(holder.getValue(), "Foo");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void autobuild_via_registry()
+    {
+        Registry r = buildRegistry();
+
+        StringHolder holder = r.autobuild(StringHolderImpl.class);
+
+        assertSame(holder.getClass(), StringHolderImpl.class);
+
+        // Check that it works.
+
+        holder.setValue("Foo");
+
+        assertEquals(holder.getValue(), "Foo");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void service_builder_method_uses_autobuild_with_failure()
+    {
+        Registry r = buildRegistry(ServiceBuilderAutobuilderModule.class);
+
+        // We can get the proxy.
+
+        Pingable pingable = r.getService(Pingable.class);
+
+        try
+        {
+            // But it fails at realization
+
+            pingable.ping();
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "Class org.apache.tapestry.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
+
+            // Like to check that the message includes the source location
+
+            assertTrue(ex.getMessage().matches(".*\\(at ServiceBuilderAutobuilderModule.java:\\d+\\).*"));
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void autobuild_via_registry_no_constructor()
+    {
+        Registry r = buildRegistry();
+
+        try
+        {
+            r.autobuild(UnbuildablePingable.class);
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex,
+                                  "Class org.apache.tapestry.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void autobuild_via_registry_constructor_exception()
+    {
+        Registry r = buildRegistry();
+
+        try
+        {
+            r.autobuild(FailInConstructorRunnable.class);
+
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Error invoking constructor org.apache.tapestry.ioc.FailInConstructorRunnable()",
+                                  "Failure in Runnable constructor.");
+
+            // Like to check that the message includes the source location
+
+            assertTrue(ex.getMessage().matches(".*\\(at FailInConstructorRunnable.java:\\d+\\).*"));
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void get_service_by_unknown_id()
+    {
+        Registry r = buildRegistry();
+
+        try
+        {
+            r.getService("PeekABoo", Runnable.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Service id \'PeekABoo\' is not defined by any module.");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void request_service_by_type_with_no_matches()
+    {
+
+        Registry r = buildRegistry();
+
+        try
+        {
+            r.getService(PreparedStatement.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "No service implements the interface java.sql.PreparedStatement.");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void request_service_by_type_with_multiple_matches()
+    {
+        Registry r = buildRegistry(DuplicateServiceTypeModule.class);
+
+        try
+        {
+            r.getService(Pingable.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Service interface org.apache.tapestry.ioc.Pingable is matched by 2 services: Barney, Fred.  Automatic dependency resolution requires that exactly one service implement the interface.");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void service_build_method_return_type_not_interface()
+    {
+        Registry r = buildRegistry(ConcreteServiceBuilderModule.class);
+
+        StringHolder holder = r.getService(StringHolder.class);
+
+        // No interface means no proxy.
+
+        assertTrue(holder instanceof StringHolderImpl);
+
+        // But the implementation is cached
+
+        assertSame(r.getService(StringHolder.class), holder);
+
+        r.shutdown();
+    }
+
+    @Test
+    public void symbol_in_inject_annotation_is_expanded()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("Greeter", Greeter.class);
+
+        assertEquals(g.getGreeting(), "Hello");
+        assertEquals(g.toString(), "<Proxy for Greeter(org.apache.tapestry.ioc.Greeter)>");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void symbol_in_registry_call_for_service_is_expanded()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("${greeter}", Greeter.class);
+
+        assertEquals(g.getGreeting(), "Hello");
+        assertEquals(g.toString(), "<Proxy for HelloGreeter(org.apache.tapestry.ioc.Greeter)>");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void injection_by_marker_with_single_match()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedBlueGreeter", Greeter.class);
+
+        assertEquals(g.getGreeting(), "Blue");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void injection_by_marker_with_multiple_matches()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedRedGreeter", Greeter.class);
+
+        try
+        {
+            g.getGreeting();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Error invoking service builder method",
+                                  "Unable to locate a single service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.RedMarker",
+                                  "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter1()",
+                                  "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter2()");
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void injection_by_marker_with_zero_matches()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        Greeter g = r.getService("InjectedYellowGreeter", Greeter.class);
+
+        try
+        {
+            g.getGreeting();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Error invoking service builder method",
+                                  " Unable to locate any service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.YellowMarker.");
+        }
+
+        r.shutdown();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void builtin_services_available_via_marker_annotation()
+    {
+        Registry r = buildRegistry();
+
+        TypeCoercer tc1 = r.getService("TypeCoercer", TypeCoercer.class);
+
+        Builtin annotation = newMock(Builtin.class);
+
+        AnnotationProvider ap = mockAnnotationProvider();
+
+        train_getAnnotation(ap, Builtin.class, annotation);
+
+        // On the build server, the order of keys inside the RegistryImpl's _markerToServiceDef
+        // is different, and so it *may* query ofr a number of other annotation
+        // besides Builtin.
+
+        expect(ap.getAnnotation(EasyMock.isA(Class.class))).andStubReturn(null);
+
+        replay();
+
+        TypeCoercer tc2 = r.getObject(TypeCoercer.class, ap);
+
+        assertSame(tc1, tc2);
+
+        verify();
+
+        r.shutdown();
+    }
+
+    /**
+     * A cursory test for {@link ServiceActivityScoreboard}, just to see if any data has been collected.
+     */
+    @Test
+    public void service_activity_scoreboard()
+    {
+        Registry r = buildRegistry(GreeterModule.class);
+
+        ServiceActivityScoreboard scoreboard = r.getService(ServiceActivityScoreboard.class);
+
+        // Force the state of a few services.
+
+        TypeCoercer tc = r.getService("TypeCoercer", TypeCoercer.class);
+
+        tc.coerce("123", Integer.class);
+
+        r.getService("BlueGreeter", Greeter.class);
+
+        // Now get the activity list and poke around.
+
+        List<ServiceActivity> serviceActivity = scoreboard.getServiceActivity();
+
+        assertTrue(serviceActivity.size() > 0);
+
+        for (ServiceActivity a : serviceActivity)
+        {
+            String serviceId = a.getServiceId();
+
+            if (serviceId.equals("ClassFactory")) assertEquals(a.getStatus(), Status.BUILTIN);
+
+            if (serviceId.equals("RedGreeter1")) assertEquals(a.getStatus(), Status.DEFINED);
+
+            if (serviceId.equals("TypeCoercer")) assertEquals(a.getStatus(), Status.REAL);
+
+            if (serviceId.equals("BlueGreeter")) assertEquals(a.getStatus(), Status.VIRTUAL);
+        }
+
+        r.shutdown();
+    }
+
+    @Test
+    public void proxy_autobuild_object()
+    {
+        Registry r = buildRegistry();
+
+        CountingGreeterImpl.instantiationCount = 0;
+
+        Greeter g = r.proxy(Greeter.class, CountingGreeterImpl.class);
+
+        assertEquals(CountingGreeterImpl.instantiationCount, 0);
+
+        assertEquals(g.toString(),
+                     "<Autobuild proxy org.apache.tapestry.ioc.CountingGreeterImpl(org.apache.tapestry.ioc.Greeter)>");
+
+        assertEquals(CountingGreeterImpl.instantiationCount, 0);
+
+        // Show that the class is not instantiated until a method is invoked, and that its
+        // only instantiated once.
+
+        for (int i = 0; i < 5; i++)
+        {
+            assertEquals(g.getGreeting(), "Hello");
+            assertEquals(CountingGreeterImpl.instantiationCount, 1);
+        }
+
+        r.shutdown();
+    }
+
+
+    /**
+     * TAPESTRY-2117
+     */
+    @Test
+    public void circular_module_references_are_ignored()
+    {
+        Registry r = buildRegistry(HelterModule.class);
+
+        Runnable helter = r.getService("Helter", Runnable.class);
+        Runnable skelter = r.getService("Skelter", Runnable.class);
+
+        assertNotSame(helter, skelter);
+
+        r.shutdown();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java
new file mode 100644
index 0000000..5cc89d2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MarkerModule.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Marker;
+
+public class MarkerModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(Greeter.class, RedGreeterImpl.class).withId("RedGreeter");
+        binder.bind(Greeter.class, UnknownColorGreeterImpl.class).withId("SecondRedGreeter")
+                .withMarker(RedMarker.class);
+        binder.bind(Greeter.class, RedGreeterImpl.class).withId("SurprisinglyBlueGreeter")
+                .withMarker(BlueMarker.class);
+    }
+
+    @Marker(BlueMarker.class)
+    public Greeter build()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MasterModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MasterModule.java
new file mode 100644
index 0000000..2db09b8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/MasterModule.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.SubModule;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.RegistryBuilderTest}.
+ */
+@SubModule(
+        { FredModule.class, BarneyModule.class })
+public final class MasterModule
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java
new file mode 100644
index 0000000..95399a1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NameListHolder.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+import java.util.List;

+

+/**

+ * Used for testing of ordered and unordered contributions. The names are contributed in from

+ * multiple modules. For unordered contributions, the values are sorted alphabetically. For ordered

+ * contributions, the values are ordered as per the contributions.

+ */

+public interface NameListHolder

+{

+    public List<String> getNames();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NonProxiedServiceModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NonProxiedServiceModule.java
new file mode 100644
index 0000000..1351bbb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/NonProxiedServiceModule.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class NonProxiedServiceModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(StringHolderImpl.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java
new file mode 100644
index 0000000..0a6f700
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/PerThreadModule.java
@@ -0,0 +1,27 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import org.apache.tapestry.ioc.annotation.Scope;
+
+public class PerThreadModule
+{
+    @Scope(PERTHREAD_SCOPE)
+    public StringHolder buildStringHolder()
+    {
+        return new StringHolderImpl();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Pingable.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Pingable.java
new file mode 100644
index 0000000..d81957b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Pingable.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Interface used as a stand-in for testing for more complicated services.
+ */
+public interface Pingable
+{
+    void ping();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RecursiveConstructorModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RecursiveConstructorModule.java
new file mode 100644
index 0000000..74eec14
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RecursiveConstructorModule.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.InjectService;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.IntegrationTest}.
+ */
+public class RecursiveConstructorModule
+{
+
+    public RecursiveConstructorModule(@InjectService("Runnable")
+    Runnable r)
+    {
+        // Invoking a method on the service proxy is going to cause a recursive attempt to
+        // instantiate the module. Hilarity ensues.
+
+        r.run();
+    }
+
+    public Runnable buildRunnable()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedGreeterImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedGreeterImpl.java
new file mode 100644
index 0000000..ea7f14d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedGreeterImpl.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Marker;
+
+@Marker(RedMarker.class)
+public class RedGreeterImpl implements Greeter
+{
+
+    public String getGreeting()
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedMarker.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedMarker.java
new file mode 100644
index 0000000..6e4b0b7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RedMarker.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface RedMarker
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java
new file mode 100644
index 0000000..5bdfdfc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java
@@ -0,0 +1,69 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class RegistryBuilderTest extends IOCTestCase
+{
+    @Test
+    public void sub_module()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        builder.add(MasterModule.class);
+
+        Registry r = builder.build();
+
+        // Borrowed from IntegrationTest, this will only work if both FredModule and BarneyModule
+        // are loaded.
+
+        NameListHolder service = r.getService("UnorderedNames", NameListHolder.class);
+
+        List<String> names = service.getNames();
+
+        assertEquals(names, Arrays.asList("Beta", "Gamma", "UnorderedNames"));
+
+        r.shutdown();
+    }
+
+    @Test
+    public void manifest()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        String value = String.format("%s, %s, %s", FredModule.class.getName(), BarneyModule.class
+                .getName(), RegistryBuilderTestModule.class.getName());
+
+        IOCUtilities.addModulesInList(builder, value);
+
+        Registry registry = builder.build();
+
+        Square service = registry.getService(Square.class);
+
+        assertEquals(service.square(4), 16l);
+
+        // This proves that the IOC works, the service builder method was invoked, that the
+        // ClassFactory service was accessed and used.
+
+        assertEquals(service.toString(), "<Proxy for Square(org.apache.tapestry.ioc.Square)>");
+
+        registry.shutdown();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTestModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTestModule.java
new file mode 100644
index 0000000..f03e1c8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTestModule.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class RegistryBuilderTestModule
+{
+    /**
+     * Arbitrary interface and service name.
+     */
+    public Square buildSquare()
+    {
+        return new Square()
+        {
+            public long square(long input)
+            {
+                return input * input;
+            }
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ServiceBuilderAutobuilderModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ServiceBuilderAutobuilderModule.java
new file mode 100644
index 0000000..f10416d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/ServiceBuilderAutobuilderModule.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class ServiceBuilderAutobuilderModule
+{
+    public StringHolder build(ServiceResources resources)
+    {
+        return resources.autobuild(StringHolderImpl.class);
+    }
+
+    public Pingable buildPingable(ServiceResources resources)
+    {
+        return resources.autobuild(UnbuildablePingable.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Sizer.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Sizer.java
new file mode 100644
index 0000000..7425abd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Sizer.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Encapsulates a strategy for determining the size of an object. Different implementations are

+ * mapped to different types.

+ */

+public interface Sizer

+{

+    int size(Object object);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/SkelterModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/SkelterModule.java
new file mode 100644
index 0000000..c6f4352
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/SkelterModule.java
@@ -0,0 +1,26 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.SubModule;
+
+@SubModule(HelterModule.class)
+public class SkelterModule
+{
+    public Runnable buildSkelter()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Square.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Square.java
new file mode 100644
index 0000000..56c5433
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/Square.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.RegistryBuilderTest}.

+ */

+public interface Square

+{

+    long square(long input);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StaticModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StaticModule.java
new file mode 100644
index 0000000..5caef20
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StaticModule.java
@@ -0,0 +1,120 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class StaticModule
+{
+    private static boolean instantiated;
+
+    private static boolean fredRan;
+
+    private static boolean decoratorRan;
+
+    public StaticModule()
+    {
+        setInstantiated(true);
+    }
+
+    public static Runnable buildFred()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+                setFredRan(true);
+            }
+        };
+    }
+
+    public static Runnable buildBarney()
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+            }
+        };
+    }
+
+    public static Runnable decorateBarney(final Object delegate)
+    {
+        return new Runnable()
+        {
+            public void run()
+            {
+                setDecoratorRan(true);
+
+                ((Runnable) delegate).run();
+            }
+        };
+    }
+
+    public static synchronized void setFredRan(boolean fredRan)
+    {
+        StaticModule.fredRan = fredRan;
+    }
+
+    public static synchronized boolean getFredRan()
+    {
+        return fredRan;
+    }
+
+    public static synchronized void setInstantiated(boolean instantiated)
+    {
+        StaticModule.instantiated = instantiated;
+    }
+
+    public static synchronized boolean isInstantiated()
+    {
+        return instantiated;
+    }
+
+    public static synchronized void setDecoratorRan(boolean decoratorRan)
+    {
+        StaticModule.decoratorRan = decoratorRan;
+    }
+
+    public static synchronized boolean getDecoratorRan()
+    {
+        return decoratorRan;
+    }
+
+    public static NameListHolder buildNames(final Collection<String> configuration)
+    {
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                List<String> result = CollectionFactory.newList(configuration);
+
+                Collections.sort(result);
+
+                return result;
+            }
+        };
+    }
+
+    public static void contributeNames(Configuration<String> configuration)
+    {
+        configuration.add("Fred");
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolder.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolder.java
new file mode 100644
index 0000000..5abfa6b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolder.java
@@ -0,0 +1,25 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ *

+ */

+public interface StringHolder

+{

+    void setValue(String value);

+

+    String getValue();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java
new file mode 100644
index 0000000..8e1a411
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringHolderImpl.java
@@ -0,0 +1,33 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc;

+

+/**

+ *

+ */

+public class StringHolderImpl implements StringHolder

+{

+    private String value;

+

+    public String getValue()

+    {

+        return value;

+    }

+

+    public void setValue(String value)

+    {

+        this.value = value;

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringTransformer.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringTransformer.java
new file mode 100644
index 0000000..194ec3e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/StringTransformer.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.IntegrationTest}.

+ */

+public interface StringTransformer

+{

+    String transform(String input);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnbuildablePingable.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnbuildablePingable.java
new file mode 100644
index 0000000..c27d6f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnbuildablePingable.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+/**
+ * Used to test failure to autobuild a service because of a lack of a public constructor.
+ */
+public class UnbuildablePingable implements Pingable
+{
+    private UnbuildablePingable()
+    {
+    }
+
+    public void ping()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownColorGreeterImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownColorGreeterImpl.java
new file mode 100644
index 0000000..326fcde
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownColorGreeterImpl.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+public class UnknownColorGreeterImpl implements Greeter
+{
+
+    public String getGreeting()
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownScopeModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownScopeModule.java
new file mode 100644
index 0000000..ed4b8b5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/UnknownScopeModule.java
@@ -0,0 +1,26 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import org.apache.tapestry.ioc.annotation.Scope;
+
+public class UnknownScopeModule
+{
+    @Scope("magic")
+    public Runnable buildUnknownScope()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/YellowMarker.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/YellowMarker.java
new file mode 100644
index 0000000..1381921
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/YellowMarker.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface YellowMarker
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ArrayDecoratorMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ArrayDecoratorMethodModule.java
new file mode 100644
index 0000000..8c55b70
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ArrayDecoratorMethodModule.java
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.

+ */

+public class ArrayDecoratorMethodModule

+{

+    public Object[] decorateArray(Object delegate)

+    {

+        return null;

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/BuilderMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/BuilderMethodModule.java
new file mode 100644
index 0000000..81aa221
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/BuilderMethodModule.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+public class BuilderMethodModule
+{
+    public String[] buildStringArray()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ComplexAutobuildModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ComplexAutobuildModule.java
new file mode 100644
index 0000000..b0b27da
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ComplexAutobuildModule.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.StringHolder;
+import org.apache.tapestry.ioc.StringHolderImpl;
+
+public class ComplexAutobuildModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(StringHolder.class, StringHolderImpl.class).eagerLoad().scope("magic").withId("SH");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ContributionDefImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ContributionDefImplTest.java
new file mode 100644
index 0000000..6c71d91
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ContributionDefImplTest.java
@@ -0,0 +1,192 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.annotation.InjectService;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+public class ContributionDefImplTest extends IOCTestCase implements ModuleBuilderSource
+{
+    private Object toContribute;
+
+    public Object getModuleBuilder()
+    {
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void unordered_contribution()
+    {
+        toContribute = new Object();
+        Configuration configuration = mockConfiguration();
+        ObjectLocator locator = mockObjectLocator();
+
+        configuration.add(toContribute);
+
+        replay();
+
+        Method m = findMethod("contributeUnordered");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+
+        def.contribute(this, locator, configuration);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void unordered_collection_with_service_lookup()
+    {
+        Configuration configuration = mockConfiguration();
+        ObjectLocator locator = mockObjectLocator();
+        UpcaseService service = mockUpcaseService();
+
+        train_getService(locator, "zip.Zap", UpcaseService.class, service);
+
+        configuration.add(service);
+
+        replay();
+
+        Method m = findMethod("contributeUnorderedParameter");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+
+        def.contribute(this, locator, configuration);
+
+        verify();
+    }
+
+    @Test
+    public void unordered_collection_with_incorrect_configuration_parameter()
+    {
+        Configuration configuration = mockConfiguration();
+        ObjectLocator locator = mockObjectLocator();
+
+        Throwable t = new RuntimeException("Missing service.");
+
+        expect(locator.getObject(eq(MappedConfiguration.class), isA(AnnotationProvider.class)))
+                .andThrow(t);
+
+        replay();
+
+        Method m = findMethod("contributeUnorderedWrongParameter");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+
+        try
+        {
+            def.contribute(this, locator, configuration);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Error invoking service contribution method "
+                    + getClass().getName()
+                    + ".contributeUnorderedWrongParameter(MappedConfiguration): Missing service.");
+        }
+
+        verify();
+    }
+
+    // From here on in, it's an almost identical code path, so we won't be
+    // as exhaustive.
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void ordered_collection_with_service_lookup()
+    {
+        OrderedConfiguration configuration = mockOrderedConfiguration();
+        ObjectLocator locator = mockObjectLocator();
+        UpcaseService service = mockUpcaseService();
+
+        train_getService(locator, "zip.Zap", UpcaseService.class, service);
+
+        configuration.add("fred", service);
+
+        replay();
+
+        Method m = findMethod("contributeOrderedParameter");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+
+        def.contribute(this, locator, configuration);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void mapped_collection_with_service_lookup()
+    {
+        MappedConfiguration configuration = mockMappedConfiguration();
+        ObjectLocator locator = mockObjectLocator();
+        UpcaseService service = mockUpcaseService();
+
+        train_getService(locator, "zip.Zap", UpcaseService.class, service);
+
+        configuration.add("upcase", service);
+
+        replay();
+
+        Method m = findMethod("contributeMappedParameter");
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+
+        def.contribute(this, locator, configuration);
+
+        verify();
+    }
+
+    private UpcaseService mockUpcaseService()
+    {
+        return newMock(UpcaseService.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void contributeUnordered(Configuration configuration)
+    {
+        configuration.add(toContribute);
+    }
+
+    public void contributeUnorderedParameter(Configuration<UpcaseService> configuration,
+                                             @InjectService("zip.Zap")
+                                             UpcaseService service)
+    {
+        configuration.add(service);
+    }
+
+    public void contributeOrderedParameter(OrderedConfiguration<UpcaseService> configuration,
+                                           @InjectService("zip.Zap")
+                                           UpcaseService service)
+    {
+        configuration.add("fred", service);
+    }
+
+    public void contributeMappedParameter(MappedConfiguration<String, UpcaseService> configuration,
+                                          @InjectService("zip.Zap")
+                                          UpcaseService service)
+    {
+        configuration.add("upcase", service);
+    }
+
+    public void contributeUnorderedWrongParameter(MappedConfiguration configuration)
+    {
+        unreachable();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java
new file mode 100644
index 0000000..2897933
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java
@@ -0,0 +1,563 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.*;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.ioc.internal.IOCMessages.buildMethodConflict;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import static org.easymock.EasyMock.and;
+import static org.easymock.EasyMock.contains;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+
+public class DefaultModuleDefImplTest extends IOCTestCase
+{
+    private ClassFactory classFactory;
+
+    @BeforeClass
+    public void setup()
+    {
+        classFactory = new ClassFactoryImpl();
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        classFactory = null;
+    }
+
+    @Test
+    public void simple_module() throws Exception
+    {
+        String className = SimpleModule.class.getName();
+
+        Logger logger = mockLogger();
+
+        replay();
+
+        // BigDecimal is arbitrary, any class would do.
+
+        ModuleDef md = new DefaultModuleDefImpl(SimpleModule.class, logger, classFactory);
+
+        assertEquals(md.toString(), "ModuleDef[" + className + " Barney, Fred, Wilma]");
+
+        Set<String> ids = md.getServiceIds();
+
+        assertEquals(ids.size(), 3);
+        assertTrue(ids.contains("Fred"));
+        assertTrue(ids.contains("Barney"));
+        assertTrue(ids.contains("Wilma"));
+
+        ServiceDef sd = md.getServiceDef("Fred");
+
+        assertEquals(sd.getServiceId(), "Fred");
+
+        assertEquals(sd.getServiceInterface(), FieService.class);
+
+        assertTrue(sd.toString().contains(className + ".buildFred()"));
+        assertEquals(sd.getServiceScope(), IOCConstants.DEFAULT_SCOPE);
+        assertEquals(sd.isEagerLoad(), false);
+        assertTrue(sd.getMarkers().isEmpty());
+
+        sd = md.getServiceDef("Wilma");
+        assertEquals(sd.isEagerLoad(), true);
+
+        // Now the decorator method.
+
+        Set<DecoratorDef> defs = md.getDecoratorDefs();
+
+        assertEquals(defs.size(), 1);
+
+        DecoratorDef dd = defs.iterator().next();
+
+        assertEquals(dd.getDecoratorId(), "Logging");
+        assertTrue(dd.toString().contains(className + ".decorateLogging(Class, Object)"));
+
+        verify();
+    }
+
+    @Test
+    public void default_service_id_from_return_type()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef def = new DefaultModuleDefImpl(DefaultServiceIdModule.class, logger, null);
+
+        assertEquals(def.getServiceIds().size(), 1);
+
+        ServiceDef sd = def.getServiceDef("FieService");
+
+        assertEquals(sd.getServiceId(), "FieService");
+
+        verify();
+    }
+
+    /**
+     * Two different methods both claim to build the same service.
+     */
+    @Test
+    public void service_id_conflict() throws Exception
+    {
+        Method conflictMethod = ServiceIdConflictMethodModule.class.getMethod("buildFred");
+        String conflictMethodString = InternalUtils.asString(conflictMethod, classFactory);
+
+        String expectedMethod = InternalUtils.asString(ServiceIdConflictMethodModule.class
+                .getMethod("buildFred", Object.class), classFactory);
+
+        Logger logger = mockLogger();
+
+        logger.warn(buildMethodConflict(conflictMethodString, expectedMethod));
+
+        replay();
+
+        // BigDecimal is arbitrary, any class would do.
+
+        ModuleDef md = new DefaultModuleDefImpl(ServiceIdConflictMethodModule.class, logger, classFactory);
+
+        Set<String> ids = md.getServiceIds();
+
+        assertEquals(ids.size(), 1);
+        assertTrue(ids.contains("Fred"));
+
+        ServiceDef sd = md.getServiceDef("Fred");
+
+        assertEquals(sd.getServiceId(), "Fred");
+
+        assertEquals(sd.getServiceInterface(), FieService.class);
+
+        // The methods are considered in ascending order, by name, then descending order, by
+        // parameter count. So the grinder will latch onto the method that takes a parameter,
+        // and consider the other method (with no parameters) the conflict.
+
+        assertEquals(sd.toString(), expectedMethod.toString());
+
+        verify();
+    }
+
+    @Test
+    public void builder_method_returns_void() throws Exception
+    {
+        Method m = VoidBuilderMethodModule.class.getMethod("buildNull");
+
+        Logger logger = mockLogger();
+
+        logger.warn(IOCMessages.buildMethodWrongReturnType(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(VoidBuilderMethodModule.class, logger, null);
+
+        assertTrue(md.getServiceIds().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void builder_method_returns_array() throws Exception
+    {
+        Method m = BuilderMethodModule.class.getMethod("buildStringArray");
+
+        Logger logger = mockLogger();
+
+        logger.warn(IOCMessages.buildMethodWrongReturnType(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(BuilderMethodModule.class, logger, null);
+
+        assertTrue(md.getServiceIds().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void decorator_method_returns_void() throws Exception
+    {
+        invalidDecoratorMethod(VoidDecoratorMethodModule.class, "decorateVoid");
+    }
+
+    private void invalidDecoratorMethod(Class moduleClass, String methodName) throws NoSuchMethodException
+    {
+        Method m = moduleClass.getMethod(methodName, Object.class);
+
+        Logger logger = mockLogger();
+
+        logger.warn(IOCMessages.decoratorMethodWrongReturnType(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, null);
+
+        assertTrue(md.getDecoratorDefs().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void decorator_method_returns_primitive() throws Exception
+    {
+        invalidDecoratorMethod(PrimitiveDecoratorMethodModule.class, "decoratePrimitive");
+    }
+
+    @Test
+    public void decorator_method_returns_array() throws Exception
+    {
+        invalidDecoratorMethod(ArrayDecoratorMethodModule.class, "decorateArray");
+    }
+
+    @Test
+    public void decorator_method_does_not_include_delegate_parameter() throws Exception
+    {
+        Class moduleClass = NoDelegateDecoratorMethodModule.class;
+        Method m = moduleClass.getMethod("decorateNoDelegate");
+
+        Logger logger = mockLogger();
+
+        logger.warn(IOCMessages.decoratorMethodNeedsDelegateParameter(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, null);
+
+        assertTrue(md.getDecoratorDefs().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void contribution_without_annotation()
+    {
+        attemptConfigurationMethod(SimpleModule.class, "Barney", "contributeBarney(Configuration)");
+    }
+
+    @Test
+    public void ordered_contribution_method()
+    {
+        attemptConfigurationMethod(OrderedConfigurationModule.class, "Ordered",
+                                   "contributeOrdered(OrderedConfiguration)");
+    }
+
+    @Test
+    public void mapped_contribution_method()
+    {
+        attemptConfigurationMethod(MappedConfigurationModule.class, "Mapped", "contributeMapped(MappedConfiguration)");
+    }
+
+    private void attemptConfigurationMethod(Class moduleClass, String expectedServiceId, String expectedMethodSignature)
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, classFactory);
+
+        Set<ContributionDef> defs = md.getContributionDefs();
+
+        assertEquals(defs.size(), 1);
+
+        ContributionDef cd = defs.iterator().next();
+
+        // The target service id is derived from the method name
+
+        assertEquals(cd.getServiceId(), expectedServiceId);
+
+        // Can't be exact, because the source file & line number are probably attached (and those
+        // can change)
+
+        assertTrue(cd.toString().contains(moduleClass.getName() + "." + expectedMethodSignature));
+
+        verify();
+    }
+
+    @Test
+    public void contribution_with_too_many_parameters() throws Exception
+    {
+        Class moduleClass = TooManyContributionParametersModule.class;
+        Method m = findMethod(moduleClass, "contributeTooMany");
+
+        Logger logger = mockLogger();
+        logger.warn(IOCMessages.tooManyContributionParameters(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, null);
+
+        assertTrue(md.getContributionDefs().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void contribution_with_no_contribution_parameter() throws Exception
+    {
+        Class moduleClass = NoUsableContributionParameterModule.class;
+        Method m = findMethod(moduleClass, "contributeNoParameter");
+
+        Logger logger = mockLogger();
+        logger.warn(IOCMessages.noContributionParameter(m));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(moduleClass, logger, null);
+
+        assertTrue(md.getContributionDefs().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void simple_binder_method()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(AutobuildModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("StringHolder");
+
+        assertEquals(sd.getServiceInterface(), StringHolder.class);
+        assertEquals(sd.getServiceId(), "StringHolder");
+        assertEquals(sd.getServiceScope(), IOCConstants.DEFAULT_SCOPE);
+        assertFalse(sd.isEagerLoad());
+
+        verify();
+    }
+
+    @Test
+    public void bind_service_with_all_options()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(ComplexAutobuildModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("SH");
+
+        assertEquals(sd.getServiceInterface(), StringHolder.class);
+        assertEquals(sd.getServiceId(), "SH");
+        assertEquals(sd.getServiceScope(), "magic");
+        assertTrue(sd.isEagerLoad());
+
+        verify();
+    }
+
+    @Test
+    public void attempt_to_bind_a_service_with_no_public_constructor()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        try
+        {
+            new DefaultModuleDefImpl(UninstantiableAutobuildServiceModule.class, logger, classFactory);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class org.apache.tapestry.ioc.internal.RunnableServiceImpl (implementation of service \'Runnable\') does not contain any public constructors.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void instance_method_bind_is_ignored()
+    {
+        Logger logger = mockLogger();
+
+        logger.error(and(contains(NonStaticBindMethodModule.class.getName()), contains("but is an instance method")));
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(NonStaticBindMethodModule.class, logger, classFactory);
+
+        // Prove that the bind method was not invoke
+
+        assertTrue(md.getServiceIds().isEmpty());
+
+        verify();
+    }
+
+    @Test
+    public void multiple_constructors_on_autobuild_service_implementation()
+    {
+        Logger logger = mockLogger();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+
+        train_isDebugEnabled(logger, true);
+
+        // The point is, we're choosing the constructor with the largest number of parameters.
+
+        logger
+                .debug(contains(
+                        "Invoking constructor org.apache.tapestry.ioc.internal.MultipleConstructorsAutobuildService(StringHolder)"));
+
+        train_getServiceId(resources, "StringHolder");
+        train_getLogger(resources, logger);
+        train_getServiceInterface(resources, StringHolder.class);
+        train_getService(resources, "ToUpperCaseStringHolder", StringHolder.class, new ToUpperCaseStringHolder());
+
+        replay();
+
+        ModuleDef def = new DefaultModuleDefImpl(MutlipleAutobuildServiceConstructorsModule.class, logger,
+                                                 classFactory);
+
+        ServiceDef sd = def.getServiceDef("StringHolder");
+
+        assertNotNull(sd);
+
+        ObjectCreator oc = sd.createServiceCreator(resources);
+
+        StringHolder holder = (StringHolder) oc.createObject();
+
+        holder.setValue("foo");
+        assertEquals(holder.getValue(), "FOO");
+
+        verify();
+    }
+
+    @Test
+    public void exception_from_inside_bind_method()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        try
+        {
+            new DefaultModuleDefImpl(ExceptionInBindMethod.class, logger, classFactory);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertTrue(ex
+                    .getMessage()
+                    .matches(
+                    "Error invoking service binder method org.apache.tapestry.ioc.internal.ExceptionInBindMethod.bind\\(ServiceBinder\\) " + "\\(at ExceptionInBindMethod.java:\\d+\\): Really, how often is this going to happen\\?"));
+        }
+
+        verify();
+    }
+
+    @Test
+    public void autoload_service_is_eager_load_via_annotation()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(EagerLoadViaAnnotationModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("Runnable");
+
+        assertTrue(sd.isEagerLoad());
+
+        verify();
+    }
+
+    @Test
+    public void service_builder_method_has_marker_annotation()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(MarkerModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("Greeter");
+
+        assertListsEquals(CollectionFactory.newList(sd.getMarkers()), BlueMarker.class);
+
+        verify();
+    }
+
+    @Test
+    public void bound_service_has_marker_annotation()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(MarkerModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("RedGreeter");
+
+        assertListsEquals(CollectionFactory.newList(sd.getMarkers()), RedMarker.class);
+
+        verify();
+    }
+
+    @Test
+    public void bound_service_explicit_marker()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(MarkerModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("SecondRedGreeter");
+
+        assertListsEquals(CollectionFactory.newList(sd.getMarkers()), RedMarker.class);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void explicit_marker_overrides_marker_annotation()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        ModuleDef md = new DefaultModuleDefImpl(MarkerModule.class, logger, classFactory);
+
+        ServiceDef sd = md.getServiceDef("SurprisinglyBlueGreeter");
+
+        // BlueMarker from ServiceBindingOptions, RedMarker from @Marker on class
+
+        Set<Class> markers = sd.getMarkers();
+
+        assertTrue(markers.contains(RedMarker.class));
+        assertTrue(markers.contains(BlueMarker.class));
+        assertEquals(markers.size(), 2);
+
+        verify();
+    }
+
+    // TODO: We're short on tests that ensure that marker annotation are additive (i.e., module
+    // marker annotation are
+    // merged into the set specific to the service).
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultServiceIdModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultServiceIdModule.java
new file mode 100644
index 0000000..7eab8be
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultServiceIdModule.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+public class DefaultServiceIdModule
+{
+    public FieService build()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationModule.java
new file mode 100644
index 0000000..4532d16
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationModule.java
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+
+public class EagerLoadViaAnnotationModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(Runnable.class, EagerLoadViaAnnotationServiceImpl.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationServiceImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationServiceImpl.java
new file mode 100644
index 0000000..694d4bc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/EagerLoadViaAnnotationServiceImpl.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+
+@EagerLoad
+public class EagerLoadViaAnnotationServiceImpl implements Runnable
+{
+
+    public void run()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInBindMethod.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInBindMethod.java
new file mode 100644
index 0000000..f575737
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInBindMethod.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+
+public class ExceptionInBindMethod
+{
+    public static void bind(ServiceBinder binder)
+    {
+        throw new RuntimeException("Really, how often is this going to happen?");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorModule.java
new file mode 100644
index 0000000..850dda6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorModule.java
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Pingable;
+import org.apache.tapestry.ioc.ServiceBinder;
+
+public class ExceptionInConstructorModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(Pingable.class, ExceptionInConstructorServiceImpl.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorServiceImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorServiceImpl.java
new file mode 100644
index 0000000..7e84409
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExceptionInConstructorServiceImpl.java
@@ -0,0 +1,31 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Pingable;
+
+public class ExceptionInConstructorServiceImpl implements Pingable
+{
+
+    public ExceptionInConstructorServiceImpl()
+    {
+        throw new RuntimeException("Yes, we have no tomatoes.");
+    }
+
+    public void ping()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExtraPublicConstructorsModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExtraPublicConstructorsModule.java
new file mode 100644
index 0000000..b18dbd9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ExtraPublicConstructorsModule.java
@@ -0,0 +1,40 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.annotation.InjectService;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.ModuleImplTest}.
+ */
+public class ExtraPublicConstructorsModule
+{
+
+    public ExtraPublicConstructorsModule()
+    {
+
+    }
+
+    /**
+     * Should be the first constructor, the one that gets invoked. I'm worried that different compilers or JVMs will
+     * order the constructors differently.
+     */
+    public ExtraPublicConstructorsModule(@InjectService("ClassFactory")
+    ClassFactory factory)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FieService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FieService.java
new file mode 100644
index 0000000..2b63f10
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FieService.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * A placeholder for a real service interface.

+ */

+public interface FieService

+{

+    void fie();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FoeService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FoeService.java
new file mode 100644
index 0000000..929d26e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/FoeService.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * A placeholder for a real service interface.

+ */

+public interface FoeService

+{

+    int foe();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/GlobPatternMatcherTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/GlobPatternMatcherTest.java
new file mode 100644
index 0000000..7f64c3e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/GlobPatternMatcherTest.java
@@ -0,0 +1,80 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+import static org.testng.Assert.assertFalse;

+import static org.testng.Assert.assertTrue;

+import org.testng.annotations.Test;

+

+/**

+ *

+ */

+public class GlobPatternMatcherTest

+{

+    private boolean globMatch(String input, String pattern)

+    {

+        return new GlobPatternMatcher(pattern).matches(input);

+    }

+

+    @Test

+    public void glob_match_exact()

+    {

+        assertTrue(globMatch("fred", "fred"));

+        assertTrue(globMatch("fred", "FRED"));

+        assertFalse(globMatch("xfred", "fred"));

+        assertFalse(globMatch("fredx", "fred"));

+        assertFalse(globMatch("fred", "xfred"));

+        assertFalse(globMatch("fred", "fredx"));

+    }

+

+    @Test

+    public void glob_match_wild()

+    {

+        assertTrue(globMatch("fred", "*"));

+        assertTrue(globMatch("", "*"));

+    }

+

+    @Test

+    public void glob_match_prefix()

+    {

+        assertTrue(globMatch("fred.Barney", "*Barney"));

+        assertTrue(globMatch("fred.Barney", "*BARNEY"));

+        assertFalse(globMatch("fred.Barneyx", "*Barney"));

+        assertFalse(globMatch("fred.Barney", "*Barneyx"));

+        assertFalse(globMatch("fred.Barney", "*xBarney"));

+    }

+

+    @Test

+    public void glob_match_suffix()

+    {

+        assertTrue(globMatch("fred.Barney", "fred*"));

+        assertTrue(globMatch("fred.Barney", "FRED*"));

+        assertFalse(globMatch("xfred.Barney", "fred*"));

+        assertFalse(globMatch("fred.Barney", "fredx*"));

+        assertFalse(globMatch("fred.Barney", "xfred*"));

+    }

+

+    @Test

+    public void glob_match_infix()

+    {

+        assertTrue(globMatch("fred.Barney", "*d.B*"));

+        assertTrue(globMatch("fred.Barney", "*D.B*"));

+        assertTrue(globMatch("fred.Barney", "*Barney*"));

+        assertTrue(globMatch("fred.Barney", "*fred*"));

+        assertTrue(globMatch("fred.Barney", "*FRED*"));

+        assertFalse(globMatch("fred.Barney", "*flint*"));

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilderTest.java
new file mode 100644
index 0000000..365180f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/InterceptorStackBuilderTest.java
@@ -0,0 +1,111 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.testng.annotations.Test;
+
+import static java.util.Arrays.asList;
+import java.util.List;
+
+public class InterceptorStackBuilderTest extends IOCInternalTestCase
+{
+    private static final String SERVICE_ID = "foo.bar.Baz";
+
+    @Test
+    public void no_decorators()
+    {
+        ObjectCreator core = mockObjectCreator();
+        Module module = mockModule();
+        Object coreObject = new Object();
+        List<ServiceDecorator> decorators = newList();
+
+        train_createObject(core, coreObject);
+
+        train_findDecoratorsForService(module, SERVICE_ID, decorators);
+
+        replay();
+
+        ObjectCreator isb = new InterceptorStackBuilder(module, SERVICE_ID, core);
+
+        Object intercepted = isb.createObject();
+
+        assertSame(intercepted, coreObject);
+
+        verify();
+    }
+
+    @Test
+    public void decorator_returns_null_interceptor()
+    {
+        ObjectCreator core = mockObjectCreator();
+        Module module = mockModule();
+        Object coreObject = new Object();
+        ServiceDecorator decorator = mockServiceDecorator();
+
+        List<ServiceDecorator> decorators = asList(decorator);
+
+        train_createObject(core, coreObject);
+
+        train_findDecoratorsForService(module, SERVICE_ID, decorators);
+
+        train_createInterceptor(decorator, coreObject, null);
+
+        replay();
+
+        ObjectCreator isb = new InterceptorStackBuilder(module, SERVICE_ID, core);
+
+        Object intercepted = isb.createObject();
+
+        assertSame(intercepted, coreObject);
+
+        verify();
+    }
+
+    @Test
+    public void decorator_orderering()
+    {
+        ObjectCreator core = mockObjectCreator();
+        Module module = mockModule();
+        Object coreObject = new Object();
+        Object interceptor1 = new Object();
+        Object interceptor2 = new Object();
+        ServiceDecorator decorator1 = mockServiceDecorator();
+        ServiceDecorator decorator2 = mockServiceDecorator();
+
+        List<ServiceDecorator> decorators = asList(decorator1, decorator2);
+
+        train_createObject(core, coreObject);
+
+        train_findDecoratorsForService(module, SERVICE_ID, decorators);
+
+        // Notice: reverse order!
+
+        train_createInterceptor(decorator2, coreObject, interceptor2);
+        train_createInterceptor(decorator1, interceptor2, interceptor1);
+
+        replay();
+
+        ObjectCreator isb = new InterceptorStackBuilder(module, SERVICE_ID, core);
+
+        Object intercepted = isb.createObject();
+
+        assertSame(intercepted, interceptor1);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java
new file mode 100644
index 0000000..2dd5f13
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/LoggerSourceImplTest.java
@@ -0,0 +1,48 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.LoggerSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+public class LoggerSourceImplTest extends IOCInternalTestCase
+{
+    @Test
+    public void get_by_class()
+    {
+        Class clazz = getClass();
+
+        Logger expected = LoggerFactory.getLogger(clazz);
+        LoggerSource logSource = new LoggerSourceImpl();
+        Logger actual = logSource.getLogger(clazz);
+
+        assertSame(actual, expected);
+    }
+
+    @Test
+    public void get_by_name()
+    {
+        String name = "foo.Bar";
+
+        Logger expected = LoggerFactory.getLogger(name);
+        LoggerSource logSource = new LoggerSourceImpl();
+        Logger actual = logSource.getLogger(name);
+
+        assertSame(actual, expected);
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MappedConfigurationModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MappedConfigurationModule.java
new file mode 100644
index 0000000..e5a3cad
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MappedConfigurationModule.java
@@ -0,0 +1,28 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.MappedConfiguration;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImpl}.
+ */
+public class MappedConfigurationModule
+{
+    public void contributeMapped(MappedConfiguration configuration)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleBuilderWithId.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleBuilderWithId.java
new file mode 100644
index 0000000..ef4fe6a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleBuilderWithId.java
@@ -0,0 +1,23 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.
+ */
+public class ModuleBuilderWithId
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
new file mode 100644
index 0000000..7822397
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
@@ -0,0 +1,241 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.RegistryBuilder;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.apache.tapestry.ioc.services.Status;
+import static org.easymock.EasyMock.contains;
+import static org.easymock.EasyMock.isA;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+
+public class ModuleImplTest extends IOCInternalTestCase
+{
+    @Test
+    public void get_service_by_id_exists()
+    {
+        InternalRegistry registry = mockInternalRegistry();
+        Logger logger = mockLogger();
+        ClassFactory factory = new ClassFactoryImpl();
+        ServiceActivityTracker tracker = mockServiceActivityTracker();
+
+        ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger, getClassFactory());
+
+        Module module = new ModuleImpl(registry, tracker, moduleDef, null, logger);
+
+        expect(registry.getServiceLogger("Upcase")).andReturn(logger);
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("Creating service 'Upcase'.");
+
+        tracker.setStatus("Upcase", Status.VIRTUAL);
+
+        train_newClass(registry, factory, UpcaseService.class);
+
+        registry.addRegistryShutdownListener(isA(RegistryShutdownListener.class));
+
+        replay();
+
+        UpcaseService service = module.getService("Upcase", UpcaseService.class);
+
+        verify();
+
+        train_getLifecycle(registry, "singleton", new SingletonServiceLifecycle());
+
+        train_isDebugEnabled(logger, false);
+
+        train_findDecoratorsForService(registry);
+
+        tracker.setStatus("Upcase", Status.REAL);
+
+        replay();
+
+        assertEquals(service.upcase("hello"), "HELLO");
+
+        verify();
+    }
+
+    protected final void train_newClass(InternalRegistry registry, ClassFactory factory, Class serviceInterface)
+    {
+        expect(registry.newClass(serviceInterface)).andReturn(factory.newClass(serviceInterface));
+    }
+
+    @Test
+    public void find_service_ids_for_interface()
+    {
+        InternalRegistry registry = mockInternalRegistry();
+        Logger logger = mockLogger();
+
+        ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger, null);
+
+        Module module = new ModuleImpl(registry, null, moduleDef, null, logger);
+
+        replay();
+
+        Collection<String> ids = module.findServiceIdsForInterface(FieService.class);
+
+        assertEquals(ids.size(), 2);
+        assertTrue(ids.contains("Fie"));
+        assertTrue(ids.contains("OtherFie"));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void find_decorator_defs_for_service()
+    {
+        InternalRegistry registry = mockInternalRegistry();
+        ServiceDef serviceDef = mockServiceDef();
+        DecoratorDef def1 = mockDecoratorDef();
+        DecoratorDef def2 = mockDecoratorDef();
+        Set<DecoratorDef> rawDefs = newMock(Set.class);
+        Logger logger = mockLogger();
+
+        ModuleDef moduleDef = mockModuleDef();
+
+        expect(moduleDef.getDecoratorDefs()).andReturn(rawDefs);
+
+        expect(rawDefs.iterator()).andReturn(Arrays.asList(def1, def2).iterator());
+
+        train_matches(def1, serviceDef, false);
+        train_matches(def2, serviceDef, true);
+
+        replay();
+
+        Module module = new ModuleImpl(registry, null, moduleDef, null, logger);
+
+        Set<DecoratorDef> defs = module.findMatchingDecoratorDefs(serviceDef);
+
+        assertEquals(defs.size(), 1);
+        assertTrue(defs.contains(def2));
+
+        verify();
+    }
+
+    @Test
+    public void no_public_constructor_on_module_builder_class()
+    {
+        InternalRegistry registry = mockInternalRegistry();
+        Logger logger = mockLogger();
+        ModuleDef def = new DefaultModuleDefImpl(PrivateConstructorModule.class, logger, null);
+
+        replay();
+
+        Module module = new ModuleImpl(registry, null, def, null, logger);
+
+        try
+        {
+            module.getModuleBuilder();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Module builder class org.apache.tapestry.ioc.internal.PrivateConstructorModule " + "does not contain any public constructors.");
+        }
+
+        verify();
+
+    }
+
+    @Test
+    public void too_many_public_constructors_on_module_builder_class()
+    {
+        InternalRegistry registry = mockInternalRegistry();
+        Logger logger = mockLogger();
+        ModuleDef def = new DefaultModuleDefImpl(ExtraPublicConstructorsModule.class, logger, null);
+        ClassFactory factory = newMock(ClassFactory.class);
+        Module module = new ModuleImpl(registry, null, def, null, logger);
+
+        logger.warn(contains("contains more than one public constructor"));
+
+        train_expandSymbols(registry, "ClassFactory", "ClassFactory");
+
+        train_getService(registry, "ClassFactory", ClassFactory.class, factory);
+
+        replay();
+
+        assertTrue(module.getModuleBuilder() instanceof ExtraPublicConstructorsModule);
+
+        verify();
+    }
+
+    protected void train_expandSymbols(InternalRegistry registry, String input, String expanded)
+    {
+        expect(registry.expandSymbols(input)).andReturn(expanded);
+    }
+
+    private Registry buildRegistry()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.add(ModuleImplTestModule.class);
+
+        return builder.build();
+    }
+
+    /**
+     * The following tests work better as integration tests.
+     */
+
+    @Test
+    public void integration_tests()
+    {
+        Registry registry = buildRegistry();
+
+        UpcaseService us = registry.getService(UpcaseService.class);
+
+        assertEquals(us.upcase("hello"), "HELLO");
+        assertEquals(us.toString(), "<Proxy for Upcase(org.apache.tapestry.ioc.internal.UpcaseService)>");
+
+        ToStringService ts = registry.getService(ToStringService.class);
+
+        assertEquals(ts.toString(), "<ToStringService: ToString>");
+
+        registry.shutdown();
+    }
+
+    @Test
+    public void recursive_singleton_integration_test()
+    {
+        Registry registry = buildRegistry();
+
+        FoeService foe = registry.getService("RecursiveFoe", FoeService.class);
+
+        try
+        {
+            foe.foe();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            // The details are checked elsewhere.
+        }
+
+        registry.shutdown();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTestModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTestModule.java
new file mode 100644
index 0000000..9b8ddba
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTestModule.java
@@ -0,0 +1,61 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.annotation.InjectService;
+
+/**
+ * Module builder used by {@link ModuleImplTest}.
+ */
+public class ModuleImplTestModule
+{
+    public UpcaseService buildUpcase()
+    {
+        return new UpcaseServiceImpl();
+    }
+
+    public FieService buildOtherFie()
+    {
+        return null;
+    }
+
+    public ToStringService buildToString(final String serviceId)
+    {
+        return new ToStringService()
+        {
+            @Override
+            public String toString()
+            {
+                return "<ToStringService: " + serviceId + ">";
+            }
+        };
+    }
+
+    public FieService buildFie()
+    {
+        return null;
+    }
+
+    public FoeService buildRecursiveFoe(@InjectService("RecursiveFoe")
+    FoeService self)
+    {
+        // While constructing self, we invoke a method on self.
+
+        self.foe();
+
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MultipleConstructorsAutobuildService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MultipleConstructorsAutobuildService.java
new file mode 100644
index 0000000..15ca944
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MultipleConstructorsAutobuildService.java
@@ -0,0 +1,44 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.StringHolder;
+import org.apache.tapestry.ioc.annotation.InjectService;
+
+public class MultipleConstructorsAutobuildService implements StringHolder
+{
+    private final StringHolder delegate;
+
+    public MultipleConstructorsAutobuildService()
+    {
+        this(null);
+    }
+
+    public MultipleConstructorsAutobuildService(@InjectService("ToUpperCaseStringHolder")StringHolder delegate)
+    {
+        this.delegate = delegate;
+    }
+
+    public String getValue()
+    {
+        return delegate.getValue();
+    }
+
+    public void setValue(String value)
+    {
+        delegate.setValue(value);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java
new file mode 100644
index 0000000..1fa1707
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.StringHolder;
+
+public class MutlipleAutobuildServiceConstructorsModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(StringHolder.class, ToUpperCaseStringHolder.class).withId(
+                "ToUpperCaseStringHolder");
+        binder.bind(StringHolder.class, MultipleConstructorsAutobuildService.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoDelegateDecoratorMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoDelegateDecoratorMethodModule.java
new file mode 100644
index 0000000..6005f96
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoDelegateDecoratorMethodModule.java
@@ -0,0 +1,30 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.

+ */

+public class NoDelegateDecoratorMethodModule

+{

+    /**

+     * Decorator methods need to define a parameter of type Object which is the delegate object.

+     * Typically, it is a parameterized type, but it has to be there.

+     */

+    public Object decorateNoDelegate()

+    {

+        return null;

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoUsableContributionParameterModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoUsableContributionParameterModule.java
new file mode 100644
index 0000000..06185dd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NoUsableContributionParameterModule.java
@@ -0,0 +1,29 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.annotation.InjectService;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImpl}.
+ */
+public class NoUsableContributionParameterModule
+{
+    public void contributeNoParameter(@InjectService("foo.Bar")
+    UpcaseService service)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NonStaticBindMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NonStaticBindMethodModule.java
new file mode 100644
index 0000000..e3c1707
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/NonStaticBindMethodModule.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+import org.apache.tapestry.ioc.StringHolder;
+import org.apache.tapestry.ioc.StringHolderImpl;
+
+public class NonStaticBindMethodModule
+{
+    public void bind(ServiceBinder binder)
+    {
+        binder.bind(StringHolder.class, StringHolderImpl.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/OrderedConfigurationModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/OrderedConfigurationModule.java
new file mode 100644
index 0000000..7d36409
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/OrderedConfigurationModule.java
@@ -0,0 +1,28 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.OrderedConfiguration;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImpl}.
+ */
+public class OrderedConfigurationModule
+{
+    public void contributeOrdered(OrderedConfiguration configuration)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrimitiveDecoratorMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrimitiveDecoratorMethodModule.java
new file mode 100644
index 0000000..e78c7cb
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrimitiveDecoratorMethodModule.java
@@ -0,0 +1,26 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.

+ */

+public class PrimitiveDecoratorMethodModule

+{

+    public int decoratePrimitive(Object delegate)

+    {

+        return 0;

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrivateConstructorModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrivateConstructorModule.java
new file mode 100644
index 0000000..7108e2f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/PrivateConstructorModule.java
@@ -0,0 +1,26 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.ModuleImplTest}.
+ */
+public class PrivateConstructorModule
+{
+    private PrivateConstructorModule()
+    {
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ReadManifest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ReadManifest.java
new file mode 100644
index 0000000..4a2e0ac
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ReadManifest.java
@@ -0,0 +1,91 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;

+

+import java.io.InputStream;

+import static java.lang.String.format;

+import java.net.URL;

+import java.util.Collections;

+import java.util.Enumeration;

+import java.util.List;

+import java.util.Map;

+import java.util.jar.Attributes;

+import java.util.jar.Manifest;

+

+public class ReadManifest

+{

+

+    /**

+     * @param args

+     */

+    public static void main(String[] args) throws Exception

+    {

+        ClassLoader loader = ReadManifest.class.getClassLoader();

+

+        Enumeration<URL> urls = loader.getResources("META-INF/MANIFEST.MF");

+

+        while (urls.hasMoreElements())

+        {

+            URL url = urls.nextElement();

+

+            System.out.println(url);

+

+            InputStream is = url.openStream();

+

+            Manifest mf = new Manifest(is);

+

+            is.close();

+

+            printManifest(mf);

+        }

+

+    }

+

+    static void printManifest(Manifest mf)

+    {

+

+        printAttributes(mf.getMainAttributes());

+

+        if (false)

+        {

+            Map<String, Attributes> entries = mf.getEntries();

+            List<String> keys = newList(entries.keySet());

+            Collections.sort(keys);

+

+            for (String key : keys)

+            {

+                System.out.println(format("  %s", key));

+

+                Attributes a = entries.get(key);

+

+                printAttributes(a);

+

+            }

+        }

+    }

+

+    private static void printAttributes(Attributes a)

+    {

+        for (Object key : a.keySet())

+        {

+            Object value = a.get(key);

+

+            System.out.println(format("    %30s: %s", key, value));

+        }

+

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapperTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapperTest.java
new file mode 100644
index 0000000..765146b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RecursiveServiceCreationCheckWrapperTest.java
@@ -0,0 +1,106 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class RecursiveServiceCreationCheckWrapperTest extends IOCInternalTestCase
+{
+
+    private static final String SOURCE_DESCRIPTION = "{SOURCE DESCRIPTION}";
+
+    @Test
+    public void ensure_only_called_once() throws Exception
+    {
+        Logger logger = mockLogger();
+        ObjectCreatorSource source = mockObjectCreatorSource();
+        ObjectCreator delegate = mockObjectCreator();
+        Object service = new Object();
+
+        ServiceDef def = new ServiceDefImpl(Runnable.class, "Bar", null, "singleton", false, source);
+
+        train_createObject(delegate, service);
+
+        train_getDescription(source, SOURCE_DESCRIPTION);
+
+        replay();
+
+        ObjectCreator wrapper = new RecursiveServiceCreationCheckWrapper(def, delegate, logger);
+
+        assertSame(wrapper.createObject(), service);
+
+        try
+        {
+            wrapper.createObject();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertMessageContains(
+                    ex,
+                    "Construction of service 'Bar' has failed due to recursion: the service depends on itself in some way.",
+                    SOURCE_DESCRIPTION,
+                    "for references to another service that is itself dependent on service 'Bar'.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void reporting_of_construction_failure() throws Exception
+    {
+        RuntimeException failure = new RuntimeException("Just cranky.");
+        Logger logger = mockLogger();
+        ObjectCreatorSource source = mockObjectCreatorSource();
+        ObjectCreator delegate = mockObjectCreator();
+        Object service = new Object();
+
+        ServiceDef def = new ServiceDefImpl(Runnable.class, "Bar", null, "singleton", false, source);
+
+        expect(delegate.createObject()).andThrow(failure);
+
+        logger.error("Construction of service Bar failed: Just cranky.", failure);
+
+        replay();
+
+        ObjectCreator wrapper = new RecursiveServiceCreationCheckWrapper(def, delegate, logger);
+
+        try
+        {
+            wrapper.createObject();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertSame(ex, failure);
+        }
+
+        verify();
+
+        // Now test that the locked flag is not set and that the object may still be created.
+
+        train_createObject(delegate, service);
+
+        replay();
+
+        assertSame(service, wrapper.createObject());
+
+        verify();
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RunnableServiceImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RunnableServiceImpl.java
new file mode 100644
index 0000000..b2bc4c6
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/RunnableServiceImpl.java
@@ -0,0 +1,30 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+/**
+ * This service implementation is not instantiable, which triggers an exception.
+ */
+public class RunnableServiceImpl implements Runnable
+{
+    private RunnableServiceImpl()
+    {
+    }
+
+    public void run()
+    {
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodFixture.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodFixture.java
new file mode 100644
index 0000000..a77691f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodFixture.java
@@ -0,0 +1,121 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.annotation.InjectService;
+import org.apache.tapestry.ioc.annotation.Value;
+import org.slf4j.Logger;
+import org.testng.Assert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.ServiceBuilderMethodInvokerTest}.
+ */
+public class ServiceBuilderMethodFixture extends Assert
+{
+    FieService fie;
+
+    String expectedServiceId;
+
+    ServiceResources expectedServiceResources;
+
+    Class expectedServiceInterface;
+
+    Logger expectedLogger;
+
+    FoeService expectedFoe;
+
+    Object expectedConfiguration;
+
+    String expectedString;
+
+    public FieService buildWithUnorderedConfiguration(Collection<Runnable> configuration)
+    {
+        assertSame(configuration, expectedConfiguration);
+
+        return fie;
+    }
+
+    public FieService buildWithOrderedConfiguration(List<Runnable> configuration)
+    {
+        assertSame(configuration, expectedConfiguration);
+
+        return fie;
+    }
+
+    public void methodWithParameterizedList(List<Runnable> list)
+    {
+    }
+
+    public void methodWithList(List list)
+    {
+    }
+
+    public void methodWithWildcardList(List<? super ArrayList> list)
+    {
+
+    }
+
+    public FieService build_noargs()
+    {
+        return fie;
+    }
+
+    public FieService build_injected(@InjectService("Foe")
+    FoeService foe)
+    {
+        assertSame(expectedFoe, foe);
+
+        return fie;
+    }
+
+    public FieService build_auto(FoeService foe)
+    {
+        assertSame(expectedFoe, foe);
+
+        return fie;
+    }
+
+    public FieService build_fail()
+    {
+        throw new RuntimeException("Method failed.");
+    }
+
+    public FieService build_args(String serviceId, ServiceResources resources,
+                                 Class serviceInterface, Logger log)
+    {
+        assertEquals(serviceId, expectedServiceId);
+        assertSame(resources, expectedServiceResources);
+        assertSame(serviceInterface, expectedServiceInterface);
+        assertSame(log, expectedLogger);
+
+        return fie;
+    }
+
+    public FieService build_with_forced_injection(@Inject
+    @Value("Injected")
+    String string)
+    {
+        assertEquals(string, expectedString);
+
+        return fie;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvokerTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvokerTest.java
new file mode 100644
index 0000000..ecf5dec
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceBuilderMethodInvokerTest.java
@@ -0,0 +1,407 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import static org.apache.tapestry.ioc.internal.AbstractServiceCreator.findParameterizedTypeFromGenericType;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.slf4j.Logger;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+
+public class ServiceBuilderMethodInvokerTest extends IOCInternalTestCase
+{
+    private static final String SERVICE_ID = "Fie";
+
+    private static final String CREATOR_DESCRIPTION = "{CREATOR DESCRIPTION}";
+
+    @Test
+    public void noargs_method()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION,
+                                                           findMethod(fixture, "build_noargs"));
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
+
+    private void trainForConstructor(ServiceBuilderResources resources, Logger logger)
+    {
+        train_getServiceId(resources, SERVICE_ID);
+
+        train_getLogger(resources, logger);
+
+        train_getServiceInterface(resources, FieService.class);
+    }
+
+    @Test
+    public void method_with_args()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        Method method = findMethod(fixture, "build_args");
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+
+        Logger logger = mockLogger();
+
+        fixture.expectedServiceId = SERVICE_ID;
+        fixture.expectedServiceInterface = FieService.class;
+        fixture.expectedServiceResources = resources;
+        fixture.expectedLogger = logger;
+
+        fixture.fie = mockFieService();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_isDebugEnabled(logger, true);
+
+        logger.debug(IOCMessages.invokingMethod(CREATOR_DESCRIPTION));
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, method);
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
+
+    @Test
+    public void inject_annotation_bypasses_resources()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        Method method = findMethod(fixture, "build_with_forced_injection");
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+
+        Logger logger = mockLogger();
+
+        fixture.expectedString = "Injected";
+
+        fixture.fie = mockFieService();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_isDebugEnabled(logger, true);
+
+        logger.debug(IOCMessages.invokingMethod(CREATOR_DESCRIPTION));
+
+        // This simulates what the real stack does when it sees @Value("Injected")
+
+        expect(resources.getObject(eq(String.class), isA(AnnotationProvider.class))).andReturn(
+                "Injected");
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, method);
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
+
+    @Test
+    public void injected_service_method()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+        fixture.expectedFoe = newFoe();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_getService(resources, "Foe", FoeService.class, fixture.expectedFoe);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION,
+                                                           findMethod(fixture, "build_injected"));
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void injected_ordered_collection()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+        List<Runnable> result = newMock(List.class);
+        fixture.expectedConfiguration = result;
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        expect(resources.getOrderedConfiguration(Runnable.class)).andReturn(result);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION,
+                                                           findMethod(fixture, "buildWithOrderedConfiguration"));
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void injected_unordered_collection()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+        Collection<Runnable> result = newMock(Collection.class);
+        fixture.expectedConfiguration = result;
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        expect(resources.getUnorderedConfiguration(Runnable.class)).andReturn(result);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION,
+                                                           findMethod(fixture, "buildWithUnorderedConfiguration"));
+
+        Object actual = sc.createObject();
+
+        assertSame(actual, fixture.fie);
+
+        verify();
+    }
+
+    private FoeService newFoe()
+    {
+        return mockFoeService();
+    }
+
+    @Test
+    public void builder_method_returns_null()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        Method method = findMethod(fixture, "build_noargs");
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, method);
+
+        try
+        {
+            sc.createObject();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            Assert.assertEquals(ex.getMessage(), "Builder method " + CREATOR_DESCRIPTION
+                    + " (for service 'Fie') returned null.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void builder_method_failed()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        Method method = findMethod(fixture, "build_fail");
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, method);
+
+        try
+        {
+            sc.createObject();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Error invoking service builder method "
+                    + CREATOR_DESCRIPTION + " (for service 'Fie'): Method failed.");
+
+            Throwable cause = ex.getCause();
+
+            assertEquals(cause.getMessage(), "Method failed.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void auto_dependency()
+    {
+        ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
+        Method method = findMethod(fixture, "build_auto");
+
+        ServiceBuilderResources resources = mockServiceBuilderResources();
+        Logger logger = mockLogger();
+
+        fixture.fie = mockFieService();
+        fixture.expectedFoe = mockFoeService();
+
+        trainForConstructor(resources, logger);
+
+        train_getModuleBuilder(resources, fixture);
+
+        expect(resources.getObject(eq(FoeService.class), isA(AnnotationProvider.class))).andReturn(
+                fixture.expectedFoe);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        ObjectCreator sc = new ServiceBuilderMethodInvoker(resources, CREATOR_DESCRIPTION, method);
+
+        Object actual = sc.createObject();
+
+        verify();
+
+        assertSame(actual, fixture.fie);
+    }
+
+    protected final void train_getModuleBuilder(ServiceBuilderResources resources,
+                                                Object moduleBuilder)
+    {
+        expect(resources.getModuleBuilder()).andReturn(moduleBuilder);
+    }
+
+    @Test
+    public void parameterized_type_of_generic_parameter()
+    {
+        Method m = findMethod(ServiceBuilderMethodFixture.class, "methodWithParameterizedList");
+
+        assertEquals(m.getParameterTypes()[0], List.class);
+        Type type = m.getGenericParameterTypes()[0];
+
+        assertEquals(type.toString(), "java.util.List<java.lang.Runnable>");
+        assertEquals(findParameterizedTypeFromGenericType(type), Runnable.class);
+    }
+
+    @Test
+    public void parameterized_type_of_nongeneric_parameter()
+    {
+        Method m = findMethod(ServiceBuilderMethodFixture.class, "methodWithList");
+
+        assertEquals(m.getParameterTypes()[0], List.class);
+        Type type = m.getGenericParameterTypes()[0];
+
+        assertEquals(type.toString(), "interface java.util.List");
+        assertEquals(findParameterizedTypeFromGenericType(type), Object.class);
+    }
+
+    @Test
+    public void parameterize_type_for_non_supported_type()
+    {
+        Method m = findMethod(ServiceBuilderMethodFixture.class, "methodWithWildcardList");
+
+        assertEquals(m.getParameterTypes()[0], List.class);
+        Type type = m.getGenericParameterTypes()[0];
+
+        try
+        {
+            findParameterizedTypeFromGenericType(type);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), IOCMessages.genericTypeNotSupported(type));
+        }
+    }
+
+    private FoeService mockFoeService()
+    {
+        return newMock(FoeService.class);
+    }
+
+    private FieService mockFieService()
+    {
+        return newMock(FieService.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorFixture.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorFixture.java
new file mode 100644
index 0000000..cea830e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorFixture.java
@@ -0,0 +1,54 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal;

+

+import org.testng.Assert;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.ServiceDecoratorImplTest}.

+ */

+public class ServiceDecoratorFixture extends Assert

+{

+    Object expectedDelegate;

+

+    Object interceptorToReturn;

+

+    RuntimeException exception;

+

+    public <T> T decoratorReturnsInterceptor(Class<T> serviceInterface, T delegate)

+    {

+        assertSame(serviceInterface, FieService.class);

+        assertSame(delegate, expectedDelegate);

+

+        return serviceInterface.cast(interceptorToReturn);

+    }

+

+    public Object decoratorUntyped(Object delegate)

+    {

+        assertSame(delegate, expectedDelegate);

+

+        return interceptorToReturn;

+    }

+

+    public Object decoratorThrowsException(Object delegate)

+    {

+        throw exception;

+    }

+

+    public Object decorateReturnNull(Object delegate)

+    {

+        return null;

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImplTest.java
new file mode 100644
index 0000000..036e86c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceDecoratorImplTest.java
@@ -0,0 +1,192 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+public class ServiceDecoratorImplTest extends IOCInternalTestCase
+{
+    private static final String SERVICE_ID = "ioc.Fie";
+
+    private ModuleBuilderSource newSource(final Object builder)
+    {
+        return new ModuleBuilderSource()
+        {
+            public Object getModuleBuilder()
+            {
+                return builder;
+            }
+        };
+    }
+
+    /**
+     * Also, test logging of decorator method invocation.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void decorator_returns_interceptor() throws Exception
+    {
+        ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        Method m = findMethod(fixture, "decoratorReturnsInterceptor");
+
+        ServiceResources resources = mockServiceResources();
+        Logger logger = mockLogger();
+        fixture.expectedDelegate = mockFieService();
+        fixture.interceptorToReturn = mockFieService();
+        ModuleBuilderSource source = newSource(fixture);
+
+        trainForConstructor(resources, logger);
+
+        train_isDebugEnabled(logger, true);
+
+        logger.debug(IOCMessages.invokingMethod(InternalUtils.asString(m, getClassFactory())));
+
+        replay();
+
+        // Check that the delegate gets passed in; check that the return value of the
+        // decorator method is the return value of the ServiceDecorator.
+
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources,
+                                                                  getClassFactory());
+
+        Object interceptor = decorator.createInterceptor(fixture.expectedDelegate);
+
+        assertSame(interceptor, fixture.interceptorToReturn);
+
+        verify();
+    }
+
+    @Test
+    public void decorator_returns_null_interceptor() throws Exception
+    {
+        ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
+        ServiceResources resources = mockServiceResources();
+        Logger logger = mockLogger();
+        Object delegate = mockFieService();
+
+        trainForConstructor(resources, logger);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        Method m = findMethod(fixture, "decorateReturnNull");
+
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources,
+                                                                  getClassFactory());
+
+        Object interceptor = decorator.createInterceptor(delegate);
+
+        assertNull(interceptor);
+
+        verify();
+    }
+
+    @Test
+    public void decorator_returns_incorrect_type() throws Exception
+    {
+        ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
+        ServiceResources resources = mockServiceResources();
+        Logger logger = mockLogger();
+        fixture.expectedDelegate = mockFieService();
+        fixture.interceptorToReturn = newMock(FoeService.class);
+
+        Method m = findMethod(fixture, "decoratorUntyped");
+
+        trainForConstructor(resources, logger);
+
+        train_isDebugEnabled(logger, false);
+
+        logger.warn(IOCMessages.decoratorReturnedWrongType(
+                m,
+                SERVICE_ID,
+                fixture.interceptorToReturn,
+                FieService.class));
+
+        replay();
+
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources,
+                                                                  getClassFactory());
+
+        Object interceptor = decorator.createInterceptor(fixture.expectedDelegate);
+
+        assertNull(interceptor);
+
+        verify();
+    }
+
+    @Test
+    public void decorator_method_throws_exception() throws Exception
+    {
+        ServiceDecoratorFixture fixture = new ServiceDecoratorFixture();
+        ModuleBuilderSource source = newSource(fixture);
+        ServiceResources resources = mockServiceResources();
+        Logger logger = mockLogger();
+        Object delegate = mockFieService();
+        fixture.exception = new RuntimeException("Ouch!");
+
+        trainForConstructor(resources, logger);
+
+        train_isDebugEnabled(logger, false);
+
+        replay();
+
+        Method m = findMethod(fixture, "decoratorThrowsException");
+
+        ServiceDecoratorImpl decorator = new ServiceDecoratorImpl(m, source, resources,
+                                                                  getClassFactory());
+
+        try
+        {
+            decorator.createInterceptor(delegate);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), IOCMessages.decoratorMethodError(m, SERVICE_ID, ex
+                    .getCause()));
+
+            Throwable cause = ex.getCause();
+
+            assertSame(cause, fixture.exception);
+        }
+
+        verify();
+    }
+
+    private FieService mockFieService()
+    {
+        return newMock(FieService.class);
+    }
+
+    private void trainForConstructor(ServiceResources resources, Logger logger)
+    {
+        train_getServiceId(resources, SERVICE_ID);
+
+        train_getServiceInterface(resources, FieService.class);
+
+        train_getLogger(resources, logger);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceIdConflictMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceIdConflictMethodModule.java
new file mode 100644
index 0000000..b2b9f9a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceIdConflictMethodModule.java
@@ -0,0 +1,32 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.
+ */
+public class ServiceIdConflictMethodModule
+{
+    public FieService buildFred()
+    {
+        return null;
+    }
+
+    public FieService buildFred(Object param)
+    {
+        return null;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java
new file mode 100644
index 0000000..4044065
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java
@@ -0,0 +1,96 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.io.*;
+
+public class ServiceProxySerializationTest extends IOCTestCase
+{
+    @Test
+    public void serialization_deserialization() throws Exception
+    {
+        Registry r = buildRegistry();
+
+        TypeCoercer proxy = r.getService(TypeCoercer.class);
+
+        byte[] serialized = serialize(proxy);
+
+        TypeCoercer proxy2 = deserialize(TypeCoercer.class, serialized);
+
+        assertSame(proxy2, proxy, "De-serialized proxy is same object if Registry unchanged.");
+
+        r.shutdown();
+
+        r = buildRegistry();
+
+        TypeCoercer proxy3 = deserialize(TypeCoercer.class, serialized);
+
+        assertNotNull(proxy3);
+        assertNotSame(proxy3, proxy, "New proxy should be different, as it is from a different Registry.");
+
+        r.shutdown();
+    }
+
+    @Test
+    public void deserialize_with_no_registry() throws Exception
+    {
+        Registry r = buildRegistry();
+
+        TypeCoercer proxy = r.getService(TypeCoercer.class);
+
+        byte[] serialized = serialize(proxy);
+
+        r.shutdown();
+
+        try
+        {
+            deserialize(TypeCoercer.class, serialized);
+            unreachable();
+        }
+        catch (Exception ex)
+        {
+            assertMessageContains(ex,
+                                  "Service token for service 'TypeCoercer' can not be converted back into a proxy because no proxy provider has been registered");
+        }
+    }
+
+    private byte[] serialize(Object object) throws IOException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        oos.writeObject(object);
+
+        oos.close();
+
+        return baos.toByteArray();
+    }
+
+    private <T> T deserialize(Class<T> type, byte[] serialized) throws IOException, ClassNotFoundException
+    {
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(serialized));
+
+        Object raw = ois.readObject();
+
+        ois.close();
+
+        return type.cast(raw);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SimpleModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SimpleModule.java
new file mode 100644
index 0000000..6e2e0ef
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SimpleModule.java
@@ -0,0 +1,62 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.annotation.EagerLoad;
+import org.apache.tapestry.ioc.annotation.Scope;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.
+ */
+public class SimpleModule
+{
+    @Scope("threaded")
+    public FoeService buildBarney()
+    {
+        return null;
+    }
+
+    public FieService buildFred()
+    {
+        return null;
+    }
+
+    @EagerLoad
+    public FoeService buildWilma()
+    {
+        return null;
+    }
+
+    public void ignoredMethod()
+    {
+    }
+
+    /**
+     * Minimal decorator method that uses generics to qualify the delegate passed in and the object returned.
+     */
+    public <T> T decorateLogging(Class<T> serviceInterace, T delegate)
+    {
+        return null;
+    }
+
+    /**
+     * Minimal contribution method.
+     */
+    public void contributeBarney(Configuration configuration)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycleTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycleTest.java
new file mode 100644
index 0000000..6b6f0ee
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/SingletonServiceLifecycleTest.java
@@ -0,0 +1,43 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.testng.annotations.Test;
+
+public class SingletonServiceLifecycleTest extends IOCInternalTestCase
+{
+    @Test
+    public void test()
+    {
+        ServiceResources resources = mockServiceResources();
+        ObjectCreator creator = mockObjectCreator();
+        Object expected = new Object();
+
+        train_createObject(creator, expected);
+
+        replay();
+
+        ServiceLifecycle lifecycle = new SingletonServiceLifecycle();
+
+        Object actual = lifecycle.createService(resources, creator);
+
+        assertSame(actual, expected);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToStringService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToStringService.java
new file mode 100644
index 0000000..dc28abd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToStringService.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.SingletonServiceLifecycleTest}.

+ */

+public interface ToStringService

+{

+    String toString();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToUpperCaseStringHolder.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToUpperCaseStringHolder.java
new file mode 100644
index 0000000..aa5d643
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ToUpperCaseStringHolder.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.StringHolder;
+
+public class ToUpperCaseStringHolder implements StringHolder
+{
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value.toUpperCase();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/TooManyContributionParametersModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/TooManyContributionParametersModule.java
new file mode 100644
index 0000000..0fc0b0a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/TooManyContributionParametersModule.java
@@ -0,0 +1,30 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImpl}.
+ */
+public class TooManyContributionParametersModule
+{
+
+    public void contributeTooMany(Configuration configuration1, OrderedConfiguration configuration2)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UninstantiableAutobuildServiceModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UninstantiableAutobuildServiceModule.java
new file mode 100644
index 0000000..2b661c5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UninstantiableAutobuildServiceModule.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.ServiceBinder;
+
+public class UninstantiableAutobuildServiceModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(Runnable.class, RunnableServiceImpl.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseService.java
new file mode 100644
index 0000000..464f044
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseService.java
@@ -0,0 +1,26 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.SingletonServiceLifecycleTest}.

+ */

+public interface UpcaseService

+{

+    /**

+     * Returns the uppercase version of an input string.

+     */

+    String upcase(String input);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseServiceImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseServiceImpl.java
new file mode 100644
index 0000000..1f2a76b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/UpcaseServiceImpl.java
@@ -0,0 +1,28 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ *

+ */

+public class UpcaseServiceImpl implements UpcaseService

+{

+

+    public String upcase(String input)

+    {

+        return input.toUpperCase();

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapperTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapperTest.java
new file mode 100644
index 0000000..202ccfd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapperTest.java
@@ -0,0 +1,100 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class ValidatingConfigurationWrapperTest extends IOCInternalTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void valid_contribution()
+    {
+        ContributionDef def = mockContributionDef();
+        Logger logger = mockLogger();
+        Configuration configuration = mockConfiguration();
+        Runnable value = mockRunnable();
+
+        configuration.add(value);
+
+        replay();
+
+        Configuration wrapper = new ValidatingConfigurationWrapper("foo.Bar", logger,
+                                                                   Runnable.class, def, configuration);
+
+        wrapper.add(value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void null_contribution()
+    {
+        Logger logger = mockLogger();
+        Configuration configuration = mockConfiguration();
+        ContributionDef def = new ContributionDefImpl("Bar", findMethod("contributeUnorderedNull"),
+                                                      getClassFactory());
+
+        logger.warn(IOCMessages.contributionWasNull("Bar", def));
+
+        replay();
+
+        Configuration wrapper = new ValidatingConfigurationWrapper("Bar", logger, Runnable.class,
+                                                                   def, configuration);
+
+        wrapper.add(null);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void wrong_type_of_contribution()
+    {
+        Logger logger = mockLogger();
+        Configuration configuration = mockConfiguration();
+        ContributionDef def = new ContributionDefImpl("Bar", findMethod("contributeUnorderedNull"),
+                                                      getClassFactory());
+
+        logger.warn(IOCMessages
+                .contributionWrongValueType("Bar", def, String.class, Runnable.class));
+
+        replay();
+
+        Configuration wrapper = new ValidatingConfigurationWrapper("Bar", logger, Runnable.class,
+                                                                   def, configuration);
+
+        wrapper.add("runnable");
+
+        verify();
+    }
+
+    // Just a placeholder to give the errors something to report about
+
+    public void contributeUnorderedNull()
+    {
+
+    }
+
+    public void contributeWrongType()
+    {
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapperTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
new file mode 100644
index 0000000..a6e69cd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
@@ -0,0 +1,191 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import java.util.Map;
+
+public class ValidatingMappedConfigurationWrapperTest extends IOCInternalTestCase
+{
+    private static final String SERVICE_ID = "Baz";
+
+    @Test
+    public void proper_key_and_value()
+    {
+        ContributionDef def = mockContributionDef();
+        Logger logger = mockLogger();
+        Map<Class, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration<Class, Runnable> delegate = mockMappedConfiguration();
+
+        Class key = Integer.class;
+        Runnable value = mockRunnable();
+
+        delegate.add(key, value);
+
+        replay();
+
+        MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
+                SERVICE_ID, def, logger, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(key, value);
+
+        verify();
+
+        assertSame(keyToContribution.get(Integer.class), def);
+    }
+
+    @Test
+    public void duplicate_key()
+    {
+        ContributionDef def1 = newContributionDef("contributionPlaceholder1");
+        ContributionDef def2 = newContributionDef("contributionPlaceholder2");
+        Logger logger = mockLogger();
+        Map<Class, ContributionDef> keyToContribution = newMap();
+
+        keyToContribution.put(Integer.class, def1);
+
+        MappedConfiguration<Class, Runnable> delegate = mockMappedConfiguration();
+
+        Class key = Integer.class;
+        Runnable value = mockRunnable();
+
+        logger.warn(IOCMessages.contributionDuplicateKey(SERVICE_ID, def2, def1));
+
+        replay();
+
+        MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
+                SERVICE_ID, def2, logger, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(key, value);
+
+        verify();
+
+        assertSame(keyToContribution.get(Integer.class), def1);
+    }
+
+    @Test
+    public void null_key()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Logger logger = mockLogger();
+        Map<Class, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration<Class, Runnable> delegate = mockMappedConfiguration();
+        Runnable value = mockRunnable();
+
+        logger.warn(IOCMessages.contributionKeyWasNull(SERVICE_ID, def));
+
+        replay();
+
+        MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
+                SERVICE_ID, def, logger, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(null, value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void wrong_key_type()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Logger logger = mockLogger();
+        Map<?, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration delegate = mockMappedConfiguration();
+        Runnable value = mockRunnable();
+
+        logger.warn(IOCMessages
+                .contributionWrongKeyType(SERVICE_ID, def, String.class, Class.class));
+
+        replay();
+
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(SERVICE_ID, def,
+                                                                               logger, Class.class, Runnable.class,
+                                                                               keyToContribution, delegate);
+
+        wrapper.add("java.util.List", value);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void wrong_value_type()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Logger logger = mockLogger();
+        Map<?, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration delegate = mockMappedConfiguration();
+
+        logger.warn(IOCMessages.contributionWrongValueType(
+                SERVICE_ID,
+                def,
+                String.class,
+                Runnable.class));
+
+        replay();
+
+        MappedConfiguration wrapper = new ValidatingMappedConfigurationWrapper(SERVICE_ID, def,
+                                                                               logger, Class.class, Runnable.class,
+                                                                               keyToContribution, delegate);
+
+        wrapper.add(List.class, "do something");
+
+        verify();
+    }
+
+    @Test
+    public void null_value()
+    {
+        ContributionDef def = newContributionDef("contributionPlaceholder1");
+        Logger logger = mockLogger();
+        Map<Class, ContributionDef> keyToContribution = newMap();
+        MappedConfiguration<Class, Runnable> delegate = mockMappedConfiguration();
+
+        logger.warn(IOCMessages.contributionWasNull(SERVICE_ID, def));
+
+        replay();
+
+        MappedConfiguration<Class, Runnable> wrapper = new ValidatingMappedConfigurationWrapper<Class, Runnable>(
+                SERVICE_ID, def, logger, Class.class, Runnable.class, keyToContribution, delegate);
+
+        wrapper.add(Integer.class, null);
+
+        verify();
+
+    }
+
+    private ContributionDef newContributionDef(String methodName)
+    {
+        return new ContributionDefImpl(SERVICE_ID, findMethod(methodName), getClassFactory());
+    }
+
+    public void contributionPlaceholder1()
+    {
+
+    }
+
+    public void contributionPlaceholder2()
+    {
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapperTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapperTest.java
new file mode 100644
index 0000000..1437c1e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapperTest.java
@@ -0,0 +1,117 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+public class ValidatingOrderedConfigurationWrapperTest extends IOCInternalTestCase
+{
+    @Test
+    public void valid_type_long_form()
+    {
+        ContributionDef def = mockContributionDef();
+        Logger logger = mockLogger();
+        OrderedConfiguration<Runnable> configuration = mockOrderedConfiguration();
+        Runnable contribution = mockRunnable();
+
+        configuration.add("id", contribution, "after:pre", "before:post");
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "Service", def, logger, Runnable.class, configuration);
+
+        wrapper.add("id", contribution, "after:pre", "before:post");
+
+        verify();
+    }
+
+    @Test
+    public void valid_type_short_form()
+    {
+        ContributionDef def = mockContributionDef();
+        Logger logger = mockLogger();
+        OrderedConfiguration<Runnable> configuration = mockOrderedConfiguration();
+        Runnable contribution = mockRunnable();
+
+        configuration.add("id", contribution);
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "Service", def, logger, Runnable.class, configuration);
+
+        wrapper.add("id", contribution);
+
+        verify();
+    }
+
+    @Test
+    public void null_object_passed_through()
+    {
+        ContributionDef def = mockContributionDef();
+        Logger logger = mockLogger();
+        OrderedConfiguration<Runnable> configuration = mockOrderedConfiguration();
+
+        configuration.add("id", null);
+
+        replay();
+
+        OrderedConfiguration<Runnable> wrapper = new ValidatingOrderedConfigurationWrapper<Runnable>(
+                "Service", def, logger, Runnable.class, configuration);
+
+        wrapper.add("id", null);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void incorrect_contribution_type_is_passed_through_as_null()
+    {
+        Method method = findMethod("contributeBarneyService");
+
+        ContributionDef def = new ContributionDefImpl("Service", method, getClassFactory());
+        Logger log = mockLogger();
+        OrderedConfiguration<Runnable> configuration = mockOrderedConfiguration();
+
+        log.warn(IOCMessages.contributionWrongValueType(
+                "Service",
+                def,
+                String.class,
+                Runnable.class));
+
+        configuration.add("id", null);
+
+        replay();
+
+        OrderedConfiguration wrapper = new ValidatingOrderedConfigurationWrapper("Service", def,
+                                                                                 log, Runnable.class, configuration);
+
+        wrapper.add("id", "string");
+
+        verify();
+    }
+
+    public void contributeBarneyService(OrderedConfiguration<Runnable> configuration)
+    {
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidBuilderMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidBuilderMethodModule.java
new file mode 100644
index 0000000..bc4e3b3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidBuilderMethodModule.java
@@ -0,0 +1,28 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.

+ */

+public class VoidBuilderMethodModule

+{

+    /**

+     * Builder methods should not return void.

+     */

+    public void buildNull()

+    {

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidDecoratorMethodModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidDecoratorMethodModule.java
new file mode 100644
index 0000000..ad72037
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/VoidDecoratorMethodModule.java
@@ -0,0 +1,31 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal;

+

+/**

+ * Used by {@link org.apache.tapestry.ioc.internal.DefaultModuleDefImplTest}.

+ */

+public class VoidDecoratorMethodModule

+{

+    /**

+     * Decorator methods are not supposed to return void. They can return null.

+     *

+     * @param delegate

+     */

+    public void decorateVoid(Object delegate)

+    {

+

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractIntWrapper.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractIntWrapper.java
new file mode 100644
index 0000000..b8a9b72
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractIntWrapper.java
@@ -0,0 +1,23 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.ClassFabImplTest}.
+ */
+public abstract class AbstractIntWrapper
+{
+    public abstract int getIntValue();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractInvocationTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractInvocationTest.java
new file mode 100644
index 0000000..fb3fdd1
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AbstractInvocationTest.java
@@ -0,0 +1,136 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+
+public class AbstractInvocationTest extends TestBase
+{
+    class TestInvocation extends AbstractInvocation
+    {
+        protected TestInvocation(Method method)
+        {
+            super(method);
+        }
+
+        public Object getParameter(int index)
+        {
+            return null;
+        }
+
+        public void override(int index, Object newParameter)
+        {
+        }
+
+        public void proceed()
+        {
+        }
+    }
+
+    interface Subject
+    {
+        void go() throws SQLException;
+
+        int count() throws SQLException;
+
+        void execute(Runnable runnable);
+    }
+
+    @Test
+    public void to_string() throws Exception
+    {
+        Invocation iv = new TestInvocation(Runnable.class.getMethod("run"));
+
+        assertEquals(iv.toString(), "Invocation[public abstract void java.lang.Runnable.run()]");
+    }
+
+    @Test
+    public void override_exception() throws Exception
+    {
+        SQLException se = new SQLException();
+
+        Invocation iv = new TestInvocation(Subject.class.getMethod("go"));
+
+        iv.overrideThrown(se);
+
+        assertTrue(iv.isFail());
+        assertSame(iv.getThrown(Exception.class), se);
+    }
+
+    @Test
+    public void get_thrown_returns_null_if_not_a_match() throws Exception
+    {
+        SQLException se = new SQLException();
+
+        Invocation iv = new TestInvocation(Subject.class.getMethod("go"));
+
+        iv.overrideThrown(se);
+
+        assertNull(iv.getThrown(RuntimeException.class));
+    }
+
+    @Test
+    public void override_result_clears_exception() throws Exception
+    {
+        SQLException se = new SQLException();
+        Integer override = new Integer(23);
+
+        Invocation iv = new TestInvocation(Subject.class.getMethod("count"));
+
+        iv.overrideThrown(se);
+
+        assertTrue(iv.isFail());
+
+        iv.overrideResult(override);
+        assertFalse(iv.isFail());
+        assertSame(iv.getResult(), override);
+    }
+
+    @Test
+    public void invalid_exception_for_override() throws Exception
+    {
+        SQLException se = new SQLException();
+
+        Invocation iv = new TestInvocation(Runnable.class.getMethod("run"));
+
+        try
+        {
+            iv.overrideThrown(se);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Exception java.sql.SQLException is not a declared exception of method public abstract void java.lang.Runnable.run().");
+        }
+    }
+
+    @Test
+    public void get_parameter_type() throws Exception
+    {
+        Invocation iv = new TestInvocation(Subject.class.getMethod("execute", Runnable.class));
+
+        assertEquals(iv.getParameterCount(), 1);
+        assertSame(iv.getParameterType(0), Runnable.class);
+
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AnnotatedBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AnnotatedBean.java
new file mode 100644
index 0000000..101f90b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AnnotatedBean.java
@@ -0,0 +1,55 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.annotation.Scope;
+
+public class AnnotatedBean
+{
+    public String getReadWrite()
+    {
+        return null;
+    }
+
+    public void setReadWrite(String value)
+    {
+    }
+
+    public String getAnnotationOnWrite()
+    {
+        return null;
+    }
+
+    @Scope("onwrite")
+    public void setAnnotationOnWrite(String value)
+    {
+    }
+
+    @Scope("onread")
+    public String getAnnotationOnRead()
+    {
+        return null;
+    }
+
+    @Scope("onwrite")
+    public void setAnnotationOnRead(String value)
+    {
+    }
+
+    public String getReadOnly()
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubject.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubject.java
new file mode 100644
index 0000000..73da7b2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubject.java
@@ -0,0 +1,20 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ArraysSubject
+{
+    String[] operation(String[] inputs);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubjectImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubjectImpl.java
new file mode 100644
index 0000000..23398f4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ArraysSubjectImpl.java
@@ -0,0 +1,23 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public class ArraysSubjectImpl implements ArraysSubject
+{
+    public String[] operation(String[] inputs)
+    {
+        return inputs;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImplTest.java
new file mode 100644
index 0000000..9804bac
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/AspectInterceptorBuilderImplTest.java
@@ -0,0 +1,184 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Invocation;
+import org.apache.tapestry.ioc.MethodAdvice;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.ioc.services.AspectInterceptorBuilder;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Tests a few edge and error cases not covered by {@link org.apache.tapestry.ioc.internal.services.LoggingDecoratorImplTest}.
+ */
+public class AspectInterceptorBuilderImplTest extends IOCInternalTestCase
+{
+    private AspectDecorator decorator;
+
+    @BeforeClass
+    public void setup()
+    {
+        decorator = getService(AspectDecorator.class);
+    }
+
+    public interface Subject
+    {
+        void advised();
+
+        void notAdvised();
+    }
+
+    @Test
+    public void some_methods_not_intercepted() throws Exception
+    {
+        Subject delegate = mockSubject();
+
+        MethodAdvice advice = new MethodAdvice()
+        {
+            public void advise(Invocation invocation)
+            {
+                assertEquals(invocation.getMethodName(), "advised");
+
+                invocation.proceed();
+            }
+        };
+
+        delegate.advised();
+        delegate.notAdvised();
+
+        replay();
+
+        AspectInterceptorBuilder<Subject> builder = decorator.createBuilder(Subject.class, delegate, "<Subject>");
+
+        builder.adviseMethod(Subject.class.getMethod("advised"), advice);
+
+        Subject interceptor = builder.build();
+
+        interceptor.advised();
+        interceptor.notAdvised();
+
+        verify();
+    }
+
+    @Test
+    public void method_not_in_service_interface() throws Exception
+    {
+        Subject delegate = mockSubject();
+
+        MethodAdvice advice = mockAdvice();
+
+        replay();
+
+        AspectInterceptorBuilder<Subject> builder = decorator.createBuilder(Subject.class, delegate, "<Subject>");
+
+        // This method doesn't belong.
+
+        try
+        {
+            builder.adviseMethod(Runnable.class.getMethod("run"), advice);
+
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Method public abstract void java.lang.Runnable.run() is not defined for interface interface org.apache.tapestry.ioc.internal.services.AspectInterceptorBuilderImplTest$Subject.");
+        }
+
+
+        verify();
+    }
+
+    @Test
+    public void method_with_duplicate_advice() throws Exception
+    {
+        Subject delegate = mockSubject();
+
+        MethodAdvice advice = mockAdvice();
+
+        replay();
+
+        AspectInterceptorBuilder<Subject> builder = decorator.createBuilder(Subject.class, delegate, "<Subject>");
+
+
+        builder.adviseMethod(Subject.class.getMethod("advised"), advice);
+
+        try
+        {
+            // Second is failure.
+
+            builder.adviseMethod(Subject.class.getMethod("advised"), advice);
+
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Method public abstract void org.apache.tapestry.ioc.internal.services.AspectInterceptorBuilderImplTest$Subject.advised() has already been advised.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void arrays_as_parameters_and_result()
+    {
+        ArraysSubject delegate = new ArraysSubjectImpl();
+
+        MethodAdvice advice = new MethodAdvice()
+        {
+            public void advise(Invocation invocation)
+            {
+                String[] param = (String[]) invocation.getParameter(0);
+
+                for (int i = 0; i < param.length; i++)
+                {
+                    param[i] = param[i].toUpperCase();
+                }
+
+                invocation.proceed();
+
+                String[] result = (String[]) invocation.getResult();
+
+                for (int i = 0; i < result.length; i++)
+                {
+                    result[i] = i + ":" + result[i];
+                }
+            }
+        };
+
+        ArraysSubject advised = decorator.build(ArraysSubject.class, delegate, advice, "whatever");
+
+        String[] inputs = { "Fred", "Barney" };
+
+        String[] result = advised.operation(inputs);
+
+        assertEquals(result[0], "0:FRED");
+        assertEquals(result[1], "1:BARNEY");
+    }
+
+    protected final MethodAdvice mockAdvice()
+    {
+        return newMock(MethodAdvice.class);
+    }
+
+    protected final Subject mockSubject()
+    {
+        return newMock(Subject.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BeanWithIndexedProperty.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BeanWithIndexedProperty.java
new file mode 100644
index 0000000..d214d77
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BeanWithIndexedProperty.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public class BeanWithIndexedProperty
+{
+    public int getPrimitiveProperty()
+    {
+        return 0;
+    }
+
+    public String getIndexedProperty(int index)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BridgeBuilderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BridgeBuilderTest.java
new file mode 100644
index 0000000..dcd8e4b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/BridgeBuilderTest.java
@@ -0,0 +1,203 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+
+public class BridgeBuilderTest extends IOCInternalTestCase
+{
+    private ClassFactory classFactory = new ClassFactoryImpl();
+
+    @Test
+    public void standard_interface_and_filter()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        BridgeBuilder<StandardService, StandardFilter> bb = new BridgeBuilder<StandardService, StandardFilter>(
+                logger, StandardService.class, StandardFilter.class, classFactory);
+
+        StandardFilter sf = new StandardFilter()
+        {
+            public int run(int i, StandardService ss)
+            {
+                return ss.run(i + 1);
+            }
+        };
+
+        StandardService ss = new StandardService()
+        {
+            public int run(int i)
+            {
+                return i * 3;
+            }
+        };
+
+        StandardService bridge = bb.instantiateBridge(ss, sf);
+
+        // The filter adds 1, then the service multiplies by 3.
+        // (5 +_1) * 3 = 18.
+
+        assertEquals(bridge.run(5), 18);
+
+        // Since toString() is not part of the service interface,
+        // it will be implemented in the bridge.
+
+        assertEquals(
+                bridge.toString(),
+                "<PipelineBridge from org.apache.tapestry.ioc.internal.services.StandardService to org.apache.tapestry.ioc.internal.services.StandardFilter>");
+
+        verify();
+    }
+
+    @Test
+    public void toString_part_of_service_interface()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        BridgeBuilder<ToStringService, ToStringFilter> bb = new BridgeBuilder<ToStringService, ToStringFilter>(
+                logger, ToStringService.class, ToStringFilter.class, classFactory);
+
+        ToStringFilter f = new ToStringFilter()
+        {
+            public String toString(ToStringService s)
+            {
+                return s.toString().toUpperCase();
+            }
+        };
+
+        ToStringService s = new ToStringService()
+        {
+            @Override
+            public String toString()
+            {
+                return "Service";
+            }
+        };
+
+        ToStringService bridge = bb.instantiateBridge(s, f);
+
+        assertEquals("SERVICE", bridge.toString());
+
+        verify();
+    }
+
+    @Test
+    public void service_interface_method_not_matched_in_filter_interface()
+    {
+        Logger logger = mockLogger();
+        ExtraServiceMethod next = newMock(ExtraServiceMethod.class);
+        Serializable filter = newMock(Serializable.class);
+
+        logger
+                .error("Method void extraServiceMethod() has no match in filter interface java.io.Serializable.");
+
+        replay();
+
+        BridgeBuilder<ExtraServiceMethod, Serializable> bb = new BridgeBuilder<ExtraServiceMethod, Serializable>(
+                logger, ExtraServiceMethod.class, Serializable.class, classFactory);
+
+        ExtraServiceMethod esm = bb.instantiateBridge(next, filter);
+
+        try
+        {
+            esm.extraServiceMethod();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Method void extraServiceMethod() has no match in filter interface java.io.Serializable.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void filter_interface_contains_extra_methods()
+    {
+        Logger logger = mockLogger();
+        Serializable next = newMock(Serializable.class);
+        ExtraFilterMethod filter = newMock(ExtraFilterMethod.class);
+
+        logger
+                .error("Method void extraFilterMethod() of filter interface "
+                        + "org.apache.tapestry.ioc.internal.services.ExtraFilterMethod does not have a matching method "
+                        + "in java.io.Serializable.");
+
+        replay();
+
+        BridgeBuilder<Serializable, ExtraFilterMethod> bb = new BridgeBuilder<Serializable, ExtraFilterMethod>(
+                logger, Serializable.class, ExtraFilterMethod.class, classFactory);
+
+        assertNotNull(bb.instantiateBridge(next, filter));
+
+        verify();
+    }
+
+    @Test
+    public void service_parameter_in_middle_of_filter_method()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        BridgeBuilder<MiddleService, MiddleFilter> bb = new BridgeBuilder<MiddleService, MiddleFilter>(
+                logger, MiddleService.class, MiddleFilter.class, classFactory);
+
+        MiddleFilter mf = new MiddleFilter()
+        {
+            public void execute(int count, char ch, MiddleService service, StringBuilder buffer)
+            {
+                service.execute(count, ch, buffer);
+
+                buffer.append(' ');
+
+                service.execute(count + 1, Character.toUpperCase(ch), buffer);
+
+            }
+        };
+
+        MiddleService ms = new MiddleService()
+        {
+            public void execute(int count, char ch, StringBuilder buffer)
+            {
+                for (int i = 0; i < count; i++)
+                    buffer.append(ch);
+            }
+        };
+
+        // This also tests building the bridge methods with a void return type.
+
+        MiddleService bridge = bb.instantiateBridge(ms, mf);
+
+        StringBuilder buffer = new StringBuilder("CODE: ");
+
+        bridge.execute(3, 'a', buffer);
+
+        assertEquals("CODE: aaa AAAA", buffer.toString());
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImplTest.java
new file mode 100644
index 0000000..56085f2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainBuilderImplTest.java
@@ -0,0 +1,191 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.ChainBuilder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ChainBuilderImplTest extends IOCInternalTestCase
+{
+    private final ChainBuilder builder = new ChainBuilderImpl(new ClassFactoryImpl());
+
+    @Test
+    public void simple_void_method()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        // Training:
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        Runnable chain = build(Runnable.class, r1, r2);
+
+        chain.run();
+
+        verify();
+
+        Assert.assertEquals(chain.toString(), "<Command chain of java.lang.Runnable>");
+    }
+
+    @Test
+    public void int_method()
+    {
+        ChainCommand c1 = mockChainCommand();
+        ChainCommand c2 = mockChainCommand();
+
+        expect(c1.workInt(7)).andReturn(0);
+
+        expect(c2.workInt(7)).andReturn(99);
+
+        replay();
+
+        ChainCommand chain = build(ChainCommand.class, c1, c2);
+
+        assertEquals(chain.workInt(7), 99);
+
+        verify();
+    }
+
+    @Test
+    public void int_method_shortcircuits()
+    {
+        ChainCommand c1 = mockChainCommand();
+        ChainCommand c2 = mockChainCommand();
+
+        expect(c1.workInt(7)).andReturn(88);
+
+        replay();
+
+        ChainCommand chain = build(ChainCommand.class, c1, c2);
+
+        assertEquals(chain.workInt(7), 88);
+
+        verify();
+    }
+
+    @Test
+    public void boolean_method()
+    {
+        ChainCommand c1 = mockChainCommand();
+        ChainCommand c2 = mockChainCommand();
+
+        train_workBoolean(c1, true, false);
+        train_workBoolean(c2, true, true);
+
+        replay();
+
+        ChainCommand chain = build(ChainCommand.class, c1, c2);
+
+        assertEquals(chain.workBoolean(true), true);
+
+        verify();
+    }
+
+    protected final void train_workBoolean(ChainCommand command, boolean parameter, boolean result)
+    {
+        expect(command.workBoolean(parameter)).andReturn(result);
+    }
+
+    @Test
+    public void string_method()
+    {
+        ChainCommand c1 = mockChainCommand();
+        ChainCommand c2 = mockChainCommand();
+
+        expect(c1.workString("fred")).andReturn(null);
+
+        expect(c2.workString("fred")).andReturn("flintstone");
+
+        replay();
+
+        ChainCommand chain = build(ChainCommand.class, c1, c2);
+
+        assertEquals(chain.workString("fred"), "flintstone");
+
+        verify();
+
+    }
+
+    @Test
+    public void double_method()
+    {
+        ChainCommand c1 = mockChainCommand();
+        ChainCommand c2 = mockChainCommand();
+
+        expect(c1.workDouble(1.2d)).andReturn(0d);
+
+        expect(c2.workDouble(1.2d)).andReturn(3.14d);
+
+        replay();
+
+        ChainCommand chain = build(ChainCommand.class, c1, c2);
+
+        assertEquals(chain.workDouble(1.2d), 3.14d);
+
+        verify();
+    }
+
+    private ChainCommand mockChainCommand()
+    {
+        return newMock(ChainCommand.class);
+    }
+
+    @Test
+    public void fabricated_classes_are_reused()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        Runnable chain1 = build(Runnable.class, r1);
+        Runnable chain2 = build(Runnable.class, r2);
+
+        Assert.assertSame(chain1.getClass(), chain2.getClass());
+
+        // Now make sure that the two instances are independent.
+
+        r1.run();
+
+        replay();
+
+        chain1.run();
+
+        verify();
+
+        r2.run();
+
+        replay();
+
+        chain2.run();
+
+        verify();
+    }
+
+    private <T> T build(Class<T> commandInterface, T... commands)
+    {
+        List<T> list = Arrays.asList(commands);
+
+        return builder.build(commandInterface, list);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainCommand.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainCommand.java
new file mode 100644
index 0000000..3a32c86
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ChainCommand.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;

+

+/**

+ * Used with {@link org.apache.tapestry.ioc.internal.services.ChainBuilderImplTest}.

+ */

+public interface ChainCommand

+{

+    int workInt(int input);

+

+    boolean workBoolean(boolean input);

+

+    double workDouble(double input);

+

+    String workString(String input);

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFabImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFabImplTest.java
new file mode 100644
index 0000000..fb4a927
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFabImplTest.java
@@ -0,0 +1,432 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import javassist.CtClass;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.internal.services.LoggingDecoratorImplTest.ToStringService;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.DataFormatException;
+
+public class ClassFabImplTest extends IOCTestCase
+{
+    private final CtClassSource source;
+
+    private final PropertyAccess access = new PropertyAccessImpl();
+
+    public interface SampleService
+    {
+        int primitiveMethod(int primitiveValue);
+
+        void voidMethod(String input);
+
+        String objectMethod(String input);
+    }
+
+    public interface SampleToStringService
+    {
+        String toString();
+    }
+
+    public ClassFabImplTest()
+    {
+        ClassLoader threadLoader = Thread.currentThread().getContextClassLoader();
+
+        ClassFactoryClassPool pool = new ClassFactoryClassPool(threadLoader);
+
+        pool.addClassLoaderIfNeeded(threadLoader);
+
+        source = new CtClassSourceImpl(pool, threadLoader);
+    }
+
+    private ClassFab newClassFab(String className, Class superClass)
+    {
+        CtClass ctClass = source.newClass(className, superClass);
+
+        return new ClassFabImpl(source, ctClass, LoggerFactory.getLogger("ClassFab"));
+    }
+
+    @Test
+    public void create_simple_bean() throws Exception
+    {
+        ClassFab cf = newClassFab("TargetBean", Object.class);
+
+        cf.addField("_stringValue", String.class);
+
+        MethodSignature setStringValue = new MethodSignature(void.class, "setStringValue", new Class[] { String.class },
+                                                             null);
+
+        cf.addMethod(Modifier.PUBLIC, setStringValue, "_stringValue = $1;");
+
+        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null, null);
+
+        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
+
+        Class targetClass = cf.createClass();
+
+        Object targetBean = targetClass.newInstance();
+
+        access.set(targetBean, "stringValue", "Fred");
+
+        // May keep a test-time dependency on HiveMind, just for PropertyUtils.
+
+        String actual = (String) access.get(targetBean, "stringValue");
+
+        assertEquals(actual, "Fred");
+    }
+
+    @Test
+    public void add_to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("ToString", Object.class);
+
+        cf.addToString("ToString Description");
+
+        Class clazz = cf.createClass();
+
+        Object instance = clazz.newInstance();
+
+        assertEquals(instance.toString(), "ToString Description");
+    }
+
+    @Test
+    public void proxy_methods_to_delegate() throws Exception
+    {
+        ClassFab cf = newClassFab("Delegator", Object.class);
+
+        cf.addField("_delegate", SampleService.class);
+        cf.addConstructor(new Class[] { SampleService.class }, null, "_delegate = $1;");
+
+        cf.proxyMethodsToDelegate(SampleService.class, "_delegate", "<Delegator>");
+
+        SampleService delegate = newMock(SampleService.class);
+
+        Class clazz = cf.createClass();
+
+        SampleService proxy = (SampleService) clazz.getConstructors()[0].newInstance(delegate);
+
+        expect(delegate.primitiveMethod(5)).andReturn(10);
+
+        delegate.voidMethod("fred");
+
+        expect(delegate.objectMethod("barney")).andReturn("rubble");
+
+        replay();
+
+        assertEquals(proxy.primitiveMethod(5), 10);
+
+        proxy.voidMethod("fred");
+
+        assertEquals(proxy.objectMethod("barney"), "rubble");
+        assertEquals(proxy.toString(), "<Delegator>");
+
+        verify();
+    }
+
+    @Test
+    public void proxy_methods_to_delegate_with_to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("ToStringDelegator", Object.class);
+
+        cf.addField("_delegate", ToStringService.class);
+        cf.addConstructor(new Class[] { ToStringService.class }, null, "_delegate = $1;");
+
+        cf.proxyMethodsToDelegate(ToStringService.class, "_delegate", "<ToStringDelegator>");
+
+        ToStringService delegate = new ToStringService()
+        {
+            @Override
+            public String toString()
+            {
+                return "ACTUAL TO-STRING";
+            }
+        };
+
+        Class clazz = cf.createClass();
+
+        ToStringService proxy = (ToStringService) clazz.getConstructors()[0].newInstance(delegate);
+
+        assertEquals(proxy.toString(), "ACTUAL TO-STRING");
+    }
+
+    @Test
+    public void add_constructor() throws Exception
+    {
+        ClassFab cf = newClassFab("ConstructableBean", Object.class);
+
+        cf.addField("_stringValue", String.class);
+        cf.addConstructor(new Class[] { String.class }, null, "{ _stringValue = $1; }");
+
+        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null, null);
+
+        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
+
+        Class targetClass = cf.createClass();
+
+        try
+        {
+            targetClass.newInstance();
+            unreachable();
+        }
+        catch (InstantiationException ex)
+        {
+        }
+
+        Constructor c = targetClass.getConstructors()[0];
+
+        Object targetBean = c.newInstance(new Object[] { "Buffy" });
+
+        String actual = (String) access.get(targetBean, "stringValue");
+
+        assertEquals("Buffy", actual);
+    }
+
+    @Test
+    public void add_constructor_from_base_class() throws Exception
+    {
+        ClassFab cf = newClassFab("MyIntHolder", AbstractIntWrapper.class);
+
+        cf.addField("_intValue", int.class);
+        cf.addConstructor(new Class[] { int.class }, null, "{ _intValue = $1; }");
+
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "getIntValue", null, null), "return _intValue;");
+
+        Class targetClass = cf.createClass();
+        Constructor c = targetClass.getConstructors()[0];
+
+        AbstractIntWrapper targetBean = (AbstractIntWrapper) c.newInstance(new Object[] { new Integer(137) });
+
+        assertEquals(targetBean.getIntValue(), 137);
+    }
+
+    @Test
+    public void invalid_super_class() throws Exception
+    {
+        ClassFab cf = newClassFab("InvalidSuperClass", List.class);
+
+        try
+        {
+            cf.createClass();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to create class InvalidSuperClass");
+        }
+    }
+
+    private void assertExceptionSubstring(Throwable t, String partialMessage)
+    {
+        assertTrue(t.getMessage().contains(partialMessage));
+    }
+
+    @Test
+    public void add_interface() throws Exception
+    {
+        ClassFab cf = newClassFab("SimpleService", Object.class);
+
+        cf.addInterface(SimpleService.class);
+
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "add", new Class[] { int.class, int.class }, null),
+                     "return $1 + $2;");
+
+        Class targetClass = cf.createClass();
+
+        SimpleService s = (SimpleService) targetClass.newInstance();
+
+        assertEquals(207, s.add(99, 108));
+    }
+
+    @Test
+    public void attempt_to_subclass_from_final_class() throws Exception
+    {
+        ClassFab cf = newClassFab("StringSubclass", String.class);
+
+        try
+        {
+            cf.createClass();
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionRegexp(ex, "Unable to create class StringSubclass\\: .*");
+        }
+    }
+
+    private void assertExceptionRegexp(Throwable ex, String pattern)
+    {
+        assertTrue(ex.getMessage().matches(pattern));
+    }
+
+    @Test
+    public void create_class_within_non_default_package() throws Exception
+    {
+        ClassFab cf = newClassFab("org.apache.hivemind.InPackage", Object.class);
+
+        Class c = cf.createClass();
+
+        Object o = c.newInstance();
+
+        assertEquals("org.apache.hivemind.InPackage", o.getClass().getName());
+    }
+
+    @Test
+    public void invalid_method_body() throws Exception
+    {
+        ClassFab cf = newClassFab("BadMethodBody", Object.class);
+
+        cf.addInterface(Runnable.class);
+
+        try
+        {
+            cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "run", null, null), "fail;");
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to add method void run() to class BadMethodBody:");
+        }
+    }
+
+    @Test
+    public void add_duplicate_method_signature() throws Exception
+    {
+        ClassFab cf = newClassFab("DupeMethodAdd", Object.class);
+
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
+
+        try
+        {
+            cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals("Attempt to redefine method void foo() of class DupeMethodAdd.", ex
+                    .getMessage());
+        }
+    }
+
+    @Test
+    public void invalid_constructor_body() throws Exception
+    {
+        ClassFab cf = newClassFab("BadConstructor", Object.class);
+
+        try
+        {
+            cf.addConstructor(null, null, " woops!");
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to add constructor to class BadConstructor");
+        }
+
+    }
+
+    @Test
+    public void invalid_field() throws Exception
+    {
+        ClassFab cf = newClassFab("InvalidField", Object.class);
+
+        // You'd think some of these would fail, but the ultimate failure
+        // occurs when we create the class.
+
+        cf.addField("a%b", String.class);
+        cf.addField("", int.class);
+
+        // Aha! Adding a duplicate fails!
+
+        cf.addField("buffy", int.class);
+
+        try
+        {
+            cf.addField("buffy", String.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Unable to add field buffy to class InvalidField: duplicate field: buffy");
+        }
+
+    }
+
+    @Test
+    public void to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("FredRunnable", BaseLocatable.class);
+
+        cf.addInterface(Runnable.class);
+        cf.addInterface(Serializable.class);
+
+        cf.addField("_map", Map.class);
+
+        cf.addConstructor(new Class[] { Map.class, Runnable.class },
+                          new Class[] { IllegalArgumentException.class, DataFormatException.class }, "{ _map = $1; }");
+
+        MethodSignature sig = new MethodSignature(Map.class, "doTheNasty", new Class[] { int.class, String.class },
+                                                  new Class[] { InstantiationException.class,
+                                                          IllegalAccessException.class });
+
+        cf.addMethod(Modifier.PUBLIC + Modifier.FINAL + Modifier.SYNCHRONIZED, sig, "{ return _map; }");
+
+        String toString = cf.toString();
+
+        assertContains(toString,
+                       "public class FredRunnable extends " + BaseLocatable.class.getName() + "\n" + "  implements java.lang.Runnable, java.io.Serializable");
+
+        assertContains(toString, "private java.util.Map _map;");
+
+        assertContains(toString,
+                       "public FredRunnable(java.util.Map $1, java.lang.Runnable $2)\n" + "  throws java.lang.IllegalArgumentException, java.util.zip.DataFormatException\n" + "{ _map = $1; }");
+
+        assertContains(toString,
+                       "public final synchronized java.util.Map doTheNasty(int $1, java.lang.String $2)\n" + "  throws java.lang.InstantiationException, java.lang.IllegalAccessException\n" + "{ return _map; }");
+
+    }
+
+    @Test
+    public void add_noop_method() throws Exception
+    {
+        ClassFab cf = newClassFab("NoOp", Object.class);
+        cf.addInterface(Runnable.class);
+
+        cf.addNoOpMethod(new MethodSignature(void.class, "run", null, null));
+        cf.addNoOpMethod(new MethodSignature(int.class, "getInt", null, null));
+        cf.addNoOpMethod(new MethodSignature(double.class, "getDouble", null, null));
+
+        Class clazz = cf.createClass();
+
+        Runnable instance = (Runnable) clazz.newInstance();
+
+        instance.run();
+
+        assertEquals(access.get(instance, "int"), 0);
+        assertEquals(access.get(instance, "double"), 0.0d);
+    }
+
+    private void assertContains(String actual, String expectedSubstring)
+    {
+        assertTrue(actual.contains(expectedSubstring), "Missing substring: " + expectedSubstring);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImplTest.java
new file mode 100644
index 0000000..9c020bf
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImplTest.java
@@ -0,0 +1,173 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.LocationImpl;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class ClassFactoryImplTest extends IOCTestCase
+{
+    public static class BaseClass
+    {
+        public void run()
+        {
+        }
+    }
+
+    @Test
+    public void new_class_with_name_and_base_class() throws Exception
+    {
+        ClassFactory factory = new ClassFactoryImpl();
+        String name = ClassFabUtils.generateClassName(Runnable.class);
+
+        ClassFab cf = factory.newClass(name, Object.class);
+        cf.addInterface(Runnable.class);
+
+        addRunMethod(cf);
+
+        Class newClass = cf.createClass();
+
+        Runnable instance = (Runnable) newClass.newInstance();
+
+        instance.run();
+    }
+
+    @Test
+    public void new_class_with_non_object_base_class() throws Exception
+    {
+        ClassFactory factory = new ClassFactoryImpl();
+        String name = ClassFabUtils.generateClassName(Runnable.class);
+
+        ClassFab cf = factory.newClass(name, BaseClass.class);
+        cf.addInterface(Runnable.class);
+
+        Class newClass = cf.createClass();
+
+        Runnable instance = (Runnable) newClass.newInstance();
+
+        instance.run();
+    }
+
+    @Test
+    public void new_class_with_interface() throws Exception
+    {
+        ClassFactory factory = new ClassFactoryImpl();
+
+        ClassFab cf = factory.newClass(Runnable.class);
+
+        addRunMethod(cf);
+
+        Class newClass = cf.createClass();
+
+        Runnable instance = (Runnable) newClass.newInstance();
+
+        instance.run();
+    }
+
+    @Test
+    public void get_method_location() throws Exception
+    {
+        ClassFactory factory = new ClassFactoryImpl();
+
+        Class target = LineNumberBean.class;
+
+        Method m = target.getMethod("fred");
+
+        // 21 is the line containing the close brace
+
+        Location l = factory.getMethodLocation(m);
+        assertEquals(
+                l.toString(),
+                "org.apache.tapestry.ioc.internal.services.LineNumberBean.fred() (at LineNumberBean.java:25)");
+        assertEquals(l.getLine(), 25);
+
+        m = target.getMethod("betty", String.class, int.class);
+
+        // 25 is the line of the return statement
+
+        assertEquals(
+                factory.getMethodLocation(m).toString(),
+                "org.apache.tapestry.ioc.internal.services.LineNumberBean.betty(String, int) (at LineNumberBean.java:29)");
+
+        m = target.getDeclaredMethod("wilma", int[].class, Double[][][].class);
+
+        assertEquals(
+                factory.getMethodLocation(m).toString(),
+                "org.apache.tapestry.ioc.internal.services.LineNumberBean.wilma(int[], Double[][][]) (at LineNumberBean.java:34)");
+    }
+
+    private void addRunMethod(ClassFab cf)
+    {
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "run", null, null), " { } ");
+    }
+
+    @Test
+    public void get_constructor_location() throws Exception
+    {
+        Constructor cc = LineNumberBean.class.getConstructors()[0];
+
+        ClassFactory factory = new ClassFactoryImpl();
+
+        // Eclipse and Sun JDK don't agree on the line number, so we'll accept either.
+
+        assertTrue(factory
+                .getConstructorLocation(cc)
+                .toString()
+                .matches(
+                "org.apache.tapestry.ioc.internal.services.LineNumberBean\\(String, int\\) \\(at LineNumberBean.java:(19|20)\\)"));
+    }
+
+    /**
+     * Import a class (or two) where the class is from a known and available class loader.
+     */
+    @Test
+    public void import_ordinary_class()
+    {
+        ClassFactory factory = new ClassFactoryImpl();
+
+        assertSame(factory.importClass(Object.class), Object.class);
+        assertSame(factory.importClass(LocationImpl.class), LocationImpl.class);
+    }
+
+    /**
+     * Import a class where the bytecode is not available, to ensure that the super-class (from an
+     * available class loader) is returned.
+     */
+    @Test
+    public void import_proxy_class() throws Exception
+    {
+        ClassFactory alienFactory = new ClassFactoryImpl();
+
+        Class<TargetBean> clazz = TargetBean.class;
+
+        ClassFab cf = alienFactory.newClass(clazz.getName() + "$$Proxy", clazz);
+
+        Class alienClass = cf.createClass();
+
+        ClassFactory factory = new ClassFactoryImpl();
+
+        assertSame(factory.importClass(alienClass), clazz);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImplTest.java
new file mode 100644
index 0000000..ddc8c75
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ClassNameLocatorImplTest.java
@@ -0,0 +1,138 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassNameLocator;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Tricky to test, since the code is literally hunting around inside its own brain. There's a lot of room for unintended
+ * consequences here.
+ */
+public class ClassNameLocatorImplTest extends Assert
+{
+    /**
+     * Use various packages in javassist to test this, as those don't change unexpectedly(-ish) and we know they are in
+     * a JAR on the classpath.
+     */
+    @Test
+    public void classes_in_jar_file()
+    {
+        ClassNameLocator locator = new ClassNameLocatorImpl();
+
+        Collection<String> names = locator
+                .locateClassNames("javassist.util");
+
+        assertInList(
+                names,
+                "javassist.util",
+                "HotSwapper",
+                "Trigger");
+        assertNotInList(
+                names,
+                "javassist.util",
+                "Orderer$1");
+    }
+
+    @Test
+    public void classes_in_subpackage_in_jar_file()
+    {
+        ClassNameLocator locator = new ClassNameLocatorImpl();
+
+        Collection<String> names = locator.locateClassNames("javassist.util");
+
+        assertInList(
+                names,
+                "javassist.util",
+                "proxy.ProxyFactory");
+
+    }
+
+    /**
+     * This time, we use a selection of classes from tapestry-ioc, since those will never be packaged inside a JAR at
+     * this time.
+     */
+
+    @Test
+    public void classes_in_local_folders()
+    {
+        ClassNameLocator locator = new ClassNameLocatorImpl();
+
+        Collection<String> names = locator
+                .locateClassNames("org.apache.tapestry.ioc.services");
+
+        assertInList(names, "org.apache.tapestry.ioc.services", "SymbolSource", "TapestryIOCModule");
+
+        assertNotInList(names, "org.apache.tapestry.ioc.services", "TapestryIOCModule$1");
+    }
+
+    @Test
+    public void classes_in_subpackages_in_local_folders()
+    {
+        ClassNameLocator locator = new ClassNameLocatorImpl();
+
+        Collection<String> names = locator.locateClassNames("org.apache.tapestry");
+
+        assertInList(
+                names,
+                "org.apache.tapestry",
+                "ioc.Orderable",
+                "ioc.services.ChainBuilder");
+
+        assertNotInList(names, "org.apache.tapestry.ioc", "services.TapestryIOCModule$1");
+    }
+
+    void assertInList(Collection<String> names, String packageName, String... classNames)
+    {
+        Set<String> classNameSet = CollectionFactory.newSet(names);
+
+        for (String className : classNames)
+        {
+            String fullName = packageName + "." + className;
+
+            if (classNameSet.contains(fullName))
+                continue;
+
+            String message = String.format("%s not found in %s.", fullName, InternalUtils
+                    .joinSorted(names));
+
+            throw new AssertionError(message);
+        }
+    }
+
+    void assertNotInList(Collection<String> names, String packageName, String... classNames)
+    {
+        Set<String> classNameSet = CollectionFactory.newSet(names);
+
+        for (String className : classNames)
+        {
+            String fullName = packageName + "." + className;
+
+            if (!classNameSet.contains(fullName))
+                continue;
+
+            String message = String.format("%s found in %s.", fullName, InternalUtils
+                    .joinSorted(names));
+
+            throw new AssertionError(message);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImplTest.java
new file mode 100644
index 0000000..9b02c37
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/DefaultImplementationBuilderImplTest.java
@@ -0,0 +1,81 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.DefaultImplementationBuilder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class DefaultImplementationBuilderImplTest extends IOCInternalTestCase
+{
+    private DefaultImplementationBuilder builder;
+
+    @BeforeClass
+    public void setup_builder()
+    {
+        builder = getService("DefaultImplementationBuilder", DefaultImplementationBuilder.class);
+    }
+
+    @AfterClass
+    public void cleanup_builder()
+    {
+        builder = null;
+    }
+
+    @Test
+    public void simple_interface()
+    {
+        Runnable r = builder.createDefaultImplementation(Runnable.class);
+
+        r.run();
+
+        assertEquals(r.toString(), "<NoOp java.lang.Runnable>");
+    }
+
+    public interface ToString
+    {
+        String toString();
+    }
+
+    @Test
+    public void interface_has_toString()
+    {
+        ToString ts = builder.createDefaultImplementation(ToString.class);
+
+        assertNull(ts.toString());
+    }
+
+    @Test
+    public void instances_are_cached()
+    {
+        Runnable r1 = null;
+        Runnable r2 = null;
+
+        // With tests in parallel, there's a harmless race condition that can cause r1 != r2
+        // for one pass, so we give it a second chance to prove itself.
+
+        for (int i = 0; i < 2; i++)
+        {
+            r1 = builder.createDefaultImplementation(Runnable.class);
+            r2 = builder.createDefaultImplementation(Runnable.class);
+
+            if (r1 == r2) break;
+        }
+
+        assertSame(r2, r1);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImplTest.java
new file mode 100644
index 0000000..f7e6cbe
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionAnalyzerImplTest.java
@@ -0,0 +1,163 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.ioc.services.ExceptionAnalysis;
+import org.apache.tapestry.ioc.services.ExceptionAnalyzer;
+import org.apache.tapestry.ioc.services.ExceptionInfo;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+public class ExceptionAnalyzerImplTest extends IOCInternalTestCase
+{
+    private ExceptionAnalyzer analyzer;
+
+    @BeforeClass
+    public void setup_analyzer()
+    {
+        analyzer = getService("ExceptionAnalyzer", ExceptionAnalyzer.class);
+    }
+
+    @AfterClass
+    public void cleanup_analyzer()
+    {
+        analyzer = null;
+    }
+
+    @Test
+    public void basic_exception()
+    {
+        String message = "Hey! We've Got Not Tomatoes!";
+
+        Throwable t = new RuntimeException(message);
+
+        ExceptionAnalysis ea = analyzer.analyze(t);
+
+        assertEquals(ea.getExceptionInfos().size(), 1);
+
+        ExceptionInfo ei = ea.getExceptionInfos().get(0);
+
+        assertEquals(ei.getClassName(), RuntimeException.class.getName());
+        assertEquals(ei.getMessage(), message);
+
+        assertTrue(ei.getPropertyNames().isEmpty());
+        assertFalse(ei.getStackTrace().isEmpty());
+    }
+
+    @Test
+    public void exception_properties()
+    {
+        Location l = mockLocation();
+
+        replay();
+
+        Throwable t = new TapestryException("Message", l, null);
+
+        ExceptionAnalysis ea = analyzer.analyze(t);
+
+        assertEquals(ea.getExceptionInfos().size(), 1);
+
+        ExceptionInfo ei = ea.getExceptionInfos().get(0);
+
+        assertEquals(ei.getPropertyNames(), Arrays.asList("location"));
+
+        assertEquals(ei.getProperty("location"), l);
+
+        verify();
+    }
+
+    @Test
+    public void nested_exceptions()
+    {
+        Throwable inner = new RuntimeException("Inner");
+        Throwable outer = new RuntimeException("Outer", inner);
+
+        ExceptionAnalysis ea = analyzer.analyze(outer);
+
+        assertEquals(ea.getExceptionInfos().size(), 2);
+
+        ExceptionInfo ei = ea.getExceptionInfos().get(0);
+
+        assertEquals(ei.getMessage(), "Outer");
+        assertTrue(ei.getStackTrace().isEmpty());
+
+        ei = ea.getExceptionInfos().get(1);
+
+        assertEquals(ei.getMessage(), "Inner");
+        assertFalse(ei.getStackTrace().isEmpty());
+    }
+
+    @Test
+    public void middle_exception_removed_with_no_value()
+    {
+        Throwable inner = new RuntimeException("Inner");
+        Throwable middle = new RuntimeException("Middle", inner);
+        Throwable outer = new RuntimeException("Outer: Middle", middle);
+
+        ExceptionAnalysis ea = analyzer.analyze(outer);
+
+        assertEquals(ea.getExceptionInfos().size(), 2);
+
+        ExceptionInfo ei = ea.getExceptionInfos().get(0);
+
+        assertEquals(ei.getMessage(), "Outer: Middle");
+        assertTrue(ei.getStackTrace().isEmpty());
+
+        ei = ea.getExceptionInfos().get(1);
+
+        assertEquals(ei.getMessage(), "Inner");
+        assertFalse(ei.getStackTrace().isEmpty());
+    }
+
+    @Test
+    public void middle_exception_retained_due_to_extra_property()
+    {
+        Location l = mockLocation();
+
+        replay();
+
+        Throwable inner = new RuntimeException("Inner");
+        Throwable middle = new TapestryException("Middle", l, inner);
+        Throwable outer = new RuntimeException("Outer: Middle", middle);
+
+        ExceptionAnalysis ea = analyzer.analyze(outer);
+
+        assertEquals(ea.getExceptionInfos().size(), 3);
+
+        ExceptionInfo ei = ea.getExceptionInfos().get(0);
+
+        assertEquals(ei.getMessage(), "Outer: Middle");
+        assertTrue(ei.getStackTrace().isEmpty());
+
+        ei = ea.getExceptionInfos().get(1);
+
+        assertEquals(ei.getMessage(), "Middle");
+        assertTrue(ei.getStackTrace().isEmpty());
+
+        ei = ea.getExceptionInfos().get(2);
+
+        assertEquals(ei.getMessage(), "Inner");
+        assertFalse(ei.getStackTrace().isEmpty());
+
+        verify();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImplTest.java
new file mode 100644
index 0000000..d359575
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExceptionTrackerImplTest.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.services;

+

+import org.apache.tapestry.ioc.services.ExceptionTracker;

+import org.testng.Assert;

+import org.testng.annotations.Test;

+

+public class ExceptionTrackerImplTest extends Assert

+{

+    @Test

+    public void check_exception_tracking()

+    {

+        Throwable t1 = new RuntimeException();

+        Throwable t2 = new RuntimeException();

+

+        ExceptionTracker et = new ExceptionTrackerImpl();

+

+        for (int i = 0; i < 3; i++)

+        {

+            assertEquals(et.exceptionLogged(t1), i != 0);

+            assertEquals(et.exceptionLogged(t2), i != 0);

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraFilterMethod.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraFilterMethod.java
new file mode 100644
index 0000000..738d2e5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraFilterMethod.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ExtraFilterMethod
+{
+    public void extraFilterMethod();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraServiceMethod.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraServiceMethod.java
new file mode 100644
index 0000000..a2d9dac
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ExtraServiceMethod.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ExtraServiceMethod
+{
+    public void extraServiceMethod();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzerTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzerTest.java
new file mode 100644
index 0000000..877fb79
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/FilterMethodAnalyzerTest.java
@@ -0,0 +1,76 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+public class FilterMethodAnalyzerTest extends IOCInternalTestCase
+{
+    private MethodSignature find(Class target, String name)
+    {
+        Method method = findMethod(target, name);
+
+        return new MethodSignature(method);
+    }
+
+    private void assertPosition(String methodName, int expected)
+    {
+        FilterMethodAnalyzer a = new FilterMethodAnalyzer(SampleService.class);
+
+        MethodSignature ms = find(SampleService.class, methodName);
+        MethodSignature fms = find(SampleFilter.class, methodName);
+
+        assertEquals(expected, a.findServiceInterfacePosition(ms, fms));
+    }
+
+    private void assertMismatch(String methodName)
+    {
+        assertPosition(methodName, -1);
+    }
+
+    @Test
+    public void simple_match()
+    {
+        assertPosition("simpleMatch", 0);
+    }
+
+    @Test
+    public void mismatched_parameter_count()
+    {
+        assertMismatch("mismatchParameterCount");
+    }
+
+    @Test
+    public void mismatch_on_method_return_type()
+    {
+        assertMismatch("mismatchReturnType");
+    }
+
+    @Test
+    public void service_interface_not_in_filter_method_signature()
+    {
+        assertMismatch("missingServiceInterface");
+    }
+
+    @Test
+    public void match_with_multiple_parameters()
+    {
+        assertPosition("complexMatch", 2);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java
new file mode 100644
index 0000000..973215f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface GrandparentInterface
+{
+    String getGrandParentProperty();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java
new file mode 100644
index 0000000..520c7fd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java
@@ -0,0 +1,84 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.internal.ServiceActivityTracker;
+import org.apache.tapestry.ioc.services.Status;
+import org.testng.annotations.Test;
+
+public class JustInTimeObjectCreatorTest extends IOCInternalTestCase
+{
+    private static final String SERVICE_ID = "FooBar";
+
+    @Test
+    public void create_after_shutdown()
+    {
+        ObjectCreator creator = mockObjectCreator();
+
+        replay();
+
+        JustInTimeObjectCreator j = new JustInTimeObjectCreator(null, creator, SERVICE_ID);
+
+        j.registryDidShutdown();
+
+        try
+        {
+            j.createObject();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Proxy for service FooBar is no longer active because the IOC Registry has been shut down.");
+        }
+    }
+
+    @Test
+    public void eager_load()
+    {
+        ObjectCreator creator = mockObjectCreator();
+        Object service = new Object();
+        ServiceActivityTracker tracker = mockServiceActivityTracker();
+
+        replay();
+
+        JustInTimeObjectCreator j = new JustInTimeObjectCreator(tracker, creator, SERVICE_ID);
+
+        verify();
+
+        // First access: use the creator to get the actual object.
+
+        train_createObject(creator, service);
+
+        tracker.setStatus(SERVICE_ID, Status.REAL);
+
+        replay();
+
+        j.eagerLoadService();
+
+        verify();
+
+        // This part tests the caching part.
+
+        replay();
+
+        assertSame(j.createObject(), service);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/KindOf.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/KindOf.java
new file mode 100644
index 0000000..ecd3f01
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/KindOf.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Converts an object to a string describing the kind of the object.
+ */
+public interface KindOf
+{
+    String kindOf(Object value);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LineNumberBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LineNumberBean.java
new file mode 100644
index 0000000..cd6cb86
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LineNumberBean.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public class LineNumberBean
+{
+    public LineNumberBean(String foo, int bar)
+    {
+    }
+
+    public void fred()
+    {
+    }
+
+    public int betty(String foo, int bar)
+    {
+        return bar;
+    }
+
+    protected String wilma(int[] first, Double[][][] threed)
+    {
+        return null;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImplTest.java
new file mode 100644
index 0000000..9d59a61
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/LoggingDecoratorImplTest.java
@@ -0,0 +1,243 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.AspectDecorator;
+import org.apache.tapestry.ioc.services.LoggingDecorator;
+import org.slf4j.Logger;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Use the LoggingDecorator in a number of ways to verify its behavior. In some ways we are testing the code dynamically
+ * generated by the LoggingDecorator as much as we are testing the decorator itself -- one proves the other.
+ * <p/>
+ * And now this test is used to integration test {@link org.apache.tapestry.ioc.internal.services.AspectDecoratorImpl}
+ * as well.
+ */
+public class LoggingDecoratorImplTest extends IOCInternalTestCase
+{
+    private AspectDecorator aspectDecorator;
+
+    @BeforeClass
+    public void setup()
+    {
+        aspectDecorator = getService(AspectDecorator.class);
+    }
+
+    public interface UpcaseService
+    {
+        String upcase(String input);
+    }
+
+    public interface AdderService
+    {
+        long add(long operand1, long operand2);
+    }
+
+    public interface ToStringService
+    {
+        String toString();
+    }
+
+    public interface ExceptionService
+    {
+        void parse() throws SAXParseException;
+    }
+
+    @Test
+    public void void_method()
+    {
+        Logger logger = mockLogger();
+        Runnable delegate = mockRunnable();
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] run()");
+
+        delegate.run();
+
+        logger.debug("[ EXIT] run");
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        Runnable interceptor = ld.build(Runnable.class, delegate, "foo.Bar", logger);
+
+        interceptor.run();
+
+        assertEquals(
+                interceptor.toString(),
+                "<Logging interceptor for foo.Bar(java.lang.Runnable)>");
+
+        verify();
+    }
+
+    private LoggingDecoratorImpl newLoggingDecorator()
+    {
+        return new LoggingDecoratorImpl(aspectDecorator, new ExceptionTrackerImpl());
+    }
+
+    @Test
+    public void method_throws_runtime_exception()
+    {
+        Throwable t = new RuntimeException("From delegate.");
+        Logger logger = mockLogger();
+        Runnable delegate = mockRunnable();
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] run()");
+
+        delegate.run();
+        setThrowable(t);
+
+        logger.debug("[ FAIL] run -- " + t.getClass().getName(), t);
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        Runnable interceptor = ld.build(Runnable.class, delegate, "foo.Bar", logger);
+
+        try
+        {
+            interceptor.run();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            Assert.assertSame(ex, t);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void method_throws_checked_exception() throws Exception
+    {
+        Throwable t = new SAXParseException("From delegate.", null);
+        Logger logger = mockLogger();
+        ExceptionService delegate = newMock(ExceptionService.class);
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] parse()");
+
+        delegate.parse();
+        setThrowable(t);
+
+        logger.debug("[ FAIL] parse -- " + t.getClass().getName(), t);
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        ExceptionService interceptor = ld
+                .build(ExceptionService.class, delegate, "foo.Bar", logger);
+
+        try
+        {
+            interceptor.parse();
+            unreachable();
+        }
+        catch (SAXParseException ex)
+        {
+            Assert.assertSame(ex, t);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void object_parameter_and_return_type()
+    {
+        Logger logger = mockLogger();
+        UpcaseService delegate = new UpcaseService()
+        {
+            public String upcase(String input)
+            {
+                return input.toUpperCase();
+            }
+        };
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] upcase(\"barney\")");
+
+        logger.debug("[ EXIT] upcase [\"BARNEY\"]");
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        UpcaseService interceptor = ld.build(UpcaseService.class, delegate, "foo.Bar", logger);
+
+        assertEquals(interceptor.upcase("barney"), "BARNEY");
+
+        verify();
+    }
+
+    @Test
+    public void primitive_parameter_and_return_type()
+    {
+        Logger logger = mockLogger();
+        AdderService delegate = new AdderService()
+        {
+            public long add(long operand1, long operand2)
+            {
+                return operand1 + operand2;
+            }
+        };
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] add(6, 13)");
+
+        logger.debug("[ EXIT] add [19]");
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        AdderService interceptor = ld.build(AdderService.class, delegate, "foo.Bar", logger);
+
+        assertEquals(interceptor.add(6, 13), 19);
+
+        verify();
+    }
+
+    @Test
+    public void to_string_method_in_service_interface_is_delegated()
+    {
+        Logger logger = mockLogger();
+        ToStringService delegate = new ToStringService()
+        {
+            @Override
+            public String toString()
+            {
+                return "FROM DELEGATE";
+            }
+        };
+
+        train_isDebugEnabled(logger, true);
+        logger.debug("[ENTER] toString()");
+
+        logger.debug("[ EXIT] toString [\"FROM DELEGATE\"]");
+
+        replay();
+
+        LoggingDecorator ld = newLoggingDecorator();
+        ToStringService interceptor = ld.build(ToStringService.class, delegate, "foo.Bar", logger);
+
+        assertEquals(interceptor.toString(), "FROM DELEGATE");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImplTest.java
new file mode 100644
index 0000000..e3d0914
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MasterObjectProviderImplTest.java
@@ -0,0 +1,128 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.services.MasterObjectProvider;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class MasterObjectProviderImplTest extends IOCTestCase
+{
+    @SuppressWarnings("unchecked")
+    @Test
+    public void found_match_first()
+    {
+        ObjectProvider prov1 = mockObjectProvider();
+        ObjectProvider prov2 = mockObjectProvider();
+        Class type = Runnable.class;
+        AnnotationProvider ap = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        Object expected = mockRunnable();
+
+        train_provide(prov1, type, ap, locator, expected);
+
+        List<ObjectProvider> configuration = Arrays.asList(prov1, prov2);
+
+        replay();
+
+        MasterObjectProvider master = new MasterObjectProviderImpl(configuration);
+
+        assertSame(master.provide(type, ap, locator, true), expected);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void found_later_match()
+    {
+        ObjectProvider prov1 = mockObjectProvider();
+        ObjectProvider prov2 = mockObjectProvider();
+        Class type = Runnable.class;
+        AnnotationProvider ap = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        Object expected = mockRunnable();
+
+        train_provide(prov1, type, ap, locator, null);
+        train_provide(prov2, type, ap, locator, expected);
+
+        List<ObjectProvider> configuration = Arrays.asList(prov1, prov2);
+
+        replay();
+
+        MasterObjectProvider master = new MasterObjectProviderImpl(configuration);
+
+        assertSame(master.provide(type, ap, locator, true), expected);
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void no_match_but_optional()
+    {
+        ObjectProvider prov1 = mockObjectProvider();
+        ObjectProvider prov2 = mockObjectProvider();
+        Class type = Runnable.class;
+        AnnotationProvider ap = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+
+        train_provide(prov1, type, ap, locator, null);
+        train_provide(prov2, type, ap, locator, null);
+
+        List<ObjectProvider> configuration = Arrays.asList(prov1, prov2);
+
+        replay();
+
+        MasterObjectProvider master = new MasterObjectProviderImpl(configuration);
+
+        assertNull(master.provide(type, ap, locator, false));
+
+        verify();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void no_match_and_required()
+    {
+        ObjectProvider prov1 = mockObjectProvider();
+        ObjectProvider prov2 = mockObjectProvider();
+        Class type = Runnable.class;
+        AnnotationProvider ap = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        Object expected = mockRunnable();
+
+        train_provide(prov1, type, ap, locator, null);
+        train_provide(prov2, type, ap, locator, null);
+
+        train_getService(locator, type, expected);
+
+        List<ObjectProvider> configuration = Arrays.asList(prov1, prov2);
+
+        replay();
+
+        MasterObjectProvider master = new MasterObjectProviderImpl(configuration);
+
+        assertSame(master.provide(type, ap, locator, true), expected);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleFilter.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleFilter.java
new file mode 100644
index 0000000..6cffae4
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleFilter.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface MiddleFilter
+{
+    public void execute(int count, char ch, MiddleService service, StringBuilder buffer);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleService.java
new file mode 100644
index 0000000..0fd151e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/MiddleService.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface MiddleService
+{
+    public void execute(int count, char ch, StringBuilder buffer);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java
new file mode 100644
index 0000000..2f3fd7d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ParentInterface extends GrandparentInterface
+{
+    String getParentProperty();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImplTest.java
new file mode 100644
index 0000000..29223dc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PerthreadManagerImplTest.java
@@ -0,0 +1,120 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class PerthreadManagerImplTest extends IOCTestCase
+{
+    @Test
+    public void no_listeners()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        new PerthreadManagerImpl(logger).cleanup();
+
+        verify();
+    }
+
+    @Test
+    public void listeners_are_one_shot()
+    {
+        Logger logger = mockLogger();
+        ThreadCleanupListener listener = mockThreadCleanupListener();
+
+        listener.threadDidCleanup();
+
+        replay();
+
+        PerthreadManagerImpl hub = new PerthreadManagerImpl(logger);
+
+        hub.addThreadCleanupListener(listener);
+
+        hub.cleanup();
+
+        verify();
+
+        // No more training.
+
+        replay();
+
+        // Listener not invoked.
+
+        hub.cleanup();
+
+        verify();
+    }
+
+    private ThreadCleanupListener mockThreadCleanupListener()
+    {
+        return newMock(ThreadCleanupListener.class);
+    }
+
+    @Test
+    public void listener_cleanup_failure()
+    {
+        final RuntimeException t = new RuntimeException("Boom!");
+
+        Logger logger = mockLogger();
+
+        ThreadCleanupListener listener = new ThreadCleanupListener()
+        {
+
+            public void threadDidCleanup()
+            {
+                throw t;
+            }
+
+        };
+
+        logger.warn(ServiceMessages.threadCleanupError(listener, t), t);
+
+        replay();
+
+        PerthreadManagerImpl hub = new PerthreadManagerImpl(logger);
+
+        hub.addThreadCleanupListener(listener);
+
+        hub.cleanup();
+
+        verify();
+    }
+
+    // @Test
+    // public void listener_list_is_per_thread()
+    // {
+    // ThreadCleanupListener l1 = newThreadCleanupListener();
+    // final ThreadCleanupListener l2 = newThreadCleanupListener();
+    //
+    // Thread thread = new Thread();
+    //
+    // l1.threadDidCleanup();
+    //
+    // replay();
+    //
+    // final PerthreadManager hub = new PerthreadManagerImpl(log);
+    //
+    // hub.addThreadCleanupListener(l1);
+    //
+    // hub.cleanup();
+    //
+    // verify();
+    // }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImplTest.java
new file mode 100644
index 0000000..5fab89a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PipelineBuilderImplTest.java
@@ -0,0 +1,149 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.services.PipelineBuilder;
+import org.slf4j.Logger;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Integration tests for the PipelineBuilder service.
+ */
+public class PipelineBuilderImplTest extends IOCInternalTestCase
+{
+
+    private PipelineBuilder builder;
+
+    private Registry registry;
+
+    @BeforeClass
+    public void setup_builder()
+    {
+        registry = buildRegistry();
+        builder = registry.getService("PipelineBuilder", PipelineBuilder.class);
+    }
+
+    @AfterClass
+    public void shutdown_builder()
+    {
+        registry.shutdown();
+
+        builder = null;
+        registry = null;
+    }
+
+    @Test
+    public void pipeline_with_filters()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        StandardFilter subtracter = new StandardFilter()
+        {
+            public int run(int i, StandardService service)
+            {
+                return service.run(i) - 2;
+            }
+        };
+
+        StandardFilter multiplier = new StandardFilter()
+        {
+            public int run(int i, StandardService service)
+            {
+                return 2 * service.run(i);
+            }
+        };
+
+        StandardFilter adder = new StandardFilter()
+        {
+            public int run(int i, StandardService service)
+            {
+                return service.run(i + 3);
+            }
+        };
+
+        StandardService terminator = new StandardService()
+        {
+            public int run(int i)
+            {
+                return i;
+            }
+        };
+
+        StandardService pipeline = builder.build(
+                logger,
+                StandardService.class,
+                StandardFilter.class,
+                Arrays.asList(subtracter, multiplier, adder),
+                terminator);
+
+        // Should be order subtracter, multipler, adder
+        assertEquals(pipeline.run(5), 14);
+        assertEquals(pipeline.run(10), 24);
+
+        verify();
+    }
+
+    @Test
+    public void pipeline_without_filters_is_terminator()
+    {
+        Logger logger = mockLogger();
+        StandardService terminator = newMock(StandardService.class);
+
+        replay();
+
+        List<StandardFilter> filters = newList();
+
+        StandardService pipeline = builder.build(
+                logger,
+                StandardService.class,
+                StandardFilter.class,
+                filters,
+                terminator);
+
+        assertSame(pipeline, terminator);
+
+        verify();
+    }
+
+    @Test
+    public void pipeline_with_default_terminator()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        List<StandardFilter> filters = newList();
+
+        StandardService pipeline = builder.build(
+                logger,
+                StandardService.class,
+                StandardFilter.class,
+                filters);
+
+        assertEquals(pipeline.run(99), 0);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java
new file mode 100644
index 0000000..2661382
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java
@@ -0,0 +1,482 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.annotation.Scope;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.internal.util.Pair;
+import org.apache.tapestry.ioc.internal.util.StringLongPair;
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+import org.testng.annotations.Test;
+
+import java.awt.*;
+import java.beans.*;
+import java.util.Arrays;
+import java.util.Random;
+
+public class PropertyAccessImplTest extends IOCInternalTestCase
+{
+    private static final String CLASS_NAME = PropertyAccessImplTest.class.getName();
+
+    private PropertyAccess access = new PropertyAccessImpl();
+
+    private Random random = new Random();
+
+    public static class Bean
+    {
+        private int value;
+
+        public int getValue()
+        {
+            return value;
+        }
+
+        public void setValue(int value)
+        {
+            this.value = value;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PropertyUtilsTestBean";
+        }
+
+        public void setWriteOnly(boolean b)
+        {
+        }
+
+        public String getReadOnly()
+        {
+            return null;
+        }
+    }
+
+    public static class ExceptionBean
+    {
+        public boolean getFailure()
+        {
+            throw new RuntimeException("getFailure");
+        }
+
+        public void setFailure(boolean b)
+        {
+            throw new RuntimeException("setFailure");
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PropertyUtilsExceptionBean";
+        }
+    }
+
+    public static class UglyBean
+    {
+    }
+
+    public static class UglyBeanBeanInfo implements BeanInfo
+    {
+
+        public BeanInfo[] getAdditionalBeanInfo()
+        {
+            return new BeanInfo[0];
+        }
+
+        public BeanDescriptor getBeanDescriptor()
+        {
+            return null;
+        }
+
+        public int getDefaultEventIndex()
+        {
+            return 0;
+        }
+
+        public int getDefaultPropertyIndex()
+        {
+            return 0;
+        }
+
+        public EventSetDescriptor[] getEventSetDescriptors()
+        {
+            return new EventSetDescriptor[0];
+        }
+
+        public Image getIcon(int iconKind)
+        {
+            return null;
+        }
+
+        public MethodDescriptor[] getMethodDescriptors()
+        {
+            return new MethodDescriptor[0];
+        }
+
+        public PropertyDescriptor[] getPropertyDescriptors()
+        {
+            throw new RuntimeException("This is the UglyBean.");
+        }
+
+    }
+
+    public static class BooleanHolder
+    {
+        private boolean flag;
+
+        public boolean isFlag()
+        {
+            return flag;
+        }
+
+        public void setFlag(boolean flag)
+        {
+            this.flag = flag;
+        }
+    }
+
+    @Test
+    public void simple_read_access()
+    {
+        Bean b = new Bean();
+
+        int value = random.nextInt();
+
+        b.setValue(value);
+
+        assertEquals(access.get(b, "value"), value);
+    }
+
+    @Test
+    public void property_name_case_is_ignored_on_read()
+    {
+        Bean b = new Bean();
+
+        int value = random.nextInt();
+
+        b.setValue(value);
+
+        assertEquals(access.get(b, "VALUE"), value);
+    }
+
+    @Test
+    public void simple_write_access()
+    {
+        Bean b = new Bean();
+
+        int value = random.nextInt();
+
+        access.set(b, "value", value);
+
+        assertEquals(b.getValue(), value);
+    }
+
+    @Test
+    public void property_name_case_is_ignored_on_write()
+    {
+        Bean b = new Bean();
+
+        int value = random.nextInt();
+
+        access.set(b, "VALUE", value);
+
+        assertEquals(b.getValue(), value);
+    }
+
+    @Test
+    public void missing_property()
+    {
+        Bean b = new Bean();
+
+        try
+        {
+            access.get(b, "zaphod");
+
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class " + CLASS_NAME + "$Bean does not " + "contain a property named 'zaphod'.");
+        }
+    }
+
+    @Test
+    public void attempt_to_update_read_only_property()
+    {
+        Bean b = new Bean();
+
+        try
+        {
+            access.set(b, "class", null);
+            unreachable();
+        }
+        catch (UnsupportedOperationException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class " + CLASS_NAME + "$Bean does not provide an mutator ('setter') method for property 'class'.");
+        }
+    }
+
+    @Test
+    public void attempt_to_read_from_write_only_property()
+    {
+        Bean b = new Bean();
+
+        try
+        {
+            access.get(b, "writeOnly");
+            unreachable();
+        }
+        catch (UnsupportedOperationException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class " + CLASS_NAME + "$Bean does not provide an accessor ('getter') method for property 'writeOnly'.");
+        }
+    }
+
+    @Test
+    public void exception_thrown_inside_getter()
+    {
+        ExceptionBean b = new ExceptionBean();
+
+        try
+        {
+            access.get(b, "failure");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Error reading property 'failure' of PropertyUtilsExceptionBean: getFailure");
+        }
+    }
+
+    @Test
+    public void exception_thrown_inside_setter()
+    {
+        ExceptionBean b = new ExceptionBean();
+
+        try
+        {
+            access.set(b, "failure", false);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Error updating property 'failure' of PropertyUtilsExceptionBean: setFailure");
+        }
+    }
+
+    @Test
+    public void failure_when_introspecting_class()
+    {
+        UglyBean b = new UglyBean();
+
+        try
+        {
+            access.get(b, "google");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "java.lang.RuntimeException: This is the UglyBean.");
+        }
+    }
+
+    @Test
+    public void clear_wipes_internal_cache()
+    {
+        ClassPropertyAdapter cpa1 = access.getAdapter(Bean.class);
+
+        assertSame(cpa1.getBeanType(), Bean.class);
+
+        ClassPropertyAdapter cpa2 = access.getAdapter(Bean.class);
+
+        assertSame(cpa2, cpa1);
+
+        access.clearCache();
+
+        ClassPropertyAdapter cpa3 = access.getAdapter(Bean.class);
+
+        assertNotSame(cpa3, cpa1);
+    }
+
+    @Test
+    public void class_property_adapter_toString()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+
+        assertEquals(cpa.toString(),
+                     "<ClassPropertyAdaptor " + CLASS_NAME + "$Bean : class, readOnly, value, writeOnly>");
+    }
+
+    @Test
+    public void property_adapter_read_only_property()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+        PropertyAdapter pa = cpa.getPropertyAdapter("readOnly");
+
+        assertTrue(pa.isRead());
+        assertFalse(pa.isUpdate());
+        assertFalse(pa.isCastRequired());
+
+        assertNull(pa.getWriteMethod());
+        assertEquals(pa.getReadMethod(), findMethod(Bean.class, "getReadOnly"));
+    }
+
+    @Test
+    public void property_adapter_write_only_property()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+        PropertyAdapter pa = cpa.getPropertyAdapter("writeOnly");
+
+        assertFalse(pa.isRead());
+        assertTrue(pa.isUpdate());
+
+        assertEquals(pa.getWriteMethod(), findMethod(Bean.class, "setWriteOnly"));
+        assertNull(pa.getReadMethod());
+    }
+
+    @Test
+    public void class_property_adapter_returns_null_for_unknown_property()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+
+        assertNull(cpa.getPropertyAdapter("google"));
+    }
+
+    @Test
+    public void access_to_property_type()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+
+        assertEquals(cpa.getPropertyAdapter("value").getType(), int.class);
+        assertEquals(cpa.getPropertyAdapter("readOnly").getType(), String.class);
+        assertEquals(cpa.getPropertyAdapter("writeOnly").getType(), boolean.class);
+    }
+
+    @Test
+    public void property_names()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(Bean.class);
+
+        assertEquals(cpa.getPropertyNames(), Arrays.asList("class", "readOnly", "value", "writeOnly"));
+    }
+
+    @Test
+    public void integration()
+    {
+        Registry registry = buildRegistry();
+
+        PropertyAccess pa = registry.getService("PropertyAccess", PropertyAccess.class);
+
+        Bean b = new Bean();
+
+        int value = random.nextInt();
+
+        pa.set(b, "value", value);
+
+        assertEquals(b.getValue(), value);
+
+        registry.shutdown();
+    }
+
+    @Test
+    public void super_interface_methods_inherited_by_sub_interface()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(SubInterface.class);
+
+        assertEquals(cpa.getPropertyNames(), Arrays.asList("grandParentProperty", "parentProperty", "subProperty"));
+    }
+
+    @Test
+    public void indexed_properties_are_ignored()
+    {
+        ClassPropertyAdapter cpa = access.getAdapter(BeanWithIndexedProperty.class);
+
+        assertEquals(cpa.getPropertyNames(), Arrays.asList("class", "primitiveProperty"));
+    }
+
+    @Test
+    public void get_annotation_when_annotation_not_present()
+    {
+        PropertyAdapter pa = access.getAdapter(AnnotatedBean.class)
+                .getPropertyAdapter("readWrite");
+
+        assertNull(pa.getAnnotation(Scope.class));
+    }
+
+    @Test
+    public void get_annotation_with_annotation_on_write_method()
+    {
+        PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("annotationOnWrite");
+
+        Scope annotation = pa.getAnnotation(Scope.class);
+        assertNotNull(annotation);
+
+        assertEquals(annotation.value(), "onwrite");
+    }
+
+    @Test
+    public void read_method_annotation_overrides_write_method_annotation()
+    {
+        PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("annotationOnRead");
+
+        Scope annotation = pa.getAnnotation(Scope.class);
+        assertNotNull(annotation);
+
+        assertEquals(annotation.value(), "onread");
+    }
+
+    @Test
+    public void no_write_method_reading_missing_annotation()
+    {
+        PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("readOnly");
+
+        assertNull(pa.getAnnotation(Scope.class));
+    }
+
+    @Test
+    public void using_generics()
+    {
+        ClassPropertyAdapter cpa1 = access.getAdapter(StringLongPair.class);
+
+        PropertyAdapter pa1 = cpa1.getPropertyAdapter("key");
+        assertSame(pa1.getType(), String.class);
+        assertTrue(pa1.isCastRequired());
+
+        PropertyAdapter pa2 = cpa1.getPropertyAdapter("value");
+        assertSame(pa2.getType(), Long.class);
+        assertTrue(pa2.isCastRequired());
+
+        // On the base class, which defines the generic parameter type variables,
+        // the properties just look like Object.
+
+        ClassPropertyAdapter cpa2 = access.getAdapter(Pair.class);
+
+        pa1 = cpa2.getPropertyAdapter("key");
+        assertSame(pa1.getType(), Object.class);
+        assertFalse(pa1.isCastRequired());
+
+        pa2 = cpa2.getPropertyAdapter("value");
+        assertSame(pa2.getType(), Object.class);
+        assertFalse(pa2.isCastRequired());
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImplTest.java
new file mode 100644
index 0000000..524dd05
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryShutdownHubImplTest.java
@@ -0,0 +1,89 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import static org.easymock.EasyMock.contains;
+import static org.easymock.EasyMock.same;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+public class RegistryShutdownHubImplTest extends IOCInternalTestCase
+{
+
+    @Test
+    public void add_and_notify()
+    {
+        RegistryShutdownListener l1 = mockListener();
+        RegistryShutdownListener l2 = mockListener();
+        Logger logger = mockLogger();
+
+        l1.registryDidShutdown();
+        l2.registryDidShutdown();
+
+        replay();
+
+        RegistryShutdownHubImpl hub = new RegistryShutdownHubImpl(logger);
+
+        hub.addRegistryShutdownListener(l1);
+        hub.addRegistryShutdownListener(l2);
+
+        hub.fireRegistryDidShutdown();
+
+        verify();
+    }
+
+    /**
+     * Shows that multiple listener will be notified, and that an error in one doesn't prevent
+     * others from being notified.
+     */
+    @Test
+    public void notification_error()
+    {
+        RegistryShutdownListener l1 = mockListener();
+        RegistryShutdownListener l2 = mockListener();
+        RegistryShutdownListener l3 = mockListener();
+
+        Logger logger = mockLogger();
+
+        Throwable t = new RuntimeException("Shutdown failure.");
+
+        l1.registryDidShutdown();
+        l2.registryDidShutdown();
+        setThrowable(t);
+
+        logger.error(contains("Shutdown failure."), same(t));
+
+        l3.registryDidShutdown();
+
+        replay();
+
+        RegistryShutdownHubImpl hub = new RegistryShutdownHubImpl(logger);
+
+        hub.addRegistryShutdownListener(l1);
+        hub.addRegistryShutdownListener(l2);
+        hub.addRegistryShutdownListener(l3);
+
+        hub.fireRegistryDidShutdown();
+
+        verify();
+    }
+
+    private RegistryShutdownListener mockListener()
+    {
+        return newMock(RegistryShutdownListener.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryStartupTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryStartupTest.java
new file mode 100644
index 0000000..38b6f0e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryStartupTest.java
@@ -0,0 +1,136 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+public class RegistryStartupTest extends IOCTestCase
+{
+    /**
+     * Runnable runs.
+     */
+    @Test
+    public void success()
+    {
+        List<Runnable> configuration = CollectionFactory.newList();
+
+        Runnable r1 = newMock(Runnable.class);
+        Runnable r2 = newMock(Runnable.class);
+
+        configuration.add(r1);
+        configuration.add(r2);
+
+        Logger logger = mockLogger();
+
+        getMocksControl().checkOrder(true);
+
+        r1.run();
+        r2.run();
+
+        replay();
+
+        Runnable startup = new RegistryStartup(logger, configuration);
+
+        startup.run();
+
+        verify();
+
+        // The configuration is cleared out at the end of the execution.
+        assertTrue(configuration.isEmpty());
+    }
+
+    @Test
+    public void failure_is_logged_but_execution_continues()
+    {
+        List<Runnable> configuration = CollectionFactory.newList();
+        RuntimeException t = new RuntimeException("Runnable r1 has been a naughty boy.");
+
+        Runnable r1 = newMock(Runnable.class);
+        Runnable r2 = newMock(Runnable.class);
+
+        configuration.add(r1);
+        configuration.add(r2);
+
+        Logger logger = mockLogger();
+
+        getMocksControl().checkOrder(true);
+
+        r1.run();
+
+        getMocksControl().andThrow(t);
+
+        logger.error(ServiceMessages.startupFailure(t));
+
+        r2.run();
+
+        replay();
+
+        Runnable startup = new RegistryStartup(logger, configuration);
+
+        startup.run();
+
+        verify();
+    }
+
+    @Test
+    public void run_may_only_be_called_once()
+    {
+        Logger logger = mockLogger();
+        List<Runnable> configuration = CollectionFactory.newList();
+
+        replay();
+
+        Runnable startup = new RegistryStartup(logger, configuration);
+
+        startup.run();
+
+        try
+        {
+            startup.run();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertMessageContains(ex, "Method org.apache.tapestry.ioc.internal.services.RegistryStartup.run(",
+                                  "may no longer be invoked.");
+
+        }
+
+        verify();
+    }
+
+    @Test
+    public void integration()
+    {
+        Registry r = buildRegistry(StartupModule.class);
+
+        assertFalse(StartupModule.startupInvoked);
+
+        r.performRegistryStartup();
+
+        assertTrue(StartupModule.startupInvoked);
+
+        // Ideally we'd have a way to show that the PerthreadManager was notified after
+        // RegistryStartup did its thing, but ...
+
+        r.shutdown();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleFilter.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleFilter.java
new file mode 100644
index 0000000..afc5f91
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleFilter.java
@@ -0,0 +1,31 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.FilterMethodAnalyzer}.
+ */
+public interface SampleFilter
+{
+    public void simpleMatch(SampleService service);
+
+    public void mismatchParameterCount(int a, SampleService service);
+
+    public int mismatchReturnType(SampleService service);
+
+    public void missingServiceInterface(boolean flag);
+
+    public void complexMatch(String title, int count, SampleService service, Runnable r);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleService.java
new file mode 100644
index 0000000..d13a45c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SampleService.java
@@ -0,0 +1,31 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.FilterMethodAnalyzer}.
+ */
+public interface SampleService
+{
+    public void simpleMatch();
+
+    public void mismatchParameterCount();
+
+    public String mismatchReturnType();
+
+    public void missingServiceInterface();
+
+    public void complexMatch(String title, int count, Runnable r);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SimpleService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SimpleService.java
new file mode 100644
index 0000000..151ab64
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SimpleService.java
@@ -0,0 +1,23 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Used by {@link org.apache.tapestry.ioc.internal.services.ClassFabImplTest}.
+ */
+public interface SimpleService
+{
+    public int add(int a, int b);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardFilter.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardFilter.java
new file mode 100644
index 0000000..73b60ee
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardFilter.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface StandardFilter
+{
+    public int run(int i, StandardService service);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardService.java
new file mode 100644
index 0000000..17e7a60
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StandardService.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface StandardService
+{
+    public int run(int i);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StartupModule.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StartupModule.java
new file mode 100644
index 0000000..bdd1610
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StartupModule.java
@@ -0,0 +1,35 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.OrderedConfiguration;
+
+public class StartupModule
+{
+    public static boolean startupInvoked;
+
+    public static void contributeRegistryStartup(OrderedConfiguration<Runnable> configuration)
+    {
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                startupInvoked = true;
+            }
+        };
+
+        configuration.add("Contribution", r);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImplTest.java
new file mode 100644
index 0000000..6d1c7d3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StrategyBuilderImplTest.java
@@ -0,0 +1,80 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.services.StrategyBuilder;
+import org.apache.tapestry.ioc.util.StrategyRegistry;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class StrategyBuilderImplTest extends IOCInternalTestCase
+{
+    private static class KindOfImpl implements KindOf
+    {
+        private final String value;
+
+        public KindOfImpl(final String value)
+        {
+            this.value = value;
+        }
+
+        public String kindOf(Object value)
+        {
+            return this.value;
+        }
+
+    }
+
+    @Test
+    public void standard()
+    {
+        StrategyRegistry<KindOf> registry = buildStrategyRegistry();
+
+        StrategyBuilder builder = getService(StrategyBuilder.class);
+
+        KindOf service = builder.build(registry);
+
+        assertEquals(service.kindOf(Collections.EMPTY_MAP), "MAP");
+        assertEquals(service.kindOf(Collections.EMPTY_LIST), "LIST");
+
+        assertEquals(service.toString(), "<Strategy for org.apache.tapestry.ioc.internal.services.KindOf>");
+
+        try
+        {
+            service.kindOf(null);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "No adapter from type void to type org.apache.tapestry.ioc.internal.services.KindOf is available (registered types are java.util.List, java.util.Map).");
+        }
+    }
+
+    private StrategyRegistry<KindOf> buildStrategyRegistry()
+    {
+        Map<Class, KindOf> registrations = newMap();
+
+        registrations.put(Map.class, new KindOfImpl("MAP"));
+        registrations.put(List.class, new KindOfImpl("LIST"));
+
+        return StrategyRegistry.newInstance(KindOf.class, registrations);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StringLocationTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StringLocationTest.java
new file mode 100644
index 0000000..0214c89
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/StringLocationTest.java
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.Location;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class StringLocationTest extends Assert
+{
+    @Test
+    public void thats_all_there_is_folks()
+    {
+        String description = "location description";
+        int line = 99;
+
+        Location l = new StringLocation(description, line);
+
+        assertEquals(l.toString(), description);
+        assertEquals(l.getLine(), line);
+        assertEquals(l.getColumn(), 0);
+        assertNull(l.getResource());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java
new file mode 100644
index 0000000..a842e57
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface SubInterface extends ParentInterface
+{
+    String getSubProperty();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProviderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProviderTest.java
new file mode 100644
index 0000000..2d1645f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolObjectProviderTest.java
@@ -0,0 +1,123 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Symbol;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+
+public class SymbolObjectProviderTest extends IOCTestCase
+{
+    @Test
+    public void no_annotation()
+    {
+        SymbolSource source = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+
+        train_getAnnotation(annotationProvider, Symbol.class, null);
+
+        replay();
+
+        ObjectProvider provider = new SymbolObjectProvider(source, coercer);
+
+        assertNull(provider.provide(Long.class, annotationProvider, locator));
+
+        verify();
+    }
+
+    @Test
+    public void annotation_present()
+    {
+        SymbolSource source = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        String symbolName = "example-symbol";
+        String symbolValue = "symbol-value";
+        Long coercedValue = 123l;
+        Symbol annotation = newSymbol(symbolName);
+
+        train_getAnnotation(annotationProvider, Symbol.class, annotation);
+        train_getAnnotation(annotationProvider, IntermediateType.class, null);
+
+        train_valueForSymbol(source, symbolName, symbolValue);
+
+        train_coerce(coercer, symbolValue, Long.class, coercedValue);
+
+        replay();
+
+        ObjectProvider provider = new SymbolObjectProvider(source, coercer);
+
+        assertSame(provider.provide(Long.class, annotationProvider, locator), coercedValue);
+
+        verify();
+    }
+
+    @Test
+    public void intermediate_type()
+    {
+        SymbolSource source = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        String symbolName = "example-symbol";
+        String symbolValue = "symbol-value";
+        Long coercedValue = 123l;
+        Symbol annotation = newSymbol(symbolName);
+        IntermediateType it = newIntermediateType();
+        BigInteger intervalue = new BigInteger("123");
+
+        train_getAnnotation(annotationProvider, Symbol.class, annotation);
+        train_getAnnotation(annotationProvider, IntermediateType.class, it);
+
+        train_valueForSymbol(source, symbolName, symbolValue);
+
+        expect(it.value()).andReturn(BigInteger.class);
+
+        train_coerce(coercer, symbolValue, BigInteger.class, intervalue);
+        train_coerce(coercer, intervalue, Long.class, coercedValue);
+
+        replay();
+
+        ObjectProvider provider = new SymbolObjectProvider(source, coercer);
+
+        assertSame(provider.provide(Long.class, annotationProvider, locator), coercedValue);
+
+        verify();
+
+    }
+
+    private Symbol newSymbol(String symbolName)
+    {
+        Symbol annotation = newMock(Symbol.class);
+        expect(annotation.value()).andReturn(symbolName);
+        return annotation;
+    }
+
+    protected final void train_valueForSymbol(SymbolSource source, String symbolName, String symbolValue)
+    {
+        expect(source.valueForSymbol(symbolName)).andReturn(symbolValue);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImplTest.java
new file mode 100644
index 0000000..1cbe5c3
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/SymbolSourceImplTest.java
@@ -0,0 +1,307 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.SymbolProvider;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class SymbolSourceImplTest extends IOCInternalTestCase
+{
+    @Test
+    public void expand_symbols_no_symbols_present()
+    {
+        String input = "A jolly good time.";
+
+        List<SymbolProvider> providers = Collections.emptyList();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        // Not just equal, but the same.
+
+        assertSame(source.expandSymbols(input), input);
+    }
+
+    @Test
+    public void simple_expansions()
+    {
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "barney", "Barney");
+        train_valueForSymbol(provider, "dino", "Dino");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        assertEquals(
+                source.expandSymbols("Fred's friends are ${barney} and ${dino}."),
+                "Fred's friends are Barney and Dino.");
+
+        verify();
+    }
+
+    @Test
+    public void undefined_symbol()
+    {
+
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "barney", null);
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        try
+        {
+            source.valueForSymbol("barney");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Symbol 'barney' is not defined.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void missing_brace()
+    {
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        try
+        {
+            source.expandSymbols("Unmatched ${this");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Input string 'Unmatched ${this' is missing a symbol closing brace.");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void indirect_expansions()
+    {
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "fred.friends", "${barney} and ${dino}");
+        train_valueForSymbol(provider, "barney", "Barney");
+        train_valueForSymbol(provider, "dino", "Dino");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        assertEquals(
+                source.expandSymbols("Fred's friends are ${fred.friends}."),
+                "Fred's friends are Barney and Dino.");
+
+        verify();
+    }
+
+    @Test
+    public void undefined_symbol_in_path()
+    {
+
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "barney", "Barney (whose friends are ${barney.friends})");
+        train_valueForSymbol(provider, "barney.friends", "${fred} and ${betty}");
+        train_valueForSymbol(provider, "fred", null);
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        try
+        {
+            source.valueForSymbol("barney");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Symbol 'fred' is not defined (in barney --> barney.friends --> fred). ");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void missing_brace_in_path()
+    {
+
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "barney", "Barney (whose friends are ${barney.friends})");
+        train_valueForSymbol(provider, "barney.friends", "${fred} and ${betty");
+        train_valueForSymbol(provider, "fred", "Fred");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        try
+        {
+            source.valueForSymbol("barney");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Input string '${fred} and ${betty' is missing a symbol closing brace (in barney --> barney.friends).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void providers_searched_in_order()
+    {
+        SymbolProvider provider1 = mockSymbolProvider();
+        SymbolProvider provider2 = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider1, provider2);
+
+        train_valueForSymbol(provider1, "fred.friends", "${barney} and ${dino}");
+        train_valueForSymbol(provider1, "barney", null);
+        train_valueForSymbol(provider2, "barney", "Barney");
+        train_valueForSymbol(provider1, "dino", null);
+        train_valueForSymbol(provider2, "dino", "Dino");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        assertEquals(
+                source.expandSymbols("Fred's friends are ${fred.friends}."),
+                "Fred's friends are Barney and Dino.");
+
+        verify();
+    }
+
+    @Test
+    public void symbols_are_cached()
+    {
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "fred", "Fred's friends are ${barney} and ${dino}.");
+        train_valueForSymbol(provider, "barney", "Barney");
+        train_valueForSymbol(provider, "dino", "Dino");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        assertEquals(source.valueForSymbol("fred"), "Fred's friends are Barney and Dino.");
+
+        verify();
+
+        replay();
+
+        // This time, comes out of the cache.
+
+        assertEquals(source.valueForSymbol("fred"), "Fred's friends are Barney and Dino.");
+
+        verify();
+    }
+
+    @Test
+    public void recursive_symbols_fail()
+    {
+        SymbolProvider provider = mockSymbolProvider();
+
+        List<SymbolProvider> providers = Arrays.asList(provider);
+
+        train_valueForSymbol(provider, "fred", "Fred (whose friends are ${fred.friends})");
+        train_valueForSymbol(provider, "fred.friends", "${barney} and ${dino}");
+        train_valueForSymbol(provider, "barney", "Barney (whose friends are ${barney.friends})");
+        train_valueForSymbol(provider, "barney.friends", "${fred} and ${betty}");
+
+        replay();
+
+        SymbolSource source = new SymbolSourceImpl(providers);
+
+        try
+        {
+            source.valueForSymbol("fred");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Symbol 'fred' is defined in terms of itself (fred --> fred.friends --> barney --> barney.friends --> fred).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void integration_test()
+    {
+        SymbolSource source = getService(SymbolSource.class);
+
+        // SystemPropertiesSymbolProvider is available by default
+
+        String userName = System.getProperty("user.name");
+
+        assertEquals(source.valueForSymbol("user.name"), userName);
+    }
+
+    protected final void train_valueForSymbol(SymbolProvider provider, String symbolName,
+                                              String value)
+    {
+        expect(provider.valueForSymbol(symbolName)).andReturn(value);
+    }
+
+    protected final SymbolProvider mockSymbolProvider()
+    {
+        return newMock(SymbolProvider.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TargetBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TargetBean.java
new file mode 100644
index 0000000..b49922d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TargetBean.java
@@ -0,0 +1,46 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+/**
+ * Used by {@link ClassFactoryImplTest}.
+ */
+public class TargetBean
+{
+    private String firstName;
+
+    private String lastName;
+
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImplTest.java
new file mode 100644
index 0000000..f30b960
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ThreadLocaleImplTest.java
@@ -0,0 +1,73 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.ThreadLocale;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class ThreadLocaleImplTest extends IOCInternalTestCase
+{
+    private ThreadLocale threadLocale;
+
+    private static final Locale FAKE_LOCALE1 = new Locale("klingon");
+
+    private static final Locale FAKE_LOCALE2 = new Locale("ferrengi");
+
+    @BeforeClass
+    public void setup()
+    {
+        threadLocale = getService(ThreadLocale.class);
+    }
+
+    @Test
+    public void different_threads_track_different_values() throws InterruptedException
+    {
+        final Locale initial = threadLocale.getLocale();
+
+        threadLocale.setLocale(FAKE_LOCALE1);
+
+        assertSame(threadLocale.getLocale(), FAKE_LOCALE1);
+
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                assertSame(threadLocale.getLocale(), initial);
+            }
+        };
+
+        Thread t = new Thread(r);
+
+        t.start();
+        t.join();
+
+        cleanupThread();
+    }
+
+    public void thread_locale_reverts_after_cleanup()
+    {
+        Locale initial = threadLocale.getLocale();
+
+        threadLocale.setLocale(FAKE_LOCALE2);
+
+        cleanupThread();
+
+        assertSame(threadLocale.getLocale(), initial);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringFilter.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringFilter.java
new file mode 100644
index 0000000..f2dce1c
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringFilter.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ToStringFilter
+{
+    public String toString(ToStringService service);
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringService.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringService.java
new file mode 100644
index 0000000..5687ffd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ToStringService.java
@@ -0,0 +1,20 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+public interface ToStringService
+{
+    public String toString();
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImplTest.java
new file mode 100644
index 0000000..a24640d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/TypeCoercerImplTest.java
@@ -0,0 +1,258 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.util.TimeInterval;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.xml.sax.XMLReader;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+public class TypeCoercerImplTest extends IOCInternalTestCase
+{
+    private TypeCoercer coercer;
+
+    @BeforeClass
+    public void setup_coercer()
+    {
+        coercer = getService(TypeCoercer.class);
+    }
+
+    @AfterClass
+    public void cleanup_coercer()
+    {
+        coercer = null;
+    }
+
+    @Test
+    public void builtin_coercion()
+    {
+        // String to Double
+
+        assertEquals(coercer.coerce("-15", Double.class), new Double(-15));
+
+        // Now a second pass through, to exercise the internal cache
+
+        assertEquals(coercer.coerce("2.27", Double.class), new Double(2.27));
+    }
+
+    @Test
+    public void primitive_type_as_target()
+    {
+        assertEquals(coercer.coerce(227l, int.class), new Integer(227));
+    }
+
+    @Test
+    public void no_coercion_necessary()
+    {
+        Object input = new Integer(-37);
+
+        assertSame(coercer.coerce(input, Number.class), input);
+    }
+
+    @Test
+    public void combined_coercion()
+    {
+        StringBuilder builder = new StringBuilder("12345");
+
+        // This should trigger Object -> String, String -> Integer
+
+        assertEquals(coercer.coerce(builder, int.class), new Integer(12345));
+
+        // This should trigger String -> Double, Number -> Integer
+
+        assertEquals(coercer.coerce("52", Integer.class), new Integer(52));
+    }
+
+    @Test
+    public void no_coercion_found()
+    {
+        try
+        {
+            coercer.coerce("", Map.class);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertTrue(ex.getMessage().contains(
+                    "Could not find a coercion from type java.lang.String to type java.util.Map"));
+        }
+    }
+
+    @Test
+    public void coercion_failure()
+    {
+        try
+        {
+            coercer.coerce(Collections.EMPTY_MAP, Float.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertTrue(ex
+                    .getMessage()
+                    .contains(
+                    "Coercion of {} to type java.lang.Float (via Object --> String, String --> Double, Double --> Float) failed"));
+            assertTrue(ex.getCause() instanceof NumberFormatException);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test(dataProvider = "coercions_inputs")
+    public void builtin_coercions(Object input, Class targetType, Object expected)
+    {
+        Object actual = coercer.coerce(input, targetType);
+
+        assertEquals(actual, expected);
+    }
+
+    @SuppressWarnings("unchecked")
+    @DataProvider(name = "coercions_inputs")
+    public Object[][] coercions_inputs()
+    {
+        String bigDecimalValue = "12345656748352435842385234598234958234574358723485.35843534285293857298457234587";
+        String bigIntegerValue = "12384584574874385743";
+
+        Object object = new Object();
+        // Over time, some of these may evolve from testing specific tuples to
+        // compound tuples (built around specific tuples).
+
+        Float floatValue = new Float(31.14);
+        byte byte1 = 12, byte2 = 56;
+        short short1 = 34, short2 = 98;
+        return new Object[][] {
+                // There's a lot of these!
+
+                { this, String.class, toString() },
+
+                { 55l, Integer.class, 55 },
+
+                { "", Boolean.class, false },
+
+                { "  ", Boolean.class, false },
+
+                { "x", Boolean.class, true },
+
+                { " z ", Boolean.class, true },
+
+                { "false", Boolean.class, false },
+
+                { "  False ", Boolean.class, false },
+
+                { null, Boolean.class, false },
+
+                { new Double(256), Integer.class, new Integer(256) },
+
+                { new Double(22.7), Integer.class, new Integer(22) },
+
+                { new Integer(0), Boolean.class, false },
+
+                { new Long(32838), Boolean.class, true },
+
+                { new Integer(127), Byte.class, new Byte("127") },
+
+                { new Double(58), Short.class, new Short("58") },
+
+                { new Integer(33), Long.class, new Long(33) },
+
+                { new Integer(22), Float.class, new Float(22) },
+
+                { new Integer(1234), Double.class, new Double(1234) },
+
+                { floatValue, Double.class, floatValue.doubleValue() },
+
+                { Collections.EMPTY_LIST, Boolean.class, false },
+
+                { Collections.singleton(this), Boolean.class, true },
+
+                { bigDecimalValue, BigDecimal.class, new BigDecimal(bigDecimalValue) },
+
+                { new BigDecimal(bigDecimalValue), Double.class, 1.2345656748352436E49 },
+
+                { bigIntegerValue, BigInteger.class, new BigInteger(bigIntegerValue) },
+
+                { new BigInteger("12345678"), Long.class, 12345678l },
+
+                { -12345678l, BigInteger.class, new BigInteger("-12345678") },
+
+                { object, List.class, Collections.singletonList(object) },
+
+                { null, Iterable.class, null },
+
+                { null, List.class, null },
+
+                { null, Collection.class, null },
+
+                { null, String.class, null },
+
+                { new Object[] { "a", 123 }, List.class, Arrays.asList("a", 123) },
+
+                { new String[] { "a", "b" }, List.class, Arrays.asList("a", "b") },
+
+                { new byte[] { byte1, byte2 }, List.class, Arrays.asList(byte1, byte2) },
+
+                { new short[] { short1, short2 }, List.class, Arrays.asList(short1, short2) },
+
+                { new int[] { 1, 2 }, List.class, Arrays.asList(1, 2) },
+
+                { new long[] { 123L, 321L }, List.class, Arrays.asList(123L, 321L) },
+
+                { new float[] { 3.4f, 7.777f }, List.class, Arrays.asList(3.4f, 7.777f) },
+
+                { new double[] { 3.4, 7.777 }, List.class, Arrays.asList(3.4, 7.777) },
+
+                { new char[] { 'a', 'b' }, List.class, Arrays.asList('a', 'b') },
+
+                { new boolean[] { true, false }, List.class, Arrays.asList(true, false) },
+
+                { "foo/bar/baz.txt", File.class, new File("foo/bar/baz.txt") },
+
+                { new TimeInterval("2 h"), Long.class, 2 * 60 * 60 * 1000l },
+
+                { "2 h", TimeInterval.class, new TimeInterval("120 m") },
+
+                // null to arbitrary object is still null
+
+                { null, XMLReader.class, null } };
+    }
+
+    @Test(dataProvider = "explain_inputs")
+    public <S, T> void explain(Class<S> inputType, Class<T> outputType, String expected)
+    {
+        assertEquals(coercer.explain(inputType, outputType), expected);
+    }
+
+    @DataProvider(name = "explain_inputs")
+    public Object[][] explain_inputs()
+    {
+        return new Object[][] {
+                { StringBuffer.class, Integer.class, "Object --> String, String --> Long, Long --> Integer" },
+                { void.class, Map.class, "null --> null" }, { void.class, Boolean.class, "null --> Boolean" },
+                { String[].class, List.class, "Object[] --> java.util.List" },
+                { Float.class, Double.class, "Float --> Double" },
+                { Double.class, BigDecimal.class, "Object --> String, String --> java.math.BigDecimal" },
+
+        };
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ValueObjectProviderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ValueObjectProviderTest.java
new file mode 100644
index 0000000..676682f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/ValueObjectProviderTest.java
@@ -0,0 +1,120 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.services;
+
+import org.apache.tapestry.ioc.AnnotationProvider;
+import org.apache.tapestry.ioc.ObjectLocator;
+import org.apache.tapestry.ioc.annotation.IntermediateType;
+import org.apache.tapestry.ioc.annotation.Value;
+import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.math.BigDecimal;
+
+public class ValueObjectProviderTest extends IOCTestCase
+{
+    @Test
+    public void no_value_annotation()
+    {
+        SymbolSource symbolSource = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+
+        train_getAnnotation(annotationProvider, Value.class, null);
+
+        replay();
+
+        ValueObjectProvider provider = new ValueObjectProvider(symbolSource, coercer);
+
+        assertNull(provider.provide(Runnable.class, annotationProvider, locator));
+
+        verify();
+    }
+
+    @Test
+    public void value_annotation_present()
+    {
+        SymbolSource symbolSource = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        String annotationValue = "${foo}";
+        String expanded = "Foo";
+        Runnable coerced = mockRunnable();
+        Value annotation = newValue(annotationValue);
+
+        train_getAnnotation(annotationProvider, Value.class, annotation);
+
+        train_getAnnotation(annotationProvider, IntermediateType.class, null);
+
+        train_expandSymbols(symbolSource, annotationValue, expanded);
+        train_coerce(coercer, expanded, Runnable.class, coerced);
+
+        replay();
+
+        ValueObjectProvider provider = new ValueObjectProvider(symbolSource, coercer);
+
+        assertSame(provider.provide(Runnable.class, annotationProvider, locator), coerced);
+
+        verify();
+    }
+
+    @Test
+    public void intermediate_type()
+    {
+        SymbolSource symbolSource = mockSymbolSource();
+        TypeCoercer coercer = mockTypeCoercer();
+        AnnotationProvider annotationProvider = mockAnnotationProvider();
+        ObjectLocator locator = mockObjectLocator();
+        String annotationValue = "${foo}";
+        String expanded = "Foo";
+        Runnable coerced = mockRunnable();
+        Value annotation = newValue(annotationValue);
+        IntermediateType it = newIntermediateType();
+        BigDecimal intervalue = new BigDecimal("1234");
+
+        train_getAnnotation(annotationProvider, Value.class, annotation);
+
+        train_getAnnotation(annotationProvider, IntermediateType.class, it);
+
+        train_value(it, BigDecimal.class);
+
+        train_expandSymbols(symbolSource, annotationValue, expanded);
+        train_coerce(coercer, expanded, BigDecimal.class, intervalue);
+        train_coerce(coercer, intervalue, Runnable.class, coerced);
+
+        replay();
+
+        ValueObjectProvider provider = new ValueObjectProvider(symbolSource, coercer);
+
+        assertSame(provider.provide(Runnable.class, annotationProvider, locator), coerced);
+
+        verify();
+    }
+
+    private Value newValue(String value)
+    {
+        Value annotation = newMock(Value.class);
+
+        expect(annotation.value()).andReturn(value);
+
+        return annotation;
+    }
+
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Bar.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Bar.java
new file mode 100644
index 0000000..9636cb2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Bar.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public interface Bar

+{

+    void bar();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BarImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BarImpl.java
new file mode 100644
index 0000000..142fc2b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BarImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public class BarImpl implements Bar

+{

+

+    public void bar()

+    {

+

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BaseGenericBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BaseGenericBean.java
new file mode 100644
index 0000000..e16cb32
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/BaseGenericBean.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+public class BaseGenericBean<T>
+{
+    private T value;
+
+    public T getValue()
+    {
+        return value;
+    }
+
+    public void setValue(T value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ClasspathResourceTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ClasspathResourceTest.java
new file mode 100644
index 0000000..c87c6e5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ClasspathResourceTest.java
@@ -0,0 +1,251 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Resource;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Locale;
+
+public class ClasspathResourceTest extends Assert
+{
+    private static final String RESOURCE_TXT_CONTENT = "content from resource.txt";
+
+    private static final String FOLDER = "org/apache/tapestry/ioc/internal/util";
+
+    private static final String PATH = FOLDER + "/resource.txt";
+
+    @Test
+    public void get_resource_URL() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        assertEquals(content(r), RESOURCE_TXT_CONTENT);
+    }
+
+    @Test
+    public void relative_to_root_resource() throws Exception
+    {
+        Resource r = new ClasspathResource("").forFile(PATH);
+
+        assertEquals(content(r), RESOURCE_TXT_CONTENT);
+    }
+
+    @Test
+    public void relative_to_root_resource_using_leading_slash() throws Exception
+    {
+        Resource r = new ClasspathResource("/").forFile(PATH);
+
+        assertEquals(content(r), RESOURCE_TXT_CONTENT);
+    }
+
+    @Test
+    public void leading_slash_on_path_relative_to_root_doesnt_matter() throws Exception
+    {
+        Resource r = new ClasspathResource("/").forFile("/" + PATH);
+
+        assertEquals(content(r), RESOURCE_TXT_CONTENT);
+    }
+
+    @Test
+    public void path_and_file()
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        assertEquals(r.getFolder(), FOLDER);
+        assertEquals(r.getFile(), "resource.txt");
+
+    }
+
+    @Test
+    public void for_file_in_same_folder() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource n = r.forFile("same-folder.txt");
+
+        assertEquals(content(n), "content from same-folder resource");
+    }
+
+    @Test
+    public void for_file_single_dot() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource n = r.forFile("./same-folder.txt");
+
+        assertEquals(content(n), "content from same-folder resource");
+    }
+
+    @Test
+    public void multiple_slashes_treated_as_single_slash() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource n = r.forFile("././/.///same-folder.txt");
+
+        assertEquals(content(n), "content from same-folder resource");
+    }
+
+    @Test
+    public void for_file_in_subfolder() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource n = r.forFile("sub/sub-folder.txt");
+
+        assertEquals(content(n), "content from sub-folder resource");
+    }
+
+    @Test
+    public void for_file_same_resource() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        assertSame(r.forFile("../util/resource.txt"), r);
+    }
+
+    @Test
+    public void for_file_in_parent_folder() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource n = r.forFile("../parent-folder.txt");
+
+        assertEquals(content(n), "content from parent-folder resource");
+    }
+
+    @Test
+    public void to_string() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        assertEquals(r.toString(), "classpath:" + PATH);
+    }
+
+    @Test
+    public void get_URL_for_missing_resource() throws Exception
+    {
+        Resource r = new ClasspathResource(FOLDER + "/missing-resource.txt");
+
+        assertNull(r.toURL());
+    }
+
+    @Test
+    public void localization_of_resource() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource l = r.forLocale(Locale.FRENCH);
+
+        assertEquals(content(l), "french content");
+    }
+
+    @Test
+    public void localization_to_closest_match() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource l = r.forLocale(Locale.CANADA_FRENCH);
+
+        assertEquals(content(l), "french content");
+    }
+
+    @Test
+    public void localization_to_base_resource() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        Resource l = r.forLocale(Locale.JAPANESE);
+
+        assertSame(l, r);
+    }
+
+    @Test
+    public void with_extension_same_extension()
+    {
+        Resource r = new ClasspathResource(PATH);
+
+        assertSame(r.withExtension("txt"), r);
+    }
+
+    @Test
+    public void with_extension() throws Exception
+    {
+        Resource r = new ClasspathResource(PATH);
+        Resource e = r.withExtension("ext");
+
+        assertEquals(content(e), "ext content");
+    }
+
+    @Test
+    public void with_extension_adds_extension() throws Exception
+    {
+        Resource r = new ClasspathResource(FOLDER + "/resource");
+        Resource e = r.withExtension("ext");
+
+        assertEquals(content(e), "ext content");
+    }
+
+    @Test
+    public void with_extension_missing_resource_is_null()
+    {
+        Resource r = new ClasspathResource(PATH);
+        Resource e = r.withExtension("does-not-exist");
+
+        assertNull(e.toURL());
+    }
+
+    @Test
+    public void localization_of_missing_resource() throws Exception
+    {
+        Resource r = new ClasspathResource(FOLDER + "/missing-resource.txt");
+
+        assertNull(r.forLocale(Locale.FRENCH));
+    }
+
+    private String content(Resource resource) throws Exception
+    {
+        return content(resource.toURL());
+    }
+
+    private String content(URL url) throws Exception
+    {
+        InputStream is = new BufferedInputStream(url.openStream());
+        Reader r = new InputStreamReader(is);
+
+        StringBuilder builder = new StringBuilder();
+        char[] buffer = new char[2000];
+
+        while (true)
+        {
+            int length = r.read(buffer, 0, buffer.length);
+
+            if (length < 0) break;
+
+            builder.append(buffer, 0, length);
+        }
+
+        r.close();
+
+        return builder.toString().trim();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/CollectionFactoryTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/CollectionFactoryTest.java
new file mode 100644
index 0000000..baf1bf7
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/CollectionFactoryTest.java
@@ -0,0 +1,152 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.*;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.*;
+import static java.util.Arrays.asList;
+
+public class CollectionFactoryTest extends Assert
+{
+
+    @Test
+    public void new_map()
+    {
+        Map<String, Class> map = newMap();
+
+        assertTrue(map instanceof HashMap);
+    }
+
+    @Test
+    public void copy_map()
+    {
+        Map<String, Class> map = newMap();
+
+        map.put("this", CollectionFactoryTest.class);
+
+        Map<String, Class> copy = CollectionFactory.newMap(map);
+
+        assertEquals(copy, map);
+
+        map.put("other", Map.class);
+
+        assertFalse(copy.equals(map));
+    }
+
+    @Test
+    public void new_set()
+    {
+        Set<String> set = newSet();
+
+        assertTrue(set instanceof HashSet);
+    }
+
+    @Test
+    public void copy_set()
+    {
+        List<String> start = asList("fred", "barney");
+
+        Set<String> set = newSet(start);
+
+        assertEquals(set.size(), 2);
+        assertTrue(set.contains("fred"));
+        assertTrue(set.contains("barney"));
+    }
+
+    @Test
+    public void set_from_varargs()
+    {
+        Set<String> set = newSet("fred", "barney");
+
+        assertEquals(set.size(), 2);
+        assertTrue(set.contains("fred"));
+        assertTrue(set.contains("barney"));
+    }
+
+    @Test
+    public void new_list()
+    {
+        List<String> list = newList();
+
+        assertTrue(list instanceof ArrayList);
+    }
+
+    @Test
+    public void new_list_copy()
+    {
+        List<String> start = Arrays.asList("Fred", "Barney", "Wilma");
+        List<String> copy = newList(start);
+
+        assertNotSame(copy, start);
+        assertEquals(copy, start);
+    }
+
+    @Test
+    public void new_list_from_elements()
+    {
+        List<String> list = newList("Fred", "Barney");
+
+        assertEquals(list.size(), 2);
+        assertEquals(list.get(0), "Fred");
+        assertEquals(list.get(1), "Barney");
+    }
+
+    private static final int THREAD_COUNT = 20;
+
+    @Test
+    public void new_threadsafe_list() throws Exception
+    {
+        final List<String> threadNames = CollectionFactory.newThreadSafeList();
+
+        List<Thread> threads = CollectionFactory.newList();
+
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                String name = Thread.currentThread().getName();
+                threadNames.add(name);
+            }
+        };
+
+        for (int i = 0; i < THREAD_COUNT; i++)
+        {
+            Thread t = new Thread(r);
+            threads.add(t);
+        }
+
+        // Start all the threads at the same time.
+
+        for (Thread t : threads)
+        {
+            t.start();
+        }
+
+        // Wait for all threads to complete
+
+        for (Thread t : threads)
+        {
+            t.join();
+        }
+
+        // Make sure they all executed. If the list was not thread safe, highly unlikely this
+        // would work.
+
+        assertEquals(threadNames.size(), THREAD_COUNT);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrierTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrierTest.java
new file mode 100644
index 0000000..75d3743
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentBarrierTest.java
@@ -0,0 +1,230 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+/**
+ * Test is structured a bit oddly, since it evolved from when the Concurrence annotation and aspect evolved into the
+ * {@link ConcurrentBarrier} utility class.
+ */
+@Test(sequential = true)
+public class ConcurrentBarrierTest extends TestBase
+{
+    private ConcurrentTarget target = new ConcurrentTarget();
+
+    private static final int THREAD_COUNT = 100;
+
+    private static final int THREAD_BLOCK_SIZE = 5;
+
+    @Test
+    public void read_lock_then_write_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                target.incrementCounter();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test
+    public void read_lock_inside_write_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                // Gets a write lock, then a read lock.
+                target.incrementCounterHard();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test(enabled = true)
+    public void write_lock_inside_read_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                // A read lock method that upgrades to a write lock
+
+                target.incrementIfNonNegative();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test(enabled = true)
+    public void indirection_between_read_method_and_write_method() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+
+                // Read lock method invokes other class, that invokes write method.
+
+                target.incrementViaRunnable();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    /**
+     * Test that locking, especially read lock upgrade and downgrade, work properly when there's more than one object
+     * involved.
+     */
+    @Test
+    public void multiple_synchronized_objects() throws Exception
+    {
+        Runnable operation = new ConcurrentTargetWrapper(target);
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test
+    public void read_lock_then_try_write_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                target.tryIncrementCounter();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test
+    public void read_lock_inside_try_write_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                // Gets a write lock, then a read lock.
+                target.tryIncrementCounterHard();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+    @Test(enabled = true)
+    public void try_write_lock_inside_read_lock() throws Exception
+    {
+        Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                // A read lock method that upgrades to a write lock
+
+                target.tryIncrementIfNonNegative();
+            }
+        };
+
+        runOperationAndCheckCounter(operation);
+    }
+
+
+    @Test(enabled = true)
+    public void write_lock_timeout_inside_read_lock() throws Exception
+    {
+        final Runnable operation = new Runnable()
+        {
+            public void run()
+            {
+                // A read lock method that upgrades to a write lock
+
+                target.tryIncrementIfNonNegative();
+            }
+        };
+
+        target.withRead(new Runnable()
+        {
+            public void run()
+            {
+                try
+                {
+                    runOperation(operation);
+                }
+                catch (InterruptedException e)
+                {
+                }
+            }
+        });
+        assertEquals(target.getCounter(), 0);
+
+    }
+
+
+    private void runOperationAndCheckCounter(Runnable operation) throws InterruptedException
+    {
+        runOperation(operation);
+
+        assertEquals(target.getCounter(), THREAD_COUNT);
+    }
+
+    private void runOperation(Runnable operation)
+            throws InterruptedException
+    {
+        List<Thread> threads = newList();
+        List<Thread> running = newList();
+
+        target.setCounter(0);
+
+        for (int i = 0; i < THREAD_COUNT; i++)
+        {
+
+            Thread t = new Thread(operation);
+
+            threads.add(t);
+
+            if (threads.size() >= THREAD_BLOCK_SIZE)
+                startThreads(threads, running);
+        }
+
+        startThreads(threads, running);
+
+        for (Thread t : running)
+            t.join();
+    }
+
+    private void startThreads(List<Thread> threads, List<Thread> running)
+    {
+        for (Thread t : threads)
+        {
+            t.start();
+            running.add(t);
+        }
+
+        threads.clear();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTarget.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTarget.java
new file mode 100644
index 0000000..79832bd
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTarget.java
@@ -0,0 +1,151 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import java.util.concurrent.TimeUnit;
+
+public class ConcurrentTarget
+{
+    private final ConcurrentBarrier barrier = new ConcurrentBarrier();
+
+    private int counter;
+
+    // Used to check if read locks accumulate when a read lock method calls another read lock method
+    public int readCounter()
+    {
+        return barrier.withRead(new Invokable<Integer>()
+        {
+            public Integer invoke()
+            {
+                return getCounter();
+            }
+        });
+    }
+
+    public int getCounter()
+    {
+        return barrier.withRead(new Invokable<Integer>()
+        {
+            public Integer invoke()
+            {
+                return counter;
+            }
+        });
+    }
+
+    public void incrementCounter()
+    {
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                counter++;
+            }
+        });
+    }
+
+    public void setCounter(final int counter)
+    {
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                ConcurrentTarget.this.counter = counter;
+            }
+        });
+    }
+
+    public void incrementIfNonNegative()
+    {
+        barrier.withRead(new Runnable()
+        {
+            public void run()
+            {
+                if (counter >= 0)
+                    incrementCounter();
+            }
+        });
+    }
+
+    public void incrementViaRunnable()
+    {
+        barrier.withRead(new Runnable()
+        {
+            public void run()
+            {
+                Runnable r = new Runnable()
+                {
+                    public void run()
+                    {
+                        incrementCounter();
+                    }
+                };
+
+                r.run();
+            }
+        });
+    }
+
+    public void incrementCounterHard()
+    {
+        barrier.withWrite(new Runnable()
+        {
+            public void run()
+            {
+                counter = getCounter() + 1;
+            }
+        });
+    }
+
+    public void tryIncrementCounter()
+    {
+        barrier.tryWithWrite(new Runnable()
+        {
+            public void run()
+            {
+                counter++;
+            }
+        }, 20, TimeUnit.MILLISECONDS);
+    }
+
+    public void tryIncrementCounterHard()
+    {
+        barrier.tryWithWrite(new Runnable()
+        {
+            public void run()
+            {
+                counter = getCounter() + 1;
+            }
+        }, 20, TimeUnit.MILLISECONDS);
+    }
+
+    public void tryIncrementIfNonNegative()
+    {
+        barrier.withRead(new Runnable()
+        {
+            public void run()
+            {
+                if (counter >= 0)
+                    tryIncrementCounter();
+            }
+        });
+    }
+
+
+    public void withRead(Runnable runnable)
+    {
+        barrier.withRead(runnable);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTargetWrapper.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTargetWrapper.java
new file mode 100644
index 0000000..38f0526
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/ConcurrentTargetWrapper.java
@@ -0,0 +1,39 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.ioc.internal.util;

+

+

+public class ConcurrentTargetWrapper implements Runnable

+{

+    private final ConcurrentBarrier barrier = new ConcurrentBarrier();

+

+    private final ConcurrentTarget target;

+

+    public ConcurrentTargetWrapper(ConcurrentTarget target)

+    {

+        this.target = target;

+    }

+

+    public void run()

+    {

+        barrier.withRead(new Runnable()

+        {

+            public void run()

+            {

+                target.incrementCounter();

+            }

+        });

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/DefenseTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/DefenseTest.java
new file mode 100644
index 0000000..71be6ac
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/DefenseTest.java
@@ -0,0 +1,124 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+import static org.apache.tapestry.ioc.internal.util.Defense.*;

+import org.apache.tapestry.ioc.test.TestBase;

+import org.testng.annotations.Test;

+

+public class DefenseTest extends TestBase

+{

+

+    /**

+     * Check that {@link Defense#notNull(T, String)} returns a non-null value.

+     */

+    @Test

+    public void parameter_not_null()

+    {

+        assertSame(this, notNull(this, "foo"));

+    }

+

+    /**

+     * Check that {@link Defense#notNull(T, String)} throws NPE when null, and check the message.

+     */

+

+    @Test

+    public void parameter_is_null()

+    {

+        try

+        {

+            notNull(null, "foo");

+            unreachable();

+        }

+        catch (IllegalArgumentException ex)

+        {

+            assertEquals(ex.getMessage(), "Parameter foo was null.");

+        }

+    }

+

+    @Test

+    public void non_blank_parameter_is_null()

+    {

+        try

+        {

+            notBlank(null, "bar");

+            unreachable();

+        }

+        catch (IllegalArgumentException ex)

+        {

+            assertEquals(ex.getMessage(), "Parameter bar was null or contained only whitespace.");

+        }

+    }

+

+    @Test

+    public void non_blank_parameter_is_only_whitespace()

+    {

+        try

+        {

+            notBlank("  \t\n", "baz");

+            unreachable();

+        }

+        catch (IllegalArgumentException ex)

+        {

+            assertEquals(ex.getMessage(), "Parameter baz was null or contained only whitespace.");

+        }

+    }

+

+    @Test

+    public void non_blank_parameter_is_valid()

+    {

+        assertEquals("fred", notBlank(" fred\n", "biff"));

+    }

+

+    @Test

+    public void cast_is_also_not_null()

+    {

+        try

+        {

+            cast(null, String.class, "fred");

+            unreachable();

+        }

+        catch (IllegalArgumentException ex)

+        {

+            assertEquals(ex.getMessage(), "Parameter fred was null.");

+        }

+    }

+

+    @Test

+    public void succesful_cast()

+    {

+        StringBuffer b = new StringBuffer();

+

+        Appendable a = cast(b, Appendable.class, "fred");

+

+        assertSame(a, b);

+    }

+

+    @Test

+    public void bad_cast()

+    {

+        StringBuffer b = new StringBuffer("fred-value");

+

+        try

+        {

+            cast(b, String.class, "fred");

+            unreachable();

+        }

+        catch (IllegalArgumentException ex)

+        {

+            assertEquals(ex.getMessage(), "Parameter fred (fred-value) is not assignable to type java.lang.String.");

+        }

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Foo.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Foo.java
new file mode 100644
index 0000000..a7c153f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Foo.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public interface Foo extends Bar

+{

+    void foo();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBar.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBar.java
new file mode 100644
index 0000000..989a08e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBar.java
@@ -0,0 +1,24 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public interface FooBar extends Foo, Bar

+{

+    void foobar();

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBarImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBarImpl.java
new file mode 100644
index 0000000..2095e80
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooBarImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public class FooBarImpl extends FooImpl implements Bar, FooBar

+{

+

+    public void foobar()

+    {

+

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooImpl.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooImpl.java
new file mode 100644
index 0000000..d9de03e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/FooImpl.java
@@ -0,0 +1,29 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Used by {@link InheritanceSearchTest}.

+ */

+public class FooImpl extends BarImpl implements Foo

+{

+

+    public void foo()

+    {

+

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/GenericUtilsTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/GenericUtilsTest.java
new file mode 100644
index 0000000..6723e66
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/GenericUtilsTest.java
@@ -0,0 +1,61 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+public class GenericUtilsTest extends Assert
+{
+    protected Method find(Class clazz, String name)
+    {
+        for (Method m : clazz.getMethods())
+        {
+            if (m.getName().equalsIgnoreCase(name)) return m;
+        }
+
+        throw new IllegalArgumentException(
+                String.format("Could not locate a public method named '%s' in %s.", name, clazz));
+
+    }
+
+    @Test
+    public void generic_return_type_of_non_generic_type()
+    {
+        Method m = find(NonGenericBean.class, "getvalue");
+
+        assertSame(GenericsUtils.extractGenericReturnType(NonGenericBean.class, m), String.class);
+    }
+
+    @Test
+    public void generic_return_type_of_parameterized_bean()
+    {
+        Method m = find(StringBean.class, "getvalue");
+
+        assertSame(GenericsUtils.extractGenericReturnType(StringBean.class, m), String.class);
+    }
+
+    @Test
+    public void generic_bean_with_multiple_parameters()
+    {
+        Method getKey = find(StringLongPair.class, "getkey");
+        Method getValue = find(StringLongPair.class, "getvalue");
+
+        assertSame(GenericsUtils.extractGenericReturnType(StringLongPair.class, getKey), String.class);
+        assertSame(GenericsUtils.extractGenericReturnType(StringLongPair.class, getValue), Long.class);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/IdAllocatorTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/IdAllocatorTest.java
new file mode 100644
index 0000000..e55167b
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/IdAllocatorTest.java
@@ -0,0 +1,145 @@
+// Copyright 2004, 2005, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;

+import org.testng.Assert;

+import org.testng.annotations.Test;

+

+import java.util.List;

+

+public class IdAllocatorTest extends Assert

+{

+

+    @Test

+    public void simple()

+    {

+        IdAllocator a = new IdAllocator();

+        List<String> ids = newList();

+

+        assertFalse(a.isAllocated("name"));

+

+        assertEquals(a.allocateId("name"), "name");

+        assertTrue(a.isAllocated("name"));

+

+        ids.add("name");

+

+        for (int i = 0; i < 10; i++)

+        {

+

+            String expected = "name_" + i;

+

+            assertFalse(a.isAllocated(expected));

+

+            String nextId = a.allocateId("name");

+

+            assertTrue(a.isAllocated(expected));

+

+            assertEquals(nextId, expected);

+

+            ids.add(nextId);

+        }

+

+        assertEquals(a.getAllocatedIds(), ids);

+    }

+

+    @Test

+    public void simple_with_namespace()

+    {

+        IdAllocator a = new IdAllocator("_NS");

+

+        assertEquals(a.allocateId("name"), "name_NS");

+

+        for (int i = 0; i < 10; i++)

+            assertEquals(a.allocateId("name"), "name_NS_" + i);

+

+        // This is current behavior, but is probably something

+        // that could be improved.

+

+        assertEquals(a.allocateId("foo_NS"), "foo_NS_NS");

+        assertEquals(a.allocateId("foo_NS"), "foo_NS_NS_0");

+    }

+

+    @Test

+    public void degenerate()

+    {

+        IdAllocator a = new IdAllocator();

+

+        assertEquals(a.allocateId("d_1"), "d_1");

+

+        assertEquals(a.allocateId("d"), "d");

+        assertEquals(a.allocateId("d"), "d_0");

+        assertEquals(a.allocateId("d"), "d_2");

+

+        assertEquals(a.allocateId("d"), "d_3");

+        assertEquals(a.allocateId("d_1"), "d_1_0");

+    }

+

+    @Test

+    public void degenerate_with_namespace()

+    {

+        IdAllocator a = new IdAllocator("_NS");

+

+        assertEquals(a.allocateId("d_1"), "d_1_NS");

+

+        assertEquals(a.allocateId("d"), "d_NS");

+        assertEquals(a.allocateId("d"), "d_NS_0");

+        assertEquals(a.allocateId("d"), "d_NS_1");

+        assertEquals(a.allocateId("d"), "d_NS_2");

+        assertEquals(a.allocateId("d"), "d_NS_3");

+

+        assertEquals(a.allocateId("d_1"), "d_1_NS_0");

+

+        // This is very degenerate, and maybe something that needs fixing.

+

+        assertEquals(a.allocateId("d_1_NS"), "d_1_NS_NS");

+    }

+

+    @Test

+    public void clear()

+    {

+        IdAllocator a = new IdAllocator();

+

+        assertEquals(a.allocateId("foo"), "foo");

+        assertEquals(a.allocateId("foo_0"), "foo_0");

+

+        a.clear();

+

+        assertEquals(a.allocateId("foo"), "foo");

+        assertEquals(a.allocateId("foo_0"), "foo_0");

+    }

+

+    @Test

+    public void clone_test()

+    {

+        IdAllocator a = new IdAllocator();

+

+        assertEquals(a.allocateId("foo"), "foo");

+        assertEquals(a.allocateId("foo_0"), "foo_0");

+        assertEquals(a.allocateId("foo"), "foo_1");

+

+        IdAllocator b = a.clone();

+

+        // After making a clone, parallel operations should return the same results.

+        // If anything under the covers was shared, then parallel operations would

+        // interfere with each other.

+

+        assertEquals(b.allocateId("bar"), a.allocateId("bar"));

+        assertEquals(b.allocateId("foo"), a.allocateId("foo"));

+        assertEquals(b.allocateId("foo_0"), a.allocateId("foo_0"));

+

+    }

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
new file mode 100644
index 0000000..dd5a813
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
@@ -0,0 +1,173 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ *
+ */
+public class InheritanceSearchTest extends TestBase
+{
+
+    @Test
+    public void remove_always_fails()
+    {
+        try
+        {
+            new InheritanceSearch(Object.class).remove();
+            unreachable();
+        }
+        catch (UnsupportedOperationException ex)
+        {
+
+        }
+    }
+
+    @Test
+    public void next_when_no_more()
+    {
+        InheritanceSearch s = new InheritanceSearch(Object.class);
+
+        assertSame(s.next(), Object.class);
+        assertFalse(s.hasNext());
+
+        try
+        {
+            s.next();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+
+        }
+    }
+
+    @Test
+    public void inheritance_of_object()
+    {
+        check(Object.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_of_string()
+    {
+        check(
+                String.class,
+                String.class,
+                Serializable.class,
+                Comparable.class,
+                CharSequence.class,
+                Object.class);
+    }
+
+    @Test
+    public void inheritance_of_an_interface()
+    {
+        check(Comparable.class, Comparable.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_search_order_for_interfaces()
+    {
+        check(FooBar.class, FooBar.class, Foo.class, Bar.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_search_order_for_classes()
+    {
+        check(
+                FooBarImpl.class,
+                FooBarImpl.class,
+                FooImpl.class,
+                BarImpl.class,
+                Bar.class,
+                FooBar.class,
+                Foo.class,
+                Object.class);
+
+    }
+
+    @Test
+    public void inheritance_of_primitive()
+    {
+        check(
+                long.class,
+                long.class,
+                Long.class,
+                Number.class,
+                Comparable.class,
+                Serializable.class,
+                Object.class);
+    }
+
+    @Test
+    public void inheritance_of_void()
+    {
+        check(void.class, void.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_of_primitive_array()
+    {
+        check(long[].class, long[].class, Cloneable.class, Serializable.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_of_a_2d_primitive_array()
+    {
+        check(int[][].class, int[][].class, Cloneable.class, Serializable.class, Object.class);
+    }
+
+    @Test
+    public void inheritance_of_an_object_array()
+    {
+        check(
+                String[].class,
+                String[].class,
+                Object[].class,
+                Cloneable.class,
+                Serializable.class,
+                Object.class);
+    }
+
+    @Test
+    public void inheritance_of_a_2d_object_array()
+    {
+        check(
+                String[][].class,
+                String[][].class,
+                Object[].class,
+                Cloneable.class,
+                Serializable.class,
+                Object.class);
+    }
+
+    private void check(Class searchClass, Class... expected)
+    {
+        List<Class> list = CollectionFactory.newList();
+
+        // This for loop is how the class is generally used:
+
+        for (Class c : new InheritanceSearch(searchClass))
+            list.add(c);
+
+        assertEquals(list.toArray(), expected);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InjectoBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InjectoBean.java
new file mode 100644
index 0000000..cbb2058
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InjectoBean.java
@@ -0,0 +1,54 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.annotation.Inject;
+
+public class InjectoBean
+{
+    private final String foo;
+    private final Runnable bar;
+
+    public InjectoBean()
+    {
+        this(null);
+    }
+
+    @Inject
+    public InjectoBean(String foo)
+    {
+        this(foo, null);
+    }
+
+    /**
+     * Normally, this would be chosen as it has the most parameters.
+     */
+    public InjectoBean(String foo, Runnable bar)
+    {
+
+        this.foo = foo;
+        this.bar = bar;
+    }
+
+    public String getFoo()
+    {
+        return foo;
+    }
+
+    public Runnable getBar()
+    {
+        return bar;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InternalUtilsTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InternalUtilsTest.java
new file mode 100644
index 0000000..2203b84
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/InternalUtilsTest.java
@@ -0,0 +1,387 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.annotation.Inject;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import static org.apache.tapestry.ioc.internal.util.InternalUtils.toList;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.*;
+
+public class InternalUtilsTest extends IOCTestCase
+{
+    @Test
+    public void method_as_string_no_args() throws Exception
+    {
+
+        Method m = Object.class.getMethod("toString");
+
+        assertEquals(InternalUtils.asString(m), "java.lang.Object.toString()");
+    }
+
+    @Test
+    public void method_as_string_with_args() throws Exception
+    {
+        Method m = Collections.class.getMethod("sort", List.class, Comparator.class);
+
+        assertEquals(InternalUtils.asString(m), "java.util.Collections.sort(List, Comparator)");
+    }
+
+    @Test
+    public void method_as_string_primitive_arg() throws Exception
+    {
+        Method m = Object.class.getMethod("wait", long.class);
+
+        assertEquals(InternalUtils.asString(m), "java.lang.Object.wait(long)");
+    }
+
+    @Test
+    public void method_as_string_primitive_array_arg() throws Exception
+    {
+        Method m = Arrays.class.getMethod("sort", int[].class);
+
+        assertEquals(InternalUtils.asString(m), "java.util.Arrays.sort(int[])");
+    }
+
+    @Test
+    public void method_as_string_array_arg() throws Exception
+    {
+        Method m = Arrays.class.getMethod("sort", Object[].class);
+
+        assertEquals(InternalUtils.asString(m), "java.util.Arrays.sort(Object[])");
+    }
+
+    @Test
+    public void array_size_when_null()
+    {
+        assertEquals(InternalUtils.size(null), 0);
+    }
+
+    @Test
+    public void array_size_when_non_null()
+    {
+        Object[] array = { 1, 2, 3 };
+
+        assertEquals(InternalUtils.size(array), 3);
+    }
+
+    @Test(dataProvider = "memberPrefixData")
+    public void strip_member_prefix(String input, String expected)
+    {
+        assertEquals(InternalUtils.stripMemberPrefix(input), expected);
+    }
+
+    @DataProvider(name = "memberPrefixData")
+    public Object[][] memberPrefixData()
+    {
+        return new Object[][] { { "simple", "simple" }, { "_name", "name" }, { "$name", "name" },
+                { "$_$__$__$_$___$_$_$_$$name$", "name$" } };
+    }
+
+    @Test
+    public void enumeration_to_list()
+    {
+        List<String> input = Arrays.asList("wilma", "fred", "barney");
+        Enumeration e = Collections.enumeration(input);
+
+        List<String> output = toList(e);
+
+        assertEquals(output, Arrays.asList("barney", "fred", "wilma"));
+    }
+
+    @Test
+    public void join_empty_list()
+    {
+        List<String> empty = CollectionFactory.newList();
+
+        assertEquals(InternalUtils.join(empty), "");
+    }
+
+    @Test
+    public void join_single()
+    {
+        List<String> single = Arrays.asList("barney");
+
+        assertEquals(InternalUtils.join(single), "barney");
+    }
+
+    @Test
+    public void join_multiple()
+    {
+        List<String> many = Arrays.asList("fred", "barney", "wilma");
+        assertEquals(InternalUtils.join(many), "fred, barney, wilma");
+    }
+
+    @Test
+    public void join_with_blank()
+    {
+        List<String> many = Arrays.asList("fred", "barney", "", "wilma");
+        assertEquals(InternalUtils.join(many), "fred, barney, (blank), wilma");
+
+    }
+
+    @Test
+    public void join_sorted()
+    {
+        List<String> unsorted = Arrays.asList("betty", "fred", "barney", "wilma");
+        List<String> copy = CollectionFactory.newList(unsorted);
+
+        assertEquals(InternalUtils.joinSorted(copy), "barney, betty, fred, wilma");
+
+        // Make sure that joinSorted() doesn't change the input list
+
+        assertEquals(copy, unsorted);
+    }
+
+    @Test
+    public void join_sorted_with_blank()
+    {
+        List<String> unsorted = Arrays.asList("betty", "fred", "barney", "", "wilma");
+
+        assertEquals(InternalUtils.joinSorted(unsorted), "(blank), barney, betty, fred, wilma");
+
+    }
+
+    @Test(dataProvider = "capitalize_inputs")
+    public void capitalize(String input, String expected)
+    {
+        assertEquals(InternalUtils.capitalize(input), expected);
+    }
+
+    @DataProvider(name = "capitalize_inputs")
+    public Object[][] capitalize_inputs()
+    {
+        return new Object[][] { { "hello", "Hello" }, { "Goodbye", "Goodbye" }, { "", "" }, { "a", "A" },
+                { "A", "A" } };
+    }
+
+    @Test
+    public void location_of_not_found()
+    {
+        assertNull(InternalUtils.locationOf(null));
+        assertNull(InternalUtils.locationOf("La! La!"));
+    }
+
+    @Test
+    public void location_of_location()
+    {
+        Location l = mockLocation();
+
+        replay();
+
+        assertSame(l, InternalUtils.locationOf(l));
+
+        verify();
+    }
+
+    @Test
+    public void location_of_locatable()
+    {
+        Location l = mockLocation();
+        Locatable locatable = newMock(Locatable.class);
+
+        expect(locatable.getLocation()).andReturn(l);
+
+        replay();
+
+        assertSame(l, InternalUtils.locationOf(locatable));
+
+        verify();
+    }
+
+    @Test
+    public void sorted_keys_from_null_map()
+    {
+        List<String> list = InternalUtils.sortedKeys(null);
+
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void sorted_keys_from_map()
+    {
+        Map<String, String> map = newMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+
+        assertEquals(InternalUtils.sortedKeys(map), Arrays.asList("barney", "fred"));
+    }
+
+    @Test
+    public void get_from_null_map()
+    {
+        assertNull(InternalUtils.get(null, null));
+    }
+
+    @Test
+    public void get_from_map()
+    {
+        Map<String, String> map = newMap();
+
+        map.put("fred", "flintstone");
+
+        assertEquals("flintstone", InternalUtils.get(map, "fred"));
+    }
+
+    @Test
+    public void reverse_iterator()
+    {
+        List<String> list = Arrays.asList("a", "b", "c");
+
+        Iterator<String> i = InternalUtils.reverseIterator(list);
+
+        assertTrue(i.hasNext());
+        assertEquals(i.next(), "c");
+
+        assertTrue(i.hasNext());
+        assertEquals(i.next(), "b");
+
+        assertTrue(i.hasNext());
+        assertEquals(i.next(), "a");
+
+        assertFalse(i.hasNext());
+    }
+
+    @Test
+    public void reverse_iterator_does_not_support_remove()
+    {
+        List<String> list = Arrays.asList("a", "b", "c");
+
+        Iterator<String> i = InternalUtils.reverseIterator(list);
+
+        try
+        {
+            i.remove();
+            unreachable();
+        }
+        catch (UnsupportedOperationException ex)
+        {
+
+        }
+    }
+
+    @Test
+    public void last_term()
+    {
+        String input = "SimpleInput";
+
+        assertSame(InternalUtils.lastTerm(input), input);
+
+        assertEquals(InternalUtils.lastTerm("fie.fie.foe.fum"), "fum");
+    }
+
+    @Test
+    public void add_to_list_map()
+    {
+        Map<String, List<Integer>> map = CollectionFactory.newMap();
+
+        InternalUtils.addToMapList(map, "fred", 1);
+
+        assertEquals(map.get("fred"), Arrays.asList(1));
+
+        InternalUtils.addToMapList(map, "fred", 2);
+
+        assertEquals(map.get("fred"), Arrays.asList(1, 2));
+    }
+
+    // Test the check for runtime annotation. This is all well and good, we actually don't have a proper test
+    // that this code is used (ideally we should have tests for @Marker on a module, on a service impl, and passed
+    // to ServiceBindingOptions.withMarker(), to prove that those are wired for checks.
+
+    @Test
+    public void validate_marker_annotation()
+    {
+        InternalUtils.validateMarkerAnnotation(Inject.class);
+
+
+        try
+        {
+            InternalUtils.validateMarkerAnnotations(new Class[] { Inject.class, NotRetainedRuntime.class });
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Marker annotation class org.apache.tapestry.ioc.internal.util.NotRetainedRuntime is not valid because it is not visible at runtime. Add a @RetentionPolicy(RUNTIME) to the class.");
+        }
+    }
+
+    @Test
+    public void join_sorted_null()
+    {
+        assertEquals(InternalUtils.joinSorted(null), "(none)");
+    }
+
+    @Test
+    public void join_sorted_empty()
+    {
+        assertEquals(InternalUtils.joinSorted(Collections.emptyList()), "(none)");
+    }
+
+    @Test
+    public void close_null_is_noop()
+    {
+        InternalUtils.close(null);
+    }
+
+    @Test
+    public void close_success() throws Exception
+    {
+        Closeable c = newMock(Closeable.class);
+
+        c.close();
+
+        replay();
+
+        InternalUtils.close(c);
+
+        verify();
+    }
+
+    @Test
+    public void close_ignores_exceptions() throws Exception
+    {
+        Closeable c = newMock(Closeable.class);
+
+        c.close();
+        setThrowable(new IOException());
+
+        replay();
+
+        InternalUtils.close(c);
+
+        verify();
+    }
+
+    @Test
+    public void constructor_with_inject_annotation()
+    {
+        Constructor c = InternalUtils.findAutobuildConstructor(InjectoBean.class);
+
+        assertEquals(c.getParameterTypes().length, 1);
+        assertEquals(c.getParameterTypes()[0], String.class);
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGeneratorTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGeneratorTest.java
new file mode 100644
index 0000000..653c6cc
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocalizedNameGeneratorTest.java
@@ -0,0 +1,76 @@
+// Copyright 2006, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+
+public class LocalizedNameGeneratorTest extends IOCTestCase
+{
+
+    private void run(String path, Locale locale, String... expected)
+    {
+        LocalizedNameGenerator g = new LocalizedNameGenerator(path, locale);
+
+        for (String s : expected)
+        {
+            assertTrue(g.hasNext());
+            assertEquals(g.next(), s);
+        }
+
+        assertFalse(g.hasNext());
+    }
+
+    @Test
+    public void locale_with_language_and_country()
+    {
+        run("basic.test", Locale.US, "basic_en_US.test", "basic_en.test", "basic.test");
+    }
+
+    @Test
+    public void locale_with_just_language()
+    {
+        run("noCountry.zap", Locale.FRENCH, "noCountry_fr.zap", "noCountry.zap");
+    }
+
+    @Test
+    public void locale_with_variant_but_no_country()
+    {
+
+        // The double-underscore is correct, it's a kind
+        // of placeholder for the null country.
+        // JDK1.3 always converts the locale to upper case. JDK 1.4
+        // does not. To keep this test happyt, we selected an all-uppercase
+        // locale.
+
+        run("fred.foo", new Locale("en", "", "GEEK"), "fred_en__GEEK.foo", "fred_en.foo", "fred.foo");
+    }
+
+    @Test
+    public void locale_with_just_language_no_period()
+    {
+        run("context:/blah", Locale.FRENCH, "context:/blah_fr", "context:/blah");
+    }
+
+    @Test
+    public void locale_with_variant_but_no_country_no_period()
+    {
+        run("context:/blah", new Locale("fr", "", "GEEK"), "context:/blah_fr__GEEK", "context:/blah_fr",
+            "context:/blah");
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocationImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocationImplTest.java
new file mode 100644
index 0000000..20e2b6e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/LocationImplTest.java
@@ -0,0 +1,100 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.util.Random;
+
+public class LocationImplTest extends IOCTestCase
+{
+    private final Random random = new Random();
+
+    private final Resource resource = new ClasspathResource("/foo/Bar.xml");
+
+    @Test
+    public void all_three_parameters()
+    {
+
+        int line = random.nextInt();
+        int column = random.nextInt();
+
+        Location l = new LocationImpl(resource, line, column);
+
+        assertSame(l.getResource(), resource);
+        assertEquals(l.getLine(), line);
+        assertEquals(l.getColumn(), column);
+
+        assertEquals(l.toString(), String.format("%s, line %d, column %d", resource, line, column));
+    }
+
+    @Test
+    public void unknown_column()
+    {
+        int line = random.nextInt();
+
+        Location l = new LocationImpl(resource, line);
+
+        assertSame(l.getResource(), resource);
+        assertEquals(l.getLine(), line);
+        assertEquals(l.getColumn(), -1);
+
+        assertEquals(l.toString(), String.format("%s, line %d", resource, line));
+    }
+
+    @Test
+    public void unknown_line_and_column()
+    {
+        Location l = new LocationImpl(resource);
+
+        assertSame(l.getResource(), resource);
+        assertEquals(l.getLine(), -1);
+        assertEquals(l.getColumn(), -1);
+
+        assertEquals(l.toString(), resource.toString());
+    }
+
+    @Test
+    public void equality()
+    {
+        Location l1 = new LocationImpl(resource, 22, 7);
+        Location l2 = new LocationImpl(resource, 22, 7);
+        Location l3 = new LocationImpl(null, 22, 7);
+        Location l4 = new LocationImpl(resource, 99, 7);
+        Location l5 = new LocationImpl(resource, 22, 99);
+        Location l6 = new LocationImpl(new ClasspathResource("/baz/Biff.txt"), 22, 7);
+
+        assertEquals(l1, l1);
+        assertFalse(l1.equals(null));
+
+        assertEquals(l1, l2);
+        assertEquals(l2.hashCode(), l1.hashCode());
+
+        assertFalse(l3.equals(l1));
+        assertFalse(l3.hashCode() == l1.hashCode());
+
+        assertFalse(l4.equals(l1));
+        assertFalse(l4.hashCode() == l1.hashCode());
+
+        assertFalse(l5.equals(l1));
+        assertFalse(l5.hashCode() == l1.hashCode());
+
+        assertFalse(l6.equals(l1));
+        assertFalse(l6.hashCode() == l1.hashCode());
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImplTest.java
new file mode 100644
index 0000000..05cacd2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessageFormatterImplTest.java
@@ -0,0 +1,50 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class MessageFormatterImplTest extends Assert
+{
+    private String run(String format, Object... args)
+    {
+        return new MessageFormatterImpl(format, null).format(args);
+    }
+
+    @Test
+    public void standard_args()
+    {
+        assertEquals(run("Tapestry is %s.", "cool"), "Tapestry is cool.");
+        assertEquals(run("Tapestry release #%d.", 5), "Tapestry release #5.");
+        assertEquals(run("%s is %s at version %d.", "Tapestry", "cool", 5), "Tapestry is cool at version 5.");
+    }
+
+    @Test
+    public void throwable_argument()
+    {
+        Throwable t = new RuntimeException("Just didn't feel right.");
+
+        assertEquals(run("%s failed: %s", "Something", t), "Something failed: Just didn't feel right.");
+    }
+
+    @Test
+    public void throwable_argument_with_null_message()
+    {
+        Throwable t = new NullPointerException();
+
+        assertEquals(run("%s failed: %s", "Something", t), "Something failed: java.lang.NullPointerException");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessagesImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessagesImplTest.java
new file mode 100644
index 0000000..148060f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/MessagesImplTest.java
@@ -0,0 +1,95 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.MessageFormatter;
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+public class MessagesImplTest extends IOCTestCase
+{
+    private final Messages messages = MessagesImpl.forClass(TargetMessages.class);
+
+    @Test
+    public void contains_key()
+    {
+        assertTrue(messages.contains("no-args"));
+        assertFalse(messages.contains("xyzzyx"));
+    }
+
+    @Test
+    public void contains_key_is_case_insensitive()
+    {
+        assertTrue(messages.contains("No-Args"));
+        assertFalse(messages.contains("Xyzzyx"));
+    }
+
+    @Test
+    public void get_message_from_catalog()
+    {
+        assertEquals(messages.get("no-args"), "No arguments.");
+        assertEquals(messages.get("something-failed"), "Something failed: %s");
+    }
+
+    @Test
+    public void get_message_from_catalog_is_case_insensitive()
+    {
+        assertEquals(messages.get("No-args"), "No arguments.");
+        assertEquals(messages.get("Something-Failed"), "Something failed: %s");
+    }
+
+    @Test
+    public void get_unknown_message_from_catalog()
+    {
+        assertEquals(messages.get("does-not-exist"), "[[missing key: does-not-exist]]");
+    }
+
+    @Test
+    public void format_message()
+    {
+        assertEquals(messages.format("result", "good"), "The result is 'good'.");
+    }
+
+    @Test
+    public void format_message_is_case_insensitive()
+    {
+        assertEquals(messages.format("Result", "good"), "The result is 'good'.");
+    }
+
+    @Test
+    public void get_formatter()
+    {
+        MessageFormatter mf = messages.getFormatter("result");
+
+        assertEquals(mf.format("great"), "The result is 'great'.");
+    }
+
+    @Test
+    public void formatters_are_cached()
+    {
+        MessageFormatter mf1 = messages.getFormatter("result");
+        // Throw in a case-insensitive check:
+        MessageFormatter mf2 = messages.getFormatter("Result");
+
+        assertSame(mf2, mf1);
+    }
+
+    @Test
+    public void format_unknown_key()
+    {
+        assertEquals(messages.format("rezult", "good"), "[[missing key: rezult]]");
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NonGenericBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NonGenericBean.java
new file mode 100644
index 0000000..8b76496
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NonGenericBean.java
@@ -0,0 +1,30 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+public class NonGenericBean
+{
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NotRetainedRuntime.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NotRetainedRuntime.java
new file mode 100644
index 0000000..c90efe2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/NotRetainedRuntime.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * Used for testing; this annotation is NOT retained at runtime.
+ */
+@Target({ElementType.PARAMETER, ElementType.FIELD})
+public @interface NotRetainedRuntime
+{
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockSubject.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockSubject.java
new file mode 100644
index 0000000..810668f
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockSubject.java
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+/**

+ *

+ */

+package org.apache.tapestry.ioc.internal.util;

+

+

+/**

+ * Evolved from a test for aspects + annotations to a test of a class that utilizeds OneShotLock as a utility.

+ */

+public class OneShotLockSubject

+{

+    private final OneShotLock lock = new OneShotLock();

+

+    public void go()

+    {

+        lock.check();

+    }

+

+    public void done()

+    {

+        lock.lock();

+    }

+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockTest.java
new file mode 100644
index 0000000..29a2d49
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OneShotLockTest.java
@@ -0,0 +1,66 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+public class OneShotLockTest extends IOCTestCase
+{
+    private static final String CLASS_NAME = OneShotLockSubject.class.getName();
+
+    @Test
+    public void basic_locking()
+    {
+        OneShotLockSubject s = new OneShotLockSubject();
+
+        s.go();
+
+        s.done();
+
+        try
+        {
+            s.go();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertTrue(ex.getMessage().contains(CLASS_NAME + ".go"));
+            assertTrue(ex.getMessage().contains("may no longer be invoked."));
+        }
+    }
+
+    @Test
+    public void locking_method_includes_check()
+    {
+        OneShotLockSubject s = new OneShotLockSubject();
+
+        s.go();
+
+        s.done();
+
+        try
+        {
+            s.done();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertTrue(ex.getMessage().contains(CLASS_NAME + ".done"));
+            assertTrue(ex.getMessage().contains("may no longer be invoked."));
+        }
+    }
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OrdererTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OrdererTest.java
new file mode 100644
index 0000000..8c69535
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/OrdererTest.java
@@ -0,0 +1,328 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+import org.apache.tapestry.ioc.Orderable;
+import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.slf4j.Logger;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class OrdererTest extends IOCInternalTestCase
+{
+    @Test
+    public void no_dependencies()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("FRED", "BARNEY", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void missing_constraint_type()
+    {
+        Logger logger = mockLogger();
+
+        logger.warn(UtilMessages.constraintFormat("fred", "barney"));
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY", "fred");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("FRED", "BARNEY", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void unknown_constraint_type()
+    {
+        Logger logger = mockLogger();
+
+        logger.warn(UtilMessages.constraintFormat("nearby:fred", "barney"));
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY", "nearby:fred");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("FRED", "BARNEY", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void nulls_not_included_in_result()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY");
+        o.add("zippo", null);
+        o.add("wilma", "WILMA");
+        o.add("groucho", null);
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("FRED", "BARNEY", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void duplicate_id()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY");
+        o.add("wilma", "WILMA");
+
+        verify();
+
+        logger.warn(UtilMessages.duplicateOrderer("fred"));
+
+        replay();
+
+        o.add("fred", "FRED2");
+
+        verify();
+
+        replay();
+
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("FRED", "BARNEY", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void leader()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY", "before:*");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("BARNEY", "FRED", "WILMA", "BETTY"));
+
+        verify();
+    }
+
+    @Test
+    public void trailer()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED");
+        o.add("barney", "BARNEY", "after:*");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered.get(3), "BARNEY");
+
+        verify();
+    }
+
+    @Test
+    public void prereqs()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED", "after:wilma");
+        o.add("barney", "BARNEY", "after:fred,betty");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("WILMA", "FRED", "BETTY", "BARNEY"));
+
+        verify();
+    }
+
+    @Test
+    public void pre_and_post_reqs()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED", "after:wilma");
+        o.add("barney", "BARNEY", "after:fred,betty");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY", "before:wilma");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("BETTY", "WILMA", "FRED", "BARNEY"));
+
+        verify();
+    }
+
+    @Test
+    public void case_insensitivity()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED", "after:Wilma");
+        o.add("barney", "BARNEY", "after:Fred,BETTY");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY", "before:Wilma");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("BETTY", "WILMA", "FRED", "BARNEY"));
+
+        verify();
+    }
+
+    @Test
+    public void dependency_cycle()
+    {
+        Logger logger = mockLogger();
+
+        logger.warn("Unable to add 'barney' as a dependency of 'betty', as that forms a "
+                + "dependency cycle ('betty' depends on itself via 'barney'). "
+                + "The dependency has been ignored.");
+
+        replay();
+
+        Orderer<String> o = new Orderer<String>(logger);
+
+        o.add("fred", "FRED", "after:wilma");
+        o.add("barney", "BARNEY", "after:fred,betty");
+        o.add("wilma", "WILMA");
+        o.add("betty", "BETTY", "after:barney", "before:wilma");
+
+        List<String> ordered = o.getOrdered();
+
+        assertEquals(ordered, Arrays.asList("BETTY", "WILMA", "FRED", "BARNEY"));
+
+        verify();
+    }
+
+    @Test
+    public void toString_Orderable()
+    {
+        Orderable<String> simple = new Orderable<String>("simple", "SIMPLE");
+
+        assertEquals(simple.toString(), "Orderable[simple SIMPLE]");
+
+        Orderable<String> complex = new Orderable<String>("complex", "COMPLEX", "after:foo",
+                                                          "before:bar");
+
+        assertEquals(complex.toString(), "Orderable[complex after:foo before:bar COMPLEX]");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void toString_DependencyNode()
+    {
+        Logger logger = mockLogger();
+
+        replay();
+
+        DependencyNode<String> node1 = new DependencyNode<String>(logger, new Orderable("node1",
+                                                                                        "NODE1"));
+
+        assertEquals(node1.toString(), "[node1]");
+
+        DependencyNode<String> node2 = new DependencyNode<String>(logger, new Orderable("node2",
+                                                                                        "NODE2"));
+
+        DependencyNode<String> node3 = new DependencyNode<String>(logger, new Orderable("node3",
+                                                                                        "NODE3"));
+
+        DependencyNode<String> node4 = new DependencyNode<String>(logger, new Orderable("node4",
+                                                                                        "NODE4"));
+
+        DependencyNode<String> node5 = new DependencyNode<String>(logger, new Orderable("node5",
+                                                                                        "NODE5"));
+
+        node2.addDependency(node1);
+        node1.addDependency(node3);
+        node1.addDependency(node4);
+        node5.addDependency(node1);
+
+        assertEquals(node5.toString(), "[node5: [node1: [node3], [node4]]]");
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Pair.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Pair.java
new file mode 100644
index 0000000..08500b0
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/Pair.java
@@ -0,0 +1,42 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+public class Pair<K, V>
+{
+    private K key;
+
+    private V value;
+
+    public K getKey()
+    {
+        return key;
+    }
+
+    public void setKey(K key)
+    {
+        this.key = key;
+    }
+
+    public V getValue()
+    {
+        return value;
+    }
+
+    public void setValue(V value)
+    {
+        this.value = value;
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringBean.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringBean.java
new file mode 100644
index 0000000..da39a54
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringBean.java
@@ -0,0 +1,20 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+public class StringBean extends BaseGenericBean<String>
+{
+
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringLongPair.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringLongPair.java
new file mode 100644
index 0000000..f98b2f8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/StringLongPair.java
@@ -0,0 +1,19 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;
+
+public class StringLongPair extends Pair<String, Long>
+{
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/TargetMessages.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/TargetMessages.java
new file mode 100644
index 0000000..4b7c5f2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/util/TargetMessages.java
@@ -0,0 +1,23 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.internal.util;

+

+/**

+ * Used with {@link org.apache.tapestry.ioc.internal.util.MessagesImplTest}.

+ */

+public class TargetMessages

+{

+

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/ClassFabUtilsTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/ClassFabUtilsTest.java
new file mode 100644
index 0000000..b11824a
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/ClassFabUtilsTest.java
@@ -0,0 +1,96 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class ClassFabUtilsTest extends IOCTestCase
+{
+
+    @Test(dataProvider = "provider")
+    public void to_jvm_binary_name(String input, String expected)
+    {
+        String actual = ClassFabUtils.toJVMBinaryName(input);
+
+        assertEquals(actual, expected);
+    }
+
+    @DataProvider(name = "provider")
+    public Object[][] createInputs()
+    {
+        return new Object[][] { { "java.lang.Object", "java.lang.Object" },
+
+                { "int", "int" },
+
+                { "int[]", "[I" },
+
+                { "java.lang.Throwable[]", "[Ljava.lang.Throwable;" },
+
+                { "byte[][]", "[[B" },
+
+                { "java.lang.Runnable[][]", "[[Ljava.lang.Runnable;" } };
+    }
+
+    @Test(dataProvider = "typeCodeProvider")
+    public void get_type_code(Class input, String expected)
+    {
+        assertEquals(ClassFabUtils.getTypeCode(input), expected);
+    }
+
+    @DataProvider(name = "typeCodeProvider")
+    public Object[][] get_type_code_provider()
+    {
+        return new Object[][] { { int.class, "I" },
+
+                { int[].class, "[I" },
+
+                { Thread.class, "Ljava/lang/Thread;" },
+
+                { Thread[].class, "[Ljava/lang/Thread;" },
+
+                { Double[][].class, "[[Ljava/lang/Double;" },
+
+                { void.class, "V" } };
+    }
+
+    @Test
+    public void primitive_type_from_wrapper_type()
+    {
+        assertSame(ClassFabUtils.getPrimitiveType(Boolean.class), boolean.class);
+    }
+
+    @Test
+    public void get_primitive_type_from_name()
+    {
+        assertSame(ClassFabUtils.getPrimitiveType("int"), int.class);
+    }
+
+    @Test
+    public void cast_reference_to_object_type()
+    {
+        assertEquals(ClassFabUtils.castReference("ref", "java.lang.String"),
+                     "(java.lang.String)ref");
+    }
+
+    @Test
+    public void cast_reference_to_primitive_type()
+    {
+        assertEquals(ClassFabUtils.castReference("ref", "short"),
+                     "((java.lang.Short)ref).shortValue()");
+
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodIteratorTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodIteratorTest.java
new file mode 100644
index 0000000..b95da2e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodIteratorTest.java
@@ -0,0 +1,146 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.apache.tapestry.ioc.test.IOCTestCase;

+import org.testng.annotations.Test;

+

+import java.io.IOException;

+import java.util.NoSuchElementException;

+

+public class MethodIteratorTest extends IOCTestCase

+{

+    static interface Play extends Runnable

+    {

+        public void jump();

+    }

+

+    static interface Runnable2

+    {

+        public void run();

+    }

+

+    static interface Runnable3 extends Runnable, Runnable2

+    {

+    }

+

+    static interface ToString

+    {

+        public String toString();

+    }

+

+    static interface Openable

+    {

+        public void open();

+    }

+

+    static interface OpenableWithError

+    {

+        public void open() throws IOException;

+    }

+

+    static interface CombinedOpeneable extends Openable, OpenableWithError

+    {

+    }

+

+    @Test

+    public void simple_interface()

+    {

+        MethodIterator mi = new MethodIterator(Runnable.class);

+

+        assertTrue(mi.hasNext());

+

+        MethodSignature actual = mi.next();

+

+        assertEquals(new MethodSignature(void.class, "run", null, null), actual);

+

+        assertFalse(mi.hasNext());

+

+        try

+        {

+            mi.next();

+        }

+        catch (NoSuchElementException ex)

+        {

+            //

+        }

+

+        assertEquals(false, mi.getToString());

+    }

+

+    @Test

+    public void inherited_methods_from_super_interface()

+    {

+        MethodIterator mi = new MethodIterator(Play.class);

+

+        assertTrue(mi.hasNext());

+

+        // Problematic because the order in which they are returned is

+        // JDK specific and not defined! Perhaps we should sort by alpha?

+

+        MethodSignature actual = mi.next();

+

+        assertEquals(new MethodSignature(void.class, "jump", null, null), actual);

+

+        assertTrue(mi.hasNext());

+

+        actual = mi.next();

+

+        assertEquals(new MethodSignature(void.class, "run", null, null), actual);

+

+        assertFalse(mi.hasNext());

+

+        assertEquals(false, mi.getToString());

+    }

+

+    @Test

+    public void duplicate_methods_filtered_out()

+    {

+        MethodIterator mi = new MethodIterator(Runnable3.class);

+

+        MethodSignature actual = mi.next();

+

+        assertEquals(new MethodSignature(void.class, "run", null, null), actual);

+

+        assertEquals(false, mi.getToString());

+    }

+

+    @Test

+    public void to_string_method_identified()

+    {

+        MethodIterator mi = new MethodIterator(ToString.class);

+

+        // Show that this is known immediately.

+

+        assertEquals(true, mi.getToString());

+

+        MethodSignature actual = mi.next();

+

+        assertEquals(new MethodSignature(String.class, "toString", null, null), actual);

+

+    }

+

+    @Test

+    public void inherited_methods_filtered_if_less_specific()

+    {

+        MethodIterator mi = new MethodIterator(CombinedOpeneable.class);

+

+        MethodSignature actual = mi.next();

+

+        assertEquals(new MethodSignature(void.class, "open", null, new Class[]{IOException.class}), actual);

+

+        assertEquals(false, mi.hasNext());

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodSignatureTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodSignatureTest.java
new file mode 100644
index 0000000..544a436
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/MethodSignatureTest.java
@@ -0,0 +1,200 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;

+

+import org.apache.tapestry.ioc.test.IOCTestCase;

+import org.testng.annotations.Test;

+

+import java.io.IOException;

+import java.io.ObjectInput;

+import java.io.ObjectInputStream;

+import java.lang.reflect.Method;

+import java.sql.SQLException;

+

+public class MethodSignatureTest extends IOCTestCase

+{

+    private MethodSignature find(Class sourceClass, String methodName)

+    {

+        Method[] methods = sourceClass.getMethods();

+

+        for (int i = 0; i < methods.length; i++)

+        {

+            Method m = methods[i];

+

+            if (m.getName().equals(methodName)) return new MethodSignature(m);

+        }

+

+        unreachable();

+        return null;

+    }

+

+    @Test

+    public void excercize_equals_and_hashcode()

+    {

+        MethodSignature m1 = find(Object.class, "hashCode");

+        MethodSignature m2 = find(Boolean.class, "hashCode");

+

+        assertEquals(m1.hashCode(), m2.hashCode());

+        assertTrue(m1.equals(m2));

+

+        m1 = find(String.class, "charAt");

+        m2 = find(StringBuilder.class, "charAt");

+

+        assertEquals(m1.hashCode(), m2.hashCode());

+        assertTrue(m1.equals(m2));

+

+        m1 = find(ObjectInput.class, "close");

+        m2 = find(ObjectInputStream.class, "close");

+

+        assertEquals(m1.hashCode(), m2.hashCode());

+        assertTrue(m1.equals(m2));

+    }

+

+    @Test

+    public void equals_and_hashcode_with_null_parameters_and_exception_lists()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+        MethodSignature m2 = new MethodSignature(void.class, "foo", new Class[0], new Class[0]);

+

+        assertEquals(m1, m2);

+        assertEquals(m2, m1);

+

+        assertEquals(m1.hashCode(), m2.hashCode());

+    }

+

+    @Test

+    public void equals_with_name_mismatch()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+        MethodSignature m2 = new MethodSignature(void.class, "bar", null, null);

+

+        assertEquals(false, m1.equals(m2));

+    }

+

+    @Test

+    public void equals_with_parameters_mismatch()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", new Class[]{String.class}, null);

+        MethodSignature m2 = new MethodSignature(void.class, "foo", new Class[]{Boolean.class}, null);

+

+        assertEquals(false, m1.equals(m2));

+    }

+

+    @Test

+    public void equals_with_null()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+

+        assertEquals(m1.equals(null), false);

+    }

+

+    @Test

+    public void equals_with_not_method_signature()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+

+        assertEquals(m1.equals("Method Signature"), false);

+    }

+

+    @Test

+    public void to_string()

+    {

+        MethodSignature m = find(String.class, "getChars");

+

+        assertEquals(m.toString(), "void getChars(int, int, char[], int)");

+

+        m = find(Class.class, "newInstance");

+

+        assertEquals(m.toString(),

+                     "java.lang.Object newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException");

+    }

+

+    @Test

+    public void unique_id()

+    {

+        MethodSignature m = find(String.class, "getChars");

+

+        assertEquals(m.getUniqueId(), "getChars(int,int,char[],int)");

+

+        m = find(Class.class, "newInstance");

+

+        assertEquals(m.getUniqueId(), "newInstance()");

+    }

+

+    @Test

+    public void overriding_signature_type_mismatch()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+        MethodSignature m2 = new MethodSignature(int.class, "foo", null, null);

+

+        assertEquals(m1.isOverridingSignatureOf(m2), false);

+    }

+

+    @Test

+    public void overriding_signature_name_mismatch()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+        MethodSignature m2 = new MethodSignature(void.class, "bar", null, null);

+

+        assertEquals(m1.isOverridingSignatureOf(m2), false);

+    }

+

+    @Test

+    public void overriding_signature_parameters_mismatch()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "foo", null, null);

+        MethodSignature m2 = new MethodSignature(void.class, "foo", new Class[]{String.class}, null);

+

+        assertEquals(m1.isOverridingSignatureOf(m2), false);

+    }

+

+    @Test

+    public void overriding_signature()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "close", null, new Class[]{Exception.class});

+        MethodSignature m2 = new MethodSignature(void.class, "close", null, new Class[]{RuntimeException.class});

+

+        assertEquals(m1.isOverridingSignatureOf(m2), true);

+        assertEquals(m2.isOverridingSignatureOf(m1), false);

+    }

+

+    /**

+     * Tests a shorcut used when one signature has zero exceptions.

+     */

+    @Test

+    public void overriding_signature_with_no_exceptions()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "close", null, null);

+        MethodSignature m2 = new MethodSignature(void.class, "close", null, new Class[]{RuntimeException.class});

+

+        assertEquals(m1.isOverridingSignatureOf(m2), false);

+        assertEquals(m2.isOverridingSignatureOf(m1), true);

+    }

+

+    /**

+     * Fill in code coverage for multiple matched signatures.

+     */

+    @Test

+    public void overriding_signature_with_multiple_matched_exceptions()

+    {

+        MethodSignature m1 = new MethodSignature(void.class, "close", null,

+                                                 new Class[]{SQLException.class, NumberFormatException.class});

+        MethodSignature m2 = new MethodSignature(void.class, "close", null,

+                                                 new Class[]{SQLException.class, IOException.class});

+

+        assertEquals(m1.isOverridingSignatureOf(m2), false);

+        assertEquals(m2.isOverridingSignatureOf(m1), false);

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/PropertyShadowBuilderImplTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/PropertyShadowBuilderImplTest.java
new file mode 100644
index 0000000..4879104
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/PropertyShadowBuilderImplTest.java
@@ -0,0 +1,165 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class PropertyShadowBuilderImplTest extends IOCTestCase
+{
+    private Registry registry;
+    private PropertyShadowBuilder builder;
+
+    private final String CLASS_NAME = getClass().getName();
+
+    @BeforeClass
+    public void setup_registry()
+    {
+        registry = buildRegistry();
+
+        builder = registry.getService("PropertyShadowBuilder", PropertyShadowBuilder.class);
+    }
+
+    @AfterClass
+    public void shutdown_registry()
+    {
+        registry.shutdown();
+
+        registry = null;
+        builder = null;
+    }
+
+    public class FooHolder
+    {
+        private Foo foo;
+
+        private int count = 0;
+
+        public Foo getFoo()
+        {
+            count++;
+
+            return foo;
+        }
+
+        public int getCount()
+        {
+            return count;
+        }
+
+        public void setFoo(Foo foo)
+        {
+            this.foo = foo;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "[FooHolder]";
+        }
+
+        public void setWriteOnly(Foo foo)
+        {
+
+        }
+    }
+
+    public interface Foo
+    {
+        void foo();
+    }
+
+    @Test
+    public void basic_delegation()
+    {
+        Foo foo = newMock(Foo.class);
+        FooHolder holder = new FooHolder();
+
+        holder.setFoo(foo);
+
+        Foo shadow = builder.build(holder, "foo", Foo.class);
+
+        for (int i = 0; i < 3; i++)
+        {
+            foo.foo();
+
+            replay();
+
+            shadow.foo();
+
+            verify();
+
+            assertEquals(holder.getCount(), i + 1);
+        }
+
+        assertEquals(shadow.toString(), "<Shadow: property foo of [FooHolder]>");
+    }
+
+    @Test
+    public void property_does_not_exist()
+    {
+        FooHolder holder = new FooHolder();
+
+        try
+        {
+            builder.build(holder, "bar", Foo.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class " + CLASS_NAME + "$FooHolder does not contain a property named 'bar'.");
+        }
+    }
+
+    @Test
+    public void property_type_mismatch()
+    {
+        FooHolder holder = new FooHolder();
+
+        try
+        {
+            builder.build(holder, "count", Map.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Property 'count' of class " + CLASS_NAME + "$FooHolder is of type int, which is not assignable to type java.util.Map.");
+        }
+    }
+
+    @Test
+    public void property_write_only()
+    {
+        FooHolder holder = new FooHolder();
+
+        try
+        {
+            builder.build(holder, "writeOnly", Foo.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Class " + CLASS_NAME + "$FooHolder does not provide an accessor ('getter') method for property 'writeOnly'.");
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/BodyBuilderTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/BodyBuilderTest.java
new file mode 100644
index 0000000..213a361
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/BodyBuilderTest.java
@@ -0,0 +1,128 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;

+

+import org.apache.tapestry.ioc.test.IOCTestCase;

+import org.testng.annotations.Test;

+

+public class BodyBuilderTest extends IOCTestCase

+{

+    @Test

+    public void simple_nesting_and_indentation()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.begin();

+        b.addln("invoke();");

+        b.end();

+

+        assertEquals(b.toString(), join("{", "  invoke();", "}"));

+    }

+

+    @Test

+    public void block_nesting()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.begin();

+

+        b.add("while(true)");

+        b.begin();

+        b.add("_i += 1;");

+        b.end();

+

+        b.end();

+

+        assertEquals(b.toString(), join("{", "  while(true)", "  {", "    _i += 1;", "  }", "}"));

+    }

+

+    @Test

+    public void addln_idents_subsequent_line()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.begin();

+        b.addln("invoke(fred);");

+        b.addln("invoke(barney);");

+        b.end();

+

+        assertEquals(b.toString(), join("{", "  invoke(fred);", "  invoke(barney);", "}"));

+    }

+

+    @Test

+    public void clear()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.begin();

+        b.add("fred");

+        b.end();

+

+        assertEquals(b.toString(), "{\n  fred\n}\n");

+

+        b.clear();

+

+        b.begin();

+        b.add("barney");

+        b.end();

+

+        assertEquals(b.toString(), "{\n  barney\n}\n");

+    }

+

+    @Test

+    public void add_with_format_and_args()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.add("%s = %d;", "i", 3);

+

+        assertEquals(b.toString(), "i = 3;");

+    }

+

+    @Test

+    public void addln_with_format_and_args()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.addln("%s = %d;", "i", 3);

+

+        assertEquals(b.toString(), "i = 3;\n");

+    }

+

+    @Test

+    public void indent_only_on_new_line()

+    {

+        BodyBuilder b = new BodyBuilder();

+

+        b.begin();

+        b.add("if");

+        b.addln(" (debug)");

+        b.add("  log.debug(\"%s\"", "foo");

+        b.addln(");");

+        b.addln("while (true)");

+        b.begin();

+        b.addln("if (%s > 10)", "i");

+        b.addln("  return;");

+        b.add("%s++;", "i");

+        b.end();

+        b.end();

+

+        assertEquals(b.toString(), join("{", "  if (debug)", "    log.debug(\"foo\");", "  while (true)", "  {",

+                                        "    if (i > 10)", "      return;", "    i++;", "  }", "}"

+

+        ));

+

+    }

+}

diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/CaseInsensitiveMapTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/CaseInsensitiveMapTest.java
new file mode 100644
index 0000000..24f3db2
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/CaseInsensitiveMapTest.java
@@ -0,0 +1,358 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.*;
+
+public class CaseInsensitiveMapTest extends Assert
+{
+    @Test
+    public void basic_get_put_remove()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        String value = "flintstone";
+
+        map.put("fred", value);
+
+        assertEquals(map.toString(), "{fred=flintstone}");
+
+        assertSame(map.get("fred"), value);
+        assertSame(map.get("Fred"), value);
+
+        assertSame(map.remove("FRED"), value);
+
+        assertFalse(map.containsKey("fred"));
+
+        assertTrue(map.isEmpty());
+    }
+
+    @Test
+    public void copy_map_constructor()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Map<String, String> copy = newCaseInsensitiveMap(map);
+
+        assertEquals(copy, map);
+    }
+
+    @Test
+    public void put_with_different_case_replaces()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        String value = "Murray";
+
+        map.put("Fred", value);
+
+        assertEquals(map.size(), 1);
+
+        assertSame(map.get("fred"), value);
+
+        assertEquals(map.toString(), "{Fred=Murray}");
+    }
+
+    @Test
+    public void get_with_missing_key_is_null()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        assertNull(map.get("barney"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void get_with_non_string_key_is_null()
+    {
+        Map map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        assertNull(map.get(this));
+    }
+
+    /**
+     * Add a large number of keys which should stress the code that adds and expands values into the
+     * map.
+     */
+    @Test
+    public void expansion_of_internal_entry_array()
+    {
+        Map<String, Integer> map = newCaseInsensitiveMap();
+
+        int COUNT = 2000;
+
+        for (int i = 0; i < COUNT; i++)
+        {
+            assertNull(map.put("key_" + i, i));
+        }
+
+        // Now check that the values are still there.
+
+        for (int i = 0; i < COUNT; i++)
+        {
+            assertEquals(map.get("KEY_" + i).intValue(), i);
+        }
+
+        assertEquals(map.size(), COUNT);
+        assertEquals(map.entrySet().size(), COUNT);
+
+        map.clear();
+
+        assertEquals(map.size(), 0);
+    }
+
+    @Test
+    public void change_value_via_entry_set()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        Map.Entry<String, String> me = map.entrySet().iterator().next();
+
+        String value = "murray";
+
+        me.setValue(value);
+
+        assertSame(map.get("fred"), value);
+    }
+
+    @Test(expectedExceptions =
+            {ConcurrentModificationException.class})
+    public void iterator_fail_fast_after_remove()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Iterator i = map.entrySet().iterator();
+
+        i.next();
+
+        map.remove("betty");
+
+        i.next();
+    }
+
+    @Test(expectedExceptions =
+            {ConcurrentModificationException.class})
+    public void iterator_fail_fast_on_next()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Iterator<Map.Entry<String, String>> i = map.entrySet().iterator();
+
+        while (i.hasNext())
+        {
+            if (i.next().getKey().equals("betty")) map.put("pebbles", "flintstone");
+        }
+    }
+
+    @Test
+    public void iterator_may_remove_without_concurrent_exception()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Iterator<Map.Entry<String, String>> i = map.entrySet().iterator();
+
+        while (i.hasNext())
+        {
+            if (i.next().getKey().equals("wilma")) i.remove();
+        }
+
+        List<String> keys = CollectionFactory.newList(map.keySet());
+        Collections.sort(keys);
+
+        assertEquals(keys, Arrays.asList("barney", "betty", "fred"));
+    }
+
+    @Test
+    public void contains_via_entry_set()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Set<Map.Entry<String, String>> entrySet = map.entrySet();
+
+        assertTrue(entrySet.contains(newMapEntry("fred", "flintstone")));
+        assertTrue(entrySet.contains(newMapEntry("Fred", "flintstone")));
+
+        assertFalse(entrySet.contains(newMapEntry("Zaphod", "Beeblebox")));
+        assertFalse(entrySet.contains(newMapEntry("fred", "murray")));
+    }
+
+    @Test
+    public void remove_via_entry_set()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Set<Map.Entry<String, String>> entrySet = map.entrySet();
+
+        assertFalse(entrySet.remove(newMapEntry("Zaphod", "Beeblebox")));
+        assertFalse(entrySet.remove(newMapEntry("fred", "murray")));
+
+        assertTrue(entrySet.remove(newMapEntry("Fred", "flintstone")));
+    }
+
+    @Test
+    public void null_key()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put(null, "NULL");
+
+        assertEquals(map.get(null), "NULL");
+    }
+
+    @Test
+    public void clear_entry_set_clears_map()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        map.entrySet().clear();
+
+        assertTrue(map.isEmpty());
+    }
+
+    @Test(expectedExceptions =
+            {NoSuchElementException.class})
+    public void next_after_last_entry_is_failure()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+
+        Iterator i = map.entrySet().iterator();
+
+        while (i.hasNext())
+            i.next();
+
+        i.next();
+    }
+
+    @Test
+    public void entry_set_iterator_sees_all_keys()
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        Iterator<Map.Entry<String, String>> i = map.entrySet().iterator();
+        List<String> keys = CollectionFactory.newList();
+
+        while (i.hasNext())
+            keys.add(i.next().getKey());
+
+        Collections.sort(keys);
+
+        assertEquals(keys, Arrays.asList("barney", "betty", "fred", "wilma"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void serialize_deserialize() throws Exception
+    {
+        Map<String, String> map = newCaseInsensitiveMap();
+
+        map.put("fred", "flintstone");
+        map.put("barney", "rubble");
+        map.put("wilma", "flinstone");
+        map.put("betty", "rubble");
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        oos.writeObject(map);
+        oos.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bais);
+
+        Map<String, String> copy = (Map<String, String>) ois.readObject();
+
+        assertEquals(copy, map);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <K, V> Map.Entry<K, V> newMapEntry(final K key, final V value)
+    {
+        return new Map.Entry()
+        {
+
+            public Object getKey()
+            {
+                return key;
+            }
+
+            public Object getValue()
+            {
+                return value;
+            }
+
+            public Object setValue(Object value)
+            {
+                throw new UnsupportedOperationException();
+            }
+
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/ExceptionUtilsTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/ExceptionUtilsTest.java
new file mode 100644
index 0000000..93af037
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/ExceptionUtilsTest.java
@@ -0,0 +1,40 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class ExceptionUtilsTest extends Assert
+{
+    @Test
+    public void find_cause_with_match()
+    {
+        TapestryException inner = new TapestryException("foo", null);
+
+        RuntimeException outer = new RuntimeException(inner);
+
+        assertSame(ExceptionUtils.findCause(outer, TapestryException.class), inner);
+    }
+
+    @Test
+    public void find_cause_no_match()
+    {
+        RuntimeException re = new RuntimeException("No cause for you!");
+
+        assertNull(ExceptionUtils.findCause(re, TapestryException.class));
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java
new file mode 100644
index 0000000..9b80ad5
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StackTest.java
@@ -0,0 +1,116 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newStack;
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+public class StackTest extends TestBase
+{
+    @Test
+    public void peek_in_empty_stack_is_failure()
+    {
+        Stack<Integer> stack = newStack();
+
+        try
+        {
+            stack.peek();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(), "Stack is empty.");
+        }
+    }
+
+    @Test
+    public void pop_in_empty_stack_is_failure()
+    {
+        Stack<Integer> stack = newStack();
+
+        try
+        {
+            stack.pop();
+            unreachable();
+        }
+        catch (IllegalStateException ex)
+        {
+            assertEquals(ex.getMessage(), "Stack is empty.");
+        }
+    }
+
+    @Test
+    public void basic_operations()
+    {
+        Stack<String> stack = newStack();
+
+        assertTrue(stack.isEmpty());
+
+        final String fred = "fred";
+        final String barney = "barney";
+
+        stack.push(fred);
+        assertEquals(stack.peek(), fred);
+        assertFalse(stack.isEmpty());
+
+        stack.push(barney);
+        assertEquals(stack.peek(), barney);
+
+        assertEquals(stack.toString(), "Stack[barney, fred]");
+
+        Object[] snapshot = stack.getSnapshot();
+
+        assertArraysEqual(snapshot, new Object[]{fred, barney});
+
+        assertEquals(stack.pop(), barney);
+        assertEquals(stack.peek(), fred);
+
+        assertEquals(stack.pop(), fred);
+        assertTrue(stack.isEmpty());
+    }
+
+    @Test
+    public void expansion_of_inner_data()
+    {
+        final int LIMIT = 1000;
+
+        Stack<Integer> stack = newStack(10);
+
+        for (int i = 0; i < LIMIT; i++)
+        {
+            stack.push(i);
+        }
+
+        for (int i = LIMIT - 1; i >= 0; i--)
+        {
+            assertEquals(stack.pop().intValue(), i);
+        }
+    }
+
+    @Test
+    public void clear()
+    {
+        Stack<Integer> stack = newStack();
+
+        for (int i = 0; i < 10; i++) stack.push(i);
+
+        assertEquals(stack.isEmpty(), false);
+
+        stack.clear();
+
+        assertEquals(stack.isEmpty(), true);
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java
new file mode 100644
index 0000000..a3fba88
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java
@@ -0,0 +1,176 @@
+// Copyright 2006, 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.util.*;
+
+public class StrategyRegistryTest extends IOCTestCase
+{
+    @Test
+    public void adapter_not_found()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        try
+        {
+            r.get(Set.class);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "No adapter from type java.util.Set to type java.lang.Runnable is available (registered types are java.util.List, java.util.Map).");
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_types()
+    {
+
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+
+        Collection<Class> types = r.getTypes();
+
+        assertEquals(types.size(), 2);
+        assertTrue(types.contains(List.class));
+        assertTrue(types.contains(Map.class));
+
+        verify();
+    }
+
+    @Test
+    public void adapter_not_found_when_non_error()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        Runnable actual = r.get(ArrayList.class);
+
+        assertSame(actual, r1);
+
+        // The cache is almost impossible to "test", but we can at least collect some
+        // code coverage over those lines.
+
+        Runnable actual2 = r.get(ArrayList.class);
+        assertSame(actual2, r1);
+
+        r.clearCache();
+
+        Runnable actual3 = r.get(ArrayList.class);
+        assertSame(actual3, r1);
+
+        verify();
+    }
+
+    @Test
+    public void registration_map_is_copied_by_constructor()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        registrations.clear();
+
+        Runnable actual = r.get(ArrayList.class);
+
+        assertSame(actual, r1);
+    }
+
+    @Test
+    public void adapter_found_by_instance()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        assertSame(r.getByInstance(registrations), r2);
+
+        verify();
+    }
+
+    @Test
+    public void null_instance_matches_class_void()
+    {
+        Runnable r1 = mockRunnable();
+        Runnable r2 = mockRunnable();
+        Runnable r3 = mockRunnable();
+
+        replay();
+
+        Map<Class, Runnable> registrations = newMap();
+
+        registrations.put(List.class, r1);
+        registrations.put(Map.class, r2);
+        registrations.put(void.class, r3);
+
+        StrategyRegistry<Runnable> r = StrategyRegistry.newInstance(Runnable.class, registrations);
+
+        assertSame(r.getByInstance(null), r3);
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/TimeIntervalTest.java b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/TimeIntervalTest.java
new file mode 100644
index 0000000..e1ade74
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/TimeIntervalTest.java
@@ -0,0 +1,100 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ioc.util;
+
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TimeIntervalTest extends TestBase
+{
+    @Test
+    public void use_constructor()
+    {
+        TimeInterval p = new TimeInterval("30 s");
+
+        assertEquals(p.seconds(), 30);
+        assertEquals(p.milliseconds(), 30 * 1000);
+
+        assertEquals(p.toString(), "TimeInterval[30000 ms]");
+    }
+
+    @Test
+    public void invalid_units()
+    {
+        try
+        {
+            TimeInterval.parseMilliseconds("30s 500mz");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(),
+                         "Unknown time interval unit 'mz' (in '30s 500mz').  Defined units: d, h, m, ms, s, y.");
+        }
+    }
+
+    @Test
+    public void unrecognized_input()
+    {
+        try
+        {
+            TimeInterval.parseMilliseconds("30s z 500ms");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Unexpected string 'z' (in time interval '30s z 500ms').");
+        }
+    }
+
+    @Test
+    public void unrecognized_input_at_end()
+    {
+        try
+        {
+            TimeInterval.parseMilliseconds("30s  500ms xyz");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(ex.getMessage(), "Unexpected string 'xyz' (in time interval '30s  500ms xyz').");
+        }
+    }
+
+    @Test(dataProvider = "mix_of_units_data")
+    public void mix_of_units(String input, long expected)
+    {
+        assertEquals(TimeInterval.parseMilliseconds(input), expected);
+    }
+
+    @DataProvider(name = "mix_of_units_data")
+    public Object[][] mix_of_units_data()
+    {
+        return new Object[][] { { "54321", 54321 },
+
+                { "30s", 30 * 1000 },
+
+                { "1h 30m", 90 * 60 * 1000 },
+
+                { "2d", 2 * 24 * 60 * 60 * 1000 },
+
+                { "2m", 2 * 60 * 1000 },
+
+                { "23ms", 23 }
+
+        };
+    }
+}
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/log4j.properties b/hlship-20080520/tapestry-ioc/src/test/resources/log4j.properties
new file mode 100644
index 0000000..ee51f8e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/log4j.properties
@@ -0,0 +1,27 @@
+# Copyright 2005, 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootCategory=WARN, A1

+

+# A1 is set to be a ConsoleAppender. 

+log4j.appender.A1=org.apache.log4j.ConsoleAppender

+

+# A1 uses PatternLayout.

+log4j.appender.A1.layout=org.apache.log4j.PatternLayout

+log4j.appender.A1.layout.ConversionPattern=[%p] %c{1} %m%n

+

+log4j.category.org.apache.tapestry=error

+log4j.category.tapestry=error

+log4j.category.tapestry.ioc.ClassFactory=error

+

diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/parent-folder.txt b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/parent-folder.txt
new file mode 100644
index 0000000..1707262
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/parent-folder.txt
@@ -0,0 +1 @@
+content from parent-folder resource
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/TargetStrings.properties b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/TargetStrings.properties
new file mode 100644
index 0000000..21dfbc8
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/TargetStrings.properties
@@ -0,0 +1,17 @@
+# Copyright 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+no-args=No arguments.

+something-failed=Something failed: %s

+result=The result is '%s'.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.ext b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.ext
new file mode 100644
index 0000000..d48236e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.ext
@@ -0,0 +1 @@
+ext content
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.txt b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.txt
new file mode 100644
index 0000000..261ac3e
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource.txt
@@ -0,0 +1 @@
+content from resource.txt
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource_fr.txt b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource_fr.txt
new file mode 100644
index 0000000..de8bee9
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/resource_fr.txt
@@ -0,0 +1 @@
+french content
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/same-folder.txt b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/same-folder.txt
new file mode 100644
index 0000000..3fee37d
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/same-folder.txt
@@ -0,0 +1 @@
+content from same-folder resource
diff --git a/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/sub/sub-folder.txt b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/sub/sub-folder.txt
new file mode 100644
index 0000000..5552aec
--- /dev/null
+++ b/hlship-20080520/tapestry-ioc/src/test/resources/org/apache/tapestry/ioc/internal/util/sub/sub-folder.txt
@@ -0,0 +1 @@
+content from sub-folder resource
diff --git a/hlship-20080520/tapestry-spring/.classpath b/hlship-20080520/tapestry-spring/.classpath
new file mode 100644
index 0000000..df0c639
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="src" output="bin-test" path="src/test/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="lib" path="src/test/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-spring/.project b/hlship-20080520/tapestry-spring/.project
new file mode 100644
index 0000000..4d081cb
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-spring</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-spring/LICENSE.txt b/hlship-20080520/tapestry-spring/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/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/hlship-20080520/tapestry-spring/NOTICE.txt b/hlship-20080520/tapestry-spring/NOTICE.txt
new file mode 100644
index 0000000..439eb83
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/NOTICE.txt
@@ -0,0 +1,3 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/hlship-20080520/tapestry-spring/pom.xml b/hlship-20080520/tapestry-spring/pom.xml
new file mode 100644
index 0000000..fd72364
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-spring</artifactId>
+    <name>Tapestry/Spring Integration Library</name>
+    <packaging>jar</packaging>
+    <description>
+        Provides integration of Tapestry with the Spring IoC container.
+    </description>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-test</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+            <!-- This gets the plugin to clean up the cobertura.ser file left
+        in the root directory. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/internal/spring/SpringModuleDef.java b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/internal/spring/SpringModuleDef.java
new file mode 100644
index 0000000..16ba48c
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/internal/spring/SpringModuleDef.java
@@ -0,0 +1,183 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.spring;
+
+import org.apache.tapestry.ioc.IOCConstants;
+import org.apache.tapestry.ioc.ObjectCreator;
+import org.apache.tapestry.ioc.ServiceBuilderResources;
+import org.apache.tapestry.ioc.def.ContributionDef;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+import org.springframework.beans.factory.BeanFactoryUtils;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A wrapper that converts a Spring {@link ApplicationContext} into a set of service definitions, compatible with
+ * Tapestry 5 IoC, for the beans defined in the context, as well as the context itself.
+ */
+public class SpringModuleDef implements ModuleDef
+{
+    private static final String CONTEXT_SERVICE_ID = WebApplicationContext.class.getSimpleName();
+
+    private final Map<String, ServiceDef> serviceDefs = newCaseInsensitiveMap();
+
+    public SpringModuleDef(final ApplicationContext context)
+    {
+        for (final String beanName : BeanFactoryUtils.beanNamesIncludingAncestors(context))
+        {
+            ServiceDef serviceDef = new ServiceDef()
+            {
+                private Object getBean()
+                {
+                    return context.getBean(beanName);
+                }
+
+                private Class getBeanType()
+                {
+                    return context.getType(beanName);
+                }
+
+                public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
+                {
+                    return new ObjectCreator()
+                    {
+                        public Object createObject()
+                        {
+                            return getBean();
+                        }
+                    };
+                }
+
+                public String getServiceId()
+                {
+                    return beanName;
+                }
+
+                public Class getServiceInterface()
+                {
+                    return getBeanType();
+                }
+
+                public String getServiceScope()
+                {
+                    return IOCConstants.DEFAULT_SCOPE;
+                }
+
+                public boolean isEagerLoad()
+                {
+                    return false;
+                }
+
+                /** Returns an empty set, Spring has no concept of a marker annotation. */
+                public Set<Class> getMarkers()
+                {
+                    return Collections.emptySet();
+                }
+
+            };
+
+            serviceDefs.put(beanName, serviceDef);
+        }
+
+        // And add one service that is the Spring WebApplicationContext.
+
+        ServiceDef serviceDef = new ServiceDef()
+        {
+            public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
+            {
+                return new ObjectCreator()
+                {
+                    public Object createObject()
+                    {
+                        return context;
+                    }
+                };
+            }
+
+            public String getServiceId()
+            {
+                return CONTEXT_SERVICE_ID;
+            }
+
+            public Class getServiceInterface()
+            {
+                return WebApplicationContext.class;
+            }
+
+            public String getServiceScope()
+            {
+                return IOCConstants.DEFAULT_SCOPE;
+            }
+
+            public boolean isEagerLoad()
+            {
+                return false;
+            }
+
+            /** Returns null. */
+            public Set<Class> getMarkers()
+            {
+                return Collections.emptySet();
+            }
+
+        };
+
+        serviceDefs.put(CONTEXT_SERVICE_ID, serviceDef);
+    }
+
+    public Class getBuilderClass()
+    {
+        return null;
+    }
+
+    /**
+     * Returns an empty set.
+     */
+    public Set<ContributionDef> getContributionDefs()
+    {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns an empty set.
+     */
+    public Set<DecoratorDef> getDecoratorDefs()
+    {
+        return Collections.emptySet();
+    }
+
+    public String getLoggerName()
+    {
+        return "Spring";
+    }
+
+    public ServiceDef getServiceDef(String serviceId)
+    {
+        return serviceDefs.get(serviceId);
+    }
+
+    public Set<String> getServiceIds()
+    {
+        return serviceDefs.keySet();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/SpringMessages.java b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/SpringMessages.java
new file mode 100644
index 0000000..9808465
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/SpringMessages.java
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.spring;
+
+import org.apache.tapestry.ioc.Messages;
+import org.apache.tapestry.ioc.internal.util.MessagesImpl;
+import org.springframework.web.context.ContextLoaderListener;
+
+class SpringMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(SpringMessages.class);
+
+    static String failureObtainingContext(Throwable cause)
+    {
+        return MESSAGES.format("failure-obtaining-context", cause);
+    }
+
+    static String missingContext()
+    {
+        return MESSAGES.format("missing-context", ContextLoaderListener.class.getName());
+    }
+}
diff --git a/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/TapestrySpringFilter.java b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/TapestrySpringFilter.java
new file mode 100644
index 0000000..c470f94
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/main/java/org/apache/tapestry/spring/TapestrySpringFilter.java
@@ -0,0 +1,52 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.spring;
+
+import org.apache.tapestry.TapestryFilter;
+import org.apache.tapestry.internal.spring.SpringModuleDef;
+import org.apache.tapestry.ioc.def.ModuleDef;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.WebApplicationContext;
+
+import javax.servlet.ServletContext;
+
+/**
+ * Adds a {@link ModuleDef} that contains all the beans defined by the Spring
+ * {@link ApplicationContext}, as if they were Tapestry IoC services. This is done using a filter,
+ * so that the Spring beans can be "mixed into" the Tapestry IoC Registry before it even starts up.
+ */
+public class TapestrySpringFilter extends TapestryFilter
+{
+    @Override
+    protected ModuleDef[] provideExtraModuleDefs(ServletContext context)
+    {
+        ApplicationContext springContext = null;
+
+        try
+        {
+            springContext = (ApplicationContext) context
+                    .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(SpringMessages.failureObtainingContext(ex), ex);
+        }
+
+        if (springContext == null) throw new RuntimeException(SpringMessages.missingContext());
+
+        return new ModuleDef[]
+                {new SpringModuleDef(springContext)};
+    }
+}
diff --git a/hlship-20080520/tapestry-spring/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties b/hlship-20080520/tapestry-spring/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties
new file mode 100644
index 0000000..6046245
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/main/resources/org/apache/tapestry/spring/SpringStrings.properties
@@ -0,0 +1,16 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+failure-obtaining-context=An exception occurred obtaining the Spring WebApplicationContext: %s
+missing-context=The Spring WebApplicationContext is not present. The likely cause is that the %s listener was not declared inside the application's web.xml deployment descriptor.
diff --git a/hlship-20080520/tapestry-spring/src/site/apt/index.apt b/hlship-20080520/tapestry-spring/src/site/apt/index.apt
new file mode 100644
index 0000000..2e6ed53
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/site/apt/index.apt
@@ -0,0 +1,114 @@
+ ----
+ Tapestry/Spring Integration
+ ----
+ 
+Tapestry/Spring Integration
+
+  Provides integration between Tapestry and Spring, allowing beans defined by Spring to be injected into Tapestry IoC services, and into
+  Tapestry components.
+  
+Version
+
+  This module is compiled and tested against Spring 1.2.8.  However, Spring 2.0 is fully backwards compatible to Spring 1.2.8.
+  
+  This module uses the Maven scope "provided" for the dependencies on Spring. This means that in your own POM, you will need to specify your own
+  dependency to Spring, including the correct version.  Example:
+  
++---+
+<dependency>
+  <groupId>org.springframework</groupId>
+  <artifactId>spring-web</artifactId>
+  <version>1.2.8</version>
+</dependency>    
++----+
+
+  With the default Maven scope, the Spring JARs and dependencies will be packaged into your application's WAR file.
+  
+  
+Usage
+
+  The integration is designed to be a very thin layer on top of Spring's normal configuration for a web application.
+  
+  Detailed instructions are available in the
+  {{{http://static.springframework.org/spring/docs/1.2.x/reference/beans.html#context-create}Spring 1.2.x documentation}}.
+  
+* web.xml changes
+  
+  The short form is that you must make two small changes to your application's web.xml.
+  
+  First, a special filter is used in replace of the standard TapestryFilter:
+  
++---+
+  <filter>
+    <filter-name>app</filter-name>
+    <!-- Special filter that adds in a T5 IoC module derived from the Spring WebApplicationContext. -->
+    <filter-class>org.apache.tapestry.spring.TapestrySpringFilter</filter-class>
+  </filter>
++---+  
+ 
+   Secondly, you must add the normal Spring configuration, consisting of a \<listener\> element,
+   and (optionally) a \<context-param\> identifying which Spring bean configuration file(s) to load:
+ 
++---+
+<context-param>
+  <param-name>contextConfigLocation</param-name>
+  <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
+</context-param>
+
+<listener>
+  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+</listener>
++---+
+
+  The \<context-param\> lists the Spring bean configuration file.  It is optional and defaults to just /WEB-INF/applicationContext.xml if omitted.
+  
+  The ContextLoaderListener is responsible for reading the bean configuration file (or files) and storing the result in the application context, where
+  the Tapestry-Spring integration code can make use of it.
+  
+* Injecting beans
+
+  Inside your component classes, you may use the 
+  {{{http://tapestry.apache.org/tapestry5/tapestry-core/apidocs/org/apache/tapestry/ioc/annotations/Inject.html}Inject}} annotation.  Typically, just the field 
+  type is sufficient to identify the Spring bean to inject:
+  
++----+
+  @Inject
+  private UserDAO userDAO;
++----+
+
+  If you have multiple beans that implement the same interface (for instance, if you have wrapped your bean using a transaction interceptor), you must disambiguate.  The easiest way
+  to accomplish this is to add a 
+  {{{http://tapestry.apache.org/tapestry5/tapestry-core/apidocs/org/apache/tapestry/annotations/Service.html}Service}}
+  annotation to identify the name of the
+  Spring bean:
+  
++----+
+  @Inject
+  @Service("UserDAO")
+  private UserDAO userDAO;
++----+  
+  
+  Injection of Spring beans via service builder methods or autobuilding occurs just the same: the Spring beans masquerade as Tapestry IoC services and all is well.
+ 
+Case Insensitivity
+
+  Spring beans names are treated exactly as Tapestry IoC service ids.  Since service ids are case insensitive, access to Spring beans by bean name will also
+  be case insensitive.
+  
+WebApplicationContext Service
+
+  The Spring WebApplicationContext is also added as a service, in addition to any services defined within the context.
+  
+Limitations
+
+  The names of beans are obtained at application start up. If new beans are programattically added to the Spring application context at runtime,
+  these will not be visible for injection.
+  
+  Only the bean <name> is used, not any of the bean's <aliases>.
+  
+  No check is made for name clashes that would occur when two beans have names that differ only in terms of capitalization.  If you're going to go around naming beans "userDAO" and "UserDao",
+  you're just asking for trouble.
+  
+  Non-singleton beans are not handled properly. Tapestry will request the beans from the application context in a manner unsuitable for their lifecycle.
+  For the moment, you should consider the non-singleton beans to be not-injectable.  Instead, inject the WebApplicationContext service and
+  obtain the non-singleton beans as needed.
diff --git a/hlship-20080520/tapestry-spring/src/site/site.xml b/hlship-20080520/tapestry-spring/src/site/site.xml
new file mode 100644
index 0000000..702547e
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/site/site.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Spring Integration">
+    <bannerLeft>
+        <name>Tapestry 5</name>
+        <href>http://tapestry.apache.org/tapestry5/</href>
+        <src>images/tapestry_banner.gif</src>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache</name>
+        <href>http://www.apache.org</href>
+        <src>images/asf_logo_wide.gif</src>
+    </bannerRight>
+    <skin>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>maven-skin</artifactId>
+        <version>1.1</version>
+    </skin>
+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+
+        <menu name="Quick Links">
+            <item name="Download" href="http://tapestry.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="reports"/>
+
+    </body>
+</project>
diff --git a/hlship-20080520/tapestry-spring/src/test/conf/testng.xml b/hlship-20080520/tapestry-spring/src/test/conf/testng.xml
new file mode 100644
index 0000000..002055e
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/conf/testng.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapesty Spring Integration" parallel="false" thread-count="10" annotations="1.5" verbose="2">
+    <test name="Tapestry Spring Integration">
+        <packages>
+            <package name="org.apache.tapestry.spring"/>
+        </packages>
+    </test>
+</suite>
diff --git a/hlship-20080520/tapestry-spring/src/test/conf/webdefault.xml b/hlship-20080520/tapestry-spring/src/test/conf/webdefault.xml
new file mode 100644
index 0000000..5a40749
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/conf/webdefault.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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">

+

+    <description>

+        Default web.xml file.

+        This file is applied to a Web application before it's own WEB_INF/web.xml file

+    </description>

+

+

+    <!-- ==================================================================== -->

+    <!-- Context params to control Session Cookies                            -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <!-- UNCOMMENT TO ACTIVATE

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>

+      <param-value>127.0.0.1</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>

+      <param-value>/</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>

+      <param-value>-1</param-value>

+    </context-param>

+    -->

+

+

+    <!-- ==================================================================== -->

+    <!-- The default servlet.                                                 -->

+    <!-- This servlet, normally mapped to /, provides the handling for static -->

+    <!-- content, OPTIONS and TRACE methods for the context.                  -->

+    <!-- The following initParameters are supported:                          -->

+    <!--                                                                      -->

+    <!--   acceptRanges     If true, range requests and responses are         -->

+    <!--                    supported                                         -->

+    <!--                                                                      -->

+    <!--   dirAllowed       If true, directory listings are returned if no    -->

+    <!--                    welcome file is found. Else 403 Forbidden.        -->

+    <!--                                                                      -->

+    <!--   putAllowed       If true, the PUT method is allowed                -->

+    <!--                                                                      -->

+    <!--   delAllowed       If true, the DELETE method is allowed             -->

+    <!--                                                                      -->

+    <!--   redirectWelcome  If true, redirect welcome file requests           -->

+    <!--                    else use request dispatcher forwards              -->

+    <!--                                                                      -->

+    <!--   minGzipLength    If set to a positive integer, then static content -->

+    <!--                    larger than this will be served as gzip content   -->

+    <!--                    encoded if a matching resource is found ending    -->

+    <!--                    with ".gz"                                        -->

+    <!--                                                                      -->

+    <!--   resoureBase      Can be set to replace the context resource base   -->

+    <!--                                                                      -->

+    <!--   relativeResourceBase                                               -->

+    <!--                    Set with a pathname relative to the base of the   -->

+    <!--                    servlet context root. Useful for only serving     -->

+    <!--                    static content from only specific subdirectories. -->

+    <!--                                                                      -->

+    <!-- The MOVE method is allowed if PUT and DELETE are allowed             -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <servlet>

+        <servlet-name>default</servlet-name>

+        <servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>

+        <init-param>

+            <param-name>acceptRanges</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>dirAllowed</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>putAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>delAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>redirectWelcome</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>minGzipLength</param-name>

+            <param-value>8192</param-value>

+        </init-param>

+        <load-on-startup>0</load-on-startup>

+    </servlet>

+

+

+    <servlet-mapping>

+        <servlet-name>default</servlet-name>

+        <url-pattern>/</url-pattern>

+    </servlet-mapping>

+

+    <!-- ==================================================================== -->

+    <session-config>

+        <session-timeout>30</session-timeout>

+    </session-config>

+

+

+    <!-- ==================================================================== -->

+    <welcome-file-list>

+        <welcome-file>index.html</welcome-file>

+        <welcome-file>index.htm</welcome-file>

+    </welcome-file-list>

+

+    <!-- ==================================================================== -->

+    <locale-encoding-mapping-list>

+        <locale-encoding-mapping>

+            <locale>ar</locale>

+            <encoding>ISO-8859-6</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>be</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>bg</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ca</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>cs</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>da</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>de</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>el</locale>

+            <encoding>ISO-8859-7</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>en</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>es</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>et</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fi</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fr</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hr</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hu</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>is</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>it</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>iw</locale>

+            <encoding>ISO-8859-8</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ja</locale>

+            <encoding>Shift_JIS</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ko</locale>

+            <encoding>EUC-KR</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lt</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lv</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>mk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>nl</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>no</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pt</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ro</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ru</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sh</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sk</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sq</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sr</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sv</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>tr</locale>

+            <encoding>ISO-8859-9</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>uk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh</locale>

+            <encoding>GB2312</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh_TW</locale>

+            <encoding>Big5</encoding>

+        </locale-encoding-mapping>

+    </locale-encoding-mapping-list>

+

+

+</web-app>

+

diff --git a/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringFilterTest.java b/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringFilterTest.java
new file mode 100644
index 0000000..5ab409e
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringFilterTest.java
@@ -0,0 +1,88 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.spring;
+
+import org.apache.tapestry.test.TapestryTestCase;
+import org.springframework.web.context.WebApplicationContext;
+import org.testng.annotations.Test;
+
+import javax.servlet.ServletContext;
+
+public class TapestrySpringFilterTest extends TapestryTestCase
+{
+    @Test
+    public void no_web_application_context_in_servlet_context() throws Exception
+    {
+        ServletContext context = mockServletContext();
+
+        expect(context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE))
+                .andReturn(null);
+
+        replay();
+
+        TapestrySpringFilter filter = new TapestrySpringFilter();
+
+        try
+        {
+            filter.provideExtraModuleDefs(context);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "The Spring WebApplicationContext is not present. "
+                            + "The likely cause is that the org.springframework.web.context.ContextLoaderListener listener was not declared "
+                            + "inside the application\'s web.xml deployment descriptor.");
+        }
+
+        verify();
+    }
+
+    protected final ServletContext mockServletContext()
+    {
+        return newMock(ServletContext.class);
+    }
+
+    @Test
+    public void failure_obtaining_context() throws Exception
+    {
+        ServletContext context = mockServletContext();
+        Throwable t = new RuntimeException("Failure.");
+
+        expect(context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE))
+                .andThrow(t);
+
+        replay();
+
+        TapestrySpringFilter filter = new TapestrySpringFilter();
+
+        try
+        {
+            filter.provideExtraModuleDefs(context);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "An exception occurred obtaining the Spring WebApplicationContext: Failure.");
+
+            assertSame(ex.getCause(), t);
+        }
+
+        verify();
+    }
+}
diff --git a/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringIntegrationTest.java b/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringIntegrationTest.java
new file mode 100644
index 0000000..263515f
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/java/org/apache/tapestry/spring/TapestrySpringIntegrationTest.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.spring;
+
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+public class TapestrySpringIntegrationTest extends AbstractIntegrationTestSuite
+{
+    public TapestrySpringIntegrationTest()
+    {
+        super("src/test/webapp");
+    }
+
+    @Test
+    public void integration_test() throws Exception
+    {
+        open(BASE_URL);
+
+        type("input", "paris in the springtime");
+        clickAndWait("//input[@value='Convert']");
+
+        assertFieldValue("input", "PARIS IN THE SPRINGTIME");
+    }
+
+    @Test
+    public void access_to_spring_context() throws Exception
+    {
+        open(BASE_URL);
+
+        assertTextPresent("[upcase]");
+    }
+}
diff --git a/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/pages/Start.java b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/pages/Start.java
new file mode 100644
index 0000000..e4a3273
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/pages/Start.java
@@ -0,0 +1,57 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.testapp.pages;
+
+import org.apache.tapestry.annotation.Retain;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.example.testapp.services.Upcase;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.util.Arrays;
+
+public class Start
+{
+    @Retain
+    private String input;
+
+    // We're matching on type here, just as we would a service provided in a T5 IoC module.
+    @Inject
+    private Upcase upcaseBean;
+
+    @Inject
+    private WebApplicationContext context;
+
+    void onSuccess()
+    {
+        input = upcaseBean.toUpperCase(input);
+    }
+
+    public String getInput()
+    {
+        return input;
+    }
+
+    public void setInput(String input)
+    {
+        this.input = input;
+    }
+
+    public String getSpringBeans()
+    {
+        return InternalUtils.join(Arrays.asList(context.getBeanDefinitionNames()));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/Upcase.java b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/Upcase.java
new file mode 100644
index 0000000..2a30537
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/Upcase.java
@@ -0,0 +1,23 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.testapp.services;
+
+/**
+ * Test interface for an injectble Spring bean.
+ */
+public interface Upcase
+{
+    String toUpperCase(String input);
+}
diff --git a/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/UpcaseImpl.java b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/UpcaseImpl.java
new file mode 100644
index 0000000..296ee90
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/java/org/example/testapp/services/UpcaseImpl.java
@@ -0,0 +1,25 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.example.testapp.services;
+
+public class UpcaseImpl implements Upcase
+{
+
+    public String toUpperCase(String input)
+    {
+        return input.toUpperCase();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-spring/src/test/resources/log4j.properties b/hlship-20080520/tapestry-spring/src/test/resources/log4j.properties
new file mode 100644
index 0000000..f6ebbaf
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/resources/log4j.properties
@@ -0,0 +1,31 @@
+# Copyright 2005, 2006 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootCategory=WARN, A1

+

+# A1 is set to be a ConsoleAppender. 

+log4j.appender.A1=org.apache.log4j.ConsoleAppender

+

+# A1 uses PatternLayout.

+log4j.appender.A1.layout=org.apache.log4j.PatternLayout

+log4j.appender.A1.layout.ConversionPattern=[%p] %c{1} %m%n

+

+log4j.category.org.apache.tapestry.TapestryFilter=info

+log4j.category.org.apache.tapestry=error

+log4j.category.tapestry=error

+log4j.category.tapestry.ioc.ClassFactory=error

+

+log4j.category.app=info

+log4j.category.org.apache.tapestry.integration.app1=error

+log4j.category.org.apache.tapestry.corelib=error
diff --git a/hlship-20080520/tapestry-spring/src/test/webapp/Start.tml b/hlship-20080520/tapestry-spring/src/test/webapp/Start.tml
new file mode 100644
index 0000000..21e77b6
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/webapp/Start.tml
@@ -0,0 +1,21 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Start Page</title>
+  </head>
+  <body>
+    <p>
+      This is a silly application for converting text to uppercase.
+    </p>
+    <t:form>
+      <t:errors/>
+      <t:label for="input"/>
+      <input t:type="textfield" t:id="input" size="40"/>
+      <br/>
+      <input type="submit" value="Convert"/>
+    </t:form>
+    
+    <p>
+      Spring beans: [${springBeans}]
+    </p>
+  </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/applicationContext.xml b/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/applicationContext.xml
new file mode 100644
index 0000000..89c4b90
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/applicationContext.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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 beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+    <bean id="upcase" class="org.example.testapp.services.UpcaseImpl"/>
+</beans>
+
diff --git a/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/web.xml b/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..402d3f8
--- /dev/null
+++ b/hlship-20080520/tapestry-spring/src/test/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+        "http://java.sun.com/dtd/web-app_2_3.dtd">
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Tapestry-Spring Integration Test Application</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.example.testapp</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <!-- Special filter that adds in a T5 IoC module derived from the Spring WebApplicationContext. -->
+        <filter-class>org.apache.tapestry.spring.TapestrySpringFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <!--
+   This is where the Spring support is configured.
+    -->
+    <listener>
+        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+    </listener>
+</web-app>
diff --git a/hlship-20080520/tapestry-test/.classpath b/hlship-20080520/tapestry-test/.classpath
new file mode 100644
index 0000000..d4e13c7
--- /dev/null
+++ b/hlship-20080520/tapestry-test/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-test/.project b/hlship-20080520/tapestry-test/.project
new file mode 100644
index 0000000..6f58b16
--- /dev/null
+++ b/hlship-20080520/tapestry-test/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-test</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-test/LICENSE.txt b/hlship-20080520/tapestry-test/LICENSE.txt
new file mode 100644
index 0000000..84712cb
--- /dev/null
+++ b/hlship-20080520/tapestry-test/LICENSE.txt
@@ -0,0 +1,250 @@
+
+                                 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.
+
+   
+
+This file contains the contents of the Ispell (ver 3.1.20) word list after
+being expand from there affix compressed form used by Ispell.
+
+Ispell can be found at http://fmg-www.cs.ucla.edu/geoff/ispell.html.
+This wordlist can be found at http://wordlist.sourceforge.net/
+
+These word lists are under the same copyright as Ispell itself:
+
+  Copyright 1993, Geoff Kuenning, Granada Hills, CA
+  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. All modifications to the source code must be clearly marked as
+     such.  Binary redistributions based on modified source code
+     must be clearly marked as modified versions in the documentation
+     and/or other materials provided with the distribution.
+  4. All advertising materials mentioning features or use of this software
+     must display the following acknowledgment:
+     This product includes software developed by Geoff Kuenning and
+     other unpaid contributors.
+  5. The name of Geoff Kuenning may not be used to endorse or promote
+     products derived from this software without specific prior
+     written permission.
+
+  THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING 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 GEOFF
+  KUENNING 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.
+   
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-test/NOTICE.txt b/hlship-20080520/tapestry-test/NOTICE.txt
new file mode 100644
index 0000000..183dd0b
--- /dev/null
+++ b/hlship-20080520/tapestry-test/NOTICE.txt
@@ -0,0 +1,10 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes software developed by Geoff Kuenning and
+other unpaid contributors.
+http://fmg-www.cs.ucla.edu/geoff/ispell.html
+
+
+
+
diff --git a/hlship-20080520/tapestry-test/pom.xml b/hlship-20080520/tapestry-test/pom.xml
new file mode 100644
index 0000000..77d7a29
--- /dev/null
+++ b/hlship-20080520/tapestry-test/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-test</artifactId>
+    <name>Tapestry Test Utilities</name>
+    <inceptionYear>2007</inceptionYear>
+    <description>Test utilities needed by Tapestry</description>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.openqa.selenium.client-drivers</groupId>
+            <artifactId>selenium-java-client-driver</artifactId>
+            <version>0.9.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openqa.selenium.server</groupId>
+            <artifactId>selenium-server</artifactId>
+            <version>0.9.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.7</version>
+            <classifier>jdk15</classifier>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/AbstractIntegrationTestSuite.java b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/AbstractIntegrationTestSuite.java
new file mode 100644
index 0000000..76bc889
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/AbstractIntegrationTestSuite.java
@@ -0,0 +1,882 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import com.thoughtworks.selenium.CommandProcessor;
+import com.thoughtworks.selenium.DefaultSelenium;
+import com.thoughtworks.selenium.HttpCommandProcessor;
+import com.thoughtworks.selenium.Selenium;
+import org.openqa.selenium.server.SeleniumServer;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+
+/**
+ * A base class for creating integration tests. Ths encapsulates starting up an in-process copy of Jetty, and in-process
+ * copy of {@link SeleniumServer}, and a Selenium client.
+ * <p/>
+ * Unless you are <em>very, very clever</em>, you will want to run the tests sequentially. TestNG tends to run them in
+ * an arbitrary order unless you explicitly set the order. If you have managed to get TestNG to run tests in parallel,
+ * you may see further problems caused by a single client jumping all over your web application in an unpredictable
+ * order.
+ * <p/>
+ * This class implements the {@link Selenium} interface, and delegates all those methods to the {@link DefaultSelenium}
+ * instance it creates. It also extends the normal exception reporting for any failed command or query to produce a more
+ * detailed report to the main console.
+ *
+ * @see org.apache.tapestry.test.JettyRunner
+ */
+public class AbstractIntegrationTestSuite extends Assert implements Selenium
+{
+    /**
+     * Default directory containing the web application to be tested (this conforms to Maven's default folder).
+     */
+    public static final String DEFAULT_WEB_APP_ROOT = "src/main/webapp";
+
+    /**
+     * Default browser in which to run tests - firefox
+     */
+    public static final String DEFAULT_WEB_BROWSER_COMMAND = "*firefox";
+
+    /**
+     * 15 seconds
+     */
+    public static final String PAGE_LOAD_TIMEOUT = "15000";
+
+    /**
+     * The port on which the internal copy of Jetty is executed.
+     */
+    public static final int JETTY_PORT = 9999;
+
+    // This is likely to be a problem, since may want to test with a context path, rather than as
+    // root.
+    public static final String BASE_URL = String.format("http://localhost:%d/", JETTY_PORT);
+
+    public static final String SUBMIT = "//input[@type='submit']";
+
+    private final String webappRoot;
+
+    private final String seleniumBrowserCommand;
+
+    private JettyRunner jettyRunner;
+
+    private Selenium selenium;
+
+    private SeleniumServer server;
+
+    /**
+     * Initializes the suite using {@link #DEFAULT_WEB_APP_ROOT}.
+     */
+    public AbstractIntegrationTestSuite()
+    {
+        this(DEFAULT_WEB_APP_ROOT, DEFAULT_WEB_BROWSER_COMMAND);
+    }
+
+    /**
+     * @param webAppRoot the directory containing the web application to be tested.
+     */
+    protected AbstractIntegrationTestSuite(String webAppRoot)
+    {
+        this(webAppRoot, DEFAULT_WEB_BROWSER_COMMAND);
+    }
+
+    /**
+     * @param webAppRoot     web application root (default src/main/webapp)
+     * @param browserCommand browser command to pass to selenium. Default is *firefox, syntax for custom browsers is
+     *                       *custom &lt;path_to_browser&gt;, e.g. *custom /usr/lib/mozilla-firefox/firefox
+     */
+    protected AbstractIntegrationTestSuite(String webAppRoot, String browserCommand)
+    {
+        webappRoot = webAppRoot;
+        seleniumBrowserCommand = browserCommand;
+    }
+
+    protected final void assertSourcePresent(String... expected)
+    {
+        String source = selenium.getHtmlSource();
+
+        for (String snippet : expected)
+        {
+            if (source.contains(snippet)) continue;
+
+            System.err.printf("Source content '%s' not found in:\n%s\n\n", snippet, source);
+
+            throw new AssertionError("Page did not contain source '" + snippet + "'.");
+        }
+    }
+
+    /**
+     * Used when the locator identifies an attribute, not an element.
+     *
+     * @param locator  identifies the attribute whose value is to be asserted
+     * @param expected expected value for the attribute
+     */
+    protected final void assertAttribute(String locator, String expected)
+    {
+        String actual = null;
+
+        try
+        {
+            actual = getAttribute(locator);
+        }
+        catch (RuntimeException ex)
+        {
+            System.err.printf("Error accessing %s: %s, in:\n\n%s\n\n", locator, ex.getMessage(),
+                              selenium.getHtmlSource());
+
+            throw ex;
+        }
+
+        if (actual.equals(expected)) return;
+
+        System.err.printf("Text for attribute %s should be '%s' but is '%s', in:\n\n%s\n\n", locator, expected, actual,
+                          getHtmlSource());
+
+        throw new AssertionError(String.format("%s was '%s' not '%s'", locator, actual, expected));
+    }
+
+    /**
+     * Asserts the text of an element, identified by the locator.
+     *
+     * @param locator  identifies the element whose text value is to be asserted
+     * @param expected expected value for the element's text
+     */
+    protected final void assertText(String locator, String expected)
+    {
+        String actual = null;
+
+        try
+        {
+            actual = getText(locator);
+        }
+        catch (RuntimeException ex)
+        {
+            System.err.printf("Error accessing %s: %s, in:\n\n%s\n\n", locator, ex.getMessage(),
+                              selenium.getHtmlSource());
+
+            throw ex;
+        }
+
+        if (actual.equals(expected)) return;
+
+        System.err.printf("Text for %s should be '%s' but is '%s', in:\n\n%s\n\n", locator, expected, actual,
+                          getHtmlSource());
+
+        throw new AssertionError(String.format("%s was '%s' not '%s'", locator, actual, expected));
+    }
+
+    protected final void assertTextPresent(String... text)
+    {
+        for (String item : text)
+        {
+            if (isTextPresent(item)) return;
+
+            System.err.printf("Text pattern '%s' not found in:\n%s\n\n", item, selenium
+                    .getHtmlSource());
+
+            throw new AssertionError("Page did not contain '" + item + "'.");
+        }
+    }
+
+    protected final void assertFieldValue(String locator, String expected)
+    {
+        assertEquals(getValue(locator), expected);
+    }
+
+    protected final void clickAndWait(String link)
+    {
+        click(link);
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+    }
+
+    protected final void assertTextSeries(String idFormat, int startIndex, String... values)
+    {
+        for (int i = 0; i < values.length; i++)
+        {
+            String id = String.format(idFormat, startIndex + i);
+
+            assertText(id, values[i]);
+        }
+    }
+
+    protected final void assertAttributeSeries(String idFormat, int startIndex, String... values)
+    {
+        for (int i = 0; i < values.length; i++)
+        {
+            String id = String.format(idFormat, startIndex + i);
+
+            assertAttribute(id, values[i]);
+        }
+    }
+
+
+    protected final void assertFieldValueSeries(String idFormat, int startIndex, String... values)
+    {
+        for (int i = 0; i < values.length; i++)
+        {
+            String id = String.format(idFormat, startIndex + i);
+
+            assertFieldValue(id, values[i]);
+        }
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void cleanup() throws Exception
+    {
+        selenium.stop();
+        selenium = null;
+
+        server.stop();
+        server = null;
+
+        jettyRunner.stop();
+        jettyRunner = null;
+    }
+
+    @BeforeClass(alwaysRun = true)
+    public void setup() throws Exception
+    {
+        jettyRunner = new JettyRunner(TapestryTestConstants.MODULE_BASE_DIR, "/", JETTY_PORT, webappRoot);
+
+        server = new SeleniumServer();
+
+        server.start();
+
+        CommandProcessor cp = new HttpCommandProcessor("localhost", SeleniumServer.DEFAULT_PORT,
+                                                       seleniumBrowserCommand, BASE_URL);
+
+        selenium = new DefaultSelenium(new ErrorReportingCommandProcessor(cp));
+
+        selenium.start();
+    }
+
+    public void addSelection(String locator, String optionLocator)
+    {
+        selenium.addSelection(locator, optionLocator);
+    }
+
+    public void answerOnNextPrompt(String answer)
+    {
+        selenium.answerOnNextPrompt(answer);
+    }
+
+    public void check(String locator)
+    {
+        selenium.check(locator);
+    }
+
+    public void chooseCancelOnNextConfirmation()
+    {
+        selenium.chooseCancelOnNextConfirmation();
+    }
+
+    public void chooseOkOnNextConfirmation()
+    {
+        selenium.chooseOkOnNextConfirmation();
+    }
+
+    public void click(String locator)
+    {
+        selenium.click(locator);
+    }
+
+    public void doubleClick(String locator)
+    {
+        selenium.doubleClick(locator);
+    }
+
+    public void clickAt(String locator, String coordString)
+    {
+        selenium.clickAt(locator, coordString);
+    }
+
+    public void doubleClickAt(String locator, String coordString)
+    {
+        selenium.doubleClickAt(locator, coordString);
+    }
+
+    public void close()
+    {
+        selenium.close();
+    }
+
+    public void fireEvent(String locator, String eventName)
+    {
+        selenium.fireEvent(locator, eventName);
+    }
+
+    public String getAlert()
+    {
+        return selenium.getAlert();
+    }
+
+    public String[] getAllButtons()
+    {
+        return selenium.getAllButtons();
+    }
+
+    public String[] getAllFields()
+    {
+        return selenium.getAllFields();
+    }
+
+    public String[] getAttributeFromAllWindows(String attributeName)
+    {
+        return selenium.getAttributeFromAllWindows(attributeName);
+    }
+
+    public void dragdrop(String locator, String movementsString)
+    {
+        selenium.dragdrop(locator, movementsString);
+    }
+
+    public void setMouseSpeed(String pixels)
+    {
+        selenium.setMouseSpeed(pixels);
+    }
+
+    public Number getMouseSpeed()
+    {
+        return selenium.getMouseSpeed();
+    }
+
+    public void dragAndDrop(String locator, String movementsString)
+    {
+        selenium.dragAndDrop(locator, movementsString);
+    }
+
+    public void dragAndDropToObject(String locatorOfObjectToBeDragged, String locatorOfDragDestinationObject)
+    {
+        selenium.dragAndDropToObject(locatorOfObjectToBeDragged, locatorOfDragDestinationObject);
+    }
+
+    public void windowFocus()
+    {
+        selenium.windowFocus();
+    }
+
+    public void windowMaximize()
+    {
+        selenium.windowMaximize();
+    }
+
+    public String[] getAllWindowIds()
+    {
+        return selenium.getAllWindowIds();
+    }
+
+    public String[] getAllWindowNames()
+    {
+        return selenium.getAllWindowNames();
+    }
+
+    public String[] getAllWindowTitles()
+    {
+        return selenium.getAllWindowTitles();
+    }
+
+    public String[] getAllLinks()
+    {
+        return selenium.getAllLinks();
+    }
+
+    public String getAttribute(String attributeLocator)
+    {
+        return selenium.getAttribute(attributeLocator);
+    }
+
+    public String getBodyText()
+    {
+        return selenium.getBodyText();
+    }
+
+    public String getConfirmation()
+    {
+        return selenium.getConfirmation();
+    }
+
+    public Number getCursorPosition(String locator)
+    {
+        return selenium.getCursorPosition(locator);
+    }
+
+    public String getEval(String script)
+    {
+        return selenium.getEval(script);
+    }
+
+    public String getExpression(String expression)
+    {
+        return selenium.getExpression(expression);
+    }
+
+    public Number getXpathCount(String xpath)
+    {
+        return selenium.getXpathCount(xpath);
+    }
+
+    public void assignId(String locator, String identifier)
+    {
+        selenium.assignId(locator, identifier);
+    }
+
+    public void allowNativeXpath(String allow)
+    {
+        selenium.allowNativeXpath(allow);
+    }
+
+    public String getHtmlSource()
+    {
+        return selenium.getHtmlSource();
+    }
+
+    public String getLocation()
+    {
+        return selenium.getLocation();
+    }
+
+    public String getPrompt()
+    {
+        return selenium.getPrompt();
+    }
+
+    public String getSelectedId(String selectLocator)
+    {
+        return selenium.getSelectedId(selectLocator);
+    }
+
+    public String[] getSelectedIds(String selectLocator)
+    {
+        return selenium.getSelectedIds(selectLocator);
+    }
+
+    public String getSelectedIndex(String selectLocator)
+    {
+        return selenium.getSelectedIndex(selectLocator);
+    }
+
+    public String[] getSelectedIndexes(String selectLocator)
+    {
+        return selenium.getSelectedIndexes(selectLocator);
+    }
+
+    public String getSelectedLabel(String selectLocator)
+    {
+        return selenium.getSelectedLabel(selectLocator);
+    }
+
+    public String[] getSelectedLabels(String selectLocator)
+    {
+        return selenium.getSelectedLabels(selectLocator);
+    }
+
+    public String getSelectedValue(String selectLocator)
+    {
+        return selenium.getSelectedValue(selectLocator);
+    }
+
+    public String[] getSelectedValues(String selectLocator)
+    {
+        return selenium.getSelectedValues(selectLocator);
+    }
+
+    public String[] getSelectOptions(String selectLocator)
+    {
+        return selenium.getSelectOptions(selectLocator);
+    }
+
+    public String getTable(String tableCellAddress)
+    {
+        return selenium.getTable(tableCellAddress);
+    }
+
+    public String getText(String locator)
+    {
+        return selenium.getText(locator);
+    }
+
+    public void highlight(String locator)
+    {
+        selenium.highlight(locator);
+    }
+
+    public String getTitle()
+    {
+        return selenium.getTitle();
+    }
+
+    public String getValue(String locator)
+    {
+        return selenium.getValue(locator);
+    }
+
+    public void goBack()
+    {
+        selenium.goBack();
+    }
+
+    public boolean isAlertPresent()
+    {
+        return selenium.isAlertPresent();
+    }
+
+    public boolean isChecked(String locator)
+    {
+        return selenium.isChecked(locator);
+    }
+
+    public boolean isConfirmationPresent()
+    {
+        return selenium.isConfirmationPresent();
+    }
+
+    public boolean isEditable(String locator)
+    {
+        return selenium.isEditable(locator);
+    }
+
+    public boolean isElementPresent(String locator)
+    {
+        return selenium.isElementPresent(locator);
+    }
+
+    public boolean isPromptPresent()
+    {
+        return selenium.isPromptPresent();
+    }
+
+    public boolean isSomethingSelected(String selectLocator)
+    {
+        return selenium.isSomethingSelected(selectLocator);
+    }
+
+    public boolean isTextPresent(String pattern)
+    {
+        return selenium.isTextPresent(pattern);
+    }
+
+    public boolean isVisible(String locator)
+    {
+        return selenium.isVisible(locator);
+    }
+
+    public void keyDown(String locator, String keycode)
+    {
+        selenium.keyDown(locator, keycode);
+    }
+
+    public void keyPress(String locator, String keycode)
+    {
+        selenium.keyPress(locator, keycode);
+    }
+
+    public void shiftKeyDown()
+    {
+        selenium.shiftKeyDown();
+    }
+
+    public void shiftKeyUp()
+    {
+        selenium.shiftKeyUp();
+    }
+
+    public void metaKeyDown()
+    {
+        selenium.metaKeyDown();
+    }
+
+    public void metaKeyUp()
+    {
+        selenium.metaKeyUp();
+    }
+
+    public void altKeyDown()
+    {
+        selenium.altKeyDown();
+    }
+
+    public void altKeyUp()
+    {
+        selenium.altKeyUp();
+    }
+
+    public void controlKeyDown()
+    {
+        selenium.controlKeyDown();
+    }
+
+    public void controlKeyUp()
+    {
+        selenium.controlKeyUp();
+    }
+
+    public void keyUp(String locator, String keycode)
+    {
+        selenium.keyUp(locator, keycode);
+    }
+
+    public void mouseDown(String locator)
+    {
+        selenium.mouseDown(locator);
+    }
+
+    public void mouseDownAt(String locator, String coordString)
+    {
+        selenium.mouseDownAt(locator, coordString);
+    }
+
+    public void mouseUp(String locator)
+    {
+        selenium.mouseUp(locator);
+    }
+
+    public void mouseUpAt(String locator, String coordString)
+    {
+        selenium.mouseUpAt(locator, coordString);
+    }
+
+    public void mouseMove(String locator)
+    {
+        selenium.mouseMove(locator);
+    }
+
+    public void mouseMoveAt(String locator, String coordString)
+    {
+        selenium.mouseMoveAt(locator, coordString);
+    }
+
+    public void mouseOver(String locator)
+    {
+        selenium.mouseOver(locator);
+    }
+
+    public void mouseOut(String locator)
+    {
+        selenium.mouseOut(locator);
+    }
+
+    public void open(String url)
+    {
+        selenium.open(url);
+
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+    }
+
+    public void openWindow(String url, String windowID)
+    {
+        selenium.openWindow(url, windowID);
+    }
+
+    public void refresh()
+    {
+        selenium.refresh();
+    }
+
+    public void removeSelection(String locator, String optionLocator)
+    {
+        selenium.removeSelection(locator, optionLocator);
+    }
+
+    public void removeAllSelections(String locator)
+    {
+        selenium.removeAllSelections(locator);
+    }
+
+    public void select(String selectLocator, String optionLocator)
+    {
+        selenium.select(selectLocator, optionLocator);
+    }
+
+    public void selectWindow(String windowID)
+    {
+        selenium.selectWindow(windowID);
+    }
+
+    public void selectFrame(String locator)
+    {
+        selenium.selectFrame(locator);
+    }
+
+    public boolean getWhetherThisFrameMatchFrameExpression(String currentFrameString, String target)
+    {
+        return selenium.getWhetherThisFrameMatchFrameExpression(currentFrameString, target);
+    }
+
+    public boolean getWhetherThisWindowMatchWindowExpression(String currentWindowString, String target)
+    {
+        return selenium.getWhetherThisWindowMatchWindowExpression(currentWindowString, target);
+    }
+
+    public void setCursorPosition(String locator, String position)
+    {
+        selenium.setCursorPosition(locator, position);
+    }
+
+    public Number getElementIndex(String locator)
+    {
+        return selenium.getElementIndex(locator);
+    }
+
+    public boolean isOrdered(String locator1, String locator2)
+    {
+        return selenium.isOrdered(locator1, locator2);
+    }
+
+    public Number getElementPositionLeft(String locator)
+    {
+        return selenium.getElementPositionLeft(locator);
+    }
+
+    public Number getElementPositionTop(String locator)
+    {
+        return selenium.getElementPositionTop(locator);
+    }
+
+    public Number getElementWidth(String locator)
+    {
+        return selenium.getElementWidth(locator);
+    }
+
+    public Number getElementHeight(String locator)
+    {
+        return selenium.getElementHeight(locator);
+    }
+
+    public void setTimeout(String timeout)
+    {
+        selenium.setTimeout(timeout);
+    }
+
+    public void start()
+    {
+        selenium.start();
+    }
+
+    public void stop()
+    {
+        selenium.stop();
+    }
+
+    public void submit(String formLocator)
+    {
+        selenium.submit(formLocator);
+    }
+
+    public void type(String locator, String value)
+    {
+        selenium.type(locator, value);
+    }
+
+    public void typeKeys(String locator, String value)
+    {
+        selenium.typeKeys(locator, value);
+    }
+
+    public void setSpeed(String value)
+    {
+        selenium.setSpeed(value);
+    }
+
+    public void getSpeed()
+    {
+        selenium.getSpeed();
+    }
+
+    public void uncheck(String locator)
+    {
+        selenium.uncheck(locator);
+    }
+
+    public void waitForCondition(String script, String timeout)
+    {
+        selenium.waitForCondition(script, timeout);
+    }
+
+    public void waitForPageToLoad(String timeout)
+    {
+        selenium.waitForPageToLoad(timeout);
+    }
+
+    public void waitForFrameToLoad(String frameAddress, String timeout)
+    {
+        selenium.waitForFrameToLoad(frameAddress, timeout);
+    }
+
+    public String getCookie()
+    {
+        return selenium.getCookie();
+    }
+
+    public void createCookie(String nameValuePair, String optionsString)
+    {
+        selenium.createCookie(nameValuePair, optionsString);
+    }
+
+    public void deleteCookie(String name, String path)
+    {
+        selenium.deleteCookie(name, path);
+    }
+
+    public void setBrowserLogLevel(String logLevel)
+    {
+        selenium.setBrowserLogLevel(logLevel);
+    }
+
+    public void runScript(String script)
+    {
+        selenium.runScript(script);
+    }
+
+    public void addLocationStrategy(String strategyName, String functionDefinition)
+    {
+        selenium.addLocationStrategy(strategyName, functionDefinition);
+    }
+
+    public void setContext(String context)
+    {
+        selenium.setContext(context);
+    }
+
+    public void captureScreenshot(String filename)
+    {
+        selenium.captureScreenshot(filename);
+    }
+
+
+    /**
+     * Waits the default time for the page to load.
+     */
+    public void waitForPageToLoad()
+    {
+        waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+    }
+
+    public void waitForPopUp(String windowID, String timeout)
+    {
+        selenium.waitForPopUp(windowID, timeout);
+    }
+
+    /**
+     * Used to start a typical test, by opening to the base URL and clicking through a series of links.
+     */
+    protected final void start(String... linkText)
+    {
+        open(BASE_URL);
+
+        for (String s : linkText)
+            clickAndWait(String.format("link=%s", s));
+    }
+
+}
diff --git a/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/ErrorReportingCommandProcessor.java b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/ErrorReportingCommandProcessor.java
new file mode 100644
index 0000000..a21322b
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/ErrorReportingCommandProcessor.java
@@ -0,0 +1,164 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import com.thoughtworks.selenium.CommandProcessor;
+
+/**
+ * A wrapper around a standard command processor that adds additional exception reporting when a failure occurs.
+ */
+public class ErrorReportingCommandProcessor implements CommandProcessor
+{
+    private final CommandProcessor delegate;
+
+    public ErrorReportingCommandProcessor(final CommandProcessor delegate)
+    {
+        this.delegate = delegate;
+    }
+
+    private static final String BORDER = "**********************************************************************";
+
+    private void reportError(String command, String[] args, RuntimeException ex)
+    {
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(BORDER);
+        builder.append("\nSeleninum failure processing comamnd ");
+        builder.append(command);
+        builder.append("(");
+
+        for (int i = 0; i < args.length; i++)
+        {
+            if (i > 0) builder.append(", ");
+            builder.append('"');
+            builder.append(args[i]);
+            builder.append('"');
+        }
+
+        builder.append("): ");
+        builder.append(ex.toString());
+
+        builder.append("\n\nPage source:\n\n");
+
+        builder.append(delegate.getString("getHtmlSource", new String[] { }));
+
+        builder.append("\n");
+        builder.append(BORDER);
+
+        System.err.println(builder.toString());
+    }
+
+    public String doCommand(String command, String[] args)
+    {
+        try
+        {
+            return delegate.doCommand(command, args);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(command, args, ex);
+            throw ex;
+        }
+    }
+
+    public boolean getBoolean(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getBoolean(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public boolean[] getBooleanArray(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getBooleanArray(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public Number getNumber(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getNumber(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public Number[] getNumberArray(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getNumberArray(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public String getString(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getString(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public String[] getStringArray(String string, String[] strings)
+    {
+        try
+        {
+            return delegate.getStringArray(string, strings);
+        }
+        catch (RuntimeException ex)
+        {
+            reportError(string, strings, ex);
+            throw ex;
+        }
+    }
+
+    public void start()
+    {
+        delegate.start();
+    }
+
+    public void stop()
+    {
+        delegate.stop();
+    }
+
+}
diff --git a/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/JettyRunner.java b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/JettyRunner.java
new file mode 100644
index 0000000..19c6e75
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/JettyRunner.java
@@ -0,0 +1,147 @@
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import org.mortbay.http.NCSARequestLog;
+import org.mortbay.http.SocketListener;
+import org.mortbay.http.SunJsseListener;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.WebApplicationContext;
+
+import java.io.File;
+import static java.lang.String.format;
+
+/**
+ * Used to start up an instance of the Jetty servlet container in-process, as part of an integration test suite. The
+ * started Jetty is reliant on the file <code>src/test/conf/webdefault.xml</code>.
+ *
+ * @see AbstractIntegrationTestSuite
+ */
+public class JettyRunner
+{
+    public static final String DEFAULT_CONTEXT_PATH = "/";
+
+    public static final int DEFAULT_PORT = 8080;
+
+    public static final int DEFAULT_SECURE_PORT = 8443;
+
+    private final File workingDir;
+
+    private final String contextPath;
+
+    private final int port;
+
+    private final String warPath;
+
+    private final Server jetty;
+
+    /**
+     * Creates and starts a new instance of Jetty. This should be done from a test case setup method.
+     *
+     * @param workingDir  current directory (used for any relative files)
+     * @param contextPath the context path for the deployed application
+     * @param port        the port number used to access the application
+     * @param warPath     the path to the exploded web application (typically, "src/main/webapp")
+     */
+    public JettyRunner(File workingDir, String contextPath, int port, String warPath)
+    {
+        this.workingDir = workingDir;
+        this.contextPath = contextPath;
+        this.port = port;
+        this.warPath = warPath;
+
+        jetty = createAndStart();
+    }
+
+    /**
+     * Stops the Jetty instance. This should be called from a test case tear down method.
+     */
+    public void stop()
+    {
+        System.out.printf("Stopping Jetty instance on port %d\n", port);
+
+        try
+        {
+            // Stop immediately and not gracefully.
+            jetty.stop(false);
+
+            while (jetty.isStarted())
+            {
+                Thread.sleep(100);
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
+        }
+
+        System.out.println("Jetty instance has stopped.");
+    }
+
+    @Override
+    public String toString()
+    {
+        return format("<JettyRunner %s:%d (%s)>", contextPath, port, warPath);
+    }
+
+
+    private Server createAndStart()
+    {
+        try
+        {
+
+            String warPath = new File(workingDir, this.warPath).getPath();
+            String webDefaults = new File(workingDir, "src/test/conf/webdefault.xml").getPath();
+
+            File keystoreFile = new File(workingDir, "src/test/conf/keystore");
+            String keystore = keystoreFile.getPath();
+
+            System.out.printf("Starting Jetty instance on port %d (%s mapped to %s)\n", port, contextPath, warPath);
+
+            Server server = new Server();
+
+
+            SocketListener socketListener = new SocketListener();
+            socketListener.setPort(port);
+            server.addListener(socketListener);
+
+            if (keystoreFile.exists())
+            {
+                SunJsseListener secureListener = new SunJsseListener();
+                secureListener.setPort(DEFAULT_SECURE_PORT);
+                secureListener.setKeystore(keystore);
+                secureListener.setPassword("tapestry");
+                secureListener.setKeyPassword("tapestry");
+
+                server.addListener(secureListener);
+            }
+
+            NCSARequestLog log = new NCSARequestLog();
+            server.setRequestLog(log);
+
+            WebApplicationContext context = server.addWebApplication(contextPath, warPath);
+
+            context.setDefaultsDescriptor(webDefaults);
+
+            server.start();
+
+            return server;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException("Failure starting Jetty instance: " + ex.toString(), ex);
+        }
+    }
+}
diff --git a/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/RandomDataSource.java b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/RandomDataSource.java
new file mode 100644
index 0000000..4c86139
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/RandomDataSource.java
@@ -0,0 +1,213 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import java.io.*;
+import static java.lang.String.format;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Provides access to random data that can be used when populating a test database with "reasonable" data. The majority
+ * of this is access to random words from an american english dictionary, which can be strung together to form names,
+ * sentences and paragraphs.
+ */
+public final class RandomDataSource
+{
+    private final Random random = new Random(System.currentTimeMillis());
+
+    private final List<String> words = new ArrayList<String>();
+
+    public RandomDataSource()
+    {
+        for (int i = 0; i < 4; i++)
+            readWords("english." + i);
+
+        for (int i = 0; i < 3; i++)
+            readWords("american." + i);
+
+        System.out.printf("Dictionary contains %d words\n", words.size());
+    }
+
+    private void readWords(String name)
+    {
+        System.out.println("Reading " + name + " ...");
+
+        int count = 0;
+
+        InputStream is = getClass().getResourceAsStream(name);
+
+        if (is == null) throw new RuntimeException(format("File '%s' not found.", name));
+
+        try
+        {
+            BufferedInputStream bis = new BufferedInputStream(is);
+            InputStreamReader isr = new InputStreamReader(bis);
+            LineNumberReader r = new LineNumberReader(isr);
+
+            while (true)
+            {
+                String word = r.readLine();
+
+                if (word == null) break;
+
+                count++;
+                words.add(word);
+            }
+
+            r.close();
+        }
+        catch (IOException ex)
+        {
+            throw new RuntimeException(format("Error reading '%s': %s", name + ex.getMessage()), ex);
+        }
+
+        System.out.printf("... %d words\n", count);
+    }
+
+    public boolean maybe(int percent)
+    {
+        assert percent > 0 && percent <= 100;
+
+        return random.nextInt(100) < percent;
+    }
+
+    public int random(int min, int max)
+    {
+        assert min <= max;
+
+        return random.nextInt(max - min + 1) + min;
+    }
+
+    /**
+     * Returns a random word frm the dictionary. These words are usually all lowercase.
+     */
+    public String word()
+    {
+        int index = random.nextInt(words.size());
+
+        return words.get(index);
+    }
+
+    /**
+     * Returns a random word, capitalized. Useful when create random names.
+     */
+    public String capitalizedWord()
+    {
+        String word = word();
+
+        char[] chars = word.toCharArray();
+
+        chars[0] = Character.toUpperCase(chars[0]);
+
+        return new String(chars);
+    }
+
+    /**
+     * Returns a word that is "safe" for use in an email address.
+     */
+    public String safeWord()
+    {
+        String word = word();
+
+        int x = word.indexOf('\'');
+
+        return x < 0 ? word : word.substring(0, x);
+    }
+
+    /**
+     * Returns a random value from the list of values supplied.
+     */
+    public <T> T oneOf(T... values)
+    {
+        assert values.length > 0;
+
+        int index = random.nextInt(values.length);
+
+        return values[index];
+    }
+
+    /**
+     * Returns a random enum value, given the enum type.
+     */
+    public <T extends Enum> T oneOf(Class<T> enumClass)
+    {
+        return oneOf(enumClass.getEnumConstants());
+    }
+
+    /**
+     * Creates a space-separated list of random words. If in sentence form, then the first word is capitalized, and a
+     * period is appended.
+     *
+     * @param minWords   minimun number of words in the list
+     * @param maxWords   maximum number of words in the list
+     * @param asSentence if true, the output is "dressed up" as a non-sensical sentence
+     * @return the word list / sentence
+     */
+    public String wordList(int minWords, int maxWords, boolean asSentence)
+    {
+        assert minWords <= maxWords;
+        assert minWords > 0;
+
+        StringBuilder builder = new StringBuilder();
+
+        int count = random(minWords, maxWords);
+
+        for (int i = 0; i < count; i++)
+        {
+
+            if (i > 0) builder.append(' ');
+
+            if (i == 0 && asSentence)
+                builder.append(capitalizedWord());
+            else
+                builder.append(word());
+        }
+
+        if (asSentence) builder.append('.');
+
+        return builder.toString();
+    }
+
+    /**
+     * Strings together a random number of word lists (in sentence form) to create something that looks like a
+     * paragraph.
+     *
+     * @param minSentences per paragraph
+     * @param maxSentences per paragraph
+     * @param minWords     per sentence
+     * @param maxWords     per sentence
+     * @return the random paragraph
+     */
+    public String paragraph(int minSentences, int maxSentences, int minWords, int maxWords)
+    {
+        assert minSentences < maxSentences;
+        assert minSentences > 0;
+
+        int count = random(minSentences, maxSentences);
+
+        StringBuilder builder = new StringBuilder();
+
+        for (int i = 0; i < count; i++)
+        {
+            if (i > 0) builder.append(' ');
+
+            builder.append(wordList(minWords, maxWords, true));
+        }
+
+        return builder.toString();
+    }
+}
diff --git a/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/TapestryTestConstants.java b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/TapestryTestConstants.java
new file mode 100644
index 0000000..832e6e8
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/java/org/apache/tapestry/test/TapestryTestConstants.java
@@ -0,0 +1,38 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.test;
+
+import java.io.File;
+
+public class TapestryTestConstants
+{
+    /**
+     * The current working directory (i.e., property "user.dir").
+     */
+    public static final String CURRENT_DIR_PATH = System.getProperty("user.dir");
+    /**
+     * The Surefire plugin sets basedir but DOES NOT change the current working directory.
+     * When building across modules, basedir changes for each module, but user.dir does not.
+     * This value should be used when referecing local files.  Outside of surefire, the
+     * "basedir" property will not be set, and the current working directory will be the
+     * default.
+     */
+    public static final String MODULE_BASE_DIR_PATH = System.getProperty("basedir", CURRENT_DIR_PATH);
+
+    /**
+     * {@link #MODULE_BASE_DIR_PATH} as a file.
+     */
+    public static final File MODULE_BASE_DIR = new File(MODULE_BASE_DIR_PATH);
+}
diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.0 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.0
new file mode 100644
index 0000000..935ff42
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.0
@@ -0,0 +1,1835 @@
+acclimatization

+acclimatization's

+acclimatizations

+acclimatized

+accouterment

+accouterment's

+accouterments

+acknowledgment

+acknowledgment's

+acknowledgments

+actualization

+actualization's

+actualizations

+aerosolize

+aerosolized

+agonize

+agonized

+agonizedlies

+agonizedly

+agonizer

+agonizers

+agonizes

+agonizing

+agonizingly

+airfoil

+airfoils

+airplane

+airplane's

+airplanes

+alphabetize

+alphabetized

+alphabetizer

+alphabetizers

+alphabetizes

+alphabetizing

+aluminum

+aluminum's

+aluminums

+amenorrhea

+amortize

+amortized

+amortizes

+amortizing

+amphitheater

+amphitheater's

+amphitheaters

+analog

+analog's

+analogs

+analyzable

+analyze

+analyzed

+analyzer

+analyzers

+analyzes

+analyzing

+anemia

+anemia's

+anemias

+anemic

+anemics

+anesthesia

+anesthesia's

+anesthesias

+anesthetic

+anesthetic's

+anesthetically

+anesthetics

+anesthetize

+anesthetized

+anesthetizer

+anesthetizer's

+anesthetizers

+anesthetizes

+anesthetizing

+anodize

+anodized

+anodizes

+anodizing

+antagonize

+antagonized

+antagonizer

+antagonizers

+antagonizes

+antagonizing

+apologize

+apologized

+apologizer

+apologizers

+apologizes

+apologizing

+appall

+appalls

+appareled

+appetizer

+appetizing

+appetizingly

+arbor

+arbor's

+arbored

+arbors

+archaize

+archaized

+archaizer

+archaizers

+archaizes

+archaizing

+ardor

+ardor's

+ardors

+arithmetize

+arithmetized

+arithmetizes

+armor

+armor's

+armored

+armorer

+armorer's

+armorers

+armoried

+armories

+armoring

+armors

+armory

+armory's

+atomization

+atomization's

+atomizations

+atomize

+atomized

+atomizer

+atomizers

+atomizes

+atomizing

+authorization

+authorization's

+authorizations

+authorize

+authorized

+authorizer

+authorizers

+authorizes

+authorizing

+autodialer

+axiomatization

+axiomatization's

+axiomatizations

+axiomatize

+axiomatized

+axiomatizes

+axiomatizing

+balkanize

+balkanized

+balkanizing

+baptize

+baptized

+baptizer

+baptizers

+baptizes

+baptizing

+barreled

+barreling

+bastardize

+bastardized

+bastardizes

+bastardizing

+bedeviled

+bedeviling

+behavior

+behavior's

+behavioral

+behaviorally

+behaviored

+behaviorism

+behaviorism's

+behaviorisms

+behavioristic

+behavioristics

+behaviors

+behoove

+behoove's

+behooved

+behooves

+behooving

+behooving's

+behoovingly

+behoovings

+belabor

+belabor's

+belabored

+belaboring

+belabors

+beveled

+beveling

+bevelings

+bowdlerize

+bowdlerized

+bowdlerizer

+bowdlerizes

+bowdlerizing

+brutalize

+brutalized

+brutalizes

+brutalizing

+burglarize

+burglarized

+burglarizes

+burglarizing

+busheled

+busheling

+bushelings

+caliber

+calibers

+canaled

+canaling

+canceled

+canceler

+canceling

+candor

+candor's

+candors

+cannibalize

+cannibalized

+cannibalizes

+cannibalizing

+canonicalization

+canonicalize

+canonicalized

+canonicalizes

+canonicalizing

+capitalization

+capitalization's

+capitalizations

+capitalize

+capitalized

+capitalizer

+capitalizers

+capitalizes

+capitalizing

+carbonization

+carbonization's

+carbonizations

+carbonize

+carbonized

+carbonizer

+carbonizers

+carbonizes

+carbonizing

+catalog

+catalog's

+cataloged

+cataloger

+cataloging

+catalogs

+categorization

+categorization's

+categorizations

+categorize

+categorized

+categorizer

+categorizers

+categorizes

+categorizing

+center

+center's

+centered

+centerer

+centerers

+centering

+centerings

+centerpiece

+centerpiece's

+centerpieces

+centers

+centimeter

+centimeter's

+centimeters

+centralization

+centralization's

+centralizations

+centralize

+centralized

+centralizer

+centralizers

+centralizes

+centralizing

+channeled

+channeler

+channeler's

+channelers

+channeling

+characterizable

+characterizable's

+characterizables

+characterization

+characterization's

+characterizations

+characterize

+characterized

+characterizer

+characterizers

+characterizes

+characterizing

+checkbook

+checkbook's

+checkbooks

+chiseled

+chiseler

+chiselers

+civilization

+civilization's

+civilizations

+civilize

+civilized

+civilizedness

+civilizer

+civilizers

+civilizes

+civilizing

+clamor

+clamored

+clamorer

+clamorer's

+clamorers

+clamoring

+clamors

+cognizance

+cognizant

+colonization

+colonization's

+colonizations

+colonize

+colonized

+colonizer

+colonizers

+colonizes

+colonizing

+color

+color's

+colored

+coloreds

+colorer

+colorer's

+colorers

+colorful

+colorfully

+colorfulness

+coloring

+colorings

+colorless

+colorlessly

+colorlessness

+colors

+columnize

+columnized

+columnizes

+columnizing

+compartmentalize

+compartmentalized

+compartmentalizes

+compartmentalizing

+computerize

+computerized

+computerizes

+computerizing

+conceptualization

+conceptualization's

+conceptualizations

+conceptualize

+conceptualized

+conceptualizer

+conceptualizes

+conceptualizing

+counseled

+counseling

+counselor

+counselor's

+counselors

+criticize

+criticized

+criticizer

+criticizers

+criticizes

+criticizing

+criticizinglies

+criticizingly

+crystallize

+crystallized

+crystallizer

+crystallizers

+crystallizes

+crystallizing

+customizable

+customization

+customization's

+customizations

+customize

+customized

+customizer

+customizers

+customizes

+customizing

+decentralization

+decentralization's

+decentralizations

+decentralized

+defense

+defense's

+defensed

+defenseless

+defenselessly

+defenselessness

+defenses

+defensing

+demeanor

+demeanor's

+demeanors

+demoralize

+demoralized

+demoralizer

+demoralizers

+demoralizes

+demoralizing

+demoralizingly

+dialed

+dialer

+dialers

+dialing

+dialings

+dichotomize

+dichotomized

+dichotomizes

+dichotomizing

+digitize

+digitized

+digitizer

+digitizer's

+digitizers

+digitizes

+digitizing

+dishonor

+dishonored

+dishonorer

+dishonorer's

+dishonorers

+dishonoring

+dishonors

+disorganized

+draftsman

+dueled

+dueler

+duelers

+dueling

+duelings

+economize

+economized

+economizer

+economizers

+economizes

+economizing

+editorialize

+editorialized

+editorializer

+editorializes

+editorializing

+enameled

+enameler

+enamelers

+enameling

+enamelings

+endeavor

+endeavor's

+endeavored

+endeavorer

+endeavorer's

+endeavorers

+endeavoring

+endeavors

+enroll

+enrollment

+enrollment's

+enrollments

+enrolls

+epitomize

+epitomized

+epitomizer

+epitomizers

+epitomizes

+epitomizing

+equaled

+equaling

+equalization

+equalization's

+equalizations

+equalize

+equalized

+equalizer

+equalizer's

+equalizers

+equalizes

+equalizing

+equalizings

+esthetic

+esthetic's

+esthetically

+esthetics

+eviler

+evilest

+factorization

+factorization's

+factorizations

+familiarization

+familiarization's

+familiarizations

+familiarize

+familiarized

+familiarizer

+familiarizers

+familiarizes

+familiarizing

+familiarizingly

+fantasize

+fantasized

+fantasizer

+fantasizes

+fantasizing

+favor

+favor's

+favorable

+favorable's

+favorableness

+favorables

+favorably

+favored

+favored's

+favoredly

+favoredness

+favoreds

+favorer

+favorer's

+favorers

+favoring

+favoring's

+favoringly

+favorings

+favorite

+favorite's

+favorites

+favors

+fertilization

+fertilization's

+fertilizations

+fertilize

+fertilized

+fertilizer

+fertilizers

+fertilizes

+fertilizing

+fervor

+fervor's

+fervors

+fiber

+fiber's

+fibered

+fiberglass

+fibers

+finalization

+finalizations

+finalize

+finalized

+finalizes

+finalizing

+flavor

+flavor's

+flavored

+flavorer

+flavorer's

+flavorers

+flavoring

+flavorings

+flavors

+formalization

+formalization's

+formalizations

+formalize

+formalized

+formalizer

+formalizers

+formalizes

+formalizing

+fueled

+fueler

+fuelers

+fueling

+fulfill

+fulfillment

+fulfillment's

+fulfillments

+fulfills

+funneled

+funneling

+generalization

+generalization's

+generalizations

+generalize

+generalized

+generalizer

+generalizers

+generalizes

+generalizing

+glamorize

+glamorized

+glamorizer

+glamorizers

+glamorizes

+glamorizing

+gospeler

+gospelers

+gossiped

+gossiping

+gram

+gram's

+grams

+graveled

+graveling

+groveled

+groveler

+grovelers

+groveling

+grovelingly

+harbor

+harbor's

+harbored

+harborer

+harborer's

+harborers

+harboring

+harbors

+harmonize

+harmonized

+harmonizer

+harmonizers

+harmonizes

+harmonizing

+honor

+honorable

+honorable's

+honorableness

+honorables

+honorablies

+honorably

+honored

+honorer

+honorer's

+honorers

+honoring

+honors

+hospitalize

+hospitalized

+hospitalizes

+hospitalizing

+humor

+humor's

+humored

+humorer

+humorers

+humoring

+humors

+hypothesize

+hypothesized

+hypothesizer

+hypothesizers

+hypothesizes

+hypothesizing

+idealization

+idealization's

+idealizations

+idealize

+idealized

+idealizer

+idealizers

+idealizes

+idealizing

+imperiled

+incognizance

+incognizant

+individualize

+individualized

+individualizer

+individualizers

+individualizes

+individualizing

+individualizingly

+industrialization

+industrialization's

+industrializations

+informalizes

+initialed

+initialer

+initialing

+initialization

+initialization's

+initializations

+initialize

+initialized

+initializer

+initializers

+initializes

+initializing

+institutionalize

+institutionalized

+institutionalizes

+institutionalizing

+internalization

+internalization's

+internalizations

+internalize

+internalized

+internalizes

+internalizing

+italicize

+italicized

+italicizes

+italicizing

+itemization

+itemization's

+itemizations

+itemize

+itemized

+itemizer

+itemizers

+itemizes

+itemizing

+jeopardize

+jeopardized

+jeopardizes

+jeopardizing

+jeweled

+jeweler

+jewelers

+jeweling

+journalize

+journalized

+journalizer

+journalizers

+journalizes

+journalizing

+judgment

+judgment's

+judgments

+kidnaped

+kidnaper

+kidnaper's

+kidnapers

+kidnaping

+kidnaping's

+kidnapings

+kilogram

+kilogram's

+kilograms

+kilometer

+kilometer's

+kilometers

+labeled

+labeler

+labeler's

+labelers

+labeling

+labor

+labored

+labored's

+laboredly

+laboredness

+laborer

+laborer's

+laborers

+laboring

+laboring's

+laboringly

+laborings

+labors

+laureled

+legalization

+legalization's

+legalizations

+legalize

+legalized

+legalizes

+legalizing

+leveled

+leveler

+levelers

+levelest

+leveling

+liberalize

+liberalized

+liberalizer

+liberalizers

+liberalizes

+liberalizing

+license's

+linearizable

+linearize

+linearized

+linearizes

+linearizing

+linearizion

+liter

+liters

+localization

+localization's

+localizations

+localize

+localized

+localizer

+localizers

+localizes

+localizing

+luster

+lustered

+lustering

+lusters

+magnetization

+magnetization's

+magnetizations

+maneuver

+maneuvered

+maneuverer

+maneuvering

+maneuvers

+marveled

+marveling

+marvelous

+marvelously

+marvelousness

+materialize

+materialized

+materializer

+materializers

+materializes

+materializing

+maximize

+maximized

+maximizer

+maximizers

+maximizes

+maximizing

+mechanization

+mechanization's

+mechanizations

+mechanize

+mechanized

+mechanizer

+mechanizers

+mechanizes

+mechanizing

+medaled

+medaling

+memorization

+memorization's

+memorizations

+memorize

+memorized

+memorizer

+memorizers

+memorizes

+memorizing

+metaled

+metaling

+millimeter

+millimeter's

+millimeters

+miniaturization

+miniaturizations

+miniaturize

+miniaturized

+miniaturizes

+miniaturizing

+minimization

+minimization's

+minimizations

+minimize

+minimized

+minimizer

+minimizers

+minimizes

+minimizing

+misjudgment

+misjudgment's

+misjudgments

+miter

+mitered

+miterer

+mitering

+modeled

+modeler

+modelers

+modeling

+modelings

+modernize

+modernized

+modernizer

+modernizers

+modernizes

+modernizing

+modularization

+modularize

+modularized

+modularizes

+modularizing

+motorize

+motorized

+motorizes

+motorizing

+multileveled

+mustache

+mustached

+mustaches

+nationalization

+nationalization's

+nationalizations

+nationalize

+nationalized

+nationalizer

+nationalizers

+nationalizes

+nationalizing

+naturalization

+naturalization's

+naturalizations

+neighbor

+neighbor's

+neighbored

+neighborer

+neighborer's

+neighborers

+neighborhood

+neighborhood's

+neighborhoods

+neighboring

+neighborings

+neighborliness

+neighborly

+neighbors

+neutralize

+neutralized

+neutralizer

+neutralizers

+neutralizes

+neutralizing

+nickeled

+nickeling

+normalization

+normalization's

+normalizations

+normalize

+normalized

+normalizer

+normalizers

+normalizes

+normalizing

+notarize

+notarized

+notarizes

+notarizing

+odor

+odor's

+odored

+odors

+offense

+offense's

+offenses

+optimization

+optimization's

+optimizations

+optimize

+optimized

+optimizer

+optimizer's

+optimizers

+optimizes

+optimizing

+organizable

+organizable's

+organizables

+organization

+organization's

+organizational

+organizational's

+organizationally

+organizationals

+organizations

+organize

+organized

+organizer

+organizers

+organizes

+organizing

+oxidize

+oxidized

+oxidizer

+oxidizers

+oxidizes

+oxidizing

+oxidizings

+pajama

+pajama's

+pajamaed

+pajamas

+paneled

+paneling

+panelings

+paralleled

+paralleling

+parallelization

+parallelization's

+parallelizations

+parallelize

+parallelized

+parallelizer

+parallelizers

+parallelizes

+parallelizing

+paralyze

+paralyzed

+paralyzedlies

+paralyzedly

+paralyzer

+paralyzer's

+paralyzers

+paralyzes

+paralyzing

+paralyzinglies

+paralyzingly

+parameterizable

+parameterization

+parameterization's

+parameterizations

+parameterize

+parameterized

+parameterizes

+parameterizing

+parceled

+parceling

+parenthesized

+parlor

+parlor's

+parlors

+patronize

+patronized

+patronizer

+patronizers

+patronizes

+patronizing

+patronizing's

+patronizingly

+patronizings

+penalize

+penalized

+penalizes

+penalizing

+penciled

+penciling

+pencilings

+personalization

+personalization's

+personalizations

+personalize

+personalized

+personalizes

+personalizing

+petaled

+philosophize

+philosophized

+philosophizer

+philosophizers

+philosophizes

+philosophizing

+plow

+plowed

+plower

+plowing

+plowman

+plows

+pluralization

+pluralization's

+pluralizations

+pluralize

+pluralized

+pluralizer

+pluralizers

+pluralizes

+pluralizing

+polarization

+polarization's

+polarizations

+popularization

+popularization's

+popularizations

+popularize

+popularized

+popularizer

+popularizers

+popularizes

+popularizing

+practiced

+practicer

+practicing

+preinitialize

+preinitialized

+preinitializes

+preinitializing

+pressurize

+pressurized

+pressurizer

+pressurizers

+pressurizes

+pressurizing

+pretense

+pretenses

+pretension

+pretensions

+pretensive

+prioritize

+prioritized

+prioritizer

+prioritizers

+prioritizes

+prioritizing

+prioritizings

+productize

+productized

+productizer

+productizers

+productizes

+productizing

+proselytize

+proselytized

+proselytizer

+proselytizers

+proselytizes

+proselytizing

+publicize

+publicized

+publicizes

+publicizing

+pulverize

+pulverized

+pulverizer

+pulverizers

+pulverizes

+pulverizing

+quantization

+quantization's

+quantizations

+quantize

+quantized

+quantizer

+quantizer's

+quantizers

+quantizes

+quantizing

+quarreled

+quarreler

+quarrelers

+quarreling

+queuing

+randomize

+randomized

+randomizer

+randomizes

+randomizing

+rationalize

+rationalized

+rationalizer

+rationalizers

+rationalizes

+rationalizing

+reacclimatization

+reacclimatization's

+reacclimatizations

+reacknowledgment

+reacknowledgment's

+reacknowledgments

+reactualization

+reactualization's

+reactualizations

+reanalyze

+reanalyzed

+reanalyzer

+reanalyzers

+reanalyzes

+reanalyzing

+reapologizes

+reauthorization

+reauthorization's

+reauthorizations

+reauthorizes

+rebrutalizes

+recapitalization

+recapitalization's

+recapitalizations

+recapitalized

+recapitalizes

+recarbonization

+recarbonization's

+recarbonizations

+recarbonizer

+recarbonizers

+recarbonizes

+recategorized

+recentralization

+recentralization's

+recentralizations

+recentralizes

+recivilization

+recivilization's

+recivilizations

+recivilizes

+recognizability

+recognizable

+recognizably

+recognizance

+recognize

+recognized

+recognizedlies

+recognizedly

+recognizer

+recognizers

+recognizes

+recognizing

+recognizinglies

+recognizingly

+recolonization

+recolonization's

+recolonizations

+recolonizes

+recolored

+recolors

+reconceptualizing

+recriticizes

+recrystallized

+recrystallizes

+redialed

+refavors

+refertilization

+refertilization's

+refertilizations

+refertilizes

+refueled

+refueling

+reharmonizes

+rehonors

+reinitialize

+reinitialized

+reinitializes

+reinitializing

+reitemizes

+relabeled

+relabeler

+relabelers

+relabeling

+remagnetization

+remagnetization's

+remagnetizations

+rematerializes

+rememorizes

+remodeled

+remodeling

+renormalized

+renormalizes

+reorganization

+reorganization's

+reorganizations

+reorganize

+reorganized

+reorganizer

+reorganizers

+reorganizes

+reorganizing

+reoxidizes

+repatronizes

+reprogram

+reprograms

+repulverizes

+resepulchers

+restandardization

+restandardization's

+restandardizations

+restandardizes

+resterilizes

+resymbolization

+resymbolization's

+resymbolizations

+resymbolizes

+resynchronizations

+resynchronized

+resynchronizes

+resynthesizes

+retranquilizes

+reutilization

+reutilizes

+reveled

+reveler

+revelers

+reveling

+revelings

+revisualizes

+revolutionize

+revolutionized

+revolutionizer

+revolutionizers

+revolutionizes

+revolutionizing

+rigor

+rigor's

+rigors

+rivaled

+rivaling

+ruble

+ruble's

+rubles

+rumor

+rumor's

+rumored

+rumorer

+rumorer's

+rumorers

+rumoring

+rumors

+saber

+saber's

+sabered

+sabering

+sabers

+sanitize

+sanitized

+sanitizer

+sanitizes

+sanitizing

+savior

+savior's

+saviors

+savor

+savored

+savorer

+savorer's

+savorers

+savorier

+savories

+savoriest

+savoriness

+savoring

+savoringlies

+savoringly

+savors

+savory

+savory's

+scepter

+scepter's

+sceptered

+sceptering

+scepters

+scrutinize

+scrutinized

+scrutinizer

+scrutinizers

+scrutinizes

+scrutinizing

+scrutinizinglies

+scrutinizingly

+sepulcher

+sepulcher's

+sepulchered

+sepulchers

+sequentialize

+sequentialized

+sequentializes

+sequentializing

+serialization

+serialization's

+serializations

+serialize

+serialized

+serializes

+serializing

+shoveled

+shoveler

+shovelers

+shoveling

+shriveled

+shriveling

+signaled

+signaler

+signalers

+signaling

+siphon

+siphon's

+siphoned

+siphoning

+siphons

+socialize

+socialized

+socializer

+socializes

+socializing

+specialization

+specialization's

+specializations

+specialize

+specialized

+specializer

+specializers

+specializes

+specializing

+specialties

+specialty

+specialty's

+specter

+specter's

+spectered

+specters

+spiraled

+spiraling

+splendor

+splendor's

+splendors

+squirreled

+squirreling

+stabilize

+stabilized

+stabilizer

+stabilizers

+stabilizes

+stabilizing

+standardization

+standardization's

+standardizations

+standardize

+standardized

+standardizer

+standardizers

+standardizes

+standardizing

+stenciled

+stenciler

+stencilers

+stenciling

+sterilization

+sterilization's

+sterilizations

+sterilize

+sterilized

+sterilizer

+sterilizers

+sterilizes

+sterilizing

+stylized

+subsidize

+subsidized

+subsidizer

+subsidizers

+subsidizes

+subsidizing

+succor

+succored

+succorer

+succorer's

+succorers

+succoring

+succors

+summarization

+summarization's

+summarizations

+summarize

+summarized

+summarizer

+summarizers

+summarizes

+summarizing

+symboled

+symboling

+symbolization

+symbolization's

+symbolizations

+symbolize

+symbolized

+symbolizer

+symbolizers

+symbolizes

+symbolizing

+sympathize

+sympathized

+sympathizer

+sympathizers

+sympathizes

+sympathizing

+sympathizing's

+sympathizingly

+sympathizings

+synchronization

+synchronization's

+synchronizations

+synchronize

+synchronized

+synchronizer

+synchronizers

+synchronizes

+synchronizing

+synthesize

+synthesized

+synthesizer

+synthesizers

+synthesizes

+synthesizing

+systematize

+systematized

+systematizer

+systematizers

+systematizes

+systematizing

+tantalize

+tantalized

+tantalizer

+tantalizers

+tantalizes

+tantalizing

+tantalizinglies

+tantalizingly

+tantalizingness

+tantalizingnesses

+terrorize

+terrorized

+terrorizer

+terrorizers

+terrorizes

+terrorizing

+theater

+theater's

+theaters

+theorization

+theorization's

+theorizations

+theorize

+theorized

+theorizer

+theorizers

+theorizes

+theorizing

+tire's

+titer

+titers

+totaled

+totaler

+totaler's

+totalers

+totaling

+toweled

+toweling

+towelings

+tranquilize

+tranquilized

+tranquilizer

+tranquilizer's

+tranquilizers

+tranquilizes

+tranquilizing

+tranquilizing's

+tranquilizingly

+tranquilizings

+transistorize

+transistorized

+transistorizes

+transistorizing

+traveled

+traveler

+traveler's

+travelers

+traveling

+travelings

+trivialize

+trivialized

+trivializes

+trivializing

+troweler

+trowelers

+tumor

+tumor's

+tumored

+tumors

+tunneled

+tunneler

+tunnelers

+tunneling

+tunnelings

+unacclimatized

+unamortized

+unanalyzable

+unanalyzed

+unantagonized

+unantagonizing

+unapologizing

+unappetizing

+unappetizingly

+unarmored

+unauthorized

+unauthorizedly

+unauthorizedness

+unauthorizes

+unbaptized

+unbaptizes

+unbastardized

+unbrutalized

+unbrutalizes

+uncanceled

+uncapitalized

+uncategorized

+uncharacterized

+uncivilized

+uncivilizedly

+uncivilizedness

+uncivilizes

+uncolonized

+uncolonizes

+uncolored

+uncoloredly

+uncoloredness

+uncoloreds

+uncriticized

+uncriticizing

+uncriticizingly

+uncrystallized

+undefenses

+undishonored

+undisorganized

+uneconomizing

+unendeavored

+unepitomized

+unequaled

+unequalized

+unequalizes

+unfamiliarized

+unfavorable

+unfavorable's

+unfavorableness

+unfavorables

+unfavorably

+unfavored

+unfavored's

+unfavorings

+unfavorite

+unfavorite's

+unfavorites

+unfertilized

+unflavored

+unformalized

+ungeneralized

+unharmonized

+unharmonizes

+unhonorables

+unhonorablies

+unhonorably

+unhonored

+unhumored

+unidealized

+unindividualized

+unindividualizes

+uninitialized

+unionization

+unionize

+unionized

+unionizer

+unionizers

+unionizes

+unionizing

+unitalicized

+unitemized

+unjournalized

+unlabeled

+unlabored

+unlabored's

+unlaborings

+unlegalized

+unleveled

+unleveling

+unliberalized

+unlocalized

+unlocalizes

+unmechanized

+unmechanizes

+unmemorized

+unminimized

+unmodernized

+unmodernizes

+unmotorized

+unnationalized

+unneighbored

+unneighborliness

+unneighborly

+unneutralized

+unnormalized

+unnormalizes

+unoptimized

+unoptimizes

+unorganizable

+unorganizable's

+unorganizables

+unorganized

+unorganizedly

+unorganizedness

+unoxidized

+unparalleled

+unparameterized

+unparceled

+unpatronized

+unpatronizing's

+unpenalized

+unphilosophized

+unphilosophizes

+unpopularizes

+unpracticed

+unpulverized

+unpulverizes

+unraveled

+unraveling

+unrecognizable

+unrecognized

+unrecognizing

+unrecognizingly

+unreorganized

+unrivaled

+unrumored

+unsabered

+unsavored

+unsavoredly

+unsavoredness

+unscepters

+unscrutinized

+unscrutinizing

+unscrutinizingly

+unsepulchers

+unsiphons

+unsocialized

+unspecialized

+unspecializing

+unstandardized

+unsterilized

+unsubsidized

+unsuccored

+unsummarized

+unsymbolized

+unsympathized

+unsympathizing

+unsympathizing's

+unsympathizingly

+unsympathizings

+unsynchronized

+unsynthesized

+unsystematized

+unsystematizedly

+unsystematizing

+untantalized

+unterrorized

+untranquilized

+unverbalized

+unvictimized

+unvisualized

+unwomanized

+unwomanizes

+utilization

+utilize

+utilized

+utilizer

+utilizers

+utilizes

+utilizing

+valor

+valor's

+valors

+vandalize

+vandalized

+vandalizes

+vandalizing

+vapor

+vapor's

+vapored

+vaporer

+vaporer's

+vaporers

+vaporing

+vaporing's

+vaporingly

+vaporings

+vapors

+vectorization

+vectorizing

+verbalize

+verbalized

+verbalizer

+verbalizers

+verbalizes

+verbalizing

+victimize

+victimized

+victimizer

+victimizers

+victimizes

+victimizing

+victualer

+victualers

+vigor

+vigor's

+vigors

+visualize

+visualized

+visualizer

+visualizers

+visualizes

+visualizing

+wagoner

+wagoner's

+wagoners

+weaseled

+weaseling

+womanize

+womanized

+womanizer

+womanizers

+womanizes

+womanizing

+worshiped

+worshiper

+worshiper's

+worshipers

+worshiping

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.1 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.1
new file mode 100644
index 0000000..eb0e6c8
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.1
@@ -0,0 +1,741 @@
+Christianizing

+Europeanization

+Europeanization's

+Europeanizations

+Europeanized

+Sanskritize

+acclimatize

+acclimatizer

+acclimatizers

+acclimatizes

+acclimatizing

+actualize

+actualized

+actualizes

+actualizing

+aggrandizement

+aggrandizement's

+aggrandizements

+americanized

+amortization

+amortization's

+amortizations

+animized

+annualized

+asshole

+asshole's

+assholes

+balkanization

+biosynthesized

+bucketfuls

+bureaucratization

+bureaucratization's

+bureaucratizations

+caliper

+calipers

+cancelate

+cancelated

+canonized

+cauterize

+cauterized

+cauterizes

+cauterizing

+caviler

+cavilers

+centerline

+centerlines

+civilizational

+civilizational's

+civilizationals

+cognizable

+colorimeter

+colorimeter's

+colorimeters

+colorimetry

+commercialization

+commercialization's

+commercializations

+communize

+communized

+communizes

+communizing

+computerization

+conventionalized

+crystallization

+crystallization's

+crystallizations

+decentralizing

+deemphasize

+deemphasized

+deemphasizer

+deemphasizers

+deemphasizes

+deemphasizing

+deglycerolized

+dehumanize

+dehumanized

+dehumanizes

+dehumanizing

+demineralization

+demineralization's

+demineralizations

+democratization

+democratization's

+democratizations

+democratize

+democratized

+democratizer

+democratizes

+democratizing

+demoralization

+demoralization's

+demoralizations

+demythologization

+demythologize

+demythologized

+demythologizer

+demythologizes

+demythologizing

+depersonalization

+depersonalization's

+depersonalizations

+depersonalized

+deputized

+destabilize

+destabilized

+destabilizes

+destabilizing

+destigmatization

+desynchronize

+desynchronized

+desynchronizes

+desynchronizing

+detribalize

+detribalized

+detribalizes

+detribalizing

+diagonalizable

+dialyzed

+diarrhea

+diarrhea's

+diarrheal

+diarrheas

+dichotomization

+digitalization

+digitalization's

+digitalizations

+digitization

+diopter

+discolored

+discolored's

+discoloredness

+discoloreds

+discolors

+disfavor

+disfavored

+disfavorer

+disfavorer's

+disfavorers

+disfavoring

+disfavors

+disheveled

+disorganization

+disorganization's

+disorganizations

+doweling

+downdraft

+draftier

+draftiness

+draftsperson

+drafty

+dramatization

+dramatization's

+dramatizations

+dramatize

+dramatized

+dramatizer

+dramatizers

+dramatizes

+dramatizing

+duelist

+duelists

+dynamized

+edema

+edema's

+edemas

+edematous

+emphasize

+emphasized

+emphasizer

+emphasizers

+emphasizes

+emphasizing

+energized

+energizes

+enthrall

+enthralls

+epicenter

+epicenter's

+epicenters

+esthete

+esthetes

+eulogize

+eulogized

+eulogizer

+eulogizers

+eulogizes

+eulogizing

+exorcize

+exorcized

+exorcizes

+exorcizing

+extemporize

+extemporized

+extemporizer

+extemporizers

+extemporizes

+extemporizing

+externalization

+externalization's

+externalizations

+favoritism

+favoritism's

+favoritisms

+federalize

+federalized

+federalizes

+federalizing

+fetid

+fetidly

+fetidness

+fetus

+fetus's

+fetuses

+fiberboard

+fossilized

+fraternize

+fraternized

+fraternizer

+fraternizers

+fraternizes

+fraternizing

+galvanizing

+generalizable

+generalizable's

+generalizables

+germanized

+gimbaled

+glottalization

+glycerolized

+grueling

+gruelingly

+gynecological

+gynecological's

+gynecologicals

+gynecologist

+gynecologist's

+gynecologists

+harmonization

+harmonization's

+harmonizations

+homeomorph

+homeopath

+homogenization

+homogenization's

+homogenizations

+homogenize

+homogenized

+homogenizer

+homogenizers

+homogenizes

+homogenizing

+honoree

+hospitalization

+hospitalization's

+hospitalizations

+humanize

+humanized

+humanizer

+humanizers

+humanizes

+humanizing

+hydrolyzed

+hypnotized

+hypophysectomized

+idolize

+idolized

+idolizer

+idolizers

+idolizes

+idolizing

+immobilize

+immobilized

+immobilizer

+immobilizes

+immobilizing

+immortalized

+immunization

+immunization's

+immunizations

+impersonalized

+industrialized

+industrializing

+inhumanizes

+institutionalization

+institutionalization's

+institutionalizations

+internationalization

+internationalization's

+internationalizations

+internationalized

+ionize

+ionized

+ionizer

+ionizers

+ionizes

+ionizing

+ionizings

+ionizion

+ionizions

+kinesthesis

+kinesthetic

+kinesthetically

+kinesthetics

+legitimize

+legitimized

+legitimizer

+legitimizes

+legitimizing

+libeler

+libelers

+libelous

+libelously

+liberalization

+liberalization's

+liberalizations

+licensable

+lionize

+lionized

+lionizer

+lionizers

+lionizes

+lionizing

+magnetized

+maneuverability

+maneuverable

+marbleized

+marbleizing

+maximization

+maximization's

+maximizations

+memorialized

+mesmerized

+metabolized

+metalization

+metalization's

+metalizations

+metropolitanization

+milligram

+milligram's

+milligrams

+milliliter

+milliliter's

+milliliters

+mineralized

+misbehavior

+misbehavior's

+misbehaviors

+misdemeanor

+misdemeanor's

+misdemeanors

+mobilization

+mobilization's

+mobilizations

+mobilize

+mobilized

+mobilizer

+mobilizes

+mobilizing

+modernization

+modernization's

+modernizations

+monetization

+monetize

+monetized

+monetizes

+monetizing

+monopolization

+monopolization's

+monopolizations

+monopolize

+monopolized

+monopolizer

+monopolizers

+monopolizes

+monopolizing

+multicolor

+multicolor's

+multicolored

+multicolors

+narcotizes

+nasalization

+nasalization's

+nasalizations

+nasalized

+naturalized

+neutralization

+neutralization's

+neutralizations

+nominalized

+novelized

+ocher

+ocher's

+ochers

+operationalization

+operationalizations

+operationalize

+operationalized

+orthogonalization

+orthogonalized

+orthopedic

+orthopedics

+ostracized

+outmaneuver

+outmaneuvered

+outmaneuvering

+outmaneuvers

+overemphasize

+overemphasized

+overemphasizer

+overemphasizers

+overemphasizes

+overemphasizing

+palatalization

+palatalize

+palatalized

+palatalizes

+palatalizing

+palletized

+panelization

+panelized

+parenthesize

+parenthesizes

+parenthesizing

+pasteurization

+pasteurizations

+pedaled

+pedaling

+peptizing

+platinize

+platinized

+platinizes

+platinizing

+plowshare

+plowshare's

+plowshares

+polarize

+polarized

+polarizer

+polarizers

+polarizes

+polarizing

+politicized

+polymerizations

+proletarianization

+proletarianized

+pronominalization

+pronominalize

+pummeled

+pyorrhea

+pyorrhea's

+pyorrheas

+pyrolyze

+pyrolyze's

+pyrolyzer

+pyrolyzes

+radiopasteurization

+radiosterilization

+radiosterilized

+rancor

+rancor's

+rancors

+randomization

+randomization's

+randomizations

+rationalization

+rationalization's

+rationalizations

+reacclimatizes

+reactualizes

+realizabilities

+realizability

+realizability's

+reconceptualization

+recrystallization

+recrystallization's

+recrystallizations

+recrystallize

+recrystallizing

+reemphasize

+reemphasized

+reemphasizer

+reemphasizers

+reemphasizes

+reemphasizing

+regularizing

+reharmonization

+rehumanizes

+remobilization

+remobilization's

+remobilizations

+remobilizes

+remonetization

+remonetize

+remonetized

+remonetizes

+remonetizing

+repopularize

+revaporization

+revaporization's

+revaporizations

+revisualization

+revisualization's

+revisualizations

+revitalization

+revitalize

+revitalized

+revitalizer

+revitalizers

+revitalizes

+revitalizing

+ritualized

+romanticize

+romanticizes

+romanticizing

+rubberized

+satirizes

+scandalized

+scandalizing

+sectionalized

+secularization

+secularization's

+secularizations

+secularized

+sensitized

+sentimentalize

+sentimentalized

+sentimentalizer

+sentimentalizers

+sentimentalizes

+sentimentalizing

+sexualized

+signalizes

+sniveled

+sniveler

+snivelers

+sniveling

+snivelings

+socialization

+socialization's

+socializations

+stabilization

+stabilization's

+stabilizations

+stigmatization

+stigmatization's

+stigmatizations

+stigmatized

+stylization

+stylization's

+stylizations

+subcategorizing

+subsidization

+subsidization's

+subsidizations

+substerilization

+suburbanization

+suburbanization's

+suburbanizations

+suburbanized

+suburbanizing

+swiveled

+swiveling

+systematization

+systematization's

+systematizations

+systemization

+systemization's

+systemizations

+teaseled

+teaseling

+teetotaler

+temporize

+temporized

+temporizer

+temporizer's

+temporizers

+temporizes

+temporizing

+temporizing's

+temporizingly

+temporizings

+theatergoer

+theatergoer's

+theatergoers

+theatergoing

+theatergoing's

+theatergoings

+thru

+tine's

+tinseled

+tinseling

+traditionalized

+travelog

+travelog's

+travelogs

+trialization

+triangularization

+triangularizations

+tricolor

+tricolor's

+tricolored

+tricolors

+tyrannize

+tyrannized

+tyrannizer

+tyrannizers

+tyrannizes

+tyrannizing

+tyrannizing's

+tyrannizingly

+tyrannizings

+unamortization

+unamortization's

+unamortizations

+uncanonized

+uncauterized

+uncauterized's

+uncauterizeds

+undemocratizes

+underutilization

+underutilized

+undialyzed

+undialyzed's

+undialyzeds

+undiscoloreds

+undramatized

+undramatized's

+undramatizeds

+unenergized

+unenergized's

+unenergizeds

+uneulogized

+uneulogized's

+uneulogizeds

+unfossilized

+unfossilized's

+unfossilizeds

+unfraternizing

+unfraternizing's

+unfraternizings

+unhydrolyzed

+unhydrolyzed's

+unhydrolyzeds

+unidolized

+unidolized's

+unidolizeds

+unimmortalized

+unindustrialized

+unindustrialized's

+unindustrializeds

+unitized

+universalize

+universalized

+universalizer

+universalizers

+universalizes

+universalizing

+unmagnetized

+unmagnetized's

+unmagnetizeds

+unmemorialized

+unmemorialized's

+unmemorializeds

+unmesmerized

+unmineralized

+unmineralized's

+unmineralizeds

+unmobilized

+unmobilized's

+unmobilizeds

+unmonopolized

+unmonopolizes

+unnaturalized

+unpatronizing

+unpolarized

+unpolarized's

+unpolarizeds

+unsatirizes

+unsavories

+unsavoriness

+unsavory

+unsavory's

+unscandalized

+unsecularized

+unsensitized

+unsentimentalizes

+unstigmatized

+unstigmatized's

+unstigmatizeds

+untemporizings

+untrammeled

+unvocalized

+unvocalized's

+unvocalizeds

+unvulcanized

+unvulcanized's

+unvulcanizeds

+updraft

+urbanization

+urbanization's

+urbanizations

+urbanized

+vacuolization

+vacuolization's

+vacuolizations

+vaporization

+vaporization's

+vaporizations

+varicolored

+varicolored's

+varicoloreds

+velarize

+velarized

+velarizes

+velarizing

+visualization

+visualization's

+visualizations

+vocalization

+vocalization's

+vocalizations

+vocalize

+vocalized

+vocalizer

+vocalizers

+vocalizes

+vocalizing

+volatilization

+volatilization's

+volatilizations

+vulcanized

+watercolor

+watercolor's

+watercolored

+watercoloring

+watercolorist

+watercolorists

+watercolors

+yodeled

+yodeler

+yodeling

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.2 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.2
new file mode 100644
index 0000000..133e19e
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/american.2
@@ -0,0 +1,6767 @@
+Africanization

+Africanization's

+Africanizations

+Africanize

+Africanized

+Africanizes

+Africanizing

+Afrikanerization

+Afrikanerize

+Afrikanerized

+Afrikanerizes

+Afrikanerizing

+Americanization

+Americanization's

+Americanizations

+Americanize

+Americanizer

+Americanizers

+Americanizes

+Americanizing

+Anglicanize

+Anglicanizes

+Arabianize

+Arabianizes

+Arabicize

+Arabicizes

+Aryanization

+Aryanize

+Aryanized

+Aryanizes

+Aryanizing

+Asiaticization

+Asiaticization's

+Asiaticizations

+Asiaticize

+Asiaticizes

+Assyrianize

+Assyrianizes

+Australianize

+Australianizes

+Austrianize

+Austrianizes

+Babelize

+Babelizes

+Babylonize

+Babylonizes

+Balkanization

+Balkanization's

+Balkanizations

+Balkanize

+Balkanizes

+Berlinize

+Berlinizes

+Bessemerize

+Bessemerizes

+Birminghamize

+Birminghamizes

+Boswellize

+Boswellizes

+Byronize

+Byronizes

+Byzantinize

+Byzantinizes

+Caesarize

+Caesarizes

+Calvinize

+Calvinizes

+Canadianization

+Canadianization's

+Canadianizations

+Canadianize

+Canadianizes

+Caponization

+Catholicization

+Catholicized

+Catholicizing

+Celticize

+Celticizes

+Chablises

+Christianization

+Christianization's

+Christianizations

+Christianize

+Christianizer

+Christianizers

+Christianizes

+Ciceronianize

+Ciceronianizes

+Continentalize

+Continentalizes

+Corinthianize

+Corinthianizes

+Creolization

+Creolize

+Creolized

+Creolizes

+Creolizing

+Cubanize

+Cubanizes

+Czechization

+Czechization's

+Czechizations

+Danization

+Danization's

+Danizations

+Danize

+Danizes

+Darwinize

+Darwinizes

+Doricize

+Doricizes

+Edenization

+Edenization's

+Edenizations

+Edenize

+Edenizes

+Egyptianization

+Egyptianization's

+Egyptianizations

+Egyptianize

+Egyptianizes

+Egyptize

+Egyptizes

+Elizabethanize

+Elizabethanizes

+Englishize

+Englishizes

+Epicurize

+Epicurizes

+Episcopalianize

+Episcopalianizes

+Eskimoized

+Eskimoized's

+Eskimoizeds

+Essenize

+Essenizes

+Etna

+Europeanize

+Europeanizes

+Europeanizing

+Fletcherize

+Fletcherizes

+Francize

+Francizes

+Franklinization

+Franklinization's

+Franklinizations

+Frenchize

+Frenchizes

+Gaelicization

+Gaelicization's

+Gaelicizations

+Gaelicize

+Gaelicizes

+Gallicization

+Gallicize

+Gallicized

+Gallicizes

+Gallicizing

+Gothicize

+Gothicized

+Gothicizer

+Gothicizers

+Gothicizes

+Gothicizing

+Grecianize

+Grecianizes

+Greekize

+Greekizes

+Hanoverianize

+Hanoverianizes

+Hanoverize

+Hanoverizes

+Harvardize

+Harvardizes

+Harveyize

+Harveyizes

+Hattize

+Hattizes

+Hebraicize

+Hebraicizes

+Hegelianize

+Hegelianizes

+Hellenization

+Hellenizations

+Hellenize

+Hellenized

+Hellenizes

+Hellenizing

+Hispanicization

+Hispanicize

+Hispanicized

+Hispanicizes

+Hispanicizing

+Hollywoodize

+Hollywoodizes

+Hoosierize

+Hoosierizes

+Hooverize

+Hooverizes

+Iliadize

+Iliadizes

+Illuminize

+Illuminizes

+Ionicization

+Ionicization's

+Ionicizations

+Ionicize

+Ionicizes

+Iranize

+Iranizes

+Irishize

+Irishizes

+Islamization

+Islamization's

+Islamizations

+Islamize

+Islamized

+Islamizes

+Islamizing

+Israelitize

+Israelitizes

+Italianism

+Italianization

+Italianization's

+Italianizations

+Italianize

+Italianized

+Italianizer

+Italianizers

+Italianizes

+Italianizing

+Jacobinize

+Japanization

+Japanization's

+Japanizations

+Japanize

+Japanized

+Japanizes

+Japanizing

+Jesuitize

+Jesuitized

+Jesuitizes

+Jesuitizing

+Jonathanization

+Jonathanization's

+Jonathanizations

+Latinization

+Latinization's

+Latinizations

+Latinize

+Latinized

+Latinizer

+Latinizers

+Latinizes

+Latinizing

+Lilliputianize

+Lilliputianizes

+Listerize

+Listerizes

+Londonization

+Londonization's

+Londonizations

+Londonize

+Londonizes

+Lutheranize

+Lutheranizer

+Lutheranizers

+Lutheranizes

+Malayize

+Malayizes

+Manhattanize

+Manhattanizes

+Mediterraneanization

+Mediterraneanization's

+Mediterraneanizations

+Mediterraneanize

+Mediterraneanizes

+Melampus

+Mendelize

+Mendelizes

+Mexicanize

+Mexicanizes

+Midlandize

+Midlandizes

+Miltonize

+Miltonized

+Miltonizes

+Miltonizing

+Mohammedanization

+Mohammedanization's

+Mohammedanizations

+Mohammedanize

+Mohammedanized

+Mohammedanizes

+Mohammedanizing

+Molochize

+Molochizes

+Moravianized

+Moravianized's

+Moravianizeds

+Moslemize

+Moslemizes

+Napoleonize

+Napoleonizes

+Negroization

+Negroization's

+Negroizations

+Negroize

+Negroizes

+Newmanize

+Newmanizes

+Nipponize

+Nipponizes

+Normanization

+Normanization's

+Normanizations

+Normanize

+Normanized

+Normanizer

+Normanizers

+Normanizes

+Normanizing

+Occidentalization

+Occidentalization's

+Occidentalizations

+Occidentalize

+Occidentalized

+Occidentalizes

+Occidentalizing

+Olympianize

+Olympianizes

+Ottomanization

+Ottomanization's

+Ottomanizations

+Ottomanize

+Ottomanizes

+Parisianization

+Parisianization's

+Parisianizations

+Parisianize

+Parisianizes

+Pasteurizers

+Paulinize

+Paulinizes

+Paynize

+Paynizes

+Persianization

+Persianization's

+Persianizations

+Persianize

+Persianizes

+Peruvianize

+Peruvianizes

+Philistinize

+Philistinizes

+Presbyterianize

+Presbyterianizes

+Procrusteanize

+Procrusteanizes

+Protestantize

+Protestantizes

+Prussianization

+Prussianization's

+Prussianizations

+Prussianize

+Prussianized

+Prussianizer

+Prussianizers

+Prussianizes

+Prussianizing

+Pullmanize

+Pullmanizes

+Puritanize

+Puritanizer

+Puritanizers

+Puritanizes

+Pythagoreanize

+Pythagoreanizes

+Quakerization

+Quakerization's

+Quakerizations

+Quakerize

+Quakerizes

+Romania

+Romanization

+Romanization's

+Romanizations

+Romanize

+Romanized

+Romanizer

+Romanizers

+Romanizes

+Romanizing

+Russianization's

+Russianizations

+Russianized

+Russianizes

+Russianizing

+Sabbathize

+Sabbathizes

+Saxonization

+Saxonization's

+Saxonizations

+Saxonize

+Saxonizes

+Semiticize

+Semiticizes

+Semitization

+Semitization's

+Semitizations

+Semitize

+Semitizes

+Shakespearize

+Shakespearizes

+Shintoize

+Shintoizes

+Slavicize

+Slavicizes

+Slavization

+Slavization's

+Slavizations

+Slavize

+Slavizes

+Slavonicize

+Slavonicizes

+Sovietized

+Sovietizing

+Spaniardization

+Spaniardization's

+Spaniardizations

+Spaniardize

+Spaniardizes

+Spanishize

+Spanishizes

+Spartanize

+Spartanizes

+Syrianize

+Syrianizes

+Talmudization

+Talmudization's

+Talmudizations

+Talmudize

+Talmudizes

+Tammanyize

+Tammanyizes

+Taylorize

+Taylorizes

+Timonize

+Timonizes

+Toryize

+Toryizes

+Turkize

+Turkizes

+Tuscanize

+Tuscanizes

+Tylerize

+Tylerizes

+Unitarianize

+Unitarianizes

+Utopianize

+Utopianizes

+Vaticanization

+Vaticanization's

+Vaticanizations

+Vaticanize

+Vaticanizes

+Victorianize

+Victorianizes

+Vietnamization

+Vietnamize

+Vietnamized

+Vietnamizes

+Vietnamizing

+Wagnerize

+Wagnerizes

+Whitmanize

+Whitmanizes

+abnormalize

+abnormalizes

+abolitionize

+abolitionizes

+absolutization

+absolutization's

+absolutizations

+absolutize

+absolutizes

+accessorize

+acclimatizable

+acclimatizable's

+acclimatizables

+accouter

+accoutered

+accoutering

+accouters

+acculturize

+acetonization

+acetonization's

+acetonizations

+acetonize

+acetonizes

+achromatization

+achromatize

+achromatized

+achromatizes

+achromatizing

+acidize

+acidizes

+acronymize

+acronymizes

+actionize

+actionizes

+activize

+activizes

+adrenalize

+adrenalizes

+adulterize

+adulterizes

+adverbialize

+adverbializes

+aerosolization

+aestheticize

+aestheticizes

+agatize

+agatizes

+agenize

+aggrandizable

+aggrandizable's

+aggrandizables

+aggrandization

+aggrandize

+aggrandized

+aggrandizer

+aggrandizers

+aggrandizes

+aggrandizing

+agnize

+agnized

+agnizes

+agnizing

+agrarianize

+agrarianizes

+albumenization

+albumenize

+albumenized

+albumenizes

+albumenizing

+albuminization

+albuminization's

+albuminizations

+albuminize

+albuminizes

+alchemize

+alcoholizable

+alcoholizable's

+alcoholizables

+alcoholization

+alcoholization's

+alcoholizations

+alcoholize

+alcoholizes

+algebraization

+algebraization's

+algebraizations

+algebraize

+algebraizes

+alienize

+alienizes

+alkalinization

+alkalinization's

+alkalinizations

+alkalinize

+alkalinizes

+alkalization

+alkalize

+alkalized

+alkalizes

+alkalizing

+allegorization

+allegorize

+allegorized

+allegorizer

+allegorizes

+allegorizing

+alphabetization

+alphabetization's

+alphabetizations

+alternize

+alternizes

+aluminization

+aluminize

+aluminized

+aluminizes

+aluminizing

+amalgamatize

+amalgamatizes

+amalgamization

+amalgamization's

+amalgamizations

+amalgamize

+amalgamizes

+amor

+amor's

+amoralize

+amoralizes

+amorism

+amorism's

+amorisms

+amoristic

+amoristics

+amorphization

+amorphize

+amors

+amortizable

+amortizable's

+amortizables

+amortizement

+amortizement's

+amortizements

+anagrammatization

+anagrammatize

+analogism

+analogism's

+analogisms

+analogize

+analogizes

+analyzation

+anarchize

+anarchizes

+anathematization

+anathematize

+anathematized

+anathematizes

+anathematizing

+anatomize

+anemically

+anesthesiologist

+anesthesiology

+anesthetist

+anesthetization

+anesthetization's

+anesthetizations

+angelicize

+angelicizes

+angelize

+angelizes

+anglicization

+anglicization's

+anglicizations

+anglicize

+anglicized

+anglicizes

+angularization

+angularization's

+angularizations

+angularize

+angularizes

+anhydridization

+anhydridization's

+anhydridizations

+anhydridize

+anhydridizes

+animalization

+animalization's

+animalizations

+animalize

+animalized

+animalizes

+animalizing

+annalize

+annalizes

+annualization

+annualize

+annualizes

+annualizing

+anodization

+antagonization

+antagonization's

+antagonizations

+anthologization

+anthologize

+anthologized

+anthologizer

+anthologizes

+anthologizing

+anthracitization

+anthracitization's

+anthracitizations

+anthropomorphization

+anthropomorphize

+anthropomorphized

+anthropomorphizes

+anthropomorphizing

+anticatalyzer

+anticatalyzer's

+anticatalyzers

+anticentralization

+anticentralization's

+anticentralizations

+anticize

+anticizes

+antiepicenter

+antiepicenter's

+antiepicenters

+antifertilizer

+antifertilizer's

+antifertilizers

+antilabor

+antilabor's

+antilabors

+antioxidizer

+antioxidizer's

+antioxidizers

+antioxidizing

+antioxidizing's

+antioxidizings

+antipathize

+antipathizes

+antiquarianize

+antiquarianizes

+antirumor

+antirumor's

+antirumors

+antisensitize

+antisensitizer

+antisensitizer's

+antisensitizers

+antisensitizes

+antisepticize

+antisepticizes

+antiseptize

+antiseptizes

+antisiphon

+antisiphon's

+antisiphons

+antithesize

+antithesizes

+anviled

+anviling

+aphorize

+aphorized

+aphorizer

+aphorizers

+aphorizes

+aphorizing

+apostatization

+apostatize

+apostatized

+apostatizes

+apostatizing

+apostrophize

+apostrophized

+apostrophizes

+apostrophizing

+apotheosize

+appareling

+appetize

+appetized

+appetizement

+appetizement's

+appetizements

+appetizers

+appetizes

+arabization

+arabize

+arabized

+arabizes

+arabizing

+arbores

+arborization

+arborize

+arborized

+arborizes

+arborizing

+arcticize

+arcticizes

+arithmetization

+arithmetization's

+arithmetizations

+aromatization

+aromatize

+aromatized

+aromatizes

+aromatizing

+arsenicize

+arsenicizes

+arterialization

+arterialization's

+arterializations

+arterialize

+arterialized

+arterializes

+arterializing

+artificialize

+artificializes

+asafetida

+asepticize

+asepticizes

+astigmatizer

+astigmatizer's

+astigmatizers

+asynchronize

+asynchronized

+asynchronizes

+asynchronizing

+atomizability

+atomizable

+atticize

+atticizes

+attitudinization

+attitudinize

+attitudinized

+attitudinizes

+attitudinizing

+autoimmunization

+autoionization

+automatization

+automatization's

+automatizations

+automatize

+automatizes

+autotomize

+avianize

+azotization

+azotize

+azotized

+azotizes

+azotizing

+bachelorize

+bachelorizes

+baconize

+baconizes

+bacterize

+balladize

+balladizes

+balsamize

+balsamizes

+bantamize

+bantamizes

+baptizable

+baptizable's

+baptizables

+baptizement

+baptizement's

+baptizements

+barbarianize

+barbarianizes

+barbarization

+barbarize

+barbarized

+barbarizes

+barbarizing

+baronize

+baronizes

+bastardization

+bastardization's

+bastardizations

+beaverize

+beaverizes

+beclamor

+beclamored

+beclamoring

+beclamors

+becudgeled

+becudgeling

+bedlamize

+bedlamizes

+bedriveled

+bedriveling

+bejeweled

+bejeweling

+bemedaled

+bestialize

+bestialized

+bestializes

+bestializing

+beveler

+bevelers

+bichromatize

+bichromatizes

+bicolor

+bicolored

+bimetalist

+bimetalistic

+biographize

+biographizes

+biologize

+biologizes

+bipolarization

+bipolarize

+bipolarizes

+bister

+bistered

+bituminization

+bituminize

+bituminized

+bituminizes

+bituminizing

+bolshevize

+bonderize

+borize

+borizes

+botanize

+botanized

+botanizes

+botanizing

+boulevardize

+boulevardizes

+bourbonize

+bourbonizes

+bowdlerization

+boweled

+boweling

+brominize

+brominizes

+brutalization

+brutalization's

+brutalizations

+bureaucratize

+bureaucratized

+bureaucratizes

+busheler

+bushelers

+cadaverize

+cadaverizes

+cadmiumize

+cadmiumizes

+canaler

+canalers

+canalization

+canalization's

+canalizations

+canalize

+canalized

+canalizes

+canalizing

+cancelable

+cancelous

+cannibalization

+cannibalization's

+cannibalizations

+canonization

+canonization's

+canonizations

+canonize

+canonizer

+canonizers

+canonizes

+canonizing

+capitalizable

+capitalizable's

+capitalizables

+caponize

+caponized

+caponizes

+caponizing

+capsulization

+capsulize

+capsulized

+capsulizes

+capsulizing

+caracoled

+caracoling

+caramelization

+caramelization's

+caramelizations

+caramelize

+caramelized

+caramelizes

+caramelizing

+carbolization

+carbolize

+carbolized

+carbolizes

+carbolizing

+carbonatization

+carbonatization's

+carbonatizations

+carbonizable

+carbonizable's

+carbonizables

+carburization

+carburize

+carburized

+carburizes

+carburizing

+carnalize

+carnalizes

+caroled

+caroler

+carolers

+caroling

+cartelization

+cartelization's

+cartelizations

+cartelize

+cartelizes

+castorized

+castorized's

+castorizeds

+catabolize

+cataloguize

+cataloguizes

+catalyze

+catalyzer

+catalyzer's

+catalyzers

+catalyzes

+catechizable

+catechizable's

+catechizables

+catechization

+catechization's

+catechizations

+catechize

+catechized

+catechizer

+catechizers

+catechizes

+catechizing

+catheterization

+catheterization's

+catheterizations

+catheterize

+catheterizes

+catheti

+catheti's

+cathetis

+catholicize

+catholicizer

+catholicizers

+catholicizes

+causticization

+causticization's

+causticizations

+causticize

+causticizer

+causticizers

+causticizes

+cauterization

+cauterization's

+cauterizations

+cavilation

+caviled

+caviling

+cavilings

+celestialize

+celestializes

+centerable

+centerable's

+centerables

+centerboard

+centerless

+centigram

+centigram's

+centigrams

+centiliter

+centrifugalization

+centrifugalization's

+centrifugalizations

+centrifugalize

+centrifugalizes

+cephalization

+cerebralization

+cerebralization's

+cerebralizations

+cerebralize

+cerebralizes

+ceremonialize

+ceremonializes

+chameleonize

+chameleonizes

+championize

+championizes

+channelization

+channelization's

+channelizations

+channelize

+channelizes

+chattelization

+chattelization's

+chattelizations

+chattelize

+chattelizes

+cheerfulize

+cheerfulizes

+chemicalization

+chemicalization's

+chemicalizations

+chemicalize

+chemicalizes

+chiseling

+chiselings

+chloridize

+chloridizes

+chlorinize

+chlorinizes

+chloroformization

+chloroformization's

+chloroformizations

+chloroformize

+chloroformizes

+chorization

+chorization's

+chorizations

+chromatize

+chromatizes

+chromicize

+chromicizes

+chromize

+chromized

+chromizes

+chromizing

+chronologize

+chronologizes

+cinchonize

+cinematize

+circularization

+circularization's

+circularizations

+circularize

+circularized

+circularizer

+circularizers

+circularizes

+circularizing

+citizenize

+citizenizes

+civilianization

+civilianizations

+civilianize

+civilianized

+civilianizes

+civilianizing

+civilizable

+civilizable's

+civilizables

+clangor

+clangor's

+clangored

+clangoring

+clangors

+classicalize

+classicalizes

+classicization

+classicize

+classicized

+classicizes

+classicizing

+clericalize

+clericalizes

+climatize

+climatizes

+coalize

+coalizer

+coalizers

+coalizes

+cocainization

+cocainization's

+cocainizations

+cocainize

+cocainizes

+coeducationalize

+coeducationalizes

+coenamor

+coenamored

+coenamoring

+coenamors

+coequalize

+coequalizes

+cognizably

+cognize

+cognized

+cognizer

+cognizers

+cognizes

+cognizing

+collateralize

+collectivization

+collectivization's

+collectivizations

+collectivize

+collectivized

+collectivizes

+colloquialize

+colloquializes

+colonialize

+colonializes

+colonizabilities

+colonizability

+colonizability's

+colonizable

+colonizable's

+colonizables

+colonizationist

+colonizationist's

+colonizationists

+colorabilities

+colorability

+colorability's

+colorable

+colorable's

+colorableness

+colorables

+colorablies

+colorably

+colorama

+colorant

+colorants

+colorcast

+colorcaster

+colorcasters

+colorfast

+colorfastness

+colorific

+colorimetric

+colorimetrically

+colorism

+colorisms

+colorist

+colorist's

+coloristic

+coloristically

+coloristics

+colorists

+colorization

+colorization's

+colorizations

+colorize

+colorizes

+colorman

+colormap

+colormap's

+colormaps

+colormen

+columnization

+columnization's

+columnizations

+commercialize

+commercialized

+commercializes

+commercializing

+commonize

+commonizes

+communalization

+communalization's

+communalizations

+communalize

+communalized

+communalizer

+communalizers

+communalizes

+communalizing

+communization

+communization's

+communizations

+companionize

+companionizes

+compartmentalization

+compartmentalization's

+compartmentalizations

+compartmentize

+compartmentizes

+complementizer

+computerizable

+concenter

+concertize

+concertizer

+concertizers

+concertizes

+concretization

+concretizations

+concretize

+concretized

+concretizes

+concretizing

+conditionalize

+conditionalizes

+confederatize

+confederatizes

+congenialize

+congenializes

+congregationalize

+congregationalizes

+conservatize

+conservatized

+conservatizes

+conservatizing

+consonantize

+consonantizes

+constitutionalization

+constitutionalization's

+constitutionalizations

+constitutionalize

+constitutionalizes

+containerization

+containerize

+containerized

+containerizes

+containerizing

+contemporization

+contemporize

+contemporized

+contemporizes

+contemporizing

+controversialize

+controversializes

+conundrumize

+conundrumizes

+conventionalization

+conventionalization's

+conventionalizations

+conventionalize

+conventionalizes

+conventionalizing

+conventionize

+conventionizes

+conversationize

+conversationizes

+conveyorize

+conveyorized

+conveyorizes

+conveyorizing

+convivialize

+convivializes

+copolymerization

+copolymerization's

+copolymerizations

+copolymerize

+copolymerized

+copolymerizes

+copolymerizing

+copperization

+copperization's

+copperizations

+copperize

+copperizes

+coraled

+corbeled

+corbeling

+corbelings

+cordialize

+cordializes

+corporealization

+corporealization's

+corporealizations

+corporealize

+corporealizes

+cosmopolitanization

+cosmopolitanization's

+cosmopolitanizations

+cosmopolitanize

+cosmopolitanizes

+cottonization

+cottonization's

+cottonizations

+cottonize

+cottonizes

+councilorship

+counselee

+counselorship

+crawlerize

+crawlerizes

+creaturize

+creaturizes

+crenelate

+crenelated

+crenelates

+crenelation

+creneled

+creneling

+cretinization

+cretinization's

+cretinizations

+cretinize

+cretinizes

+criminalization

+criminalization's

+criminalize

+criticizable

+criticizable's

+criticizables

+crofterization

+crofterization's

+crofterizations

+crofterize

+crofterizes

+cruelize

+cruelizes

+crystallizabilities

+crystallizability

+crystallizability's

+crystallizable

+crystallizable's

+crystallizables

+cudgeled

+cudgeler

+cudgelers

+cudgeling

+cudgelings

+culturization

+culturization's

+culturizations

+culturize

+culturizes

+cupelation

+cupeled

+cupeler

+cupelers

+cupeling

+curarize

+curarized

+curarizes

+curarizing

+curatize

+curatizes

+curricularization

+curricularization's

+curricularizations

+curricularize

+curricularizes

+cutinize

+cutinized

+cutinizes

+cutinizing

+cutization

+cutization's

+cutizations

+cyclization

+cyclization's

+cyclizations

+cyclize

+cyclized

+cyclizes

+cyclizing

+dandyize

+dandyizes

+dastardize

+dastardizes

+deaconize

+deaconizes

+deaminize

+decaliter

+decaliters

+decameter

+decameter's

+decameters

+decarbonization

+decarbonize

+decarbonized

+decarbonizer

+decarbonizes

+decarbonizing

+decarburization

+decarburize

+decarburized

+decarburizes

+decarburizing

+decasualization

+decentralizationist

+decentralize

+decentralizes

+decigram

+decigram's

+decigrams

+deciliter

+deciliters

+decimalization

+decimalization's

+decimalizations

+decimalize

+decimalized

+decimalizes

+decimalizing

+decimeter

+decimeter's

+decimeters

+decolonization

+decolonize

+decolonized

+decolonizes

+decolonizing

+decolor

+decolorant

+decolorants

+decolorate

+decolorated

+decolorates

+decolored

+decoloring

+decolorise

+decolorised

+decolorises

+decolorization

+decolorize

+decolorized

+decolorizer

+decolorizes

+decolors

+decriminalization

+decriminalization's

+decriminalize

+deemphasization

+deemphasization's

+deenergize

+deenergized

+deenergizer

+deenergizes

+deenergizing

+defeminize

+defeminized

+defeminizes

+defeminizing

+defenseman

+definitization

+definitization's

+definitizations

+definitize

+definitized

+definitizes

+definitizing

+deflectionization

+deflectionization's

+deflectionizations

+deflectionize

+deflectionizes

+deformalize

+defunctionalization

+defunctionalization's

+defunctionalizations

+defunctionalize

+defunctionalizes

+dehumanization

+dehumanization's

+dehumanizations

+dehypnotization

+dehypnotize

+dehypnotized

+dehypnotizes

+dehypnotizing

+deindustrialization

+deindustrialize

+deionization

+deionize

+deionizes

+dekagram

+dekagram's

+dekagrams

+dekaliter

+dekameter

+dekameter's

+dekameters

+delimitize

+delimitizes

+delocalization

+delocalize

+deluster

+demagnetizable

+demagnetizable's

+demagnetizables

+demagnetization

+demagnetization's

+demagnetizations

+demagnetize

+demagnetized

+demagnetizer

+demagnetizers

+demagnetizes

+demagnetizing

+dematerialization

+dematerialize

+dematerialized

+dematerializes

+dematerializing

+demilitarization

+demilitarize

+demilitarized

+demilitarizes

+demilitarizing

+demineralize

+demineralized

+demineralizer

+demineralizes

+demineralizing

+demobilization

+demobilize

+demobilized

+demobilizes

+demobilizing

+demonetization

+demonetize

+demonetized

+demonetizes

+demonetizing

+demonization

+demonize

+demonized

+demonizes

+demonizing

+denationalization

+denationalize

+denationalized

+denationalizes

+denationalizing

+denaturalization

+denaturalize

+denaturalized

+denaturalizes

+denaturalizing

+denaturization

+denaturization's

+denaturizations

+denaturize

+denaturizer

+denaturizers

+denaturizes

+denicotinize

+denizenize

+denizenizes

+denominationalize

+denominationalizes

+denormalize

+dentalization

+dentalization's

+dentalizations

+dentalize

+dentalizes

+denuclearization

+denuclearize

+denuclearized

+denuclearizes

+denuclearizing

+deodorize

+deodorized

+deodorizes

+deodorizing

+deoxidizer

+departmentalization

+departmentalization's

+departmentalizations

+departmentalize

+departmentalizes

+departmentization

+departmentization's

+departmentizations

+departmentize

+departmentizes

+depersonalize

+depersonalizes

+depersonalizing

+depolarization

+depolarization's

+depolarizations

+depolarize

+depolarized

+depolarizer

+depolarizers

+depolarizes

+depolarizing

+depoliticization

+depoliticize

+depoliticized

+depoliticizes

+depoliticizing

+depolymerization

+depolymerize

+depolymerized

+depolymerizes

+depolymerizing

+depressurization

+depressurize

+depressurized

+depressurizes

+depressurizing

+deputationize

+deputationizes

+deputization

+deputize

+deputizes

+deputizing

+derationalization

+derationalization's

+derationalizations

+derationalize

+derationalizes

+deratization

+deratization's

+deratizations

+derealization

+deregulationize

+deregulationizes

+desalinization

+desalinize

+desensitization

+desensitization's

+desensitizations

+desensitize

+desensitized

+desensitizer

+desensitizers

+desensitizes

+desensitizing

+desexualization

+desexualize

+desexualized

+desexualizes

+desexualizing

+despiritualization

+despiritualize

+despotize

+despotizes

+destabilization

+destalinize

+destalinized

+destalinizes

+destalinizing

+desterilize

+desulfurization

+desulfurize

+desulphurization

+desulphurize

+desulphurized

+desulphurizes

+desulphurizing

+desynchronization

+detribalization

+detribalization's

+detribalizations

+develed

+develing

+deviled

+deviling

+devilize

+devilizes

+devitalization

+devitalize

+devitalized

+devitalizes

+devitalizing

+devocalize

+devolatilization

+devolatilize

+devolatilized

+devolatilizes

+devolatilizing

+diabolization

+diabolize

+diabolized

+diabolizes

+diabolizing

+diagonalization

+diagonalize

+diagonalizes

+dialecticize

+dialecticizes

+dialist

+dialists

+dialyzabilities

+dialyzability

+dialyzability's

+dialyzable

+dialyzable's

+dialyzables

+dialyze

+dialyzer

+dialyzer's

+dialyzers

+dialyzes

+diamondize

+diamondizes

+diarrheic

+diarrhetic

+dieselization

+dieselization's

+dieselizations

+dieselize

+dieselizes

+differentialize

+differentializes

+digitalize

+digitalized

+digitalizes

+digitalizing

+dimensionalization

+dimensionalize

+dimensionalized

+dimensionalizes

+dimensionalizing

+dimerization

+dimerization's

+dimerizations

+dimerize

+dimerized

+dimerizes

+dimerizing

+diminutivize

+diminutivizes

+diphthongization

+diphthongization's

+diphthongizations

+diphthongize

+diphthongizes

+diplomatize

+diplomatizes

+disangularize

+disangularizes

+disauthorize

+disauthorizes

+disboweled

+disboweling

+discanonization

+discanonization's

+discanonizations

+discanonize

+discanonizes

+discolor

+discolor's

+discoloration

+discoloring

+discolorization

+discolorization's

+discolorizations

+discolorment

+discolorment's

+discolorments

+discretization

+discretize

+disdenominationalize

+disdenominationalizes

+disdiplomatize

+disdiplomatizes

+disemboweled

+disemboweling

+disenamor

+disenamor's

+disenamors

+disenthrall

+disenthralls

+disharmonize

+disharmonizes

+disheveler

+disheveling

+dishonorable

+dishonorable's

+dishonorableness

+dishonorables

+dishonorablies

+dishonorably

+dishumanize

+dishumanizes

+dishumor

+dishumored

+dishumors

+disillusionize

+disillusionizer

+disillusionizers

+disillusionizes

+disindividualize

+disindividualizes

+dismalize

+dismalizes

+disnaturalization

+disnaturalization's

+disnaturalizations

+disnaturalize

+disnaturalizes

+disorganize

+disorganizer

+disorganizers

+disorganizes

+disorganizing

+disozonize

+disozonizes

+dispapalize

+dispapalizes

+dispauperize

+dispauperizes

+dispersonalize

+dispersonalizes

+dispopularize

+dispopularizes

+disrealize

+disrealizes

+disscepter

+disscepter's

+disscepters

+disseize

+disseized

+disseizes

+disseizin

+disseizing

+disseizins

+disseizor

+disseizors

+dissensualize

+dissensualizes

+dissocialize

+dissympathize

+dissympathizes

+disutilize

+disutilizes

+divinization

+divinization's

+divinizations

+divinize

+divinized

+divinizes

+divinizing

+dizequalise

+dizequalise's

+dizequaliser

+dizequalisers

+dizequalises

+dizorganisation

+dizorganise

+dockization

+dockization's

+dockizations

+dockize

+dockizes

+doctorization

+doctorization's

+doctorizations

+doctorize

+doctorizes

+doctrinization

+doctrinization's

+doctrinizations

+doctrinize

+doctrinizes

+documentize

+documentizes

+dogmatization

+dogmatize

+dogmatizer

+dognaped

+dognaping

+dolomitization

+dolomitization's

+dolomitizations

+dolomitize

+dolomitizes

+dolor

+domesticize

+domesticizes

+doweled

+doweler

+draftboard

+draftily

+draftsmanship

+dragonize

+dragonizes

+dramatizable

+dramatizable's

+dramatizables

+driveled

+driveler

+drivelers

+driveling

+dualization

+dualization's

+dualizations

+dualize

+dualizes

+ductilize

+ductilizes

+easternize

+ebonization

+ebonize

+ebonized

+ebonizes

+ebonizing

+ecclesiasticize

+ecclesiasticizes

+echoize

+echoizes

+eclecticize

+eclecticizes

+economization

+economization's

+economizations

+ecstaticize

+ecstaticizes

+editorialization

+effectualize

+effectualizes

+effeminatize

+effeminatizes

+egoize

+egoizer

+egoizers

+egoizes

+egyptus

+elasticization

+elasticize

+elasticized

+elasticizer

+elasticizers

+elasticizes

+elasticizing

+electricalize

+electricalizes

+electricize

+electricizes

+electroanesthesia

+electroanesthesia's

+electroanesthesias

+electrocauterization

+electrocauterization's

+electrocauterizations

+electrodialyze

+electrodialyzer

+electrodialyzer's

+electrodialyzers

+electrodialyzes

+electrogalvanize

+electrogalvanizes

+electrohomeopathies

+electrohomeopathy

+electrohomeopathy's

+electrolyze

+electrolyzed

+electrolyzes

+electrolyzing

+electromagnetizable

+electrotonize

+electrotonizes

+elegize

+elegized

+elegizes

+elegizing

+elementalize

+elementalizes

+emblematicize

+emblematicizes

+emblematization

+emblematize

+emblematized

+emblematizes

+emblematizing

+emblemize

+emblemizes

+embolization

+emboweled

+emboweling

+emotionalization

+emotionalization's

+emotionalizations

+emotionalize

+emotionalized

+emotionalizes

+emotionalizing

+emotionize

+emotionizes

+empaneled

+empaneling

+empathize

+empathized

+empathizes

+empathizing

+emulsionize

+emulsionizes

+enamelist

+enamelists

+enamor

+enamor's

+enamored

+enamored's

+enamoredness

+enamoreds

+enamoring

+enamorment

+enamorment's

+enamorments

+enamors

+enarbor

+enarbor's

+enarbors

+encarnalization

+encarnalize

+encarnalized

+encarnalizes

+encarnalizing

+encolor

+encolor's

+encolored

+encoloring

+encolors

+energization

+energize

+energizer

+energizers

+energizing

+engram

+engram's

+engrams

+engrandize

+engrandizement

+engrandizement's

+engrandizements

+engrandizes

+enhypostatize

+enhypostatizes

+enolization

+enolization's

+enolizations

+enolize

+enolizes

+ensepulcher

+ensepulcher's

+ensepulchers

+ensorceled

+ensorcels

+enthrallment

+enthrallment's

+enthrallments

+enthronization

+enthronization's

+enthronizations

+enthronize

+enthronizes

+entomologize

+entomologized

+entomologizes

+entomologizing

+envapor

+envapor's

+envapors

+envenomization

+eonism

+eonism's

+eonisms

+epigrammatization

+epigrammatize

+epigrammatized

+epigrammatizer

+epigrammatizes

+epigrammatizing

+epitaphize

+epitaphizes

+epithetize

+epithetizes

+epitomization

+epitomization's

+epitomizations

+epoches

+equestrianize

+equestrianizes

+ergotized

+ergotizes

+eroticization

+eroticize

+eroticized

+eroticizes

+eroticizing

+esophagus

+essentialize

+essentializes

+esterization

+esterization's

+esterizations

+esterize

+esterizes

+esthesia

+esthesiometer

+esthesiometer's

+esthesiometers

+esthesis

+eternalization

+eternalization's

+eternalizations

+eternalize

+eternalized

+eternalizes

+eternalizing

+eternize

+eternized

+eternizes

+eternizing

+etherealization

+etherealization's

+etherealizations

+etherealize

+etherealized

+etherealizes

+etherealizing

+etherization

+etherization's

+etherizations

+etherize

+etherized

+etherizer

+etherizers

+etherizes

+etherizing

+ethicization

+ethicize

+ethicized

+ethicizes

+ethicizing

+ethnicize

+ethnicizes

+etiologies

+etiology

+etiology's

+etymologization

+etymologize

+etymologized

+etymologizes

+etymologizing

+euhemerize

+eulogization

+eulogization's

+eulogizations

+euphemize

+euphemized

+euphemizer

+euphemizes

+euphemizing

+euphonization

+euphonize

+euphonized

+euphonizes

+euphonizing

+evangelization

+evangelization's

+evangelizations

+evangelize

+evangelized

+evangelizer

+evangelizers

+evangelizes

+evangelizing

+eventualize

+eventualizes

+evolutionize

+evolutionizes

+excursionize

+excursionizes

+exhibitionize

+exhibitionizes

+existentialize

+existentializes

+experimentalize

+experimentalizes

+experimentize

+experimentizes

+extemporization

+extemporization's

+extemporizations

+exteriorization

+exteriorization's

+exteriorizations

+exteriorize

+exteriorized

+exteriorizes

+exteriorizing

+externalize

+externalized

+externalizes

+externalizing

+facsimilize

+facsimilizes

+factorize

+factorized

+factorizes

+factorizing

+fanaticize

+fanaticized

+fanaticizes

+fanaticizing

+faradization

+faradization's

+faradizations

+faradize

+faradized

+faradizer

+faradizers

+faradizes

+faradizing

+fascisticization

+fascisticization's

+fascisticizations

+fascisticize

+fascisticizes

+fascistization

+fascistization's

+fascistizations

+fascistize

+fascistized

+fascistizes

+fascistizing

+fashionize

+fashionizes

+fatalize

+fatalizes

+favorless

+favorlesses

+fecundize

+fecundizes

+federalization

+federalization's

+federalizations

+femalize

+femalizes

+feminization

+feminizations

+feminize

+feminized

+feminizes

+feminizing

+ferreled

+ferreling

+ferritization

+ferritization's

+ferritizations

+fertilizable

+fertilizable's

+fertilizables

+fertilizational

+fertilizational's

+fertilizationals

+fervorless

+fervorlesses

+fetalization

+fetalization's

+fetalizations

+fetishization

+fetishization's

+fetishizations

+fetishize

+fetishized

+fetishizes

+fetishizing

+feudalizable

+feudalizable's

+feudalizables

+feudalization

+feudalization's

+feudalizations

+feudalize

+feudalized

+feudalizes

+feudalizing

+fiberization

+fiberize

+fiberized

+fiberizer

+fiberizer's

+fiberizers

+fiberizes

+fiberizing

+fiberless

+fiberlesses

+fibrize

+fibrizer

+fibrizers

+fibrizes

+fictionalization

+fictionalize

+fictionalized

+fictionalizes

+fictionalizing

+fictionization

+fictionization's

+fictionizations

+fictionize

+fictionizes

+figurize

+figurizes

+filmize

+filmizes

+fiscalization

+fiscalization's

+fiscalizations

+fiscalize

+fiscalizes

+flamboyantize

+flamboyantizes

+flanneled

+flanneling

+flavorful

+flavorfully

+flavorless

+flavorlesses

+flavorsome

+flavory

+floralize

+floralizes

+fluidization

+fluidization's

+fluidizations

+fluidize

+fluidized

+fluidizer

+fluidizes

+fluidizing

+fluoridization

+fluoridization's

+fluoridizations

+fluoridize

+fluoridizes

+focalization

+focalization's

+focalizations

+focalize

+focalized

+focalizes

+focalizing

+foreignization

+foreignization's

+foreignizations

+foreignize

+foreignizes

+forejudgment

+forejudgment's

+forejudgments

+formalizable

+formularization

+formularizations

+formularize

+formularized

+formularizer

+formularizes

+formularizing

+formulization

+formulizations

+formulize

+formulized

+formulizes

+formulizing

+forumize

+forumizes

+fossiled

+fossilizable

+fossilizable's

+fossilizables

+fossilization

+fossilization's

+fossilizations

+fossilize

+fossilizes

+fossilizing

+fractionalization

+fractionalize

+fractionalized

+fractionalizes

+fractionalizing

+fractionization

+fractionization's

+fractionizations

+fractionize

+fractionizes

+fragmentize

+fragmentized

+fragmentizer

+fragmentizes

+fragmentizing

+fraternization

+fraternization's

+fraternizations

+frictionize

+frictionizes

+frivoled

+frivoler

+frivoling

+fuelizer

+fuelizer's

+fuelizers

+functionalize

+functionalizes

+functionize

+functionizes

+funeralize

+funeralizes

+funneler

+futilize

+futilizes

+futurize

+futurizes

+gallantize

+gallantizes

+galvanization

+galvanization's

+galvanizations

+galvanize

+galvanized

+galvanizer

+galvanizers

+galvanizes

+gamboled

+gamboling

+gardenize

+gardenizes

+gaveled

+gaveler

+gaveling

+gelatinizabilities

+gelatinizability

+gelatinizability's

+gelatinizable

+gelatinizable's

+gelatinizables

+gelatinization

+gelatinization's

+gelatinizations

+gelatinize

+gelatinized

+gelatinizer

+gelatinizers

+gelatinizes

+gelatinizing

+generalizability

+generalizational

+genialize

+genializes

+genteelize

+genteelizes

+gentilization

+gentilization's

+gentilizations

+gentilize

+gentilizes

+gentlemanize

+gentlemanizes

+geologize

+geologized

+geologizes

+geologizing

+geometricize

+geometricizes

+geometrize

+geometrized

+geometrizes

+geometrizing

+germanization

+germanization's

+germanizations

+germanize

+germanizer

+germanizers

+germanizes

+germanizing

+ghettoization

+ghettoization's

+ghettoizations

+ghettoize

+ghettoized

+ghettoizes

+ghettoizing

+giantize

+giantizes

+gimbaling

+glacialize

+glacializes

+glamorization

+glamorizations

+glamorless

+globalization

+globalizations

+globalize

+globalized

+globalizes

+globalizing

+glottalize

+glottalizes

+gluttonize

+gluttonizes

+glycerinize

+glycerinizes

+glycerolize

+glycerolizes

+glycogenize

+glycogenizes

+gnosticize

+gnosticizer

+gnosticizers

+gnosticizes

+goddize

+goddizes

+goiter

+goiters

+gonorrhea

+gonorrheal

+gorgonize

+gorgonized

+gorgonizes

+gorgonizing

+gormandize

+gormandized

+gormandizer

+gormandizes

+gormandizing

+gospelize

+gospelizes

+gourmandize

+gourmandized

+gourmandizes

+gourmandizing

+governmentalize

+governmentalized

+governmentalizes

+governmentalizing

+grammaticize

+grammaticizes

+grangerize

+grangerized

+grangerizer

+grangerizes

+grangerizing

+granitization

+granitization's

+granitizations

+granitize

+granitizes

+granulize

+granulizes

+graphitizable

+graphitization

+graphitization's

+graphitizations

+graphitize

+graphitizes

+grecize

+grecized

+grecizing

+grueled

+grueler

+gruelers

+gutturalization

+gutturalization's

+gutturalizations

+gutturalize

+gutturalized

+gutturalizes

+gutturalizing

+gynecocrat

+gynecocratic

+gynecologic

+gynecologics

+gynecologies

+gynecology

+gynecology's

+gyrostabilizer

+habitualize

+habitualizes

+hamletization

+hamletization's

+hamletizations

+hamletize

+hamletizes

+handseled

+handseling

+hanseled

+hanseling

+harborage

+harborages

+harborful

+harborless

+harborlesses

+harmonizable

+harmonizable's

+harmonizables

+hatcheled

+hatcheling

+hazardize

+hazardizes

+heathenization

+heathenize

+heathenized

+heathenizes

+heathenizing

+heavenize

+heavenizes

+hebraization

+hebraizations

+hebraize

+hebraized

+hebraizes

+hebraizing

+hectogram

+hectogram's

+hectograms

+hectoliter

+hectometer

+hectometer's

+hectometers

+heparinize

+hepatize

+hepatized

+hepatizes

+hepatizing

+heraldize

+heraldizes

+hereticize

+hereticizes

+heroinize

+heroinizes

+heroization

+heroization's

+heroizations

+heroize

+heroized

+heroizes

+heroizing

+hiccup

+hiccuped

+hiccuping

+hiccups

+hirseled

+hirseling

+historicize

+historicized

+historicizes

+historicizing

+homeopathic

+homeopathically

+homeopathies

+homeopathy

+homeopathy's

+homeostasis

+homeostatic

+homeotypic

+hominization

+hominized

+homologization

+homologize

+homologized

+homologizer

+homologizes

+homologizing

+honorabilities

+honorability

+honorability's

+honorableship

+honorableship's

+honorableships

+honorless

+honorlesses

+hoodlumize

+hoodlumizes

+hooliganize

+hooliganizes

+horizontalization

+horizontalization's

+horizontalizations

+horizontalize

+horizontalizes

+hormonize

+hormonizes

+horrorize

+horrorizes

+hostilize

+hostilizes

+hotelization

+hotelization's

+hotelizations

+hotelize

+hotelizes

+houseled

+houseling

+houselings

+hoveled

+hoveler

+hovelers

+hoveling

+hucksterize

+hucksterizes

+humanitarianize

+humanitarianizes

+humanization

+humanization's

+humanizations

+humoral

+humorize

+humorizes

+humorless

+humorlesses

+humorlessness

+humorsome

+hurricanize

+hurricanizes

+hyalinization

+hyalinization's

+hyalinizations

+hyalinize

+hyalinizes

+hybridizable

+hybridizable's

+hybridizables

+hybridization

+hybridization's

+hybridizations

+hybridize

+hybridized

+hybridizer

+hybridizers

+hybridizes

+hybridizing

+hydrocaryaceous

+hydrocaryaceouses

+hydrogenization

+hydrogenization's

+hydrogenizations

+hydrogenize

+hydrogenized

+hydrogenizes

+hydrogenizing

+hydrolyzable

+hydrolyzable's

+hydrolyzables

+hydrolyze

+hydrolyze's

+hydrolyzes

+hydroxylization

+hydroxylization's

+hydroxylizations

+hydroxylize

+hydroxylizes

+hygienization

+hygienization's

+hygienizations

+hygienize

+hygienizes

+hyperbolize

+hyperbolized

+hyperbolizes

+hyperbolizing

+hypercatharsises

+hypercivilization

+hypercivilization's

+hypercivilizations

+hypercivilized

+hypercivilized's

+hypercivilizeds

+hypercriticize

+hypercriticizes

+hyperemphasize

+hyperemphasizes

+hyperesthesia

+hyperesthetic

+hyperimmunization

+hyperimmunization's

+hyperimmunizations

+hyperimmunize

+hyperimmunizes

+hyperinsulinization

+hyperinsulinization's

+hyperinsulinizations

+hyperinsulinize

+hyperinsulinizes

+hyperoxygenize

+hyperoxygenizes

+hyperparasitize

+hyperparasitizes

+hyperrealize

+hyperrealizes

+hypersensitization

+hypersensitization's

+hypersensitizations

+hypersensitize

+hypersensitized

+hypersensitizes

+hypersensitizing

+hyperspiritualizing

+hyperspiritualizing's

+hyperspiritualizings

+hyperthyroidization

+hyperthyroidization's

+hyperthyroidizations

+hyperthyroidize

+hyperthyroidizes

+hypervitalization

+hypervitalization's

+hypervitalizations

+hypervitalize

+hypervitalizes

+hyphenization

+hyphenization's

+hyphenizations

+hyphenize

+hyphenizes

+hypnotizabilities

+hypnotizability

+hypnotizability's

+hypnotizable

+hypnotizable's

+hypnotizables

+hypnotization

+hypnotization's

+hypnotizations

+hypnotize

+hypnotizer

+hypnotizers

+hypnotizes

+hypnotizing

+hypocenter

+hyposensitization

+hyposensitize

+hypostatization

+hypostatization's

+hypostatizations

+hypostatize

+hypostatizes

+hysterectomize

+hysterectomized

+hysterectomizes

+hysterectomizing

+ichneumonized

+ichneumonized's

+ichneumonizeds

+idiotize

+idiotizes

+idolatrize

+idolatrized

+idolatrizes

+idolatrizing

+idolization

+idolization's

+idolizations

+illegalization

+illegalize

+illegalized

+illegalizes

+illegalizing

+illegitimatize

+illegitimatizes

+illutation

+illutation's

+illutations

+immaterialization

+immaterialize

+immaterialized

+immaterializes

+immaterializing

+immobilization

+immobilization's

+immobilizations

+immoralize

+immoralizes

+immortalizable

+immortalizable's

+immortalizables

+immortalization

+immortalization's

+immortalizations

+immortalize

+immortalizer

+immortalizers

+immortalizes

+immortalizing

+immunize

+immunized

+immunizes

+immunizing

+impactionize

+impactionizes

+impaneled

+impaneling

+imperialization

+imperialization's

+imperializations

+imperialize

+imperializes

+imperiling

+impersonalization

+impersonalization's

+impersonalizations

+impersonalize

+impersonalizes

+impersonalizing

+improvizatorize

+improvizatorizes

+individualization

+individualization's

+individualizations

+indraft

+industrialize

+industrializes

+inferiorize

+inferiorizes

+infernalize

+infernalizes

+infidelize

+infidelizes

+infinitize

+infinitizes

+informalize

+inhumanize

+initializable

+insolubilization

+insolubilize

+institutionize

+institutionizes

+instrumentalize

+instrumentalizes

+insularize

+insularizes

+insurrectionize

+insurrectionizes

+integralization

+integralization's

+integralizations

+integralize

+integralizes

+intellectualization

+intellectualization's

+intellectualizations

+intellectualize

+intellectualized

+intellectualizer

+intellectualizers

+intellectualizes

+intellectualizing

+intercivilization

+intercivilization's

+intercivilizations

+intercolonization

+intercolonization's

+intercolonizations

+intercrystallization

+intercrystallization's

+intercrystallizations

+intercrystallize

+intercrystallizes

+interhybridize

+interhybridizes

+interiorization

+interiorize

+interiorized

+interiorizes

+interiorizing

+interjectionalize

+interjectionalizes

+interjectionize

+interjectionizes

+interjudgment

+interjudgment's

+interjudgments

+internationalize

+internationalizes

+internationalizing

+interorganizational

+intraorganization

+intraorganization's

+intraorganizations

+iodization

+iodize

+iodized

+iodizer

+iodizers

+iodizes

+iodizing

+ionizable

+ionizable's

+ionizables

+ionization

+ionization's

+ionizations

+ironize

+ironizes

+irrationalize

+irrationalizes

+irregularize

+irregularizes

+isochronization

+isochronize

+isochronized

+isochronizes

+isochronizing

+isoimmunization

+isoimmunization's

+isoimmunizations

+isoimmunize

+isoimmunizes

+isomerization

+isomerization's

+isomerizations

+isomerize

+isomerized

+isomerizeparabolization

+isomerizes

+isomerizing

+italicization

+italicization's

+italicizations

+jargonization

+jargonization's

+jargonizations

+jargonize

+jargonized

+jargonizes

+jargonizing

+jasperize

+jasperizes

+jeopardization

+jeweleries

+jewelery

+journalization

+journalization's

+journalizations

+jovialize

+jovializes

+judgmental

+judicialize

+judicializes

+juvenilize

+juvenilizes

+kaolinization

+kaolinization's

+kaolinizations

+kaolinize

+kaolinizes

+kenneled

+kenneling

+keratinization

+keratinize

+keratinized

+keratinizes

+keratinizing

+kerneled

+kerneling

+ketonization

+ketonization's

+ketonizations

+ketonize

+ketonizes

+kiloliter

+kiloliter's

+kiloliters

+kinesthesia

+kyanize

+kyanized

+kyanizes

+kyanizing

+labelable

+labialization

+labialization's

+labializations

+labialize

+labialized

+labializes

+labializing

+labilization

+labilization's

+labilizations

+labilize

+labilizes

+laborabilities

+laborability

+laborability's

+laborable

+laborable's

+laborables

+laborhood

+laborhood's

+laborhoods

+laborism

+laborism's

+laborisms

+laborist

+laborist's

+laborists

+laborite

+laborite's

+laborites

+laborless

+laborlesses

+labour's

+lackluster

+laconize

+laconized

+laconizes

+laconizing

+lactonized

+laicization

+laicizations

+laicize

+laicized

+laicizes

+laicizing

+lapeled

+latentize

+latentizes

+lateralization

+lateralization's

+lateralizations

+lateralize

+lateralizes

+laterization

+laterization's

+laterizations

+laureling

+leatherize

+leatherizes

+legitimatize

+legitimatized

+legitimatizes

+legitimatizing

+legitimization

+legitimization's

+legitimizations

+lethalize

+lethalizes

+leukemia

+lexiconize

+lexiconizes

+libelant

+libelants

+libeled

+libelee

+libelees

+libeling

+lichenization

+lichenization's

+lichenizations

+lichenize

+lichenizes

+lignitize

+lignitizes

+linearization

+linearization's

+linearizations

+linenize

+linenizer

+linenizers

+linenizes

+lingualize

+lingualizes

+lionizable

+lionizable's

+lionizables

+lionization

+lionization's

+lionizations

+liquidization

+liquidize

+liquidized

+liquidizer

+liquidizers

+liquidizes

+liquidizing

+literalization

+literalization's

+literalizations

+literalize

+literalized

+literalizer

+literalizers

+literalizes

+lithographize

+lithographizes

+localizable

+localizable's

+localizables

+logicalization

+logicalization's

+logicalizations

+logicalize

+logicalizes

+logicize

+logicized

+logicizes

+logicizing

+logorrhea

+logorrhea's

+logorrheas

+louver

+louvered

+louvers

+loyalize

+loyalizes

+lumbarization

+lumbarization's

+lumbarizations

+lunatize

+lunatizes

+lusterless

+lusterware

+luteinization

+luteinize

+lyophilization

+lyophilize

+lyophilized

+lyophilizer

+lyricize

+lyricized

+lyricizes

+lyricizing

+lysogenization

+lysogenize

+macadamization

+macadamize

+macadamized

+macadamizes

+macadamizing

+macarize

+macarized

+macarizes

+macarizing

+machinization

+machinization's

+machinizations

+machinize

+machinizes

+magicalize

+magicalizes

+magnetizabilities

+magnetizability

+magnetizability's

+magnetizable

+magnetizable's

+magnetizables

+magnetize

+magnetizer

+magnetizers

+magnetizes

+magnetizing

+mahoganize

+mahoganized

+mahoganizes

+mahoganizing

+majorize

+majorizes

+malleablize

+malleablizes

+malodor

+mandarinize

+mandarinizes

+mannerize

+mannerizes

+marbleize

+marbleizes

+marginalization

+marginalize

+marginalized

+marginalizes

+marginalizing

+marsupialization

+marsupialization's

+marsupializations

+marsupialize

+marsupializes

+martialization

+martialization's

+martializations

+martialize

+martializes

+martyrization

+martyrization's

+martyrizations

+martyrize

+martyrized

+martyrizer

+martyrizers

+martyrizes

+martyrizing

+marveler

+masculinization

+masculinization's

+masculinizations

+masculinize

+masculinized

+masculinizes

+masculinizing

+materialization

+materialization's

+materializations

+maternalize

+maternalizes

+mathematicize

+mathematicizes

+mathematization

+matronize

+matronized

+matronizes

+matronizing

+maudlinize

+maudlinizes

+mazurka

+mazurka's

+mazurkas

+mechanicalization

+mechanicalization's

+mechanicalizations

+mechanicalize

+mechanicalizes

+mechanizable

+medalist

+medalists

+medalize

+medalizes

+medialization

+medialization's

+medializations

+medialize

+medializes

+mediatization

+mediatization's

+mediatizations

+mediatize

+mediatized

+mediatizes

+mediatizing

+medievalize

+medievalizes

+mediumization

+mediumization's

+mediumizations

+mediumize

+mediumizes

+melanization

+melanize

+melanized

+melanizes

+melanizing

+melodization

+melodize

+melodized

+melodizer

+melodizes

+melodizing

+melodramatization

+melodramatize

+melodramatized

+melodramatizes

+melodramatizing

+memorialization

+memorialization's

+memorializations

+memorialize

+memorializer

+memorializers

+memorializes

+memorializing

+memorizable

+memorizable's

+memorizables

+mentalization

+mentalization's

+mentalizations

+mentalize

+mentalizes

+mercerization

+mercerization's

+mercerizations

+mercerize

+mercerized

+mercerizer

+mercerizers

+mercerizes

+mercerizing

+mercurialization

+mercurialization's

+mercurializations

+mercurialize

+mercurializes

+mesmerizabilities

+mesmerizability

+mesmerizability's

+mesmerizable

+mesmerizable's

+mesmerizables

+mesmerization

+mesmerization's

+mesmerizations

+mesmerize

+mesmerizer

+mesmerizers

+mesmerizes

+mesmerizing

+metabolizable

+metabolizable's

+metabolizables

+metabolize

+metabolizes

+metabolizing

+metacenter

+metagram

+metagram's

+metagrams

+metalize

+metalized

+metalizes

+metalizing

+metallicize

+metallicizes

+metamerization

+metamerization's

+metamerizations

+metamerized

+metamerized's

+metamerizeds

+metaphonize

+metaphonizes

+metaphorize

+metaphorizes

+metaphysicize

+metaphysicizes

+metastasize

+metastasized

+metastasizes

+metastasizing

+meteorization

+meteorization's

+meteorizations

+meteorize

+meteorizes

+methodization

+methodization's

+methodizations

+methodize

+methodized

+methodizer

+methodizers

+methodizes

+methodizing

+metricize

+metricized

+metricizes

+metricizing

+metropolitanize

+metropolitanizes

+microgram

+microgram's

+micrograms

+microliter

+microliter's

+microliters

+micromillimeter

+micromillimeter's

+micromillimeters

+microminiaturization

+microminiaturize

+microminiaturized

+microminiaturizer

+microminiaturizers

+microminiaturizes

+microminiaturizing

+micronization

+micronization's

+micronizations

+micronize

+micronizes

+micropolarization

+micropolarization's

+micropolarizations

+microscopize

+microscopizes

+militarization

+militarizations

+militarize

+militarized

+militarizes

+militarizing

+millionize

+millionizes

+mineralizable

+mineralizable's

+mineralizables

+mineralization

+mineralization's

+mineralizations

+mineralize

+mineralizer

+mineralizers

+mineralizes

+mineralizing

+miraculize

+miraculized

+miraculizes

+miraculizing

+mirrorize

+mirrorizes

+misalphabetize

+misalphabetizes

+misanthropize

+misanthropized

+misanthropizes

+misanthropizing

+misauthorization

+misauthorization's

+misauthorizations

+misauthorize

+misauthorizes

+misbaptize

+misbaptizes

+miscanonize

+miscanonizes

+mischaracterization

+mischaracterization's

+mischaracterizations

+mischaracterize

+mischaracterizes

+miscolor

+miscolor's

+miscolored

+miscoloring

+miscolors

+misendeavor

+misendeavor's

+misendeavors

+mislabeled

+mislabeling

+mislabor

+mislabor's

+mislabored

+mislaboring

+mislabors

+misorganization

+misorganization's

+misorganizations

+misorganize

+misorganizes

+misrealize

+misrealizes

+misrecognize

+misrecognizes

+misrouting

+missionarize

+missionarizes

+missionization

+missionize

+missionized

+missionizer

+missionizers

+missionizes

+missionizing

+mizanthropise

+mizanthropises

+mobilizable

+mobilizable's

+mobilizables

+modalize

+modalizes

+modernizable

+modernizable's

+modernizables

+moisturization

+moisturize

+moisturized

+moisturizer

+moisturizers

+moisturizes

+moisturizing

+molarization

+molarizations

+monarchize

+monarchizer

+monarchizers

+monarchizes

+monasticize

+monasticizes

+mongrelization

+mongrelizations

+mongrelize

+mongrelized

+mongrelizer

+mongrelizes

+mongrelizing

+monochordize

+monochordizes

+monologize

+monologized

+monologizes

+monologizing

+monometalism

+monometalist

+monopolizable

+monopolizable's

+monopolizables

+monotonize

+monotonizes

+monumentalization

+monumentalization's

+monumentalizations

+monumentalize

+monumentalized

+monumentalizes

+monumentalizing

+moralization

+moralization's

+moralizations

+moralize

+moralized

+moralizer

+moralizers

+moralizes

+moralizing

+moralizinglies

+moralizingly

+morbidize

+morbidizes

+morphinization

+morphinization's

+morphinizations

+morphinize

+morphinizes

+morseled

+morseling

+morselization

+morselization's

+morselizations

+morselize

+morselizes

+mortalize

+mortalizes

+mortarize

+mortarizes

+motorization

+motorization's

+motorizations

+multifibered

+multifibered's

+multifibereds

+municipalization

+municipalization's

+municipalizations

+municipalize

+municipalized

+municipalizer

+municipalizers

+municipalizes

+municipalizing

+muscularize

+muscularizes

+museumize

+museumizes

+musicalization

+musicalization's

+musicalizations

+musicalize

+musicalizes

+mutualization

+mutualization's

+mutualizations

+mutualize

+mutualized

+mutualizes

+mutualizing

+myelinization

+myelinization's

+myelinizations

+mysticize

+mysticizes

+mythicization

+mythicize

+mythicized

+mythicizer

+mythicizers

+mythicizes

+mythicizing

+mythize

+mythizes

+mythologization

+mythologize

+mythologized

+mythologizer

+mythologizes

+mythologizing

+nakedize

+nakedizes

+nanogram

+nanograms

+nanometer

+nanometers

+narcotization

+narcotize

+narcotized

+narcotizing

+nasalize

+nasalizes

+nasalizing

+naturalize

+naturalizer

+naturalizers

+naturalizes

+naturalizing

+naturize

+naturizes

+nebularization

+nebularization's

+nebularizations

+nebularize

+nebularizes

+nebulization

+nebulizations

+nebulize

+nebulized

+nebulizer

+nebulizes

+nebulizing

+necrotize

+necrotized

+necrotizes

+necrotizing

+nectarize

+nectarizes

+neighborless

+neighborlesses

+neighborlike

+neighborlike's

+neighborlikes

+neighborship

+neighborship's

+neighborships

+neologization

+neologize

+neologized

+neologizes

+neologizing

+neuroticize

+neuroticizes

+newspaperized

+newspaperized's

+newspaperizeds

+nickelization

+nickelization's

+nickelizations

+nickelize

+nickelizes

+nicotinize

+nicotinizes

+nightingalize

+nightingalizes

+niter

+nitridization

+nitridization's

+nitridizations

+nitridize

+nitridizes

+nitrogenization

+nitrogenization's

+nitrogenizations

+nitrogenize

+nitrogenized

+nitrogenizes

+nitrogenizing

+nodulize

+nodulizes

+nomadization

+nomadization's

+nomadizations

+nomadize

+nomadized

+nomadizes

+nomadizing

+nominalize

+nominalizes

+nominalizing

+nonacknowledgment

+nonacknowledgment's

+nonacknowledgments

+nonanesthetized

+nonapostatizing

+nonapostatizing's

+nonapostatizings

+noncanonization

+noncanonization's

+noncanonizations

+noncartelized

+noncartelized's

+noncartelizeds

+noncatechizable

+noncatechizable's

+noncatechizables

+noncivilized

+noncivilized's

+noncivilizeds

+noncoloring

+noncoloring's

+noncolorings

+noncrystallizable

+noncrystallizable's

+noncrystallizables

+noncrystallized

+noncrystallized's

+noncrystallizeds

+noncrystallizing

+noncrystallizing's

+noncrystallizings

+nondemobilization

+nondemobilization's

+nondemobilizations

+nondialyzing

+nondialyzing's

+nondialyzings

+nondimensionalize

+nondimensionalized

+nonfavorite

+nonfavorite's

+nonfavorites

+nonfulfillment

+nonfulfillment's

+nonfulfillments

+nongalvanized

+nongalvanized's

+nongalvanizeds

+nongelatinizing

+nongelatinizing's

+nongelatinizings

+nonhydrolyzable

+nonhydrolyzable's

+nonhydrolyzables

+nonimmunized

+nonimmunized's

+nonimmunizeds

+nonionized

+nonionized's

+nonionizeds

+nonionizing

+nonionizing's

+nonionizings

+nonlocalized

+nonlocalized's

+nonlocalizeds

+nonmagnetizable

+nonmagnetizable's

+nonmagnetizables

+nonnitrogenized

+nonnitrogenized's

+nonnitrogenizeds

+nonorganization

+nonorganization's

+nonorganizations

+nonoxidizable

+nonoxidizable's

+nonoxidizables

+nonoxidizing

+nonoxidizing's

+nonoxidizings

+nonparlor

+nonparlor's

+nonparlors

+nonpenalized

+nonpenalized's

+nonpenalizeds

+nonphosphorized

+nonphosphorized's

+nonphosphorizeds

+nonpolarizable

+nonpolarizable's

+nonpolarizables

+nonpolarized

+nonpolarizing

+nonpolarizing's

+nonpolarizings

+nonrationalized

+nonrationalized's

+nonrationalizeds

+nonrealization

+nonrealization's

+nonrealizations

+nonrecognized

+nonrecognized's

+nonrecognizeds

+nonschematized

+nonschematized's

+nonschematizeds

+nonsensitized

+nonsensitized's

+nonsensitizeds

+nonspecialized

+nonspecialized's

+nonspecializeds

+nonstandardized

+nonstandardized's

+nonstandardizeds

+nonstylized

+nonstylized's

+nonstylizeds

+nonsympathizer

+nonsympathizer's

+nonsympathizers

+nonsynthesized

+nonsynthesized's

+nonsynthesizeds

+nontemporizing

+nontemporizing's

+nontemporizings

+nonutilized

+nonutilized's

+nonutilizeds

+nonvisualized

+nonvisualized's

+nonvisualizeds

+nonvolatilized

+nonvolatilized's

+nonvolatilizeds

+nonvulcanizable

+nonvulcanizable's

+nonvulcanizables

+normalizable

+northernize

+northernizes

+nosize

+notarization

+notarizations

+nothingize

+nothingizes

+nounize

+nounizes

+novelization

+novelization's

+novelizations

+novelize

+novelizer

+novelizers

+novelizes

+novelizing

+nuptialize

+nuptializes

+obelize

+obelized

+obelizes

+obelizing

+objectivize

+objectivizes

+objectization

+objectization's

+objectizations

+objectize

+objectizes

+oblivionize

+oblivionizes

+ocherous

+odorful

+odorize

+odorized

+odorizer

+odorizes

+odorizing

+odorless

+odorlesses

+offenseless

+offenselesses

+offenselessly

+officialization

+officialization's

+officializations

+officialize

+officializes

+onionized

+onionized's

+onionizeds

+opaled

+opalize

+opalizes

+operatize

+operatizes

+optionalize

+optionalizes

+oralization

+oralization's

+oralizations

+oralize

+oralizes

+orangize

+orangizes

+oratorize

+oratorizes

+organizabilities

+organizability

+organizability's

+organizationist

+organizationist's

+organizationists

+orientalization

+orientalization's

+orientalizations

+orientalize

+orientalized

+orientalizes

+orientalizing

+orientization

+orientization's

+orientizations

+orientize

+orientizes

+ornamentalize

+ornamentalizes

+orphanize

+orphanizes

+orthocenter

+orthogonalize

+orthogonalizes

+orthogonalizing

+orthopedically

+orthopedist

+ostracizable

+ostracizable's

+ostracizables

+ostracization

+ostracization's

+ostracizations

+ostracize

+ostracizer

+ostracizers

+ostracizes

+ostracizing

+outcaviled

+outcaviling

+outclamor

+outclamor's

+outclamors

+outhumor

+outhumor's

+outhumored

+outhumoring

+outhumors

+outhyperbolize

+outhyperbolizes

+outlabor

+outlabor's

+outlabors

+outrivaled

+outrivaling

+outsavor

+outsavor's

+outsavoring

+outsavors

+outsplendor

+outsplendor's

+outsplendors

+outtyrannize

+outtyrannizes

+ovalization

+ovalization's

+ovalizations

+ovalize

+ovalizes

+ovariectomized

+overagonize

+overagonizes

+overbrutalize

+overbrutalizes

+overcapitalization

+overcapitalization's

+overcapitalizations

+overcapitalize

+overcapitalized

+overcapitalizes

+overcapitalizing

+overcentralization

+overcentralization's

+overcentralizations

+overcentralize

+overcentralizes

+overcivilization

+overcivilization's

+overcivilizations

+overcivilize

+overcivilizes

+overclamor

+overclamor's

+overclamors

+overcolor

+overcolor's

+overcolors

+overcriticize

+overcriticizes

+overdoctrinize

+overdoctrinizes

+overemotionalize

+overemotionalizes

+overfavor

+overfavor's

+overfavorable

+overfavorable's

+overfavorables

+overfavorablies

+overfavorably

+overfavors

+overfertilization

+overgeneralize

+overgeneralizes

+overhonor

+overhonor's

+overhonors

+overhumanize

+overhumanizes

+overindustrialization

+overindustrialization's

+overindustrializations

+overindustrialize

+overindustrializes

+overjudgment

+overjudgment's

+overjudgments

+overlabor

+overlabor's

+overlabors

+overnationalization

+overnationalization's

+overnationalizations

+overrapturize

+overrapturizes

+overrationalize

+overrationalizes

+oversentimentalize

+oversentimentalizes

+overspecialization

+overspecialization's

+overspecializations

+overspecialize

+overspecialized

+overspecializes

+oversystematize

+oversystematizes

+overunionized

+overunionized's

+overunionizeds

+overurbanization

+overurbanization's

+overurbanizations

+overwomanize

+overwomanizes

+oxidizabilities

+oxidizability

+oxidizability's

+oxidizable

+oxidizable's

+oxidizables

+oxidization

+oxidization's

+oxidizations

+oxidizement

+oxidizement's

+oxidizements

+oxygenizable

+oxygenizable's

+oxygenizables

+oxygenize

+oxygenizement

+oxygenizement's

+oxygenizements

+oxygenizer

+oxygenizers

+oxygenizes

+ozonization

+ozonization's

+ozonizations

+ozonize

+ozonized

+ozonizer

+ozonizers

+ozonizes

+ozonizing

+packetization

+packetize

+packetized

+packetizer

+packetizer's

+packetizers

+packetizes

+packetizing

+paeanize

+paeanizes

+paganization

+paganization's

+paganizations

+paganize

+paganized

+paganizer

+paganizers

+paganizes

+paganizing

+palatization

+palatization's

+palatizations

+palatize

+palatizes

+palladiumize

+palladiumizes

+palletization

+palletizations

+palletize

+palletizer

+palletizes

+palletizing

+pamperize

+pamperizes

+pamphletize

+pamphletizes

+panderize

+panderizes

+pantheonization

+pantheonization's

+pantheonizations

+pantheonize

+pantheonizes

+papalization

+papalization's

+papalizations

+papalize

+papalizer

+papalizers

+papalizes

+parabolize

+parabolized

+parabolizes

+parabolizing

+paraffinize

+paraffinizes

+paragraphize

+paragraphizes

+paralyzation

+parasitization

+parasitize

+parasitized

+parasitizes

+parasitizing

+parathyroidectomize

+parathyroidectomized

+parathyroidectomizes

+parathyroidectomizing

+parceler

+parchmentize

+parchmentizes

+parenthesization

+parfocalization

+parfocalize

+parochialization

+parochialization's

+parochializations

+parochialize

+parochializes

+parrotize

+parrotizes

+parsonize

+parsonizes

+partialize

+partializes

+particularization

+particularization's

+particularizations

+particularize

+particularized

+particularizes

+particularizing

+partisanize

+partisanizes

+pasteurize

+pasteurized

+pasteurizer

+pasteurizes

+pasteurizing

+pastoralize

+pastoralizes

+pastorize

+pastorizes

+paternalize

+paternalizes

+patronizable

+patronizable's

+patronizables

+patronization

+patronization's

+patronizations

+patternize

+patternizes

+pauperization

+pauperization's

+pauperizations

+pauperize

+pauperized

+pauperizer

+pauperizers

+pauperizes

+pauperizing

+pavior

+pearlization

+pearlize

+pearlized

+pearlizes

+pearlizing

+peasantize

+peasantizes

+pectization

+pectize

+pectized

+pectizes

+pectizing

+peculiarize

+peculiarizes

+pedaler

+pedalers

+pedantize

+pedantizes

+pedestaled

+pedestaling

+pedestrianization

+pedestrianize

+pedestrianized

+pedestrianizes

+pedestrianizing

+pelletization

+pelletizations

+pelletize

+pelletized

+pelletizer

+pelletizes

+pelletizing

+pemmicanization

+pemmicanization's

+pemmicanizations

+pemmicanize

+pemmicanizes

+penalizable

+penalizable's

+penalizables

+penalization

+penalization's

+penalizations

+penciler

+pencilers

+peptizable

+peptizable's

+peptizables

+peptization

+peptization's

+peptizations

+peptize

+peptized

+peptizer

+peptizers

+peptizes

+peptonization

+peptonize

+peptonized

+peptonizes

+peptonizing

+percussionize

+percussionizes

+perennialize

+perennializes

+perfectivize

+perfectivizes

+periled

+periling

+periodicalize

+periodicalizes

+periodization

+periodizations

+periodize

+periodized

+periodizes

+periodizing

+peroxidize

+peroxidizement

+peroxidizement's

+peroxidizements

+peroxidizes

+personization

+personization's

+personizations

+personize

+personizes

+petrolization

+petrolization's

+petrolizations

+petrolize

+petrolizes

+phagocytize

+phagocytizes

+phantomize

+phantomizer

+phantomizers

+phantomizes

+phenolization

+phenolization's

+phenolizations

+phenolize

+phenolizes

+phenomenalization

+phenomenalization's

+phenomenalizations

+phenomenalize

+phenomenalizes

+philanthropize

+philanthropizes

+philosophization

+philosophization's

+philosophizations

+phlebotomization

+phlebotomize

+phlebotomized

+phlebotomizes

+phlebotomizing

+phoneticization

+phoneticization's

+phoneticizations

+phoneticize

+phoneticizes

+phosphatization

+phosphatization's

+phosphatizations

+phosphatize

+phosphatized

+phosphatizes

+phosphatizing

+phosphorize

+phosphorizes

+photocatalyzer

+photocatalyzer's

+photocatalyzers

+photographize

+photographizes

+photoionization

+photoionization's

+photoionizations

+photoisomerization

+photoisomerization's

+photoisomerizations

+photolabeled

+photolabeler

+photolabeling

+photolyzable

+photolyze

+photolyzed

+photolyzes

+photolyzing

+photopolymerization

+photopolymerization's

+photopolymerizations

+photosensitization

+photosensitization's

+photosensitizations

+photosensitize

+photosensitized

+photosensitizer

+photosensitizers

+photosensitizes

+photosensitizing

+photosynthesize

+photosynthesized

+photosynthesizes

+photosynthesizing

+piaster

+picogram

+picogram's

+picograms

+picometer

+picometer's

+picometers

+pictorialization

+pictorialization's

+pictorializations

+pictorialize

+pictorialized

+pictorializes

+pictorializing

+picturization

+picturization's

+picturizations

+picturize

+picturized

+picturizes

+picturizing

+pidginization

+pidginize

+pidginized

+pidginizes

+pidginizing

+pigmentize

+pigmentizes

+pilgrimize

+pilgrimizes

+pillarize

+pillarizes

+piratize

+piratizes

+pistoled

+pistoling

+plagiarization

+plagiarization's

+plagiarizations

+plagiarize

+plagiarized

+plagiarizer

+plagiarizers

+plagiarizes

+plagiarizing

+plasmolyze

+plasticization

+plasticization's

+plasticizations

+plasticize

+plasticized

+plasticizer

+plasticizers

+plasticizes

+plasticizing

+platinization

+platinization's

+platinizations

+platitudinization

+platitudinize

+platitudinized

+platitudinizes

+platitudinizing

+platonization

+platonize

+platonized

+platonizes

+platonizing

+plebeianize

+plebeianizes

+plowable

+plowboy

+plowhead

+poeticization

+poeticize

+poeticized

+poeticizes

+poeticizing

+poetization

+poetization's

+poetizations

+poetize

+poetized

+poetizer

+poetizers

+poetizes

+poetizing

+pogromize

+pogromizes

+polarizabilities

+polarizability

+polarizability's

+polarizable

+polarizable's

+polarizables

+polemicize

+polemicized

+polemicizes

+polemicizing

+polemize

+polemized

+polemizes

+polemizing

+policize

+policizer

+policizers

+policizes

+politicalize

+politicalizes

+politicization

+politicize

+politicizer

+politicizers

+politicizes

+politicizing

+politize

+politizes

+pollenizer

+pollinize

+pollinized

+pollinizer

+pollinizes

+pollinizing

+polychromatize

+polychromatizes

+polychromize

+polychromizes

+polygamize

+polygamizes

+polymerization

+polymerization's

+polymerize

+polymerizes

+polysulphurization

+polysulphurization's

+polysulphurizations

+pommeled

+pommeling

+porcelainization

+porcelainization's

+porcelainizations

+porcelainize

+porcelainizes

+portionize

+portionizes

+positivize

+positivizes

+posterize

+posterizes

+postsynchronization

+posturize

+posturizes

+potentialization

+potentialization's

+potentializations

+potentialize

+potentializes

+potentize

+potentizes

+powderization

+powderization's

+powderizations

+powderize

+powderizer

+powderizers

+powderizes

+practicalization

+practicalization's

+practicalizations

+practicalize

+practicalizer

+practicalizers

+practicalizes

+preacherize

+preacherizes

+preacknowledgment

+preacknowledgment's

+preacknowledgments

+preanesthetic

+preanesthetics

+prebaptize

+prebaptizes

+precancelation

+precisionize

+precisionizes

+precivilization

+precivilization's

+precivilizations

+precolor

+precolor's

+precolorable

+precolorable's

+precolorables

+precoloring

+precolorings

+precolors

+preconization

+preconization's

+preconizations

+preconize

+preconizer

+preconizers

+preconizes

+precriticize

+precriticizes

+prefavor

+prefavor's

+prefavorable

+prefavorable's

+prefavorables

+prefavorablies

+prefavorably

+prefavorite

+prefavorite's

+prefavorites

+prefavors

+prefertilization

+prefertilization's

+prefertilizations

+prefertilize

+prefertilizes

+preflavor

+preflavor's

+preflavoring

+preflavorings

+preflavors

+pregalvanize

+pregalvanizes

+prehumor

+prehumor's

+prehumors

+prejudgment

+prejudgment's

+prejudgments

+prelabor

+prelabor's

+prelabors

+prelatize

+prelatizes

+prelocalization

+prelocalization's

+prelocalizations

+preludize

+preludizes

+premonopolize

+premonopolizes

+preoffense

+preoffense's

+preoffenses

+preorganization

+preorganization's

+preorganizations

+preorganize

+preorganizes

+preoxidize

+preoxidized

+preoxidizes

+preoxidizing

+preprogram

+prerecognize

+prerecognizes

+prespecialize

+prespecializes

+presplendor

+presplendor's

+presplendors

+pressurization

+prestandardization

+prestandardization's

+prestandardizations

+prestandardize

+prestandardizes

+presympathize

+presympathizes

+preutilizable

+preutilizable's

+preutilizables

+preutilization

+preutilization's

+preutilizations

+preutilize

+preutilizes

+prioritization

+priorization

+priorizations

+priorize

+priorized

+priorizes

+priorizing

+privatization

+privatize

+privatized

+privatizing

+problemize

+problemizes

+processionize

+processionizes

+proctorization

+proctorization's

+proctorizations

+proctorize

+proctorizes

+prodigalize

+prodigalizes

+profanize

+profanizes

+professionalization

+professionalization's

+professionalizations

+professionalize

+professionalized

+professionalizes

+professionalizing

+professionize

+professionizes

+programist

+programist's

+programistic

+programistics

+programists

+proletarianize

+proletarianizes

+proletarianizing

+prologize

+prologuize

+prologuizer

+prologuizers

+prologuizes

+prolusionize

+prolusionizes

+propagandize

+propagandized

+propagandizes

+propagandizing

+prophetize

+prophetizes

+propositionize

+propositionizes

+propretor

+proselytization

+proselytization's

+proselytizations

+protectionize

+protectionizes

+protocoled

+protocoling

+protocolization

+protocolization's

+protocolizations

+protocolize

+protocolizes

+proverbialize

+proverbializes

+proverbize

+proverbizes

+provincialization

+provincialization's

+provincializations

+provincialize

+provincializes

+pseudoanemia

+pseudoanemia's

+pseudoanemias

+pseudoanemic

+pseudoanemics

+pseudoedema

+pseudoedema's

+pseudoedemas

+pseudographize

+pseudographizes

+psychoanalyze

+psychoanalyzer

+psychoanalyzer's

+psychoanalyzers

+psychoanalyzes

+psychologization

+psychologize

+psychologized

+psychologizes

+psychologizing

+psycoanalyze

+puebloization

+puebloization's

+puebloizations

+puebloize

+puebloizes

+pulpitize

+pulpitizes

+pulverizable

+pulverizable's

+pulverizables

+pulverization

+pulverization's

+pulverizations

+pummeler

+pummeling

+pupilize

+pupilizes

+puppetize

+puppetizes

+pyorrheal

+pyramidize

+pyramidizes

+pyridinize

+pyridinizes

+pyritization

+pyritization's

+pyritizations

+pyritize

+pyritizes

+pyrolyzable

+pyrolyzate

+pythonize

+pythonizes

+quarrelous

+quarterization

+quarterization's

+quarterizations

+quininize

+quininizes

+racemization

+racemize

+racemized

+racemizes

+racemizing

+racialization

+racialization's

+racializations

+racialize

+racializes

+radialization

+radialization's

+radializations

+radialize

+radializes

+radicalization

+radicalization's

+radicalizations

+radicalize

+radicalized

+radicalizes

+radicalizing

+radiosterilize

+radiosterilizes

+radiosterilizing

+radiumization

+radiumization's

+radiumizations

+radiumize

+radiumizes

+rapturize

+rapturizes

+rascalize

+rascalizes

+rationalizable

+rationalizable's

+rationalizables

+raveled

+raveler

+ravelers

+raveling

+ravelings

+reacclimatize

+reactualize

+realisticize

+realisticizes

+reanimalize

+reanimalizes

+reapologize

+reauthorize

+rebaptization

+rebaptization's

+rebaptizations

+rebourbonize

+rebourbonizes

+rebrutalize

+recanalization

+recapitalize

+recarbonize

+recausticize

+recausticizes

+recentralize

+reciprocalize

+reciprocalizes

+recivilize

+recolonize

+recolor

+recolor's

+recoloring

+reconnoiter

+reconnoitered

+reconnoiterer

+reconnoiterer's

+reconnoiterers

+reconnoitering

+reconnoiters

+recriticize

+redialer

+redialing

+refavor

+refavor's

+refertilize

+reflectorize

+reflectorized

+reflectorizes

+reflectorizing

+reforestization

+reforestization's

+reforestize

+reforestizes

+regalize

+regalizes

+regalvanization

+regalvanization's

+regalvanizations

+regalvanize

+regalvanizes

+regionalization

+regionalization's

+regionalizations

+regionalize

+regionalized

+regionalizes

+regionalizing

+regularization

+regularization's

+regularizations

+regularize

+regularized

+regularizer

+regularizers

+regularizes

+reharmonize

+rehonor

+rehonor's

+rehumanization

+rehumanize

+rehybridize

+rehybridizes

+reinitialization

+reitemize

+relativization

+relativization's

+relativizations

+relativize

+relativized

+relativizes

+relativizing

+religionize

+religionizes

+remagnetize

+remagnetizes

+rematerialize

+rememorize

+remilitarization

+remilitarize

+remineralization

+remineralization's

+remineralizations

+remineralize

+remineralizes

+remobilize

+rencounter

+renormalization

+renormalize

+renormalizing

+reobjectivization

+reobjectivization's

+reobjectivizations

+reobjectivize

+reobjectivizes

+reorganizational

+reorganizationist

+reorganizationist's

+reorganizationists

+reoxidize

+reoxygenize

+reoxygenizes

+repaganization

+repaganization's

+repaganizations

+repaganize

+repaganizer

+repaganizers

+repaganizes

+repatronize

+repersonalize

+rephosphorization

+rephosphorization's

+rephosphorizations

+rephosphorize

+rephosphorizes

+repolymerization

+repolymerization's

+repolymerizations

+repolymerize

+repolymerizes

+reprivatization

+reprivatization's

+reprivatizations

+reprivatize

+reprivatizes

+republicanization

+republicanization's

+republicanizations

+republicanize

+republicanized

+republicanizer

+republicanizers

+republicanizes

+republicanizing

+repulverize

+reroyalize

+reroyalizes

+resensitization

+resensitization's

+resensitizations

+resensitize

+resensitizes

+resepulcher

+resinize

+resinizes

+resolemnize

+resolemnizes

+restandardize

+resterilize

+restigmatize

+restigmatizes

+resurrectionize

+resurrectionizes

+resymbolize

+resynchronization

+resynchronize

+resynchronizing

+resynthesize

+retinize

+retinizes

+retranquilize

+reutilize

+revalorization

+revalorization's

+revalorizations

+revalorize

+revalorized

+revalorizes

+revalorizing

+revaporize

+revaporizes

+revelationize

+revelationizes

+revisualize

+revitalization's

+revitalizations

+revivalize

+revivalizes

+revolatilize

+revolatilizes

+revolutionizement

+revolutionizement's

+revolutionizements

+rhapsodize

+rhapsodized

+rhapsodizes

+rhapsodizing

+rhythmicize

+rhythmicizes

+rhythmizable

+rhythmizable's

+rhythmizables

+rhythmization

+rhythmization's

+rhythmizations

+rhythmize

+rhythmizes

+ridiculize

+ridiculizes

+ritualization

+ritualize

+ritualizes

+ritualizing

+rivaless

+rivalesses

+rivalize

+rivalizes

+robotization

+robotization's

+robotizations

+robotize

+robotizes

+roentgenize

+romanticization

+routinization

+routinization's

+routinizations

+routinize

+routinizes

+roweled

+roweling

+royalization

+royalization's

+royalizations

+royalize

+royalizes

+rubberization

+rubberize

+rubberizes

+rubberizing

+rubricize

+rubricizes

+ruffianize

+ruffianizes

+ruggedization

+ruggedize

+ruggedized

+ruggedizes

+ruggedizing

+rumormonger

+rumormonger's

+rumormongers

+ruralization

+ruralization's

+ruralizations

+ruralize

+ruralized

+ruralizes

+ruralizing

+russianization

+russianize

+rusticize

+rusticizes

+saberlike

+saberlike's

+saberlikes

+sabertooth

+sacralization

+sacralization's

+sacralizations

+sacramentize

+sacramentizes

+sailorizing

+sailorizing's

+sailorizings

+salinization

+salinize

+salinizes

+saltpeter

+saltpeter's

+saltpeters

+sandaled

+sandaling

+sanitization

+sapientize

+sapientizes

+satanize

+satanizes

+satinize

+satinizes

+satirizable

+satirizable's

+satirizables

+satirize

+satirized

+satirizer

+satirizers

+satirizing

+savagize

+savagizes

+saviorhood

+saviorhood's

+saviorhoods

+saviorship

+saviorship's

+saviorships

+savorilies

+savorily

+savorless

+savorlesses

+savorous

+scandaled

+scandaling

+scandalization

+scandalization's

+scandalizations

+scandalize

+scandalizer

+scandalizers

+scandalizes

+scenarioization

+scenarioization's

+scenarioizations

+scenarioize

+scenarioizes

+scenarization

+scenarization's

+scenarizations

+scenarize

+scenarizes

+scepterless

+scepterlesses

+schedulize

+schedulizes

+schematization

+schematization's

+schematizations

+schematize

+schematized

+schematizer

+schematizers

+schematizes

+schematizing

+schismatize

+schismatized

+schismatizes

+schismatizing

+sclerotization

+sclerotized

+scripturalize

+scripturalizes

+scrutinization

+scrutinization's

+scrutinizations

+seborrhea

+seborrheic

+sectarianization

+sectarianize

+sectarianized

+sectarianizes

+sectarianizing

+sectionalization

+sectionalization's

+sectionalizations

+sectionalize

+sectionalizes

+sectionalizing

+sectionize

+sectionizes

+secularize

+secularizer

+secularizers

+secularizes

+secularizing

+semicarbonize

+semicarbonizes

+semicivilization

+semicivilization's

+semicivilizations

+semicivilized

+semicivilized's

+semicivilizeds

+semifossilized

+semifossilized's

+semifossilizeds

+semihonor

+semihonor's

+semihonors

+semihumanized

+semihumanized's

+semihumanizeds

+semimercerized

+semimercerized's

+semimercerizeds

+semimineralized

+semimineralized's

+semimineralizeds

+seminarize

+seminarizes

+seminationalization

+seminationalization's

+seminationalizations

+semiorganized

+semiorganized's

+semiorganizeds

+semioxidized

+semioxidized's

+semioxidizeds

+semioxygenized

+semioxygenized's

+semioxygenizeds

+semiprofessionalized

+semiprofessionalized's

+semiprofessionalizeds

+semivulcanized

+semivulcanized's

+semivulcanizeds

+senilize

+senilizes

+sensationalize

+sensationalized

+sensationalizes

+sensationalizing

+sensitization

+sensitization's

+sensitizations

+sensitize

+sensitizer

+sensitizers

+sensitizes

+sensitizing

+sensize

+sensizes

+sensualization

+sensualization's

+sensualizations

+sensualize

+sensualized

+sensualizes

+sensualizing

+sentimentalization

+sentimentalization's

+sentimentalizations

+sentineled

+sentineling

+sepaled

+septicization

+septicization's

+septicizations

+sepulchralize

+sepulchralizes

+serenize

+serenizes

+serializability

+serializable

+sermonize

+sermonized

+sermonizer

+sermonizers

+sermonizes

+sermonizing

+serpentinization

+serpentinization's

+serpentinizations

+serpentinize

+serpentinizes

+serpentize

+serpentizes

+servilize

+servilizes

+severalize

+severalizes

+severization

+severization's

+severizations

+severize

+severizes

+sexualization

+sexualization's

+sexualizations

+sexualize

+sexualizes

+shepherdize

+shepherdizes

+siderealize

+siderealizes

+signalization

+signalize

+signalized

+signalizing

+signatories

+silicatization

+silicatization's

+silicatizations

+silicidize

+silicidizes

+siliconize

+siliconizes

+silverize

+silverizer

+silverizers

+silverizes

+similarize

+similarizes

+similize

+similizes

+simonize

+singularization

+singularization's

+singularizations

+singularize

+singularizes

+sinicize

+sinicized

+sinicizes

+sinicizing

+siphonless

+siphonlesses

+siphonlike

+siphonlike's

+siphonlikes

+siphonophore

+siphonostele

+siphonostelic

+siphonostely

+sirenize

+sirenizes

+sisterize

+sisterizes

+skeletonization

+skeletonization's

+skeletonizations

+skeletonize

+skeletonized

+skeletonizer

+skeletonizers

+skeletonizes

+skeletonizing

+skepticize

+skepticizes

+slenderize

+slenderized

+slenderizes

+slenderizing

+sloganize

+sloganizes

+snobsniveling

+soberize

+soberized

+soberizes

+soberizing

+sockdologizing

+solarization

+solarization's

+solarizations

+solarize

+solarized

+solarizes

+solarizing

+soldierize

+soldierizes

+solecize

+solecized

+solecizes

+solecizing

+solemnization

+solemnization's

+solemnizations

+solemnize

+solemnized

+solemnizer

+solemnizers

+solemnizes

+solemnizing

+soliloquization

+soliloquize

+soliloquized

+soliloquizer

+soliloquizers

+soliloquizes

+soliloquizing

+soliloquizing's

+soliloquizingly

+soliloquizings

+solmization

+solubilization

+solubilize

+solubilized

+solubilizes

+solubilizing

+solutize

+solutizer

+solutizers

+solutizes

+sonantized

+sonantized's

+sonantizeds

+sonnetize

+sonnetizes

+southernize

+southernizes

+sovietization

+sovietization's

+sovietizations

+sovietize

+sovietizes

+spatialization

+spatialization's

+spatializations

+spatialize

+spatializes

+specificize

+specificizes

+specimenize

+specimenizes

+specterlike

+specterlike's

+specterlikes

+spheroidize

+spheroidizes

+spiralization

+spiralization's

+spiralizations

+spiralize

+spiralizes

+spiritize

+spiritizes

+spiritualization

+spiritualization's

+spiritualizations

+spiritualize

+spiritualized

+spiritualizer

+spiritualizers

+spiritualizes

+spiritualizing

+spirochetal

+spirochete

+spirochete's

+spirochetes

+spirochetosis

+splenectomized

+stabilizable

+stallionize

+stallionizes

+stalwartize

+stalwartizes

+standardizable

+standardizable's

+standardizables

+stapedectomized

+statisticize

+statisticizes

+stencilize

+sterilizabilities

+sterilizability

+sterilizability's

+sterilizable

+sterilizable's

+sterilizables

+stigmatize

+stigmatizer

+stigmatizers

+stigmatizes

+stigmatizing

+strobilization

+structuralization

+structuralization's

+structuralizations

+structuralize

+structuralizes

+strychninization

+strychninization's

+strychninizations

+strychninize

+strychninizes

+stylize

+stylizer

+stylizers

+stylizes

+stylizing

+subarmor

+subarmor's

+subarmors

+subcenter

+suberization

+suberization's

+suberizations

+suberize

+suberized

+suberizes

+suberizing

+subflavor

+subflavor's

+subflavors

+subjectivization

+subjectivize

+subjectivizes

+sublimize

+sublimizes

+subminiaturization

+subminiaturize

+subminiaturized

+subminiaturizes

+subminiaturizing

+subpulverizer

+subpulverizer's

+subpulverizers

+subsidizable

+subsidizable's

+subsidizables

+subspecialize

+subspecializes

+subspecialties

+subspecialty

+subspecialty's

+substandardize

+substandardizes

+substantialize

+substantializes

+substantivize

+substantivizes

+subterraneanize

+subterraneanizes

+subtilization

+subtilization's

+subtilizations

+subtilize

+subtilizer

+subtilizers

+subtilizes

+subtotaled

+subtotaling

+suburbanize

+suburbanizes

+subvitalized

+subvitalized's

+subvitalizeds

+succorable

+succorable's

+succorables

+succorless

+succorlesses

+suggestionize

+suggestionizes

+sulfatize

+sulfatizes

+sulfurization

+sulfurization's

+sulfurizations

+sulfurize

+sulfurizes

+sulphurization

+sulphurization's

+sulphurizations

+sulphurize

+sulphurizes

+sultanize

+sultanizes

+summerize

+summerizes

+superacknowledgment

+superacknowledgment's

+superacknowledgments

+supercanonization

+supercanonization's

+supercanonizations

+supercarbonization

+supercarbonization's

+supercarbonizations

+supercarbonize

+supercarbonizes

+supercivilization

+supercivilization's

+supercivilizations

+supercivilized

+supercivilized's

+supercivilizeds

+superemphasize

+superemphasizes

+superficialize

+superficializes

+superhumanize

+superhumanizes

+supernaturalize

+supernaturalizes

+superorganization

+superorganization's

+superorganizations

+superorganize

+superorganizes

+supersensitization

+supersensitization's

+supersensitizations

+superspecialize

+superspecializes

+supersubtilized

+supersubtilized's

+supersubtilizeds

+supersulphurize

+supersulphurizes

+surgerize

+surgerizes

+sycophantize

+sycophantizes

+syllogize

+sylvanize

+sylvanizes

+symmetrization

+symmetrization's

+symmetrizations

+symmetrize

+symmetrized

+symmetrizes

+symmetrizing

+symptomize

+symptomizes

+synchronizable

+synchronizable's

+synchronizables

+syncretize

+syncretized

+syncretizes

+syncretizing

+syndicalize

+syndicalizes

+synesthesia

+synesthetic

+synonymize

+synonymizes

+synopsize

+synthesization

+synthesization's

+synthesizations

+systemizable

+systemizable's

+systemizables

+systemize

+systemizer

+systemizers

+systemizes

+taboret

+taborets

+tabularization

+tabularization's

+tabularizations

+tabularize

+tabularizes

+taffetized

+tailorization

+tailorization's

+tailorizations

+tailorize

+tailorizes

+tambura

+tandemize

+tandemizes

+tantalization

+tantalization's

+tantalizations

+tariffize

+tariffizes

+tartarization

+tartarization's

+tartarizations

+tartarize

+tartarized

+tartarizes

+tasseled

+tasseling

+tassels

+tavernize

+tavernizes

+teaseler

+teaselers

+teazeled

+teazeling

+technicalization

+technicalize

+technicalizes

+technologize

+teetotaled

+teetotaling

+telesthesia

+telesthetic

+tellurize

+tellurized

+tellurizes

+tellurizing

+templize

+templizes

+temporalize

+temporalized

+temporalizes

+temporalizing

+temporization

+temporization's

+temporizations

+tenderization

+tenderize

+tenderized

+tenderizer

+tenderizes

+tenderizing

+tendriled

+tenementization

+tenementization's

+tenementizations

+tenementize

+tenementizes

+terminalization

+terminalization's

+terminalizations

+terminalized

+terminalized's

+terminalizeds

+ternize

+ternizes

+terrestrialize

+terrestrializes

+territorialization

+territorialization's

+territorializations

+territorialize

+territorializes

+terrorization

+terrorization's

+terrorizations

+testimonialization

+testimonialization's

+testimonializations

+testimonialize

+testimonializer

+testimonializers

+testimonializes

+tetanization

+tetanize

+tetanized

+tetanizes

+tetanizing

+teutonize

+texturized

+theaterless

+theaterlesses

+theaterlike

+theaterlike's

+theaterlikes

+theatricalization

+theatricalization's

+theatricalizations

+theatricalize

+theatricalized

+theatricalizes

+theatricalizing

+theatricize

+theatricizes

+theologization

+theologize

+theologized

+theologizer

+theologizes

+theologizing

+thermoanesthesia

+thermoanesthesia's

+thermoanesthesias

+thermometerize

+thermometerizes

+thermopolymerization

+thermopolymerization's

+thermopolymerizations

+thermosiphon

+thermosiphon's

+thermosiphons

+thronize

+thronizes

+thymectomize

+thyroidectomized

+thyroidization

+thyroidization's

+thyroidizations

+tinselier

+tinseliest

+tittuped

+tittuping

+tittupy

+tonicize

+tonicizes

+torporize

+torporizes

+totalitarianize

+totalization

+totalization's

+totalizations

+totalizator

+totalize

+totalized

+totalizer

+totalizers

+totalizes

+totalizing

+totemization

+totemization's

+totemizations

+tourize

+tourizes

+tractorization

+tractorization's

+tractorizations

+tractorize

+tractorizes

+traditionalize

+traditionalizes

+traditionize

+traditionizes

+tragicize

+tragicizes

+traitorize

+traitorizes

+trammeled

+trammeler

+trammelers

+trammeling

+tranquilization

+tranquilization's

+tranquilizations

+tranquillization

+tranquillize

+tranquillized

+tranquillizer

+tranquillizers

+tranquillizes

+tranquillizing

+transcendentalize

+transcendentalizes

+transistorization

+transparentize

+transparentizes

+traumatization

+traumatize

+traumatized

+traumatizes

+traumatizing

+triangularize

+triangularized

+triangularizes

+triangularizing

+trichinize

+trillionize

+trillionizes

+trimerization

+trimerization's

+trimerizations

+trivialization

+tropicalization

+tropicalization's

+tropicalizations

+tropicalize

+tropicalized

+tropicalizes

+tropicalizing

+troweled

+troweling

+trypsinize

+trypsinizes

+tuberculinization

+tuberculinization's

+tuberculinizations

+tuberculinize

+tuberculinizes

+tuberization

+tuberization's

+tuberizations

+tuberize

+tuberizes

+tubulization

+tubulization's

+tubulizations

+tutorization

+tutorization's

+tutorizations

+tutorize

+tutorizes

+ultracentralizer

+ultracentralizer's

+ultracentralizers

+ultrahonorable

+ultrahonorable's

+ultrahonorables

+ultraspecialization

+ultraspecialization's

+ultraspecializations

+ultrastandardization

+ultrastandardization's

+ultrastandardizations

+unagonize

+unalcoholized

+unalcoholized's

+unalcoholizeds

+unanimalized

+unanimalized's

+unanimalizeds

+unantagonizable

+unantagonizable's

+unantagonizables

+unapostatized

+unapostatized's

+unapostatizeds

+unauthorize

+unbaptize

+unbrutalize

+unbrutize

+unbrutizes

+uncanonize

+uncanonizes

+uncantonized

+uncantonized's

+uncantonizeds

+uncatechized

+uncatechized's

+uncatechizedness

+uncatechizeds

+uncatholicize

+uncatholicizes

+uncelestialized

+uncelestialized's

+uncelestializeds

+unchloridized

+unchloridized's

+unchloridizeds

+unchristianize

+unchristianized

+unchristianizes

+uncircularized

+uncircularized's

+uncircularizeds

+uncivilizable

+uncivilizable's

+uncivilizables

+uncivilize

+unclericalize

+unclericalizes

+uncolonize

+uncolorable

+uncolorable's

+uncolorables

+uncolorablies

+uncolorably

+unconventionalize

+unconventionalizes

+uncriticizable

+uncriticizable's

+uncriticizables

+uncrystallizabilities

+uncrystallizability

+uncrystallizability's

+uncrystallizable

+uncrystallizable's

+uncrystallizables

+uncurricularized

+uncurricularized's

+uncurricularizeds

+undefense

+undefense's

+undemagnetizable

+undemagnetizable's

+undemagnetizables

+undemocratize

+undenominationalize

+undenominationalizes

+undercapitalization

+undercapitalization's

+undercapitalizations

+undercapitalize

+undercapitalized

+undercapitalizes

+undercapitalizing

+undercolor

+undercolor's

+undercolored

+undercoloring

+undercolorings

+undercolors

+underemphasize

+underemphasized

+underemphasizes

+underemphasizing

+underlaborer

+underlaborer's

+underlaborers

+underorganization

+underorganization's

+underorganizations

+underoxidize

+underoxidizes

+underrealize

+underrealizes

+undersavior

+undersavior's

+undersaviors

+underutilize

+undervitalized

+undervitalized's

+undervitalizeds

+undiphthongize

+undiphthongizes

+undiscolored

+undiscolored's

+undramatizable

+undramatizable's

+undramatizables

+undualize

+undualizes

+unenamored

+unenamored's

+unenamoreds

+unequalize

+unevangelized

+unevangelized's

+unevangelizeds

+unfavoring

+unfavoring's

+unfertilizable

+unfertilizable's

+unfertilizables

+unfeudalize

+unfeudalized

+unfeudalizes

+ungalvanized

+ungalvanized's

+ungalvanizeds

+ungelatinizable

+ungelatinizable's

+ungelatinizables

+ungelatinized

+ungelatinized's

+ungelatinizeds

+ungentilize

+ungentilizes

+ungentlemanize

+ungentlemanizes

+ungospelized

+ungospelized's

+ungospelizeds

+ungraphitized

+ungraphitized's

+ungraphitizeds

+unharbor

+unharbor's

+unharbored

+unharmonize

+unheroize

+unheroizes

+unhonorable

+unhonorable's

+unhouseled

+unhypnotizable

+unhypnotizable's

+unhypnotizables

+unhypnotize

+unhypnotizes

+uniformization

+uniformization's

+uniformizations

+uniformize

+uniformizes

+unilateralization

+unilateralization's

+unilateralizations

+unilateralize

+unilateralizes

+unimmortalize

+unimmortalizes

+unindividualize

+uninitializable

+unionization's

+unionizations

+unitization

+unitize

+unitizes

+unitizing

+universalization

+universalization's

+universalizations

+unkenneled

+unkenneling

+unlabialize

+unlabializes

+unlaborable

+unlaborable's

+unlaborables

+unlaboring

+unlaboring's

+unlocalizable

+unlocalizable's

+unlocalizables

+unlocalize

+unmechanize

+unmediatized

+unmediatized's

+unmediatizeds

+unmercerized

+unmercerized's

+unmercerizeds

+unmesmerize

+unmesmerizes

+unmetalized

+unmetalized's

+unmetalizeds

+unmethodized

+unmethodized's

+unmethodizeds

+unmethodizing

+unmethodizing's

+unmethodizings

+unmissionized

+unmissionized's

+unmissionizeds

+unmodernize

+unmonopolize

+unmonopolizing

+unmonopolizings

+unmoralize

+unmoralized

+unmoralizes

+unmoralizing

+unmoralizings

+unmunicipalized

+unmunicipalized's

+unmunicipalizeds

+unmutualized

+unmutualized's

+unmutualizeds

+unmysticize

+unmysticizes

+unnaturalizable

+unnaturalizable's

+unnaturalizables

+unnaturalize

+unnaturalizes

+unneighborlike

+unneighborlike's

+unneighborlikes

+unnitrogenized

+unnitrogenized's

+unnitrogenizeds

+unnormalize

+unnormalizing

+unoptimize

+unoptimizing

+unoxidizable

+unoxidizable's

+unoxidizables

+unoxygenized

+unoxygenized's

+unoxygenizeds

+unpaganize

+unpaganizes

+unparagonized

+unparagonized's

+unparagonizeds

+unparalyzed

+unparalyzed's

+unparalyzeds

+unparticularized

+unparticularized's

+unparticularizeds

+unparticularizing

+unparticularizing's

+unparticularizings

+unpatronizable

+unpatronizable's

+unpatronizables

+unpauperized

+unpauperized's

+unpauperizeds

+unphilosophize

+unphosphatized

+unphosphatized's

+unphosphatizeds

+unplagiarized

+unplagiarized's

+unplagiarizeds

+unpoeticized

+unpoeticized's

+unpoeticizeds

+unpoetize

+unpoetized

+unpoetizes

+unpolarizable

+unpolarizable's

+unpolarizables

+unpolymerized

+unpolymerized's

+unpolymerizeds

+unpopularize

+unprotestantize

+unprotestantizes

+unpulverize

+unradicalize

+unradicalizes

+unrancored

+unrancored's

+unrancoreds

+unraveler

+unravelers

+unrealizable

+unrealizable's

+unrealizables

+unrealize

+unrealizing

+unrealizings

+unreconnoitered

+unreconnoitered's

+unreconnoitereds

+unrevelationize

+unrevelationizes

+unromanticized

+unromanticized's

+unromanticizeds

+unroyalized

+unroyalized's

+unroyalizeds

+unsatirize

+unsatirized

+unsavorilies

+unsavorily

+unscandalize

+unscandalizes

+unscepter

+unscepter's

+unsceptered

+unschematized

+unschematized's

+unschematizeds

+unsectarianize

+unsectarianizes

+unsecularize

+unsecularizes

+unsensitize

+unsensitizes

+unsensualize

+unsensualized

+unsensualizes

+unsentimentalize

+unsepulcher

+unsepulchered

+unsignalized

+unsignalized's

+unsignalizeds

+unsiphon

+unsiphon's

+unsolemnize

+unsolemnized

+unsolemnizes

+unspecterlike

+unspecterlike's

+unspecterlikes

+unspiritualize

+unspiritualized

+unspiritualizes

+unstoicize

+unstoicizes

+unsubstantialize

+unsubstantializes

+unsuccorable

+unsuccorable's

+unsuccorables

+unsulphurized

+unsulphurized's

+unsulphurizeds

+unsupernaturalize

+unsupernaturalized

+unsupernaturalizes

+unsymmetrized

+unsymmetrized's

+unsymmetrizeds

+unsympathizabilities

+unsympathizability

+unsympathizability's

+unsympathizable

+unsympathizable's

+unsympathizables

+unsystemizable

+unsystemizable's

+unsystemizables

+untantalizing

+untantalizing's

+untantalizings

+untartarized

+untartarized's

+untartarizeds

+untechnicalize

+untechnicalizes

+untemporizing

+untemporizing's

+untheorizable

+untheorizable's

+untheorizables

+unutilizable

+unutilizable's

+unutilizables

+unvaporized

+unvaporized's

+unvaporizeds

+unvectorizable

+unvitalized

+unvitalized's

+unvitalizeds

+unvitriolized

+unvitriolized's

+unvitriolizeds

+unvolatilize

+unvolatilized

+unvolatilizes

+unvulgarize

+unvulgarized

+unvulgarizes

+unwesternized

+unwesternized's

+unwesternizeds

+unwomanize

+urbanize

+urbanizes

+urbanizing

+utilitarianize

+utilitarianizes

+utilizabilities

+utilizability

+utilizable

+utilizable's

+utilizables

+utopianizer

+utopianizer's

+utopianizers

+vaccinization

+vaccinization's

+vaccinizations

+vacuumize

+vacuumized

+vacuumizes

+vacuumizing

+vagabondize

+vagabondizer

+vagabondizers

+vagabondizes

+vagrantize

+vagrantizes

+valorization

+valorization's

+valorizations

+valorize

+valorized

+valorizes

+valorizing

+vampirize

+vampirizes

+vandalization

+vandalization's

+vandalizations

+vaporabilities

+vaporability

+vaporability's

+vaporable

+vaporable's

+vaporables

+vaporier

+vaporiest

+vaporish

+vaporishness

+vaporizable

+vaporizable's

+vaporizables

+vaporize

+vaporized

+vaporizer

+vaporizers

+vaporizes

+vaporizing

+vaporless

+vaporlesses

+vaporlike

+vaporlike's

+vaporlikes

+vapory

+vascularization

+vascularization's

+vascularizations

+vascularize

+vascularized

+vascularizes

+vascularizing

+vassalization

+vassalize

+vassalized

+vassalizes

+vassalizing

+vectorizable

+vectorize

+vectorized

+vectorizer

+vectorizers

+vectorizes

+vegetablize

+vegetablizes

+velarization

+venalization

+venalization's

+venalizations

+venalize

+venalizes

+venomization

+venomization's

+venomizations

+venomize

+venomizes

+ventriloquize

+ventriloquized

+ventriloquizes

+ventriloquizing

+verbalization

+verbalization's

+verbalizations

+vermeiled

+vermeiles

+vermeiling

+vermilionize

+vermilionizes

+vernacularization

+vernacularization's

+vernacularizations

+vernacularize

+vernacularizes

+vernalization

+vernalization's

+vernalizations

+vernalize

+vernalized

+vernalizes

+vernalizing

+versicolor

+versicolored

+versionize

+versionizes

+vestryize

+vestryizes

+veteranize

+veteranizes

+vialed

+vialing

+victimizable

+victimizable's

+victimizables

+victimization

+victimization's

+victimizations

+victualage

+victualed

+victualess

+victualing

+vigorless

+virtualize

+virtualizes

+visionize

+visionizes

+vitalization

+vitalization's

+vitalizations

+vitalize

+vitalized

+vitalizer

+vitalizers

+vitalizes

+vitalizing

+vitalizing's

+vitalizingly

+vitalizings

+vitaminization

+vitaminize

+vitaminizes

+vitriolizable

+vitriolizable's

+vitriolizables

+vitriolization

+vitriolization's

+vitriolizations

+vitriolize

+vitriolizer

+vitriolizers

+vitriolizes

+vocationalization

+vocationalization's

+vocationalizations

+vocationalize

+vocationalizes

+volatilizable

+volatilizable's

+volatilizables

+volatilize

+volatilized

+volatilizer

+volatilizers

+volatilizes

+volatilizing

+voltize

+voltizes

+vowelization

+vowelization's

+vowelizations

+vowelize

+vowelized

+vowelizes

+vowelizing

+vulcanizable

+vulcanizable's

+vulcanizables

+vulcanizate

+vulcanization

+vulcanization's

+vulcanizations

+vulcanize

+vulcanizer

+vulcanizers

+vulcanizes

+vulcanizing

+vulgarization

+vulgarization's

+vulgarizations

+vulgarize

+vulgarized

+vulgarizer

+vulgarizers

+vulgarizes

+vulgarizing

+weeviled

+westernization

+westernization's

+westernizations

+westernize

+westernized

+westernizes

+westernizing

+winterization

+winterization's

+winterizations

+winterize

+winterized

+winterizes

+winterizing

+womanization

+womanization's

+womanizations

+woodcockize

+woodcockizes

+woolenization

+woolenization's

+woolenizations

+woolenize

+woolenizes

+zeroize

+zeroized

+zeroizes

+zeroizing

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.0 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.0
new file mode 100644
index 0000000..4008ec0
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.0
@@ -0,0 +1,47158 @@
+ACM

+ANSI

+ASAP

+ASCII

+ATM's

+Achilles

+Ada

+Ada's

+Afghanistan

+Afghanistan's

+Africa

+Africa's

+African

+African's

+Africans

+Airedale

+Airedale's

+Alabama

+Alabama's

+Alabamian

+Alabamian's

+Alaska

+Alaska's

+Albania

+Albania's

+Albanian

+Albanian's

+Albanians

+Alcibiades

+Alden

+Alden's

+Algeria

+Algeria's

+Algerian

+Algerian's

+Algol

+Algol's

+Allah

+Allah's

+Alyssa

+Alyssa's

+Amanda

+Amanda's

+Amdahl

+Amdahl's

+Amelia

+Amelia's

+America

+America's

+American

+American's

+Americana

+Americans

+Americas

+Ames

+Amsterdam

+Amsterdam's

+Amtrak

+Amtrak's

+Anabaptist

+Anabaptist's

+Anabaptists

+Andorra

+Andorra's

+Angeleno

+Angeleno's

+Angelenos

+Anglican

+Anglican's

+Anglicanism

+Anglicanism's

+Anglicans

+Anglophilia

+Anglophilia's

+Anglophobia

+Anglophobia's

+Angola

+Angola's

+Antarctica

+Antarctica's

+Aphrodite

+Aphrodite's

+Apollo

+Apollo's

+Apollonian

+Appalachia

+Appalachia's

+Appalachian

+Appalachian's

+Appalachians

+April

+April's

+Aprils

+Aquarius

+Arab

+Arab's

+Arabia

+Arabia's

+Arabian

+Arabian's

+Arabians

+Arabic

+Arabic's

+Arabs

+Archie

+Archie's

+Argentina

+Argentina's

+Argo

+Argo's

+Argos

+Arianism

+Arianism's

+Arianist

+Arianist's

+Arianists

+Aries

+Aristotelian

+Aristotelian's

+Aristotle

+Aristotle's

+Arizona

+Arizona's

+Arkansas

+Arkansas's

+Armageddon

+Armageddon's

+Armenian

+Armenian's

+Armour

+Armour's

+Armstrong

+Armstrong's

+Artemis

+Aryan

+Aryan's

+Aryans

+Asia

+Asia's

+Asian

+Asian's

+Asians

+Asiatic

+Asiatic's

+Asiatics

+Assyrian

+Assyrian's

+Assyriology

+Assyriology's

+Athena

+Athena's

+Athenian

+Athenian's

+Athenians

+Athens

+Atlantic

+Atlantic's

+Auckland

+Auckland's

+Audubon

+Audubon's

+Augusta

+Augusta's

+Augusts

+Austin

+Austin's

+Australia

+Australia's

+Australian

+Australian's

+Australians

+Austria

+Austria's

+Austrian

+Austrian's

+Ave

+BSD

+Babel

+Babel's

+Bach

+Bach's

+Bagrodia

+Bagrodia's

+Bagrodias

+Balkan

+Balkan's

+Balkans

+Baltic

+Baltic's

+Bangladesh

+Bangladesh's

+Bantu

+Bantu's

+Bantus

+Barbados

+Baxter

+Baxter's

+Beethoven

+Beethoven's

+Belgian

+Belgian's

+Belgians

+Belgium

+Belgium's

+Bellovin

+Bellovin's

+Belushi

+Belushi's

+Benedict

+Benedict's

+Benedictine

+Benedictine's

+Bengal

+Bengal's

+Bengali

+Bengali's

+Benzedrine

+Benzedrine's

+Bergsten

+Bergsten's

+Berkeley

+Berkeley's

+Berlin

+Berlin's

+Berliner

+Berliners

+Bermuda

+Bermuda's

+Bessel

+Bessel's

+Beverly

+Beverly's

+Bilbo

+Bilbo's

+Bolivia

+Bolivia's

+Bologna

+Bologna's

+Bolshevik

+Bolshevik's

+Bolsheviks

+Bolshevism

+Bolshevism's

+Borneo

+Borneo's

+Boston

+Boston's

+Bostonian

+Bostonian's

+Bostonians

+Botswana

+Botswana's

+Bourne

+Bourne's

+Brazil

+Brazil's

+Brazilian

+Brazilian's

+Bresenham

+Bresenham's

+Britain

+Britain's

+British

+Britisher

+Britishly

+Briton

+Briton's

+Britons

+Buehring

+Buehring's

+CDC

+CDC's

+CEO

+CMOS

+CPU

+CPU's

+CPUs

+California

+California's

+Californian

+Californian's

+Californians

+Cambridge

+Cambridge's

+Canada

+Canada's

+Carolina

+Carolina's

+Carolinas

+Cartesian

+Chinese

+Chinese's

+Christian

+Christian's

+Christians

+Christiansen

+Christmas

+Cobol

+Cobol's

+Coleman

+Coleman's

+Colorado

+Colorado's

+Comdex

+Comdex's

+Cray

+Cray's

+Crays

+Cupertino

+Cupertino's

+Czechoslovakian

+DARPA

+DARPA's

+DECNET

+DOS

+Dan

+Dan's

+DeMorgan

+DeMorgan's

+Debbie

+Debbie's

+December

+December's

+Decembers

+Delaware

+Delaware's

+Denmark

+Denmark's

+Dijkstra

+Dijkstra's

+Diophantine

+Dylan

+Dylan's

+EDP

+EGA

+EGA's

+Edsger

+Edsger's

+Ellen

+Ellen's

+Elvis

+Elvis's

+English

+English's

+Erlang

+Erlang's

+Ethernet

+Ethernet's

+Ethernets

+Europe

+Europe's

+European

+European's

+Europeans

+FIFO

+Fairbanks

+Februaries

+February

+February's

+Felder

+Florida

+Florida's

+Fortran

+Fortran's

+Fourier

+Fourier's

+France

+France's

+Frances

+French

+French's

+Friday

+Friday's

+Fridays

+GPSS

+Galvin

+Galvin's

+Garfunkel

+Geoff

+Geoff's

+Geoffrey

+Geoffrey's

+German

+German's

+Germans

+Germany

+Germany's

+Gibson

+Gibson's

+Gipsies

+Gipsy

+Gipsy's

+Godzilla

+Godzilla's

+Gothic

+Greek

+Greek's

+Greeks

+Greg

+Greg's

+Heinlein

+Heinlein's

+Hewlett

+Hewlett's

+Holland

+Holland's

+Hollander

+Hollanders

+Hollands

+Honda

+Honda's

+Hz

+I'd

+I'll

+I'm

+I've

+IBM

+IBM's

+IEEE

+ITCorp

+ITCorp's

+ITcorp

+ITcorp's

+Illinois

+Inc

+India

+India's

+Indian

+Indian's

+Indiana

+Indiana's

+Indians

+Intel

+Intel's

+Internet

+Internet's

+Iran

+Iran's

+Ireland

+Ireland's

+Israel

+Israel's

+Israeli

+Israeli's

+Israelis

+Italian

+Italian's

+Italians

+James

+Januaries

+January

+January's

+Japan

+Japan's

+Japanese

+Japanese's

+Jefferson

+Jefferson's

+Jill

+Jill's

+Johnnie

+Johnnie's

+Jr

+Julie

+Julie's

+Julies

+July

+July's

+Julys

+June

+June's

+Junes

+Klein

+Klein's

+Kleinrock

+Kleinrock's

+Kline

+Kline's

+Knuth

+Knuth's

+Kuenning

+Kuenning's

+LED's

+LEDs

+LaTeX

+LaTeX's

+Lagrangian

+Lagrangian's

+Lamport

+Lamport's

+Latin

+Latin's

+Laurie

+Laurie's

+Lenten

+Liz

+Liz's

+Lyle

+Lyle's

+MHz

+MIT

+MIT's

+MacDraw

+MacDraw's

+MacIntosh

+MacIntosh's

+MacPaint

+MacPaint's

+Mafia

+Mafia's

+Malibu

+Malibu's

+Mandelbrot

+Mandelbrot's

+Manhattan

+Manhattan's

+Manila

+Manila's

+Marianne

+Marianne's

+Mary

+Mary's

+Maryland

+Maryland's

+Marylanders

+Massachusetts

+Massey

+Massey's

+Matt

+Matt's

+Maxtor

+Maxtor's

+McElhaney

+McElhaney's

+McKenzie

+McKenzie's

+McMartin

+McMartin's

+Medusa

+Medusa's

+Michigan

+Michigan's

+Microport

+Microport's

+Microsoft

+Microsoft's

+Midwest

+Minnesota

+Minnesota's

+Monday

+Monday's

+Mondays

+Montana

+Montana's

+Montanan

+Montanan's

+Moslem

+Moslem's

+Moslems

+Motorola

+Motorola's

+Mr

+Mrs

+Ms

+Multibus

+Multibus's

+Multics

+Munsey

+Munsey's

+Muslim

+Muslim's

+Muslims

+NFS

+Nazi

+Nazi's

+Nazis

+NeWS

+Nebraska

+Nebraska's

+Nebraskan

+Nebraskan's

+Negro

+Negro's

+Negroes

+Nepal

+Nepal's

+Netherlands

+Newtonian

+November

+November's

+Novembers

+OEM

+OEM's

+OEMS

+OK

+OS

+OS's

+October

+October's

+Octobers

+Oderberg

+Oderberg's

+Oderbergs

+Oedipus

+Ohio

+Ohio's

+Oklahoma

+Oklahoma's

+Oklahoman

+Oklahoman's

+Oliver's

+PC

+PC's

+PCs

+PDP

+Packard

+Packard's

+Packards

+Palestinian

+Pascal

+Pascal's

+Pennsylvania

+Pennsylvania's

+Peter's

+Petkiewicz

+Petkiewicz's

+PhD

+Planck

+Planck's

+Poland

+Poland's

+Popek

+Popek's

+Popeks

+Prime's

+Prokofiev

+Prokofiev's

+QA

+RCS

+ROM

+RSX

+Redford

+Redford's

+Rick

+Rick's

+Ritchie

+Ritchie's

+Robert

+Robert's

+Roberts

+Robinson

+Robinson's

+Roman

+Roman's

+Romans

+Roy

+Roy's

+Rubens

+Russian

+Russian's

+Russians

+SCCS

+SMTP

+Sally's

+Salz

+Salz's

+Sam

+Sam's

+Saturday

+Saturday's

+Saturdays

+Scotland

+Scotland's

+Seagate

+Seagate's

+September

+September's

+Septembers

+Signor

+Sikkim

+Sikkim's

+Sikkimese

+Silverstein

+Silverstein's

+Singapore

+Singapore's

+Spafford

+Spafford's

+Spain

+Spain's

+Spanish

+Spanish's

+Spencer

+Spencer's

+Spuds

+Sr

+Sunday

+Sunday's

+Sundays

+TCP

+TV's

+TeX

+TeX's

+Teflon

+Teflon's

+Tektronix

+Tektronix's

+Tennessee

+Tennessee's

+Texas

+Texas's

+Texases

+Thursday

+Thursday's

+Thursdays

+Tinseltown

+Tinseltown's

+Trudeau

+Trudeau's

+Tuesday

+Tuesday's

+Tuesdays

+Turing

+Turing's

+UART

+UCLA

+UNIX's

+USC

+USC's

+USG

+USG's

+Ultrix

+Ultrix's

+Unix

+Unix's

+Usenet

+Usenet's

+Usenix

+Usenix's

+Utah

+Utah's

+VAR

+VCR

+VMS

+VMS's

+Vanessa

+Vanessa's

+Vax

+Vax's

+Ventura

+Ventura's

+Virginia

+Virginia's

+Warnock

+Warnock's

+Washington

+Washington's

+Wednesday

+Wednesday's

+Wednesdays

+Weibull

+Weibull's

+Wilbur

+Wilbur's

+Willisson

+Willisson's

+Wilson

+Wilson's

+Xenix

+Xenix's

+Xeroxed

+Xeroxes

+Xeroxing

+Yamaha

+Yamaha's

+Yentl

+Yentl's

+York

+York's

+Yorker

+Yorkers

+Yorks

+Zealand

+Zealand's

+Zulu

+Zulu's

+Zulus

+aback

+abaft

+abandon

+abandoned

+abandoner

+abandoning

+abandonment

+abandonments

+abandons

+abase

+abased

+abasement

+abasements

+abaser

+abases

+abash

+abashed

+abashes

+abashing

+abasing

+abate

+abated

+abatement

+abatements

+abater

+abates

+abating

+abbe

+abbey

+abbey's

+abbeys

+abbot

+abbot's

+abbots

+abbreviate

+abbreviated

+abbreviates

+abbreviating

+abbreviation

+abbreviations

+abdomen

+abdomen's

+abdomens

+abdominal

+abdominally

+abduct

+abducted

+abducting

+abduction

+abduction's

+abductions

+abductor

+abductor's

+abductors

+abducts

+abed

+aberrant

+aberrantly

+aberration

+aberrations

+abet

+abets

+abetted

+abetter

+abetting

+abettor

+abeyance

+abhor

+abhorred

+abhorrent

+abhorrently

+abhorrer

+abhorring

+abhors

+abide

+abided

+abider

+abides

+abiding

+abidingly

+abilities

+ability

+ability's

+abject

+abjection

+abjections

+abjectly

+abjectness

+abjure

+abjured

+abjurer

+abjures

+abjuring

+ablate

+ablated

+ablates

+ablating

+ablation

+ablative

+ablatively

+ablaze

+able

+abler

+ablest

+ablution

+ablutions

+ably

+abnormal

+abnormalities

+abnormality

+abnormally

+aboard

+abode

+abode's

+abodes

+abolish

+abolished

+abolisher

+abolishers

+abolishes

+abolishing

+abolishment

+abolishment's

+abolishments

+abolition

+abolitionist

+abolitionists

+abominable

+aboriginal

+aboriginally

+aborigine

+aborigine's

+aborigines

+abort

+aborted

+aborter

+aborting

+abortion

+abortion's

+abortions

+abortive

+abortively

+abortiveness

+aborts

+abound

+abounded

+abounding

+abounds

+about

+above

+aboveground

+abrade

+abraded

+abrader

+abrades

+abrading

+abrasion

+abrasion's

+abrasions

+abreaction

+abreaction's

+abreactions

+abreast

+abridge

+abridged

+abridger

+abridges

+abridging

+abridgment

+abroad

+abrogate

+abrogated

+abrogates

+abrogating

+abrogation

+abrupt

+abruptly

+abruptness

+abscess

+abscessed

+abscesses

+abscissa

+abscissa's

+abscissas

+abscond

+absconded

+absconder

+absconding

+absconds

+absence

+absence's

+absences

+absent

+absented

+absentee

+absentee's

+absenteeism

+absentees

+absentia

+absenting

+absently

+absentminded

+absentmindedly

+absentmindedness

+absents

+absinthe

+absolute

+absolutely

+absoluteness

+absolutes

+absolution

+absolve

+absolved

+absolver

+absolves

+absolving

+absorb

+absorbed

+absorbency

+absorbent

+absorbent's

+absorbents

+absorber

+absorbing

+absorbingly

+absorbs

+absorption

+absorption's

+absorptions

+absorptive

+abstain

+abstained

+abstainer

+abstaining

+abstains

+abstention

+abstentions

+abstinence

+abstract

+abstracted

+abstractedly

+abstractedness

+abstracter

+abstracting

+abstraction

+abstraction's

+abstractionism

+abstractionist

+abstractionists

+abstractions

+abstractive

+abstractly

+abstractness

+abstractor

+abstractor's

+abstractors

+abstracts

+abstruse

+abstrusely

+abstruseness

+abstrusenesses

+absurd

+absurdities

+absurdity

+absurdity's

+absurdly

+absurdness

+abundance

+abundances

+abundant

+abundantly

+abuse

+abused

+abuser

+abusers

+abuses

+abusing

+abusive

+abusively

+abusiveness

+abut

+abutment

+abutments

+abuts

+abutted

+abutter

+abutter's

+abutters

+abutting

+abysmal

+abysmally

+abyss

+abyss's

+abysses

+acacia

+academia

+academic

+academically

+academics

+academies

+academy

+academy's

+accede

+acceded

+accedes

+acceding

+accelerate

+accelerated

+accelerates

+accelerating

+acceleratingly

+acceleration

+accelerations

+accelerative

+accelerator

+accelerators

+accelerometer

+accelerometer's

+accelerometers

+accent

+accented

+accenting

+accents

+accentual

+accentually

+accentuate

+accentuated

+accentuates

+accentuating

+accentuation

+accept

+acceptability

+acceptable

+acceptableness

+acceptably

+acceptance

+acceptance's

+acceptances

+accepted

+acceptedly

+accepter

+accepters

+accepting

+acceptingly

+acceptingness

+acceptive

+acceptor

+acceptor's

+acceptors

+accepts

+access

+accessed

+accesses

+accessibility

+accessible

+accessibly

+accessing

+accession

+accession's

+accessions

+accessories

+accessory

+accessory's

+accident

+accident's

+accidental

+accidentally

+accidentalness

+accidently

+accidents

+acclaim

+acclaimed

+acclaimer

+acclaiming

+acclaims

+acclamation

+acclimate

+acclimated

+acclimates

+acclimating

+acclimation

+accolade

+accolades

+accommodate

+accommodated

+accommodates

+accommodating

+accommodatingly

+accommodation

+accommodations

+accommodative

+accommodativeness

+accompanied

+accompanier

+accompanies

+accompaniment

+accompaniment's

+accompaniments

+accompanist

+accompanist's

+accompanists

+accompany

+accompanying

+accomplice

+accomplices

+accomplish

+accomplished

+accomplisher

+accomplishers

+accomplishes

+accomplishing

+accomplishment

+accomplishment's

+accomplishments

+accord

+accordance

+accordances

+accorded

+accorder

+accorders

+according

+accordingly

+accordion

+accordion's

+accordions

+accords

+accost

+accosted

+accosting

+accosts

+account

+accountabilities

+accountability

+accountable

+accountableness

+accountably

+accountancy

+accountant

+accountant's

+accountants

+accounted

+accounting

+accountings

+accounts

+accredit

+accreditation

+accreditations

+accredited

+accretion

+accretion's

+accretions

+accrue

+accrued

+accrues

+accruing

+acculturate

+acculturated

+acculturates

+acculturating

+acculturation

+acculturative

+accumulate

+accumulated

+accumulates

+accumulating

+accumulation

+accumulations

+accumulative

+accumulatively

+accumulativeness

+accumulator

+accumulator's

+accumulators

+accuracies

+accuracy

+accurate

+accurately

+accurateness

+accursed

+accursedly

+accursedness

+accusal

+accusation

+accusation's

+accusations

+accusative

+accuse

+accused

+accuser

+accusers

+accuses

+accusing

+accusingly

+accustom

+accustomed

+accustomedness

+accustoming

+accustoms

+ace

+ace's

+aced

+acer

+aces

+acetate

+acetone

+acetylene

+ache

+ached

+aches

+achievable

+achieve

+achieved

+achievement

+achievement's

+achievements

+achiever

+achievers

+achieves

+achieving

+aching

+achingly

+acid

+acidic

+acidities

+acidity

+acidly

+acidness

+acids

+acidulous

+acing

+acknowledge

+acknowledged

+acknowledgedly

+acknowledger

+acknowledgers

+acknowledges

+acknowledging

+acme

+acne

+acned

+acolyte

+acolytes

+acorn

+acorn's

+acorns

+acoustic

+acoustical

+acoustically

+acoustician

+acoustics

+acquaint

+acquaintance

+acquaintance's

+acquaintances

+acquainted

+acquainting

+acquaints

+acquiesce

+acquiesced

+acquiescence

+acquiesces

+acquiescing

+acquirable

+acquire

+acquired

+acquires

+acquiring

+acquisition

+acquisition's

+acquisitions

+acquisitiveness

+acquit

+acquits

+acquittal

+acquittals

+acquitted

+acquitter

+acquitting

+acre

+acre's

+acreage

+acres

+acrid

+acridly

+acridness

+acrimonious

+acrimoniously

+acrimony

+acrobat

+acrobat's

+acrobatic

+acrobatics

+acrobats

+acronym

+acronym's

+acronyms

+acropolis

+across

+acrylic

+act

+acted

+acting

+actinium

+actinometer

+actinometer's

+actinometers

+action

+action's

+actions

+activate

+activated

+activates

+activating

+activation

+activations

+activator

+activator's

+activators

+active

+actively

+activeness

+activism

+activist

+activist's

+activists

+activities

+activity

+activity's

+actor

+actor's

+actors

+actress

+actress's

+actresses

+acts

+actual

+actualities

+actuality

+actually

+actuals

+actuarial

+actuarially

+actuate

+actuated

+actuates

+actuating

+actuation

+actuator

+actuator's

+actuators

+acuity

+acumen

+acute

+acutely

+acuteness

+acuter

+acutest

+acyclic

+acyclically

+ad

+adage

+adages

+adagio

+adagios

+adamant

+adamantly

+adapt

+adaptability

+adaptable

+adaptation

+adaptation's

+adaptations

+adapted

+adaptedness

+adapter

+adapters

+adapting

+adaption

+adaptive

+adaptively

+adaptiveness

+adaptor

+adaptors

+adapts

+add

+added

+addenda

+addendum

+adder

+adders

+addict

+addicted

+addicting

+addiction

+addiction's

+addictions

+addictive

+addicts

+adding

+addition

+addition's

+additional

+additionally

+additions

+additive

+additive's

+additively

+additives

+additivity

+address

+addressability

+addressable

+addressed

+addressee

+addressee's

+addressees

+addresser

+addressers

+addresses

+addressing

+adds

+adduce

+adduced

+adducer

+adduces

+adducing

+adduct

+adducted

+adducting

+adduction

+adductive

+adductor

+adducts

+adept

+adeptly

+adeptness

+adepts

+adequacies

+adequacy

+adequate

+adequately

+adequateness

+adhere

+adhered

+adherence

+adherences

+adherent

+adherent's

+adherently

+adherents

+adherer

+adherers

+adheres

+adhering

+adhesion

+adhesions

+adhesive

+adhesive's

+adhesively

+adhesiveness

+adhesives

+adiabatic

+adiabatically

+adieu

+adjacency

+adjacent

+adjacently

+adjective

+adjective's

+adjectively

+adjectives

+adjoin

+adjoined

+adjoining

+adjoins

+adjourn

+adjourned

+adjourning

+adjournment

+adjourns

+adjudge

+adjudged

+adjudges

+adjudging

+adjudicate

+adjudicated

+adjudicates

+adjudicating

+adjudication

+adjudication's

+adjudications

+adjudicative

+adjunct

+adjunct's

+adjunctive

+adjunctly

+adjuncts

+adjure

+adjured

+adjures

+adjuring

+adjust

+adjustable

+adjustably

+adjusted

+adjuster

+adjusters

+adjusting

+adjustive

+adjustment

+adjustment's

+adjustments

+adjustor

+adjustor's

+adjustors

+adjusts

+adjutant

+adjutants

+administer

+administered

+administering

+administerings

+administers

+administration

+administration's

+administrations

+administrative

+administratively

+administrator

+administrator's

+administrators

+admirable

+admirableness

+admirably

+admiral

+admiral's

+admirals

+admiralty

+admiration

+admirations

+admire

+admired

+admirer

+admirers

+admires

+admiring

+admiringly

+admissibility

+admissible

+admission

+admission's

+admissions

+admit

+admits

+admittance

+admitted

+admittedly

+admitting

+admix

+admixed

+admixes

+admixture

+admonish

+admonished

+admonisher

+admonishes

+admonishing

+admonishingly

+admonishment

+admonishment's

+admonishments

+admonition

+admonition's

+admonitions

+ado

+adobe

+adolescence

+adolescent

+adolescent's

+adolescently

+adolescents

+adopt

+adopted

+adopter

+adopters

+adopting

+adoption

+adoption's

+adoptions

+adoptive

+adoptively

+adopts

+adorable

+adorableness

+adoration

+adore

+adored

+adorer

+adores

+adoring

+adorn

+adorned

+adorning

+adornment

+adornment's

+adornments

+adorns

+adrenal

+adrenaline

+adrenally

+adrift

+adroit

+adroitly

+adroitness

+ads

+adsorb

+adsorbed

+adsorbing

+adsorbs

+adsorption

+adulate

+adulating

+adulation

+adulations

+adult

+adult's

+adulterate

+adulterated

+adulterates

+adulterating

+adulteration

+adulterer

+adulterer's

+adulterers

+adulterous

+adulterously

+adultery

+adulthood

+adultly

+adultness

+adults

+adumbrate

+adumbrated

+adumbrates

+adumbrating

+adumbration

+adumbrative

+adumbratively

+advance

+advanced

+advancement

+advancement's

+advancements

+advancer

+advancers

+advances

+advancing

+advantage

+advantaged

+advantageous

+advantageously

+advantageousness

+advantages

+advantaging

+advent

+adventist

+adventists

+adventitious

+adventitiously

+adventitiousness

+adventive

+adventively

+adventure

+adventured

+adventurer

+adventurers

+adventures

+adventuring

+adventurous

+adventurously

+adventurousness

+adverb

+adverb's

+adverbial

+adverbially

+adverbs

+adversaries

+adversary

+adversary's

+adverse

+adversed

+adversely

+adverses

+adversing

+adversities

+adversity

+advertise

+advertised

+advertisement

+advertisement's

+advertisements

+advertiser

+advertisers

+advertises

+advertising

+advice

+advisability

+advisable

+advisableness

+advisably

+advise

+advised

+advisedly

+advisee

+advisee's

+advisees

+advisement

+advisements

+adviser

+adviser's

+advisers

+advises

+advising

+advisor

+advisor's

+advisors

+advisory

+advocacy

+advocate

+advocated

+advocates

+advocating

+advocation

+advocative

+aegis

+aerate

+aerated

+aerates

+aerating

+aeration

+aerator

+aerators

+aerial

+aerial's

+aerially

+aerials

+aeroacoustic

+aerobic

+aerobics

+aerodynamic

+aerodynamics

+aeronautic

+aeronautical

+aeronautically

+aeronautics

+aerosol

+aerosols

+aerospace

+afar

+afars

+affable

+affair

+affair's

+affairs

+affect

+affectation

+affectation's

+affectations

+affected

+affectedly

+affectedness

+affecter

+affecting

+affectingly

+affection

+affection's

+affectionate

+affectionately

+affectioned

+affections

+affective

+affectively

+affects

+afferent

+afferently

+affianced

+affidavit

+affidavit's

+affidavits

+affiliate

+affiliated

+affiliates

+affiliating

+affiliation

+affiliations

+affinities

+affinity

+affinity's

+affirm

+affirmation

+affirmation's

+affirmations

+affirmative

+affirmatively

+affirmed

+affirming

+affirms

+affix

+affixed

+affixes

+affixing

+afflict

+afflicted

+afflicting

+affliction

+affliction's

+afflictions

+afflictive

+afflictively

+afflicts

+affluence

+affluent

+affluently

+afford

+affordable

+afforded

+affording

+affords

+affricate

+affricates

+affrication

+affricative

+affright

+affront

+affronted

+affronting

+affronts

+afghan

+afghans

+aficionado

+aficionados

+afield

+afire

+aflame

+afloat

+afoot

+afore

+aforementioned

+aforesaid

+aforethought

+afoul

+afraid

+afresh

+aft

+after

+aftereffect

+aftereffects

+aftermath

+aftermost

+afternoon

+afternoon's

+afternoons

+afters

+aftershock

+aftershock's

+aftershocks

+afterthought

+afterthoughts

+afterward

+afterwards

+again

+against

+agape

+agar

+agate

+agates

+age

+aged

+agedly

+agedness

+ageless

+agelessly

+agelessness

+agencies

+agency

+agency's

+agenda

+agenda's

+agendas

+agent

+agent's

+agentive

+agents

+ager

+agers

+ages

+agglomerate

+agglomerated

+agglomerates

+agglomeration

+agglomerative

+agglutinate

+agglutinated

+agglutinates

+agglutinating

+agglutination

+agglutinative

+agglutinin

+agglutinins

+aggravate

+aggravated

+aggravates

+aggravating

+aggravation

+aggravations

+aggregate

+aggregated

+aggregately

+aggregateness

+aggregates

+aggregating

+aggregation

+aggregations

+aggregative

+aggregatively

+aggression

+aggression's

+aggressions

+aggressive

+aggressively

+aggressiveness

+aggressor

+aggressors

+aggrieve

+aggrieved

+aggrievedly

+aggrieves

+aggrieving

+aghast

+agile

+agilely

+agility

+aging

+agitate

+agitated

+agitatedly

+agitates

+agitating

+agitation

+agitations

+agitative

+agitator

+agitator's

+agitators

+agleam

+aglow

+agnostic

+agnostic's

+agnostics

+ago

+agog

+agonies

+agony

+agrarian

+agree

+agreeable

+agreeableness

+agreeably

+agreed

+agreeing

+agreement

+agreement's

+agreements

+agreer

+agreers

+agrees

+agricultural

+agriculturally

+agriculture

+ague

+ah

+ahead

+aid

+aide

+aided

+aider

+aides

+aiding

+aids

+ail

+ailed

+aileron

+ailerons

+ailing

+ailment

+ailment's

+ailments

+ails

+aim

+aimed

+aimer

+aimers

+aiming

+aimless

+aimlessly

+aimlessness

+aims

+air

+airbag

+airbag's

+airbags

+airborne

+aircraft

+aircrafts

+airdrop

+airdrops

+aired

+airer

+airers

+airfield

+airfield's

+airfields

+airflow

+airframe

+airframe's

+airframes

+airhead

+airier

+airiest

+airily

+airiness

+airing

+airings

+airless

+airlessness

+airlift

+airlift's

+airlifts

+airline

+airline's

+airliner

+airliner's

+airliners

+airlines

+airlock

+airlock's

+airlocks

+airmail

+airmails

+airman

+airmen

+airport

+airport's

+airports

+airs

+airship

+airship's

+airships

+airspace

+airspeed

+airspeeds

+airstrip

+airstrip's

+airstrips

+airway

+airway's

+airways

+airy

+aisle

+aisles

+ajar

+akimbo

+akin

+alabaster

+alacrity

+alarm

+alarmed

+alarming

+alarmingly

+alarmist

+alarms

+alas

+alba

+albacore

+albeit

+album

+albumen

+albumin

+albums

+alchemy

+alcohol

+alcohol's

+alcoholic

+alcoholic's

+alcoholics

+alcoholism

+alcoholisms

+alcohols

+alcove

+alcove's

+alcoved

+alcoves

+alder

+alderman

+alderman's

+aldermen

+ale

+alee

+alert

+alerted

+alertedly

+alerter

+alerters

+alerting

+alertly

+alertness

+alerts

+alfalfa

+alfresco

+alga

+algae

+algaecide

+algebra

+algebra's

+algebraic

+algebraically

+algebras

+alginate

+alginates

+algorithm

+algorithm's

+algorithmic

+algorithmically

+algorithms

+alias

+aliased

+aliases

+aliasing

+alibi

+alibi's

+alibis

+alien

+alien's

+alienate

+alienated

+alienates

+alienating

+alienation

+aliens

+alight

+alighted

+alighting

+align

+aligned

+aligner

+aligning

+alignment

+alignments

+aligns

+alike

+alikeness

+aliment

+aliments

+alimony

+alive

+aliveness

+alkali

+alkali's

+alkaline

+alkalis

+alkaloid

+alkaloid's

+alkaloids

+alkyl

+all

+allay

+allayed

+allaying

+allays

+allegation

+allegation's

+allegations

+allege

+alleged

+allegedly

+alleges

+allegiance

+allegiance's

+allegiances

+alleging

+allegoric

+allegorical

+allegorically

+allegoricalness

+allegories

+allegory

+allegory's

+allegretto

+allegretto's

+allegrettos

+allegro

+allegro's

+allegros

+allele

+alleles

+allemande

+allergic

+allergies

+allergy

+allergy's

+alleviate

+alleviated

+alleviates

+alleviating

+alleviation

+alleviative

+alleviator

+alleviator's

+alleviators

+alley

+alley's

+alleys

+alleyway

+alleyway's

+alleyways

+alliance

+alliance's

+alliances

+allied

+allier

+allies

+alligator

+alligator's

+alligatored

+alligators

+alliteration

+alliteration's

+alliterations

+alliterative

+alliteratively

+allocate

+allocated

+allocates

+allocating

+allocation

+allocation's

+allocations

+allocative

+allocator

+allocator's

+allocators

+allophone

+allophones

+allophonic

+allot

+alloted

+allotment

+allotment's

+allotments

+allots

+allotted

+allotter

+allotting

+allow

+allowable

+allowableness

+allowably

+allowance

+allowance's

+allowanced

+allowances

+allowancing

+allowed

+allowedly

+allowing

+allows

+alloy

+alloy's

+alloyed

+alloying

+alloys

+allude

+alluded

+alludes

+alluding

+allure

+allured

+allurement

+allures

+alluring

+allusion

+allusion's

+allusions

+allusive

+allusively

+allusiveness

+ally

+allying

+alma

+almanac

+almanac's

+almanacs

+almightiness

+almighty

+almond

+almond's

+almonds

+almoner

+almost

+alms

+almsman

+alnico

+aloe

+aloes

+aloft

+aloha

+alone

+aloneness

+along

+alongside

+aloof

+aloofly

+aloofness

+aloud

+alpha

+alphabet

+alphabet's

+alphabetic

+alphabetical

+alphabetically

+alphabetics

+alphabets

+alphanumeric

+alphanumerics

+alpine

+alps

+already

+also

+altar

+altar's

+altars

+alter

+alterable

+alteration

+alteration's

+alterations

+altercation

+altercation's

+altercations

+altered

+alterer

+alterers

+altering

+alternate

+alternated

+alternately

+alternates

+alternating

+alternation

+alternations

+alternative

+alternatively

+alternativeness

+alternatives

+alternator

+alternator's

+alternators

+alters

+although

+altitude

+altitudes

+alto

+alto's

+altogether

+altos

+altruism

+altruist

+altruistic

+altruistically

+altruists

+alum

+alumna

+alumna's

+alumnae

+alumni

+alumnus

+alundum

+alveolar

+alveolarly

+alveoli

+alveolus

+always

+am

+amain

+amalgam

+amalgam's

+amalgamate

+amalgamated

+amalgamates

+amalgamating

+amalgamation

+amalgamations

+amalgamative

+amalgams

+amanuensis

+amass

+amassed

+amasser

+amasses

+amassing

+amateur

+amateur's

+amateurish

+amateurishly

+amateurishness

+amateurism

+amateurs

+amatory

+amaze

+amazed

+amazedly

+amazement

+amazer

+amazers

+amazes

+amazing

+amazingly

+amazon

+amazon's

+amazons

+ambassador

+ambassador's

+ambassadors

+amber

+ambiance

+ambiances

+ambidextrous

+ambidextrously

+ambient

+ambiguities

+ambiguity

+ambiguity's

+ambiguous

+ambiguously

+ambiguousness

+ambition

+ambition's

+ambitions

+ambitious

+ambitiously

+ambitiousness

+ambivalence

+ambivalent

+ambivalently

+amble

+ambled

+ambler

+ambles

+ambling

+ambrosial

+ambrosially

+ambulance

+ambulance's

+ambulances

+ambulatory

+ambuscade

+ambuscader

+ambush

+ambushed

+ambusher

+ambushes

+ameliorate

+ameliorated

+ameliorating

+amelioration

+ameliorative

+amen

+amenable

+amend

+amended

+amender

+amending

+amendment

+amendment's

+amendments

+amends

+amenities

+amenity

+americium

+amiable

+amiableness

+amiabler

+amiablest

+amicable

+amicableness

+amicably

+amid

+amide

+amidst

+amigo

+amino

+amiss

+amity

+ammo

+ammonia

+ammoniac

+ammonias

+ammonium

+ammunition

+ammunitions

+amnesty

+amoeba

+amoeba's

+amoebas

+amok

+among

+amongst

+amoral

+amorality

+amorally

+amorous

+amorously

+amorousness

+amorphous

+amorphously

+amorphousness

+amount

+amounted

+amounter

+amounters

+amounting

+amounts

+amour

+amour's

+amours

+amp

+ampere

+amperes

+ampersand

+ampersand's

+ampersands

+amphetamine

+amphetamines

+amphibian

+amphibian's

+amphibians

+amphibious

+amphibiously

+amphibiousness

+amphibology

+ample

+ampleness

+ampler

+amplest

+amplification

+amplifications

+amplified

+amplifier

+amplifiers

+amplifies

+amplify

+amplifying

+amplitude

+amplitude's

+amplitudes

+amply

+ampoule

+ampoule's

+ampoules

+amps

+amputate

+amputated

+amputates

+amputating

+amputation

+ams

+amulet

+amulets

+amuse

+amused

+amusedly

+amusement

+amusement's

+amusements

+amuser

+amusers

+amuses

+amusing

+amusingly

+amusingness

+amusive

+amyl

+an

+anachronism

+anachronism's

+anachronisms

+anachronistically

+anaconda

+anacondas

+anaerobic

+anagram

+anagram's

+anagrams

+anal

+analogical

+analogically

+analogies

+analogous

+analogously

+analogousness

+analogy

+analogy's

+analysis

+analyst

+analyst's

+analysts

+analytic

+analytical

+analytically

+analyticities

+analyticity

+analytics

+anaphora

+anaphoric

+anaphorically

+anaplasmosis

+anarchic

+anarchical

+anarchist

+anarchist's

+anarchists

+anarchy

+anastomoses

+anastomosis

+anastomotic

+anathema

+anatomic

+anatomical

+anatomically

+anatomicals

+anatomy

+ancestor

+ancestor's

+ancestors

+ancestral

+ancestrally

+ancestry

+anchor

+anchorage

+anchorage's

+anchorages

+anchored

+anchoring

+anchorite

+anchoritism

+anchors

+anchovies

+anchovy

+ancient

+anciently

+ancientness

+ancients

+ancillaries

+ancillary

+and

+anded

+anders

+anding

+ands

+anecdotal

+anecdotally

+anecdote

+anecdote's

+anecdotes

+anechoic

+anemometer

+anemometer's

+anemometers

+anemometry

+anemone

+anew

+angel

+angel's

+angelic

+angels

+anger

+angered

+angering

+angers

+angiography

+angle

+angled

+angler

+anglers

+angles

+angling

+angrier

+angriest

+angrily

+angriness

+angry

+angst

+angstrom

+angstroms

+anguish

+anguished

+angular

+angularly

+anhydrous

+anhydrously

+aniline

+animal

+animal's

+animally

+animalness

+animals

+animate

+animated

+animatedly

+animately

+animateness

+animates

+animating

+animation

+animations

+animator

+animator's

+animators

+animism

+animosity

+anion

+anion's

+anionic

+anionics

+anions

+anise

+aniseikonic

+anisotropic

+anisotropies

+anisotropy

+anisotropy's

+ankle

+ankle's

+ankles

+annal

+annalen

+annals

+annex

+annexation

+annexations

+annexed

+annexes

+annexing

+annihilate

+annihilated

+annihilates

+annihilating

+annihilation

+annihilative

+anniversaries

+anniversary

+anniversary's

+annotate

+annotated

+annotates

+annotating

+annotation

+annotations

+annotative

+announce

+announced

+announcement

+announcement's

+announcements

+announcer

+announcers

+announces

+announcing

+annoy

+annoyance

+annoyance's

+annoyances

+annoyed

+annoyer

+annoyers

+annoying

+annoyingly

+annoys

+annual

+annually

+annuals

+annul

+annulled

+annulling

+annulment

+annulment's

+annulments

+annuls

+annum

+annunciate

+annunciated

+annunciates

+annunciating

+annunciation

+annunciator

+annunciators

+anode

+anode's

+anodes

+anoint

+anointed

+anointer

+anointing

+anoints

+anomalies

+anomalous

+anomalously

+anomalousness

+anomaly

+anomaly's

+anomic

+anomie

+anon

+anonymity

+anonymous

+anonymously

+anonymousness

+anorexia

+another

+another's

+answer

+answerable

+answered

+answerer

+answerers

+answering

+answers

+ant

+ant's

+antagonism

+antagonisms

+antagonist

+antagonist's

+antagonistic

+antagonistically

+antagonists

+antarctic

+ante

+anteater

+anteater's

+anteaters

+antecedent

+antecedent's

+antecedently

+antecedents

+anted

+antedate

+antedated

+antedates

+antedating

+antelope

+antelope's

+antelopes

+antenna

+antenna's

+antennae

+antennas

+anterior

+anteriorly

+anteriors

+anthem

+anthem's

+anthems

+anther

+anthologies

+anthology

+anthracite

+anthropological

+anthropologically

+anthropologist

+anthropologist's

+anthropologists

+anthropology

+anthropomorphic

+anthropomorphically

+anti

+antibacterial

+antibiotic

+antibiotics

+antibodies

+antibody

+antic

+antic's

+anticipate

+anticipated

+anticipates

+anticipating

+anticipation

+anticipations

+anticipative

+anticipatively

+anticipatory

+anticoagulation

+anticompetitive

+antics

+antidisestablishmentarianism

+antidote

+antidote's

+antidotes

+antiformant

+antifundamentalist

+antigen

+antigen's

+antigens

+antihistorical

+antimicrobial

+antimony

+anting

+antinomian

+antinomy

+antipathy

+antiphonal

+antiphonally

+antipode

+antipode's

+antipodes

+antiquarian

+antiquarian's

+antiquarians

+antiquate

+antiquated

+antiquation

+antique

+antique's

+antiques

+antiquities

+antiquity

+antiredeposition

+antiresonance

+antiresonator

+antiseptic

+antisera

+antiserum

+antislavery

+antisocial

+antisubmarine

+antisymmetric

+antisymmetry

+antithesis

+antithetical

+antithetically

+antithyroid

+antitoxin

+antitoxin's

+antitoxins

+antitrust

+antitruster

+antler

+antlered

+ants

+anus

+anvil

+anvil's

+anvils

+anxieties

+anxiety

+anxious

+anxiously

+anxiousness

+any

+anybodies

+anybody

+anyhow

+anymore

+anyone

+anyone's

+anyones

+anyplace

+anything

+anythings

+anyway

+anyways

+anywhere

+anywheres

+aorta

+apace

+apart

+apartheid

+apartment

+apartment's

+apartments

+apartness

+apathetic

+apathy

+ape

+aped

+aper

+aperiodic

+aperiodicity

+aperture

+apertured

+apes

+apex

+apexes

+aphasia

+aphasic

+aphid

+aphid's

+aphids

+aphonic

+aphorism

+aphorism's

+aphorisms

+apiaries

+apiary

+apical

+apically

+apiece

+aping

+apish

+apishly

+apishness

+aplenty

+aplomb

+apocalypse

+apocalyptic

+apocrypha

+apocryphal

+apocryphally

+apocryphalness

+apogee

+apogees

+apologetic

+apologetically

+apologetics

+apologia

+apologies

+apologist

+apologist's

+apologists

+apology

+apology's

+apostate

+apostates

+apostle

+apostle's

+apostles

+apostolic

+apostrophe

+apostrophes

+apothecary

+apotheoses

+apotheosis

+appalled

+appalling

+appallingly

+appanage

+apparatus

+apparatuses

+apparel

+apparels

+apparent

+apparently

+apparentness

+apparition

+apparition's

+apparitions

+appeal

+appealed

+appealer

+appealers

+appealing

+appealingly

+appeals

+appear

+appearance

+appearances

+appeared

+appearer

+appearers

+appearing

+appears

+appease

+appeased

+appeasement

+appeaser

+appeases

+appeasing

+appellant

+appellant's

+appellants

+appellate

+appellation

+appellative

+appellatively

+append

+appendage

+appendage's

+appendages

+appended

+appender

+appenders

+appendices

+appendicitis

+appending

+appendix

+appendix's

+appendixes

+appends

+appertain

+appertained

+appertaining

+appertains

+appetite

+appetite's

+appetites

+appetitive

+applaud

+applauded

+applauder

+applauding

+applauds

+applause

+apple

+apple's

+applejack

+apples

+appliance

+appliance's

+appliances

+applicability

+applicable

+applicant

+applicant's

+applicants

+application

+application's

+applications

+applicative

+applicatively

+applicator

+applicator's

+applicators

+applied

+applier

+appliers

+applies

+applique

+appliques

+apply

+applying

+appoint

+appointed

+appointee

+appointee's

+appointees

+appointer

+appointers

+appointing

+appointive

+appointment

+appointment's

+appointments

+appoints

+apportion

+apportioned

+apportioning

+apportionment

+apportionments

+apportions

+appraisal

+appraisal's

+appraisals

+appraise

+appraised

+appraiser

+appraisers

+appraises

+appraising

+appraisingly

+appreciable

+appreciably

+appreciate

+appreciated

+appreciates

+appreciating

+appreciation

+appreciations

+appreciative

+appreciatively

+appreciativeness

+apprehend

+apprehended

+apprehender

+apprehending

+apprehends

+apprehensible

+apprehension

+apprehension's

+apprehensions

+apprehensive

+apprehensively

+apprehensiveness

+apprentice

+apprenticed

+apprentices

+apprenticeship

+apprenticeships

+apprise

+apprised

+appriser

+apprisers

+apprises

+apprising

+apprisings

+apprize

+apprized

+apprizer

+apprizers

+apprizes

+apprizing

+apprizingly

+apprizings

+approach

+approachability

+approachable

+approached

+approacher

+approachers

+approaches

+approaching

+approbate

+approbation

+appropriate

+appropriated

+appropriately

+appropriateness

+appropriates

+appropriatest

+appropriating

+appropriation

+appropriations

+appropriative

+appropriator

+appropriator's

+appropriators

+approval

+approval's

+approvals

+approve

+approved

+approver

+approvers

+approves

+approving

+approvingly

+approximate

+approximated

+approximately

+approximates

+approximating

+approximation

+approximations

+approximative

+approximatively

+appurtenance

+appurtenances

+apricot

+apricot's

+apricots

+apron

+apron's

+aprons

+apropos

+apse

+apses

+apsis

+apt

+aptitude

+aptitudes

+aptly

+aptness

+aqua

+aquaria

+aquarium

+aquas

+aquatic

+aquatics

+aqueduct

+aqueduct's

+aqueducts

+aqueous

+aqueously

+aquifer

+aquifers

+arabesque

+arable

+arachnid

+arachnid's

+arachnids

+arbiter

+arbiter's

+arbiters

+arbitrarily

+arbitrariness

+arbitrary

+arbitrate

+arbitrated

+arbitrates

+arbitrating

+arbitration

+arbitrative

+arbitrator

+arbitrator's

+arbitrators

+arboreal

+arboreally

+arc

+arcade

+arcade's

+arcaded

+arcades

+arcading

+arcane

+arced

+arch

+archaeological

+archaeologically

+archaeologist

+archaeologist's

+archaeologists

+archaeology

+archaic

+archaically

+archaicness

+archaism

+archangel

+archangel's

+archangels

+archbishop

+archdiocese

+archdioceses

+arched

+archenemy

+archer

+archers

+archery

+arches

+archetype

+archetypes

+archfool

+arching

+archipelago

+archipelagoes

+architect

+architect's

+architectonic

+architectonics

+architects

+architectural

+architecturally

+architecture

+architecture's

+architectures

+archival

+archive

+archived

+archiver

+archivers

+archives

+archiving

+archivist

+archivists

+archly

+archness

+arcing

+arclike

+arcs

+arctic

+ardent

+ardently

+arduous

+arduously

+arduousness

+are

+area

+area's

+areas

+aren't

+arena

+arena's

+arenas

+ares

+argon

+argonaut

+argonauts

+argot

+arguable

+arguably

+argue

+argued

+arguer

+arguers

+argues

+arguing

+argument

+argument's

+argumentation

+argumentative

+argumentatively

+arguments

+arid

+aridity

+aridness

+aright

+arise

+arisen

+ariser

+arises

+arising

+arisings

+aristocracy

+aristocrat

+aristocrat's

+aristocratic

+aristocratically

+aristocrats

+arithmetic

+arithmetical

+arithmetically

+arithmetics

+ark

+arm

+arm's

+armadillo

+armadillos

+armament

+armament's

+armaments

+armchair

+armchair's

+armchairs

+armed

+armer

+armers

+armful

+armfuls

+armhole

+armies

+arming

+armistice

+armload

+armpit

+armpit's

+armpits

+arms

+army

+army's

+aroma

+aromas

+aromatic

+aromaticness

+arose

+around

+arousal

+arouse

+aroused

+arouses

+arousing

+arpeggio

+arpeggio's

+arpeggios

+arrack

+arraign

+arraigned

+arraigning

+arraignment

+arraignment's

+arraignments

+arraigns

+arrange

+arranged

+arrangement

+arrangement's

+arrangements

+arranger

+arrangers

+arranges

+arranging

+arrant

+arrantly

+array

+arrayed

+arrayer

+arraying

+arrays

+arrears

+arrest

+arrested

+arrester

+arresters

+arresting

+arrestingly

+arrestor

+arrestor's

+arrestors

+arrests

+arrival

+arrival's

+arrivals

+arrive

+arrived

+arriver

+arrives

+arriving

+arrogance

+arrogant

+arrogantly

+arrogate

+arrogated

+arrogates

+arrogating

+arrogation

+arrow

+arrowed

+arrowhead

+arrowhead's

+arrowheads

+arrowing

+arrows

+arroyo

+arroyos

+arsenal

+arsenal's

+arsenals

+arsenic

+arsine

+arsines

+arson

+art

+art's

+arterial

+arterially

+arteries

+arteriolar

+arteriole

+arteriole's

+arterioles

+arteriosclerosis

+artery

+artery's

+artful

+artfully

+artfulness

+arthritis

+arthrogram

+arthrogram's

+arthrograms

+arthropod

+arthropod's

+arthropods

+artichoke

+artichoke's

+artichokes

+article

+article's

+articled

+articles

+articling

+articulate

+articulated

+articulately

+articulateness

+articulates

+articulating

+articulation

+articulations

+articulative

+articulator

+articulators

+articulatory

+artifact

+artifact's

+artifacts

+artifice

+artificer

+artifices

+artificial

+artificialities

+artificiality

+artificially

+artificialness

+artilleries

+artillerist

+artillery

+artisan

+artisan's

+artisans

+artist

+artist's

+artistic

+artistically

+artistry

+artists

+artless

+artlessly

+arts

+artwork

+as

+asbestos

+ascend

+ascendancy

+ascendant

+ascendantly

+ascended

+ascendency

+ascendent

+ascender

+ascenders

+ascending

+ascends

+ascension

+ascensions

+ascent

+ascertain

+ascertainable

+ascertained

+ascertaining

+ascertains

+ascetic

+ascetic's

+asceticism

+ascetics

+ascot

+ascribable

+ascribe

+ascribed

+ascribes

+ascribing

+ascription

+aseptic

+ash

+ashamed

+ashamedly

+ashen

+asher

+ashes

+ashman

+ashore

+ashtray

+ashtray's

+ashtrays

+aside

+asides

+asinine

+asininely

+ask

+askance

+asked

+asker

+askers

+askew

+askewness

+asking

+asks

+asleep

+asocial

+asp

+asparagus

+aspect

+aspect's

+aspects

+aspen

+asper

+aspersion

+aspersion's

+aspersions

+asphalt

+asphalted

+asphyxia

+aspic

+aspirant

+aspirant's

+aspirants

+aspirate

+aspirated

+aspirates

+aspirating

+aspiration

+aspiration's

+aspirations

+aspirator

+aspirators

+aspire

+aspired

+aspirer

+aspires

+aspirin

+aspiring

+aspirins

+ass

+ass's

+assail

+assailant

+assailant's

+assailants

+assailed

+assailing

+assails

+assassin

+assassin's

+assassinate

+assassinated

+assassinates

+assassinating

+assassination

+assassinations

+assassins

+assault

+assaulted

+assaulter

+assaulting

+assaultive

+assaultively

+assaultiveness

+assaults

+assay

+assayed

+assayer

+assayers

+assaying

+assemblage

+assemblage's

+assemblages

+assemble

+assembled

+assembler

+assemblers

+assembles

+assemblies

+assembling

+assembly

+assembly's

+assen

+assent

+assented

+assenter

+assenting

+assents

+assert

+asserted

+asserter

+asserters

+asserting

+assertion

+assertion's

+assertions

+assertive

+assertively

+assertiveness

+asserts

+asses

+assess

+assessed

+assesses

+assessing

+assessment

+assessment's

+assessments

+assessor

+assessor's

+assessors

+asset

+asset's

+assets

+assiduity

+assiduous

+assiduously

+assiduousness

+assign

+assignable

+assigned

+assignee

+assignee's

+assignees

+assigner

+assigners

+assigning

+assignment

+assignment's

+assignments

+assigns

+assimilate

+assimilated

+assimilates

+assimilating

+assimilation

+assimilations

+assimilative

+assist

+assistance

+assistances

+assistant

+assistant's

+assistants

+assistantship

+assistantships

+assisted

+assister

+assisting

+assists

+associate

+associated

+associates

+associating

+association

+association's

+associational

+associations

+associative

+associatively

+associativities

+associativity

+associator

+associator's

+associators

+assonance

+assonant

+assort

+assorted

+assorter

+assorting

+assortment

+assortment's

+assortments

+assorts

+assuage

+assuaged

+assuages

+assuaging

+assume

+assumed

+assumer

+assumes

+assuming

+assumption

+assumption's

+assumptions

+assurance

+assurance's

+assurances

+assure

+assured

+assuredly

+assuredness

+assurer

+assurers

+assures

+assuring

+assuringly

+astatine

+aster

+aster's

+asterisk

+asterisk's

+asterisks

+asteroid

+asteroid's

+asteroidal

+asteroids

+asters

+asthma

+astonish

+astonished

+astonishes

+astonishing

+astonishingly

+astonishment

+astound

+astounded

+astounding

+astoundingly

+astounds

+astral

+astrally

+astray

+astride

+astringency

+astringent

+astringently

+astronaut

+astronaut's

+astronautics

+astronauts

+astronomer

+astronomer's

+astronomers

+astronomical

+astronomically

+astronomy

+astrophysical

+astrophysics

+astute

+astutely

+astuteness

+asunder

+asylum

+asylums

+asymmetric

+asymmetrical

+asymmetrically

+asymmetries

+asymmetry

+asymptomatically

+asymptote

+asymptote's

+asymptotes

+asymptotic

+asymptotically

+asymptoticly

+asynchronism

+asynchronous

+asynchronously

+asynchrony

+at

+atavistic

+ate

+atemporal

+atheism

+atheist

+atheist's

+atheistic

+atheists

+atherosclerosis

+athlete

+athlete's

+athletes

+athletic

+athleticism

+athletics

+atlas

+atmosphere

+atmosphere's

+atmosphered

+atmospheres

+atmospheric

+atmospherics

+atoll

+atoll's

+atolls

+atom

+atom's

+atomic

+atomically

+atomics

+atoms

+atonal

+atonally

+atone

+atoned

+atonement

+atones

+atoning

+atop

+atrocious

+atrociously

+atrociousness

+atrocities

+atrocity

+atrocity's

+atrophic

+atrophied

+atrophies

+atrophy

+atrophying

+attach

+attache

+attached

+attacher

+attachers

+attaches

+attaching

+attachment

+attachment's

+attachments

+attack

+attackable

+attacked

+attacker

+attacker's

+attackers

+attacking

+attacks

+attain

+attainable

+attainableness

+attainably

+attained

+attainer

+attainers

+attaining

+attainment

+attainment's

+attainments

+attains

+attempt

+attempted

+attempter

+attempters

+attempting

+attempts

+attend

+attendance

+attendance's

+attendances

+attendant

+attendant's

+attendants

+attended

+attendee

+attendee's

+attendees

+attender

+attenders

+attending

+attends

+attention

+attention's

+attentional

+attentionality

+attentions

+attentive

+attentively

+attentiveness

+attenuate

+attenuated

+attenuates

+attenuating

+attenuation

+attenuator

+attenuator's

+attenuators

+attest

+attested

+attester

+attesting

+attests

+attic

+attic's

+attics

+attire

+attired

+attires

+attiring

+attitude

+attitude's

+attitudes

+attitudinal

+attitudinally

+attorney

+attorney's

+attorneys

+attract

+attracted

+attracting

+attraction

+attraction's

+attractions

+attractive

+attractively

+attractiveness

+attractor

+attractor's

+attractors

+attracts

+attributable

+attribute

+attributed

+attributer

+attributes

+attributing

+attribution

+attributions

+attributive

+attributively

+attrition

+attune

+attuned

+attunes

+attuning

+atypical

+atypically

+auburn

+auction

+auctioned

+auctioneer

+auctioneer's

+auctioneers

+auctioning

+audacious

+audaciously

+audaciousness

+audacity

+audible

+audibly

+audience

+audience's

+audiences

+audio

+audiogram

+audiogram's

+audiograms

+audiological

+audiologist

+audiologist's

+audiologists

+audiology

+audiometer

+audiometer's

+audiometers

+audiometric

+audiometry

+audit

+audited

+auditing

+audition

+audition's

+auditioned

+auditioning

+auditions

+auditive

+auditor

+auditor's

+auditorium

+auditoriums

+auditors

+auditory

+audits

+auger

+auger's

+augers

+aught

+augment

+augmentation

+augmentations

+augmented

+augmenter

+augmenting

+augments

+augur

+augurs

+august

+augustly

+augustness

+aunt

+aunt's

+auntly

+aunts

+aura

+aura's

+aural

+aurally

+auras

+aureole

+aureomycin

+aurora

+auscultate

+auscultated

+auscultates

+auscultating

+auscultation

+auscultations

+auspice

+auspices

+auspicious

+auspiciously

+auspiciousness

+austere

+austerely

+austereness

+austerity

+authentic

+authentically

+authenticate

+authenticated

+authenticates

+authenticating

+authentication

+authentications

+authenticator

+authenticators

+authenticity

+author

+author's

+authored

+authoring

+authoritarian

+authoritarianism

+authoritative

+authoritatively

+authoritativeness

+authorities

+authority

+authority's

+authors

+authorship

+autism

+autistic

+auto

+auto's

+autobiographic

+autobiographical

+autobiographically

+autobiographies

+autobiography

+autobiography's

+autocollimator

+autocorrelate

+autocorrelated

+autocorrelates

+autocorrelating

+autocorrelation

+autocorrelations

+autocracies

+autocracy

+autocrat

+autocrat's

+autocratic

+autocratically

+autocrats

+autodial

+autofluorescence

+autograph

+autographed

+autographing

+autographs

+automata

+automate

+automated

+automates

+automatic

+automatically

+automatics

+automating

+automation

+automaton

+automatons

+automobile

+automobile's

+automobiles

+automotive

+autonavigator

+autonavigator's

+autonavigators

+autonomic

+autonomous

+autonomously

+autonomy

+autopilot

+autopilot's

+autopilots

+autopsied

+autopsies

+autopsy

+autoregressive

+autorepeat

+autorepeating

+autorepeats

+autos

+autosuggestibility

+autotransformer

+autumn

+autumn's

+autumnal

+autumnally

+autumns

+auxiliaries

+auxiliary

+avail

+availabilities

+availability

+available

+availableness

+availably

+availed

+availer

+availers

+availing

+avails

+avalanche

+avalanched

+avalanches

+avalanching

+avant

+avarice

+avaricious

+avariciously

+avariciousness

+avenge

+avenged

+avenger

+avenges

+avenging

+avenue

+avenue's

+avenues

+aver

+average

+averaged

+averagely

+averageness

+averages

+averaging

+averred

+averrer

+averring

+avers

+averse

+aversely

+averseness

+aversion

+aversion's

+aversions

+aversive

+avert

+averted

+averting

+averts

+avian

+aviaries

+aviary

+aviation

+aviator

+aviator's

+aviators

+avid

+avidity

+avidly

+avidness

+avionic

+avionics

+avocado

+avocados

+avocation

+avocation's

+avocations

+avoid

+avoidable

+avoidably

+avoidance

+avoided

+avoider

+avoiders

+avoiding

+avoids

+avouch

+avow

+avowed

+avowedly

+avower

+avows

+await

+awaited

+awaiting

+awaits

+awake

+awaked

+awaken

+awakened

+awakener

+awakening

+awakens

+awakes

+awaking

+award

+awarded

+awarder

+awarders

+awarding

+awards

+aware

+awareness

+awash

+away

+awayness

+awe

+awed

+awesome

+awesomely

+awesomeness

+awful

+awfully

+awfulness

+awhile

+awhiles

+awing

+awkward

+awkwardly

+awkwardness

+awl

+awl's

+awls

+awning

+awning's

+awninged

+awnings

+awoke

+awry

+ax

+axe

+axed

+axer

+axers

+axes

+axial

+axially

+axing

+axiological

+axiologically

+axiom

+axiom's

+axiomatic

+axiomatically

+axiomatics

+axioms

+axion

+axion's

+axions

+axis

+axle

+axle's

+axles

+axolotl

+axolotl's

+axolotls

+axon

+axon's

+axons

+aye

+ayer

+ayers

+ayes

+azalea

+azalea's

+azaleas

+azimuth

+azimuth's

+azimuths

+azure

+babble

+babbled

+babbler

+babbles

+babbling

+babe

+babe's

+babes

+babied

+babies

+baby

+baby's

+babyhood

+babying

+babyish

+babysit

+babysits

+babysitter

+babysitters

+baccalaureate

+bachelor

+bachelor's

+bachelors

+bacilli

+bacillus

+back

+backache

+backache's

+backaches

+backbone

+backbone's

+backbones

+backdrop

+backdrop's

+backdrops

+backed

+backer

+backers

+background

+background's

+backgrounds

+backing

+backlash

+backlasher

+backlog

+backlog's

+backlogs

+backpack

+backpack's

+backpacker

+backpackers

+backpacks

+backplane

+backplane's

+backplanes

+backs

+backscatter

+backscattered

+backscattering

+backscatters

+backslash

+backslashed

+backslashes

+backslashing

+backspace

+backspaced

+backspaces

+backspacing

+backstabber

+backstabbing

+backstage

+backstairs

+backstitch

+backstitched

+backstitches

+backstitching

+backtrack

+backtracked

+backtracker

+backtrackers

+backtracking

+backtracks

+backup

+backups

+backward

+backwardly

+backwardness

+backwards

+backwater

+backwater's

+backwaters

+backwoods

+backyard

+backyard's

+backyards

+bacon

+baconer

+bacteria

+bacterial

+bacterially

+bacterium

+bad

+bade

+baden

+badge

+badged

+badger

+badger's

+badgered

+badgering

+badgers

+badges

+badging

+badlands

+badly

+badminton

+badness

+bads

+baffle

+baffled

+baffler

+bafflers

+baffles

+baffling

+bafflingly

+bag

+bag's

+bagatelle

+bagatelle's

+bagatelles

+bagel

+bagel's

+bagels

+baggage

+bagged

+bagger

+bagger's

+baggers

+baggier

+baggies

+bagginess

+bagging

+baggy

+bagpipe

+bagpipe's

+bagpiper

+bagpipes

+bags

+bah

+bail

+bailer

+bailiff

+bailiff's

+bailiffs

+bailing

+bailly

+bait

+baited

+baiter

+baiting

+baits

+bake

+baked

+baker

+bakeries

+bakers

+bakery

+bakery's

+bakes

+baking

+bakings

+baklava

+balalaika

+balalaika's

+balalaikas

+balance

+balanced

+balancedness

+balancer

+balancers

+balances

+balancing

+balconied

+balconies

+balcony

+balcony's

+bald

+balder

+balding

+baldly

+baldness

+bale

+baled

+baleful

+balefully

+balefulness

+baler

+balers

+bales

+baling

+balk

+balked

+balker

+balkier

+balkiness

+balking

+balks

+balky

+ball

+ballad

+ballad's

+ballads

+ballast

+ballast's

+ballasts

+balled

+baller

+ballerina

+ballerina's

+ballerinas

+ballers

+ballet

+ballet's

+ballets

+balling

+ballistic

+ballistics

+balloon

+ballooned

+ballooner

+ballooners

+ballooning

+balloons

+ballot

+ballot's

+balloted

+balloter

+balloting

+ballots

+ballplayer

+ballplayer's

+ballplayers

+ballroom

+ballroom's

+ballrooms

+balls

+ballyhoo

+balm

+balm's

+balmier

+balminess

+balms

+balmy

+balsa

+balsam

+balsams

+balustrade

+balustrade's

+balustrades

+bamboo

+bamboos

+ban

+ban's

+banal

+banally

+banana

+banana's

+bananas

+band

+bandage

+bandaged

+bandager

+bandages

+bandaging

+banded

+bander

+bandied

+bandies

+banding

+bandit

+bandit's

+bandits

+bandpass

+bands

+bandstand

+bandstand's

+bandstands

+bandwagon

+bandwagon's

+bandwagons

+bandwidth

+bandwidths

+bandy

+bandying

+bane

+baneful

+banefully

+bang

+banged

+banger

+banging

+bangle

+bangle's

+bangles

+bangs

+baning

+banish

+banished

+banisher

+banishes

+banishing

+banishment

+banister

+banister's

+banisters

+banjo

+banjo's

+banjos

+bank

+banked

+banker

+bankers

+banking

+bankrupt

+bankruptcies

+bankruptcy

+bankruptcy's

+bankrupted

+bankrupting

+bankrupts

+banks

+banned

+banner

+banner's

+banners

+banning

+banquet

+banqueted

+banqueter

+banqueting

+banquetings

+banquets

+bans

+banshee

+banshee's

+banshees

+bantam

+banter

+bantered

+banterer

+bantering

+banteringly

+banters

+baptism

+baptism's

+baptismal

+baptismally

+baptisms

+baptist

+baptist's

+baptistery

+baptistries

+baptistry

+baptistry's

+baptists

+bar

+bar's

+barb

+barbarian

+barbarian's

+barbarians

+barbaric

+barbarities

+barbarity

+barbarous

+barbarously

+barbarousness

+barbecue

+barbecued

+barbecuer

+barbecues

+barbecuing

+barbed

+barbedness

+barbell

+barbell's

+barbells

+barber

+barbered

+barbering

+barbers

+barbital

+barbiturate

+barbiturates

+barbs

+bard

+bard's

+bards

+bare

+bared

+barefoot

+barefooted

+barely

+bareness

+barer

+bares

+barest

+barflies

+barfly

+barfly's

+bargain

+bargained

+bargainer

+bargaining

+bargains

+barge

+barged

+barges

+barging

+baring

+baritone

+baritone's

+baritones

+barium

+bark

+barked

+barker

+barkers

+barking

+barks

+barley

+barn

+barn's

+barns

+barnstorm

+barnstormed

+barnstormer

+barnstorming

+barnstorms

+barnyard

+barnyard's

+barnyards

+barometer

+barometer's

+barometers

+barometric

+baron

+baron's

+baroness

+baronial

+baronies

+barons

+barony

+barony's

+baroque

+baroquely

+baroqueness

+barrack

+barracker

+barracks

+barracuda

+barracuda's

+barracudas

+barrage

+barrage's

+barraged

+barrages

+barraging

+barred

+barrel

+barrel's

+barrels

+barren

+barrenness

+barrens

+barricade

+barricade's

+barricades

+barrier

+barrier's

+barriers

+barring

+barringer

+barrow

+barrows

+bars

+bartender

+bartender's

+bartenders

+barter

+bartered

+barterer

+bartering

+barters

+bas

+basal

+basally

+basalt

+base

+baseball

+baseball's

+baseballs

+baseboard

+baseboard's

+baseboards

+based

+baseless

+baseline

+baseline's

+baselines

+basely

+baseman

+basement

+basement's

+basements

+baseness

+baser

+bases

+basest

+bash

+bashed

+basher

+bashes

+bashful

+bashfully

+bashfulness

+bashing

+basic

+basically

+basics

+basil

+basin

+basin's

+basined

+basing

+basins

+basis

+bask

+basked

+basket

+basket's

+basketball

+basketball's

+basketballs

+baskets

+basking

+bass

+bass's

+basses

+basset

+bassinet

+bassinet's

+bassinets

+basso

+bastard

+bastard's

+bastardly

+bastards

+baste

+basted

+baster

+bastes

+basting

+bastion

+bastion's

+bastioned

+bastions

+bat

+bat's

+batch

+batched

+batcher

+batches

+batching

+bated

+bater

+bath

+bathe

+bathed

+bather

+bathers

+bathes

+bathing

+bathos

+bathrobe

+bathrobe's

+bathrobes

+bathroom

+bathroom's

+bathroomed

+bathrooms

+baths

+bathtub

+bathtub's

+bathtubs

+bating

+baton

+baton's

+batons

+bats

+battalion

+battalion's

+battalions

+batted

+batten

+battened

+battening

+battens

+batter

+battered

+batteries

+battering

+batters

+battery

+battery's

+batting

+battle

+battled

+battlefield

+battlefield's

+battlefields

+battlefront

+battlefront's

+battlefronts

+battleground

+battleground's

+battlegrounds

+battlement

+battlement's

+battlemented

+battlements

+battler

+battlers

+battles

+battleship

+battleship's

+battleships

+battling

+bauble

+bauble's

+baubles

+baud

+bauds

+bauxite

+bawdier

+bawdiness

+bawdy

+bawl

+bawled

+bawler

+bawling

+bawls

+bay

+bayed

+baying

+bayly

+bayonet

+bayonet's

+bayoneted

+bayoneting

+bayonets

+bayou

+bayou's

+bayous

+bays

+bazaar

+bazaar's

+bazaars

+be

+beach

+beached

+beaches

+beachhead

+beachhead's

+beachheads

+beaching

+beacon

+beacon's

+beaconed

+beaconing

+beacons

+bead

+beaded

+beading

+beadle

+beadle's

+beadles

+beads

+beady

+beagle

+beagle's

+beagles

+beak

+beaked

+beaker

+beakers

+beaks

+beam

+beamed

+beamer

+beamers

+beaming

+beams

+bean

+beanbag

+beanbag's

+beanbags

+beaned

+beaner

+beaners

+beaning

+beans

+bear

+bearable

+bearably

+beard

+bearded

+beardedness

+beardless

+beards

+bearer

+bearers

+bearing

+bearings

+bearish

+bearishly

+bearishness

+bears

+beast

+beastings

+beastlier

+beastliness

+beastly

+beasts

+beat

+beatable

+beatably

+beaten

+beater

+beaters

+beatific

+beatification

+beatify

+beating

+beatings

+beatitude

+beatitude's

+beatitudes

+beatnik

+beatnik's

+beatniks

+beats

+beau

+beau's

+beaus

+beauteous

+beauteously

+beauteousness

+beauties

+beautification

+beautifications

+beautified

+beautifier

+beautifiers

+beautifies

+beautiful

+beautifully

+beautifulness

+beautify

+beautifying

+beauty

+beauty's

+beaver

+beaver's

+beavers

+becalm

+becalmed

+becalming

+becalms

+became

+because

+beck

+beckon

+beckoned

+beckoning

+beckons

+become

+becomes

+becoming

+becomingly

+bed

+bed's

+bedazzle

+bedazzled

+bedazzlement

+bedazzles

+bedazzling

+bedbug

+bedbug's

+bedbugs

+bedded

+bedder

+bedder's

+bedders

+bedding

+bedevil

+bedevils

+bedfast

+bedlam

+bedpost

+bedpost's

+bedposts

+bedraggle

+bedraggled

+bedridden

+bedrock

+bedrock's

+bedroom

+bedroom's

+bedroomed

+bedrooms

+beds

+bedside

+bedspread

+bedspread's

+bedspreads

+bedspring

+bedspring's

+bedsprings

+bedstead

+bedstead's

+bedsteads

+bedtime

+bee

+beech

+beechen

+beecher

+beef

+beefed

+beefer

+beefers

+beefier

+beefing

+beefs

+beefsteak

+beefy

+beehive

+beehive's

+beehives

+been

+beens

+beep

+beeped

+beeper

+beeping

+beeps

+beer

+beers

+bees

+beet

+beet's

+beetle

+beetle's

+beetled

+beetles

+beetling

+beets

+befall

+befallen

+befalling

+befalls

+befell

+befit

+befit's

+befits

+befitted

+befitting

+befittingly

+befog

+befogged

+befogging

+befogs

+before

+beforehand

+befoul

+befouled

+befouling

+befouls

+befriend

+befriended

+befriending

+befriends

+befuddle

+befuddled

+befuddles

+befuddling

+beg

+began

+beget

+begets

+begetting

+beggar

+beggared

+beggaring

+beggarliness

+beggarly

+beggars

+beggary

+begged

+begging

+begin

+beginner

+beginner's

+beginners

+beginning

+beginning's

+beginnings

+begins

+begot

+begotten

+begrudge

+begrudged

+begrudger

+begrudges

+begrudging

+begrudgingly

+begs

+beguile

+beguiled

+beguiler

+beguiles

+beguiling

+beguilingly

+begun

+behalf

+behave

+behaved

+behaver

+behaves

+behaving

+behead

+beheading

+beheld

+behest

+behind

+behold

+beholden

+beholder

+beholders

+beholding

+beholds

+beige

+being

+beings

+belated

+belatedly

+belatedness

+belay

+belayed

+belaying

+belays

+belch

+belched

+belches

+belching

+belfries

+belfry

+belfry's

+belie

+belied

+belief

+belief's

+beliefs

+belier

+belies

+believability

+believable

+believably

+believe

+believed

+believer

+believers

+believes

+believing

+belittle

+belittled

+belittler

+belittles

+belittling

+bell

+bell's

+bellboy

+bellboy's

+bellboys

+belle

+belle's

+belles

+bellhop

+bellhop's

+bellhops

+bellicose

+bellicosely

+bellicoseness

+bellicosity

+bellied

+bellies

+belligerence

+belligerent

+belligerent's

+belligerently

+belligerents

+bellman

+bellmen

+bellow

+bellowed

+bellowing

+bellows

+bells

+bellwether

+bellwether's

+bellwethers

+belly

+belly's

+bellyful

+bellying

+belong

+belonged

+belonging

+belongingness

+belongings

+belongs

+beloved

+below

+belt

+belted

+belting

+belts

+bely

+belying

+bemoan

+bemoaned

+bemoaning

+bemoans

+bench

+benched

+bencher

+benches

+benching

+benchmark

+benchmark's

+benchmarking

+benchmarks

+bend

+bendable

+bended

+bender

+benders

+bending

+bends

+beneath

+benediction

+benediction's

+benedictions

+benefactor

+benefactor's

+benefactors

+beneficence

+beneficences

+beneficial

+beneficially

+beneficialness

+beneficiaries

+beneficiary

+benefit

+benefited

+benefiter

+benefiters

+benefiting

+benefits

+benevolence

+benevolent

+benevolently

+benevolentness

+benighted

+benightedly

+benightedness

+benign

+benignly

+bent

+bents

+benzene

+bequeath

+bequeathed

+bequeathes

+bequeathing

+bequest

+bequest's

+bequests

+berate

+berated

+berates

+berating

+bereave

+bereaved

+bereavement

+bereavements

+bereaves

+bereaving

+bereft

+beret

+beret's

+berets

+beribboned

+beriberi

+berkelium

+berried

+berries

+berry

+berry's

+berrying

+berth

+berthed

+berthing

+berthings

+berths

+beryl

+beryllium

+bes

+beseech

+beseeches

+beseeching

+beseechingly

+beset

+besets

+besetting

+beside

+besides

+besiege

+besieged

+besieger

+besiegers

+besieging

+besmirch

+besmirched

+besmirches

+besmirching

+besotted

+besotting

+besought

+bespeak

+bespeaks

+bespectacled

+best

+bested

+bester

+bestial

+bestially

+besting

+bestow

+bestowal

+bestowed

+bests

+bestseller

+bestseller's

+bestsellers

+bestselling

+bet

+bet's

+beta

+betas

+beth

+betide

+betray

+betrayal

+betrayed

+betrayer

+betraying

+betrays

+betroth

+betrothal

+betrothals

+betrothed

+bets

+better

+bettered

+bettering

+betterment

+betterments

+betters

+betting

+between

+betweenness

+betwixt

+bevel

+bevels

+beverage

+beverage's

+beverages

+bevies

+bevy

+bewail

+bewailed

+bewailing

+bewails

+beware

+bewhiskered

+bewilder

+bewildered

+bewilderedly

+bewilderedness

+bewildering

+bewilderingly

+bewilderment

+bewilders

+bewitch

+bewitched

+bewitches

+bewitching

+bewitchingly

+beyond

+biannual

+bias

+biased

+biases

+biasing

+biasness

+bib

+bib's

+bibbed

+bibbing

+bible

+bible's

+bibles

+biblical

+biblically

+bibliographic

+bibliographical

+bibliographically

+bibliographics

+bibliographies

+bibliography

+bibliography's

+bibliophile

+bibliophiles

+bibs

+bicameral

+bicarbonate

+bicentennial

+biceps

+bicker

+bickered

+bickerer

+bickering

+bickers

+biconcave

+biconvex

+bicycle

+bicycled

+bicycler

+bicyclers

+bicycles

+bicycling

+bid

+bid's

+biddable

+bidden

+bidder

+bidder's

+bidders

+biddies

+bidding

+biddy

+bide

+bided

+bider

+bides

+biding

+bidirectional

+bids

+biennial

+biennially

+biennium

+bier

+bifocal

+bifocals

+bifurcate

+bifurcated

+bifurcately

+bifurcates

+bifurcating

+bifurcation

+bifurcations

+big

+bigger

+biggest

+bight

+bight's

+bights

+bigly

+bigness

+bigot

+bigot's

+bigoted

+bigotedly

+bigoting

+bigotry

+bigots

+bijection

+bijection's

+bijections

+bijective

+bijectively

+bike

+bike's

+biked

+biker

+biker's

+bikers

+bikes

+biking

+bikini

+bikini's

+bikinied

+bikinis

+bilabial

+bilateral

+bilaterally

+bilateralness

+bile

+bilge

+bilge's

+bilged

+bilges

+bilging

+bilinear

+bilingual

+bilingually

+bilinguals

+bilk

+bilked

+bilker

+bilking

+bilks

+bill

+billboard

+billboard's

+billboards

+billed

+biller

+billers

+billet

+billeted

+billeting

+billets

+billiard

+billiards

+billing

+billings

+billion

+billions

+billionth

+billow

+billowed

+billowing

+billows

+bills

+bimodal

+bimolecular

+bimolecularly

+bimonthlies

+bimonthly

+bin

+bin's

+binaries

+binary

+binaural

+binaurally

+bind

+binded

+binder

+binders

+binding

+bindingly

+bindingness

+bindings

+binds

+bing

+binge

+bingen

+binges

+bingo

+bingos

+binocular

+binocularly

+binoculars

+binomial

+binomially

+bins

+binuclear

+biochemical

+biochemically

+biochemistry

+biofeedback

+biographer

+biographer's

+biographers

+biographic

+biographical

+biographically

+biographies

+biography

+biography's

+biological

+biologically

+biologicals

+biologist

+biologist's

+biologists

+biology

+biomedical

+biomedicine

+biopsies

+biopsy

+bipartisan

+bipartite

+bipartitely

+bipartition

+biped

+bipeds

+biplane

+biplane's

+biplanes

+bipolar

+biracial

+birch

+birchen

+bircher

+birches

+bird

+bird's

+birdbath

+birdbath's

+birdbaths

+birder

+birdie

+birdied

+birdies

+birdlike

+birds

+birefringence

+birefringent

+birth

+birthday

+birthday's

+birthdays

+birthed

+birthplace

+birthplaces

+birthright

+birthright's

+birthrights

+births

+biscuit

+biscuit's

+biscuits

+bisect

+bisected

+bisecting

+bisection

+bisection's

+bisections

+bisector

+bisector's

+bisectors

+bisects

+bishop

+bishop's

+bishops

+bismuth

+bison

+bison's

+bisons

+bisque

+bisques

+bit

+bit's

+bitblt

+bitblts

+bitch

+bitch's

+bitches

+bite

+biter

+biters

+bites

+biting

+bitingly

+bitmap

+bitmap's

+bitmaps

+bits

+bitser

+bitten

+bitter

+bitterer

+bitterest

+bitterly

+bitterness

+bitters

+bittersweet

+bittersweetly

+bittersweetness

+bituminous

+bitwise

+bivalve

+bivalve's

+bivalved

+bivalves

+bivariate

+bivouac

+bivouacs

+biweekly

+bizarre

+bizarrely

+bizarreness

+blab

+blabbed

+blabbermouth

+blabbermouths

+blabbing

+blabs

+black

+blackberries

+blackberry

+blackberry's

+blackbird

+blackbird's

+blackbirder

+blackbirds

+blackboard

+blackboard's

+blackboards

+blacked

+blacken

+blackened

+blackener

+blackening

+blackens

+blacker

+blackest

+blacking

+blackjack

+blackjack's

+blackjacks

+blacklist

+blacklisted

+blacklister

+blacklisting

+blacklists

+blackly

+blackmail

+blackmailed

+blackmailer

+blackmailers

+blackmailing

+blackmails

+blackness

+blackout

+blackout's

+blackouts

+blacks

+blacksmith

+blacksmith's

+blacksmithing

+blacksmiths

+bladder

+bladder's

+bladders

+blade

+blade's

+bladed

+blades

+blamable

+blame

+blamed

+blameless

+blamelessly

+blamelessness

+blamer

+blamers

+blames

+blaming

+blanch

+blanched

+blancher

+blanches

+blanching

+bland

+blandly

+blandness

+blank

+blanked

+blanker

+blankest

+blanket

+blanketed

+blanketer

+blanketers

+blanketing

+blankets

+blanking

+blankly

+blankness

+blanks

+blare

+blared

+blares

+blaring

+blase

+blaspheme

+blasphemed

+blasphemer

+blasphemes

+blasphemies

+blaspheming

+blasphemous

+blasphemously

+blasphemousness

+blasphemy

+blast

+blasted

+blaster

+blasters

+blasting

+blasts

+blatant

+blatantly

+blatantness

+blaze

+blazed

+blazer

+blazers

+blazes

+blazing

+blazingly

+bleach

+bleached

+bleacher

+bleachers

+bleaches

+bleaching

+bleak

+bleakly

+bleakness

+blear

+bleariness

+bleary

+bleat

+bleater

+bleating

+bleats

+bled

+bleed

+bleeder

+bleeders

+bleeding

+bleedings

+bleeds

+blemish

+blemish's

+blemished

+blemishes

+blemishing

+blend

+blended

+blender

+blenders

+blending

+blends

+bless

+blessed

+blessedly

+blessedness

+blesses

+blessing

+blessings

+blew

+blight

+blighted

+blighter

+blimp

+blimp's

+blimps

+blind

+blinded

+blinder

+blinders

+blindfold

+blindfolded

+blindfolding

+blindfolds

+blinding

+blindingly

+blindly

+blindness

+blinds

+blink

+blinked

+blinker

+blinkered

+blinkering

+blinkers

+blinking

+blinks

+blip

+blip's

+blips

+bliss

+blissful

+blissfully

+blissfulness

+blister

+blistered

+blistering

+blisteringly

+blisters

+blithe

+blithely

+blither

+blithest

+blitz

+blitz's

+blitzes

+blitzkrieg

+blizzard

+blizzard's

+blizzards

+bloat

+bloated

+bloater

+bloaters

+bloating

+bloats

+blob

+blob's

+blobs

+bloc

+bloc's

+block

+block's

+blockade

+blockaded

+blockader

+blockades

+blockading

+blockage

+blockage's

+blockages

+blocked

+blocker

+blockers

+blockhouse

+blockhouses

+blocking

+blocks

+blocs

+bloke

+bloke's

+blokes

+blond

+blond's

+blonde

+blonde's

+blondes

+blonds

+blood

+blooded

+bloodhound

+bloodhound's

+bloodhounds

+bloodied

+bloodiest

+bloodiness

+bloodless

+bloodlessly

+bloodlessness

+bloods

+bloodshed

+bloodshot

+bloodstain

+bloodstain's

+bloodstained

+bloodstains

+bloodstream

+bloody

+bloodying

+bloom

+bloomed

+bloomer

+bloomers

+blooming

+blooms

+blossom

+blossomed

+blossoms

+blot

+blot's

+blots

+blotted

+blotting

+blouse

+blouse's

+blouses

+blousing

+blow

+blowed

+blower

+blowers

+blowfish

+blowing

+blown

+blows

+blowup

+blubber

+blubbered

+blubbering

+bludgeon

+bludgeoned

+bludgeoning

+bludgeons

+blue

+blueberries

+blueberry

+blueberry's

+bluebird

+bluebird's

+bluebirds

+bluebonnet

+bluebonnet's

+bluebonnets

+blued

+bluefish

+bluely

+blueness

+blueprint

+blueprint's

+blueprinted

+blueprinting

+blueprints

+bluer

+blues

+bluest

+bluestocking

+bluff

+bluffed

+bluffer

+bluffing

+bluffly

+bluffness

+bluffs

+bluing

+bluish

+bluishness

+blunder

+blundered

+blunderer

+blundering

+blunderingly

+blunderings

+blunders

+blunt

+blunted

+blunter

+bluntest

+blunting

+bluntly

+bluntness

+blunts

+blur

+blur's

+blurb

+blurred

+blurredly

+blurrier

+blurriness

+blurring

+blurringly

+blurry

+blurs

+blurt

+blurted

+blurter

+blurting

+blurts

+blush

+blushed

+blusher

+blushes

+blushing

+blushingly

+bluster

+blustered

+blusterer

+blustering

+blusteringly

+blusters

+blustery

+boar

+board

+boarded

+boarder

+boarders

+boarding

+boardinghouse

+boardinghouse's

+boardinghouses

+boards

+boast

+boasted

+boaster

+boasters

+boastful

+boastfully

+boastfulness

+boasting

+boastings

+boasts

+boat

+boated

+boater

+boaters

+boathouse

+boathouse's

+boathouses

+boating

+boatload

+boatload's

+boatloads

+boatman

+boatmen

+boats

+boatswain

+boatswain's

+boatswains

+boatyard

+boatyard's

+boatyards

+bob

+bob's

+bobbed

+bobbies

+bobbin

+bobbin's

+bobbing

+bobbins

+bobby

+bobolink

+bobolink's

+bobolinks

+bobs

+bobwhite

+bobwhite's

+bobwhites

+bode

+boded

+bodes

+bodice

+bodied

+bodies

+bodily

+boding

+body

+bodybuilder

+bodybuilder's

+bodybuilders

+bodybuilding

+bodyguard

+bodyguard's

+bodyguards

+bodying

+bog

+bog's

+bogged

+boggle

+boggled

+boggles

+boggling

+bogs

+bogus

+boil

+boiled

+boiler

+boilerplate

+boilers

+boiling

+boils

+boisterous

+boisterously

+boisterousness

+bold

+bolder

+boldest

+boldface

+boldfaced

+boldfaces

+boldfacing

+boldly

+boldness

+boll

+bolster

+bolstered

+bolsterer

+bolstering

+bolsters

+bolt

+bolted

+bolter

+bolting

+bolts

+bomb

+bombard

+bombarded

+bombarding

+bombardment

+bombardments

+bombards

+bombast

+bombaster

+bombastic

+bombed

+bomber

+bombers

+bombing

+bombings

+bombproof

+bombs

+bonanza

+bonanza's

+bonanzas

+bond

+bondage

+bonded

+bonder

+bonders

+bonding

+bonds

+bondsman

+bondsmen

+bone

+boned

+boner

+boners

+bones

+bonfire

+bonfire's

+bonfires

+bong

+bonier

+boning

+bonnet

+bonneted

+bonnets

+bonnier

+bonny

+bonus

+bonus's

+bonuses

+bony

+boo

+boob

+boobies

+booboo

+booby

+book

+bookcase

+bookcase's

+bookcases

+booked

+booker

+bookers

+bookie

+bookie's

+bookies

+booking

+bookings

+bookish

+bookishly

+bookishness

+bookkeeper

+bookkeeper's

+bookkeepers

+bookkeeping

+booklet

+booklet's

+booklets

+books

+bookseller

+bookseller's

+booksellers

+bookshelf

+bookshelf's

+bookshelves

+bookstore

+bookstore's

+bookstores

+boolean

+booleans

+boom

+boomed

+boomer

+boomerang

+boomerang's

+boomerangs

+booming

+booms

+boon

+boor

+boor's

+boorish

+boorishly

+boorishness

+boors

+boos

+boost

+boosted

+booster

+boosting

+boosts

+boot

+booted

+booth

+booths

+booties

+booting

+bootleg

+bootlegged

+bootlegger

+bootlegger's

+bootleggers

+bootlegging

+bootlegs

+boots

+bootstrap

+bootstrap's

+bootstrapped

+bootstrapping

+bootstraps

+booty

+booze

+boozer

+boozing

+borate

+borated

+borates

+borax

+bordello

+bordello's

+bordellos

+border

+bordered

+borderer

+bordering

+borderings

+borderland

+borderland's

+borderlands

+borderline

+borders

+bore

+bored

+boredom

+borer

+borers

+bores

+boric

+boring

+boringly

+boringness

+born

+borne

+boron

+borough

+boroughs

+borrow

+borrowed

+borrower

+borrowers

+borrowing

+borrowings

+borrows

+bosom

+bosom's

+bosoms

+boss

+bossed

+bosses

+bosun

+botanical

+botanically

+botanist

+botanist's

+botanists

+botany

+botch

+botched

+botcher

+botchers

+botches

+botching

+both

+bother

+bothered

+bothering

+bothers

+bothersome

+bottle

+bottled

+bottleneck

+bottleneck's

+bottlenecks

+bottler

+bottlers

+bottles

+bottling

+bottom

+bottomed

+bottomer

+bottoming

+bottomless

+bottomlessly

+bottomlessness

+bottoms

+botulinus

+botulism

+bouffant

+bough

+bough's

+boughed

+boughs

+bought

+boughten

+boulder

+boulder's

+bouldered

+boulders

+boulevard

+boulevard's

+boulevards

+bounce

+bounced

+bouncer

+bouncers

+bounces

+bouncier

+bouncing

+bouncingly

+bouncy

+bound

+boundaries

+boundary

+boundary's

+bounded

+bounden

+bounder

+bounding

+boundless

+boundlessly

+boundlessness

+bounds

+bounteous

+bounteously

+bounteousness

+bountied

+bounties

+bounty

+bounty's

+bouquet

+bouquet's

+bouquets

+bourbon

+bourbons

+bourgeois

+bourgeoisie

+bout

+bout's

+bouts

+bovine

+bovinely

+bovines

+bow

+bowed

+bowel

+bowel's

+bowels

+bowen

+bower

+bowers

+bowing

+bowl

+bowled

+bowler

+bowlers

+bowline

+bowline's

+bowlines

+bowling

+bowls

+bowman

+bows

+bowser

+bowstring

+bowstring's

+bowstrings

+box

+boxcar

+boxcar's

+boxcars

+boxed

+boxer

+boxers

+boxes

+boxing

+boxwood

+boy

+boy's

+boycott

+boycotted

+boycotter

+boycotting

+boycotts

+boyer

+boyfriend

+boyfriend's

+boyfriends

+boyhood

+boyish

+boyishly

+boyishness

+boys

+bra

+bra's

+brace

+braced

+bracelet

+bracelet's

+bracelets

+bracer

+braces

+bracing

+bracket

+bracketed

+bracketing

+brackets

+brackish

+brackishness

+brae

+brae's

+braes

+brag

+bragged

+bragger

+bragging

+brags

+braid

+braided

+braider

+braiding

+braids

+braille

+brain

+brainchild

+brainchild's

+brained

+brainier

+braininess

+braining

+brains

+brainstorm

+brainstorm's

+brainstormer

+brainstorming

+brainstorms

+brainwash

+brainwashed

+brainwasher

+brainwashes

+brainwashing

+brainy

+brake

+braked

+brakes

+braking

+bramble

+bramble's

+brambles

+brambling

+brambly

+bran

+branch

+branched

+branches

+branching

+branchings

+brand

+branded

+brander

+brandied

+brandies

+branding

+brandish

+brandishes

+brandishing

+brands

+brandy

+brandying

+bras

+brash

+brashly

+brashness

+brass

+brassed

+brasses

+brassier

+brassiere

+brassiness

+brassy

+brat

+brat's

+brats

+bravado

+brave

+braved

+bravely

+braveness

+braver

+bravery

+braves

+bravest

+braving

+bravo

+bravoed

+bravoing

+bravos

+bravura

+brawl

+brawled

+brawler

+brawling

+brawls

+brawn

+bray

+brayed

+brayer

+braying

+brays

+braze

+brazed

+brazen

+brazened

+brazening

+brazenly

+brazenness

+brazer

+brazes

+brazier

+brazier's

+braziers

+brazing

+breach

+breached

+breacher

+breachers

+breaches

+breaching

+bread

+breadboard

+breadboard's

+breadboards

+breaded

+breading

+breads

+breadth

+breadwinner

+breadwinner's

+breadwinners

+break

+breakable

+breakables

+breakage

+breakaway

+breakdown

+breakdown's

+breakdowns

+breaker

+breakers

+breakfast

+breakfasted

+breakfaster

+breakfasters

+breakfasting

+breakfasts

+breaking

+breakpoint

+breakpoint's

+breakpointed

+breakpointing

+breakpoints

+breaks

+breakthrough

+breakthrough's

+breakthroughes

+breakthroughs

+breakup

+breakups

+breakwater

+breakwater's

+breakwaters

+breast

+breasted

+breasting

+breasts

+breastwork

+breastwork's

+breastworks

+breath

+breathable

+breathe

+breathed

+breather

+breathers

+breathes

+breathier

+breathing

+breathless

+breathlessly

+breathlessness

+breaths

+breathtaking

+breathtakingly

+breathy

+bred

+breech

+breech's

+breeches

+breeching

+breed

+breeder

+breeding

+breeds

+breeze

+breeze's

+breezed

+breezes

+breezier

+breezily

+breeziness

+breezing

+breezy

+bremsstrahlung

+brethren

+breve

+breves

+brevet

+breveted

+breveting

+brevets

+brevity

+brew

+brewed

+brewer

+breweries

+brewers

+brewery

+brewery's

+brewing

+brews

+briar

+briar's

+briars

+bribe

+bribed

+briber

+bribers

+bribes

+bribing

+brick

+bricked

+bricker

+bricking

+bricklayer

+bricklayer's

+bricklayers

+bricklaying

+bricks

+bridal

+bride

+bride's

+bridegroom

+brides

+bridesmaid

+bridesmaid's

+bridesmaids

+bridge

+bridgeable

+bridged

+bridgehead

+bridgehead's

+bridgeheads

+bridges

+bridgework

+bridgework's

+bridging

+bridle

+bridled

+bridles

+bridling

+brief

+briefcase

+briefcase's

+briefcases

+briefed

+briefer

+briefest

+briefing

+briefing's

+briefings

+briefly

+briefness

+briefs

+brier

+brig

+brig's

+brigade

+brigade's

+brigaded

+brigades

+brigadier

+brigadier's

+brigadiers

+brigading

+brigantine

+bright

+brighten

+brightened

+brightener

+brighteners

+brightening

+brightens

+brighter

+brightest

+brighting

+brightly

+brightness

+brightnesses

+brights

+brigs

+brilliance

+brilliancy

+brilliant

+brilliantly

+brilliantness

+brim

+brimful

+brimmed

+brindle

+brindled

+brine

+briner

+bring

+bringer

+bringers

+bringing

+brings

+brining

+brink

+brinkmanship

+brisk

+brisker

+briskly

+briskness

+bristle

+bristled

+bristles

+bristling

+britches

+brittle

+brittled

+brittlely

+brittleness

+brittler

+brittlest

+brittling

+broach

+broached

+broacher

+broaches

+broaching

+broad

+broadband

+broadcast

+broadcasted

+broadcaster

+broadcasters

+broadcasting

+broadcastings

+broadcasts

+broaden

+broadened

+broadener

+broadeners

+broadening

+broadenings

+broadens

+broader

+broadest

+broadly

+broadness

+broads

+broadside

+brocade

+brocaded

+broccoli

+brochure

+brochure's

+brochures

+broil

+broiled

+broiler

+broilers

+broiling

+broils

+broke

+broken

+brokenly

+brokenness

+broker

+brokerage

+brokers

+bromide

+bromide's

+bromides

+bromine

+bromines

+bronchi

+bronchial

+bronchiole

+bronchiole's

+bronchioles

+bronchitis

+bronchus

+bronze

+bronzed

+bronzer

+bronzes

+bronzing

+brooch

+brooch's

+brooches

+brood

+brooder

+brooding

+broodingly

+broods

+brook

+brooked

+brooks

+broom

+broom's

+broomed

+brooming

+brooms

+broomstick

+broomstick's

+broomsticks

+broth

+brothel

+brothel's

+brothels

+brother

+brother's

+brotherhood

+brotherliness

+brotherly

+brothers

+brought

+brow

+brow's

+browbeat

+browbeaten

+browbeating

+browbeats

+brown

+browned

+browner

+brownest

+brownie

+brownie's

+brownies

+browning

+brownings

+brownish

+brownly

+brownness

+browns

+brows

+browse

+browsed

+browser

+browsers

+browses

+browsing

+bruise

+bruised

+bruiser

+bruisers

+bruises

+bruising

+brunch

+brunches

+brunette

+brunettes

+brunt

+brush

+brushed

+brusher

+brushes

+brushfire

+brushfire's

+brushfires

+brushier

+brushing

+brushlike

+brushy

+brusque

+brusquely

+brusqueness

+brutal

+brutalities

+brutality

+brutally

+brute

+brute's

+brutes

+brutish

+brutishly

+brutishness

+bubble

+bubbled

+bubbler

+bubbles

+bubblier

+bubbling

+bubbly

+buck

+buckboard

+buckboard's

+buckboards

+bucked

+bucker

+bucket

+bucket's

+bucketed

+bucketing

+buckets

+bucking

+buckle

+buckled

+buckler

+buckles

+buckling

+bucks

+buckshot

+buckskin

+buckskins

+buckwheat

+bucolic

+bud

+bud's

+budded

+buddies

+budding

+buddy

+buddy's

+budge

+budged

+budges

+budget

+budgetary

+budgeted

+budgeter

+budgeters

+budgeting

+budgets

+budging

+buds

+buff

+buff's

+buffalo

+buffaloes

+buffer

+buffer's

+buffered

+bufferer

+bufferer's

+bufferers

+buffering

+buffers

+buffet

+buffeted

+buffeting

+buffetings

+buffets

+buffing

+buffoon

+buffoon's

+buffoons

+buffs

+bug

+bug's

+bugged

+bugger

+bugger's

+buggered

+buggering

+buggers

+buggies

+bugging

+buggy

+buggy's

+bugle

+bugled

+bugler

+bugles

+bugling

+bugs

+build

+builded

+builder

+builders

+building

+building's

+buildings

+builds

+buildup

+buildup's

+buildups

+built

+bulb

+bulb's

+bulbed

+bulbs

+bulge

+bulged

+bulges

+bulging

+bulk

+bulked

+bulkhead

+bulkhead's

+bulkheaded

+bulkheads

+bulkier

+bulkiness

+bulks

+bulky

+bull

+bulldog

+bulldog's

+bulldogs

+bulldoze

+bulldozed

+bulldozer

+bulldozers

+bulldozes

+bulldozing

+bulled

+bullet

+bullet's

+bulletin

+bulletin's

+bulletins

+bulletproof

+bulletproofed

+bulletproofing

+bulletproofs

+bullets

+bullied

+bullies

+bulling

+bullion

+bullish

+bullishly

+bullishness

+bulls

+bully

+bullying

+bulwark

+bum

+bum's

+bumble

+bumblebee

+bumblebee's

+bumblebees

+bumbled

+bumbler

+bumblers

+bumbles

+bumbling

+bumblingly

+bummed

+bummer

+bummers

+bumming

+bump

+bumped

+bumper

+bumpers

+bumping

+bumps

+bumptious

+bumptiously

+bumptiousness

+bums

+bun

+bun's

+bunch

+bunched

+bunches

+bunching

+bundle

+bundled

+bundler

+bundles

+bundling

+bungalow

+bungalow's

+bungalows

+bungle

+bungled

+bungler

+bunglers

+bungles

+bungling

+bunglingly

+bunion

+bunion's

+bunions

+bunk

+bunked

+bunker

+bunker's

+bunkered

+bunkering

+bunkers

+bunkhouse

+bunkhouse's

+bunkhouses

+bunking

+bunkmate

+bunkmate's

+bunkmates

+bunks

+bunnies

+bunny

+bunny's

+buns

+bunt

+bunted

+bunter

+bunters

+bunting

+bunts

+buoy

+buoyancy

+buoyant

+buoyantly

+buoyed

+buoying

+buoys

+burden

+burden's

+burdened

+burdening

+burdens

+burdensome

+burdensomely

+burdensomeness

+bureau

+bureau's

+bureaucracies

+bureaucracy

+bureaucracy's

+bureaucrat

+bureaucrat's

+bureaucratic

+bureaucrats

+bureaus

+burgeon

+burgeoned

+burgeoning

+burgeons

+burger

+burgess

+burgess's

+burgesses

+burgher

+burgher's

+burghers

+burglar

+burglar's

+burglaries

+burglarproof

+burglarproofed

+burglarproofing

+burglarproofs

+burglars

+burglary

+burglary's

+burgle

+burgled

+burgles

+burgling

+burial

+buried

+burier

+buries

+burl

+burled

+burler

+burlesque

+burlesqued

+burlesquely

+burlesquer

+burlesques

+burlesquing

+burlier

+burliness

+burly

+burn

+burned

+burner

+burners

+burning

+burningly

+burnings

+burnish

+burnished

+burnisher

+burnishes

+burnishing

+burns

+burnt

+burntly

+burntness

+burp

+burped

+burping

+burps

+burr

+burr's

+burred

+burrer

+burro

+burro's

+burros

+burrow

+burrowed

+burrower

+burrowing

+burrows

+burrs

+bursa

+bursas

+bursitis

+burst

+bursted

+burster

+bursting

+bursts

+bury

+burying

+bus

+busboy

+busboy's

+busboys

+bused

+buses

+bush

+bushed

+bushel

+bushel's

+bushels

+bushes

+bushier

+bushiness

+bushing

+bushings

+bushwhack

+bushwhacked

+bushwhacker

+bushwhacking

+bushwhacks

+bushy

+busied

+busier

+busies

+busiest

+busily

+business

+business's

+businesses

+businesslike

+businessman

+businessmen

+busing

+buss

+bussed

+busses

+bussing

+bust

+bustard

+bustard's

+bustards

+busted

+buster

+busting

+bustle

+bustled

+bustling

+bustlingly

+busts

+busy

+busying

+but

+butane

+butcher

+butcher's

+butchered

+butcherer

+butchering

+butcherly

+butchers

+butchery

+butler

+butler's

+butlers

+butt

+butt's

+butte

+butted

+butter

+buttered

+butterer

+butterers

+butterfat

+butterflies

+butterfly

+butterfly's

+buttering

+butternut

+butters

+buttes

+butting

+buttock

+buttock's

+buttocks

+button

+buttoned

+buttoner

+buttonhole

+buttonhole's

+buttonholer

+buttonholes

+buttoning

+buttons

+buttress

+buttressed

+buttresses

+buttressing

+butts

+butyl

+butyrate

+buxom

+buxomly

+buxomness

+buy

+buyer

+buyer's

+buyers

+buying

+buys

+buzz

+buzzard

+buzzard's

+buzzards

+buzzed

+buzzer

+buzzes

+buzzing

+buzzword

+buzzword's

+buzzwords

+buzzy

+by

+bye

+byers

+byes

+bygone

+bygones

+bylaw

+bylaw's

+bylaws

+byline

+byline's

+byliner

+bylines

+bypass

+bypassed

+bypasses

+bypassing

+byproduct

+byproduct's

+byproducts

+bystander

+bystander's

+bystanders

+byte

+byte's

+bytes

+byway

+byways

+byword

+byword's

+bywords

+cab

+cab's

+cabbage

+cabbage's

+cabbaged

+cabbages

+cabbaging

+caber

+cabin

+cabin's

+cabinet

+cabinet's

+cabinets

+cabins

+cable

+cabled

+cables

+cabling

+cabs

+cache

+cache's

+cached

+cacher

+caches

+caching

+cackle

+cackled

+cackler

+cackles

+cackling

+cacti

+cactus

+cactuses

+cad

+cadence

+cadenced

+cadences

+cadencing

+cafe

+cafe's

+cafes

+cafeteria

+cafeteria's

+cafeterias

+cage

+caged

+cager

+cagers

+cages

+caging

+cajole

+cajoled

+cajoler

+cajoles

+cajoling

+cake

+caked

+cakes

+caking

+calamities

+calamity

+calamity's

+calcium

+calculate

+calculated

+calculatedly

+calculatedness

+calculates

+calculating

+calculation

+calculations

+calculative

+calculator

+calculator's

+calculators

+calculus

+calendar

+calendar's

+calendared

+calendaring

+calendars

+calf

+calfs

+calibrate

+calibrated

+calibrater

+calibrates

+calibrating

+calibration

+calibrations

+calibrator

+calibrators

+calico

+caliph

+caliphs

+call

+called

+caller

+caller's

+callers

+calling

+callous

+calloused

+callously

+callousness

+calls

+calm

+calmed

+calmer

+calmest

+calming

+calmingly

+calmly

+calmness

+calms

+calorie

+calorie's

+calories

+calves

+came

+camel

+camel's

+camels

+camera

+camera's

+cameras

+camion

+camouflage

+camouflaged

+camouflages

+camouflaging

+camp

+campaign

+campaigned

+campaigner

+campaigners

+campaigning

+campaigns

+camped

+camper

+campers

+camping

+camps

+campus

+campus's

+campuses

+can

+can's

+can't

+canal

+canal's

+canals

+canaries

+canary

+canary's

+cancel

+cancellation

+cancellation's

+cancellations

+cancels

+cancer

+cancer's

+cancers

+candid

+candidate

+candidate's

+candidates

+candidly

+candidness

+candied

+candies

+candle

+candled

+candler

+candles

+candlestick

+candlestick's

+candlesticks

+candling

+candy

+candying

+cane

+caned

+caner

+canes

+caning

+canker

+cankered

+cankering

+canned

+canner

+canner's

+canners

+cannibal

+cannibal's

+cannibals

+canning

+cannister

+cannister's

+cannisters

+cannon

+cannon's

+cannoned

+cannoning

+cannons

+cannot

+canoe

+canoe's

+canoed

+canoes

+canon

+canon's

+canonical

+canonically

+canonicals

+canons

+canopy

+cans

+cantankerous

+cantankerously

+cantankerousness

+canto

+canton

+canton's

+cantons

+cantor

+cantor's

+cantors

+cantos

+canvas

+canvas's

+canvaser

+canvases

+canvass

+canvassed

+canvasser

+canvassers

+canvasses

+canvassing

+canyon

+canyon's

+canyons

+cap

+cap's

+capabilities

+capability

+capability's

+capable

+capableness

+capably

+capacious

+capaciously

+capaciousness

+capacitance

+capacitances

+capacities

+capacitive

+capacitively

+capacitor

+capacitor's

+capacitors

+capacity

+cape

+caper

+capered

+capering

+capers

+capes

+capillary

+capita

+capital

+capitalism

+capitalist

+capitalist's

+capitalists

+capitally

+capitals

+capitol

+capitol's

+capitols

+capped

+capping

+capricious

+capriciously

+capriciousness

+caps

+captain

+captained

+captaining

+captains

+caption

+caption's

+captioned

+captioner

+captioning

+captions

+captivate

+captivated

+captivates

+captivating

+captivation

+captive

+captive's

+captives

+captivity

+captor

+captor's

+captors

+capture

+captured

+capturer

+capturers

+captures

+capturing

+car

+car's

+caravan

+caravan's

+caravaner

+caravans

+carbohydrate

+carbohydrate's

+carbohydrates

+carbolic

+carbon

+carbon's

+carbonate

+carbonated

+carbonates

+carbonation

+carbonic

+carbons

+carcass

+carcass's

+carcasses

+card

+card's

+cardboard

+cardboards

+carded

+carder

+cardiac

+cardinal

+cardinalities

+cardinality

+cardinality's

+cardinally

+cardinals

+carding

+cards

+care

+cared

+career

+career's

+careered

+careering

+careers

+carefree

+careful

+carefully

+carefulness

+careless

+carelessly

+carelessness

+carer

+carers

+cares

+caress

+caressed

+caresser

+caresses

+caressing

+caressingly

+caressive

+caressively

+caret

+carets

+cargo

+cargoes

+cargos

+caribou

+caribous

+caring

+carnation

+carnations

+carnival

+carnival's

+carnivals

+carnivorous

+carnivorously

+carnivorousness

+carol

+carol's

+carols

+carpenter

+carpenter's

+carpentered

+carpentering

+carpenters

+carpet

+carpeted

+carpeting

+carpets

+carriage

+carriage's

+carriages

+carried

+carrier

+carriers

+carries

+carrot

+carrot's

+carrots

+carry

+carrying

+carryover

+carryovers

+cars

+cart

+carted

+carter

+carters

+carting

+cartography

+carton

+carton's

+cartons

+cartoon

+cartoon's

+cartoons

+cartridge

+cartridge's

+cartridges

+carts

+carve

+carved

+carver

+carvers

+carves

+carving

+carvings

+cascade

+cascaded

+cascades

+cascading

+case

+cased

+casement

+casement's

+casements

+cases

+cash

+cashed

+casher

+cashers

+cashes

+cashier

+cashier's

+cashiers

+cashing

+casing

+casings

+cask

+cask's

+casket

+casket's

+caskets

+casks

+casserole

+casserole's

+casseroles

+cast

+cast's

+caste

+caste's

+casted

+caster

+casters

+castes

+casteth

+casting

+castings

+castle

+castled

+castles

+castling

+casts

+casual

+casually

+casualness

+casuals

+casualties

+casualty

+casualty's

+cat

+cat's

+catalyst

+catalyst's

+catalysts

+cataract

+cataracts

+catastrophe

+catastrophe's

+catastrophes

+catastrophic

+catch

+catchable

+catcher

+catcher's

+catchers

+catches

+catching

+categorical

+categorically

+categories

+category

+category's

+cater

+catered

+caterer

+catering

+caterpillar

+caterpillar's

+caterpillars

+caters

+cathedral

+cathedral's

+cathedrals

+catheter

+catheters

+cathode

+cathode's

+cathodes

+catholic

+catholic's

+catholics

+cats

+catsup

+cattle

+caught

+causal

+causality

+causally

+causation

+causation's

+causations

+cause

+caused

+causer

+causes

+causeway

+causeway's

+causeways

+causing

+caustic

+causticly

+caustics

+caution

+cautioned

+cautioner

+cautioners

+cautioning

+cautionings

+cautions

+cautious

+cautiously

+cautiousness

+cavalier

+cavalierly

+cavalierness

+cavalry

+cave

+caveat

+caveat's

+caveats

+caved

+caver

+cavern

+cavern's

+caverns

+caves

+caving

+cavities

+cavity

+cavity's

+caw

+cawed

+cawing

+caws

+cease

+ceased

+ceaseless

+ceaselessly

+ceaselessness

+ceases

+ceasing

+cedar

+ceiling

+ceiling's

+ceilinged

+ceilings

+celebrate

+celebrated

+celebratedness

+celebrates

+celebrating

+celebration

+celebrations

+celebratory

+celebrities

+celebrity

+celebrity's

+celery

+celestial

+celestially

+celibate

+celibates

+cell

+cellar

+cellar's

+cellared

+cellarer

+cellaring

+cellars

+celled

+cellist

+cellist's

+cellists

+cells

+cellular

+cellularly

+cement

+cemented

+cementer

+cementing

+cements

+cemeteries

+cemetery

+cemetery's

+censor

+censored

+censoring

+censors

+censorship

+censure

+censured

+censurer

+censures

+censuring

+census

+census's

+censuses

+cent

+centipede

+centipede's

+centipedes

+central

+centrally

+centrals

+centrifuge

+centrifuge's

+centrifuged

+centrifuges

+centrifuging

+centripetal

+centripetally

+cents

+centuries

+century

+century's

+cereal

+cereal's

+cereals

+cerebral

+cerebrally

+ceremonial

+ceremonially

+ceremonialness

+ceremonies

+ceremony

+ceremony's

+certain

+certainly

+certainties

+certainty

+certifiable

+certificate

+certificated

+certificates

+certificating

+certification

+certifications

+certified

+certifier

+certifiers

+certifies

+certify

+certifying

+cessation

+cessation's

+cessations

+chafe

+chafer

+chaff

+chaffer

+chaffered

+chafferer

+chaffering

+chaffing

+chafing

+chagrin

+chagrined

+chagrining

+chagrins

+chain

+chained

+chaining

+chains

+chair

+chaired

+chairing

+chairman

+chairmanship

+chairmanships

+chairmen

+chairperson

+chairperson's

+chairpersons

+chairs

+chalice

+chalice's

+chaliced

+chalices

+chalk

+chalked

+chalking

+chalks

+challenge

+challenged

+challenger

+challengers

+challenges

+challenging

+challengingly

+chamber

+chambered

+chamberer

+chamberers

+chambering

+chamberlain

+chamberlain's

+chamberlains

+chambers

+champagne

+champaign

+champion

+championed

+championing

+champions

+championship

+championship's

+championships

+chance

+chanced

+chancellor

+chancellors

+chances

+chancing

+chandelier

+chandelier's

+chandeliers

+change

+changeability

+changeable

+changeableness

+changeably

+changed

+changeover

+changeover's

+changeovers

+changer

+changers

+changes

+changing

+channel

+channels

+chant

+chanted

+chanter

+chanticleer

+chanticleer's

+chanticleers

+chanting

+chants

+chaos

+chaotic

+chap

+chap's

+chapel

+chapel's

+chapels

+chaperon

+chaperoned

+chaplain

+chaplain's

+chaplains

+chaps

+chapter

+chapter's

+chaptered

+chaptering

+chapters

+char

+character

+character's

+charactered

+charactering

+characteristic

+characteristic's

+characteristically

+characteristics

+characters

+charcoal

+charcoaled

+charcoals

+charge

+chargeable

+chargeableness

+charged

+charger

+chargers

+charges

+charging

+charing

+chariot

+chariot's

+chariots

+charitable

+charitableness

+charities

+charity

+charity's

+charm

+charmed

+charmer

+charmers

+charming

+charmingly

+charms

+chars

+chart

+chartable

+charted

+charter

+chartered

+charterer

+charterers

+chartering

+charters

+charting

+chartings

+charts

+chase

+chased

+chaser

+chasers

+chases

+chasing

+chasm

+chasm's

+chasms

+chaste

+chastely

+chasteness

+chaster

+chastest

+chastise

+chastised

+chastiser

+chastisers

+chastises

+chastising

+chat

+chateau

+chateau's

+chateaus

+chats

+chatter

+chattered

+chatterer

+chatterers

+chattering

+chatterly

+chatters

+chauffeur

+chauffeured

+chauffeuring

+chauffeurs

+chauvinism

+chauvinism's

+chauvinist

+chauvinist's

+chauvinistic

+chauvinists

+cheap

+cheapen

+cheapened

+cheapening

+cheapens

+cheaper

+cheapest

+cheaply

+cheapness

+cheat

+cheated

+cheater

+cheaters

+cheating

+cheats

+check

+checkable

+checked

+checker

+checkered

+checkering

+checkers

+checking

+checkout

+checkouts

+checkpoint

+checkpoint's

+checkpoints

+checks

+checksum

+checksum's

+checksums

+cheek

+cheek's

+cheeks

+cheer

+cheered

+cheerer

+cheerers

+cheerful

+cheerfully

+cheerfulness

+cheerier

+cheerily

+cheeriness

+cheering

+cheerless

+cheerlessly

+cheerlessness

+cheerly

+cheers

+cheery

+cheese

+cheese's

+cheesed

+cheeses

+cheesing

+chef

+chef's

+chefs

+chemical

+chemically

+chemicals

+chemise

+chemises

+chemist

+chemist's

+chemistries

+chemistry

+chemists

+cherish

+cherished

+cherisher

+cherishes

+cherishing

+cherries

+cherry

+cherry's

+cherub

+cherub's

+cherubim

+cherubs

+chess

+chest

+chester

+chestnut

+chestnut's

+chestnuts

+chests

+chew

+chewed

+chewer

+chewers

+chewing

+chews

+chick

+chickadee

+chickadee's

+chickadees

+chicken

+chickened

+chickening

+chickens

+chicks

+chide

+chided

+chides

+chiding

+chief

+chief's

+chiefly

+chiefs

+chieftain

+chieftain's

+chieftains

+chiffon

+child

+child's

+childhood

+childhoods

+childish

+childishly

+childishness

+childly

+children

+children's

+chill

+chilled

+chiller

+chillers

+chillier

+chillies

+chilliness

+chilling

+chillingly

+chillness

+chills

+chilly

+chime

+chime's

+chimed

+chimer

+chimes

+chiming

+chimney

+chimney's

+chimneyed

+chimneys

+chin

+chin's

+chink

+chinked

+chinks

+chinned

+chinner

+chinners

+chinning

+chins

+chintz

+chip

+chip's

+chipmunk

+chipmunk's

+chipmunks

+chips

+chirp

+chirped

+chirping

+chirps

+chisel

+chisels

+chivalrous

+chivalrously

+chivalrousness

+chivalry

+chlorine

+chloroplast

+chloroplast's

+chloroplasts

+chock

+chock's

+chocked

+chocker

+chocking

+chocks

+chocolate

+chocolate's

+chocolates

+choice

+choicely

+choiceness

+choicer

+choices

+choicest

+choir

+choir's

+choirs

+choke

+choked

+choker

+chokers

+chokes

+choking

+chokingly

+cholera

+choose

+chooser

+choosers

+chooses

+choosing

+chop

+chopped

+chopper

+chopper's

+choppers

+chopping

+chops

+choral

+chorally

+chord

+chord's

+chorded

+chording

+chords

+chore

+chores

+choring

+chorion

+chorus

+chorused

+choruses

+chose

+chosen

+christen

+christened

+christening

+christens

+chronic

+chronicle

+chronicled

+chronicler

+chroniclers

+chronicles

+chronological

+chronologically

+chronologies

+chronology

+chronology's

+chubbier

+chubbiest

+chubbiness

+chubby

+chuck

+chuck's

+chucked

+chucking

+chuckle

+chuckled

+chuckles

+chuckling

+chucklingly

+chucks

+chum

+chump

+chump's

+chumping

+chumps

+chums

+chunk

+chunk's

+chunks

+church

+churched

+churches

+churching

+churchliness

+churchly

+churchman

+churchyard

+churchyard's

+churchyards

+churn

+churned

+churner

+churners

+churning

+churns

+chute

+chute's

+chuted

+chutes

+chuting

+cider

+ciders

+cigar

+cigar's

+cigarette

+cigarette's

+cigarettes

+cigars

+cinder

+cinder's

+cinders

+cinnamon

+cipher

+cipher's

+ciphered

+ciphering

+ciphers

+circle

+circled

+circler

+circles

+circling

+circuit

+circuit's

+circuited

+circuiting

+circuitous

+circuitously

+circuitousness

+circuitry

+circuits

+circular

+circular's

+circularities

+circularity

+circularly

+circularness

+circulars

+circulate

+circulated

+circulates

+circulating

+circulation

+circulations

+circulative

+circumference

+circumferences

+circumflex

+circumflexes

+circumlocution

+circumlocution's

+circumlocutions

+circumspect

+circumspectly

+circumstance

+circumstance's

+circumstanced

+circumstances

+circumstancing

+circumstantial

+circumstantially

+circumvent

+circumventable

+circumvented

+circumventing

+circumvents

+circus

+circus's

+circuses

+cistern

+cistern's

+cisterns

+citadel

+citadel's

+citadels

+citation

+citation's

+citations

+cite

+cited

+cites

+citied

+cities

+citing

+citizen

+citizen's

+citizenly

+citizens

+citizenship

+city

+city's

+civic

+civics

+civil

+civilian

+civilian's

+civilians

+civilities

+civility

+civilly

+clad

+clads

+claim

+claimable

+claimant

+claimant's

+claimants

+claimed

+claimer

+claiming

+claims

+clairvoyant

+clairvoyantly

+clairvoyants

+clam

+clam's

+clamber

+clambered

+clamberer

+clambering

+clambers

+clamorous

+clamorously

+clamorousness

+clamp

+clamped

+clamper

+clamping

+clamps

+clams

+clan

+clang

+clanged

+clanger

+clangers

+clanging

+clangs

+clans

+clap

+claps

+clarification

+clarifications

+clarified

+clarifier

+clarifies

+clarify

+clarifying

+clarity

+clash

+clashed

+clasher

+clashes

+clashing

+clasp

+clasped

+clasper

+clasping

+clasps

+class

+classed

+classer

+classes

+classic

+classical

+classically

+classics

+classifiable

+classification

+classifications

+classified

+classifieds

+classifier

+classifiers

+classifies

+classify

+classifying

+classing

+classmate

+classmate's

+classmates

+classroom

+classroom's

+classrooms

+classwork

+clatter

+clattered

+clatterer

+clattering

+clatteringly

+clatters

+clause

+clause's

+clauses

+claw

+clawed

+clawer

+clawing

+claws

+clay

+clay's

+clayed

+claying

+clays

+clean

+cleaned

+cleaner

+cleaner's

+cleaners

+cleanest

+cleaning

+cleanlier

+cleanliness

+cleanly

+cleanness

+cleans

+cleanse

+cleansed

+cleanser

+cleansers

+cleanses

+cleansing

+cleanup

+cleanup's

+cleanups

+clear

+clearance

+clearance's

+clearances

+cleared

+clearer

+clearest

+clearing

+clearing's

+clearings

+clearly

+clearness

+clears

+cleavage

+cleavages

+cleave

+cleaved

+cleaver

+cleavers

+cleaves

+cleaving

+cleft

+cleft's

+clefts

+clench

+clenched

+clenches

+clenching

+clergy

+clergyman

+clerical

+clerically

+clericals

+clerk

+clerk's

+clerked

+clerking

+clerkly

+clerks

+clever

+cleverer

+cleverest

+cleverly

+cleverness

+cliche

+cliche's

+cliches

+click

+clicked

+clicker

+clickers

+clicking

+clicks

+client

+client's

+clients

+cliff

+cliff's

+cliffs

+climate

+climate's

+climates

+climatic

+climatically

+climax

+climaxed

+climaxes

+climaxing

+climb

+climbed

+climber

+climbers

+climbing

+climbs

+clime

+clime's

+climes

+clinch

+clinched

+clincher

+clinches

+clinching

+clinchingly

+cling

+clinging

+clings

+clinic

+clinic's

+clinical

+clinically

+clinics

+clink

+clinked

+clinker

+clinkered

+clinkering

+clinkers

+clip

+clip's

+clipped

+clipper

+clipper's

+clippers

+clipping

+clipping's

+clippings

+clips

+clique

+clique's

+cliques

+cloak

+cloak's

+cloaked

+cloaking

+cloaks

+clobber

+clobbered

+clobbering

+clobbers

+clock

+clocked

+clocker

+clockers

+clocking

+clockings

+clocks

+clockwise

+clockwork

+clod

+clod's

+clods

+clog

+clog's

+clogged

+clogging

+clogs

+cloister

+cloister's

+cloistered

+cloistering

+cloisters

+clone

+cloned

+cloner

+cloners

+clones

+cloning

+close

+closed

+closely

+closeness

+closenesses

+closer

+closers

+closes

+closest

+closet

+closeted

+closets

+closing

+closings

+closure

+closure's

+closured

+closures

+closuring

+cloth

+clothe

+clothed

+clothes

+clothing

+cloud

+clouded

+cloudier

+cloudiest

+cloudiness

+clouding

+cloudless

+cloudlessly

+cloudlessness

+clouds

+cloudy

+clout

+clove

+clover

+cloves

+clown

+clowning

+clowns

+club

+club's

+clubbed

+clubbing

+clubs

+cluck

+clucked

+clucking

+clucks

+clue

+clue's

+clues

+cluing

+clump

+clumped

+clumping

+clumps

+clumsier

+clumsiest

+clumsily

+clumsiness

+clumsy

+clung

+cluster

+clustered

+clustering

+clusterings

+clusters

+clutch

+clutched

+clutches

+clutching

+clutter

+cluttered

+cluttering

+clutters

+coach

+coach's

+coached

+coacher

+coaches

+coaching

+coachman

+coagulate

+coagulated

+coagulates

+coagulating

+coagulation

+coal

+coaled

+coaler

+coalesce

+coalesced

+coalesces

+coalescing

+coaling

+coalition

+coals

+coarse

+coarsely

+coarsen

+coarsened

+coarseness

+coarsening

+coarser

+coarsest

+coast

+coastal

+coasted

+coaster

+coasters

+coasting

+coasts

+coat

+coated

+coater

+coaters

+coating

+coatings

+coats

+coax

+coaxed

+coaxer

+coaxes

+coaxial

+coaxially

+coaxing

+cobbler

+cobbler's

+cobblers

+cobweb

+cobweb's

+cobwebs

+cock

+cocked

+cocker

+cocking

+cockroach

+cockroaches

+cocks

+cocktail

+cocktail's

+cocktails

+cocoa

+coconut

+coconut's

+coconuts

+cocoon

+cocoon's

+cocoons

+cod

+code

+coded

+coder

+coder's

+coders

+codes

+codeword

+codeword's

+codewords

+codification

+codification's

+codifications

+codified

+codifier

+codifier's

+codifiers

+codifies

+codify

+codifying

+coding

+codings

+cods

+coefficient

+coefficient's

+coefficiently

+coefficients

+coerce

+coerced

+coerces

+coercing

+coercion

+coercions

+coercive

+coercively

+coerciveness

+coexist

+coexisted

+coexistence

+coexisting

+coexists

+coffee

+coffee's

+coffees

+coffer

+coffer's

+coffers

+coffin

+coffin's

+coffins

+cogent

+cogently

+cogitate

+cogitated

+cogitates

+cogitating

+cogitation

+cogitative

+cognition

+cognitions

+cognitive

+cognitively

+cognitives

+cohabit

+cohabitation

+cohabitations

+cohabited

+cohabiting

+cohabits

+cohere

+cohered

+coherence

+coherent

+coherently

+coherer

+coheres

+cohering

+cohesion

+cohesive

+cohesively

+cohesiveness

+coil

+coiled

+coiling

+coils

+coin

+coinage

+coincide

+coincided

+coincidence

+coincidence's

+coincidences

+coincidental

+coincidentally

+coincides

+coinciding

+coined

+coiner

+coining

+coins

+coke

+cokes

+coking

+cold

+colder

+coldest

+coldly

+coldness

+colds

+collaborate

+collaborated

+collaborates

+collaborating

+collaboration

+collaborations

+collaborative

+collaboratively

+collaborator

+collaborator's

+collaborators

+collapse

+collapsed

+collapses

+collapsing

+collar

+collared

+collaring

+collars

+collate

+collated

+collateral

+collaterally

+collates

+collating

+collation

+collations

+collative

+collator

+collators

+colleague

+colleague's

+colleagues

+collect

+collected

+collectedly

+collectedness

+collectible

+collecting

+collection

+collection's

+collections

+collective

+collectively

+collectives

+collector

+collector's

+collectors

+collects

+college

+college's

+colleges

+collegiate

+collegiately

+collide

+collided

+collides

+colliding

+collie

+collied

+collier

+collies

+collision

+collision's

+collisions

+cologne

+cologned

+colon

+colon's

+colonel

+colonel's

+colonels

+colonial

+colonially

+colonialness

+colonials

+colonies

+colonist

+colonist's

+colonists

+colons

+colony

+colony's

+colossal

+colossally

+colt

+colt's

+colter

+colts

+column

+column's

+columnar

+columned

+columns

+comb

+combat

+combatant

+combatant's

+combatants

+combated

+combating

+combative

+combatively

+combativeness

+combats

+combed

+comber

+combers

+combination

+combination's

+combinational

+combinations

+combinator

+combinator's

+combinatorial

+combinatorially

+combinatoric

+combinatorics

+combinators

+combine

+combined

+combiner

+combiners

+combines

+combing

+combings

+combining

+combs

+combustion

+combustions

+come

+comedian

+comedian's

+comedians

+comedic

+comedies

+comedy

+comedy's

+comelier

+comeliness

+comely

+comer

+comers

+comes

+comest

+comestible

+comestibles

+comet

+comet's

+cometh

+comets

+comfort

+comfortabilities

+comfortability

+comfortable

+comfortableness

+comfortably

+comforted

+comforter

+comforters

+comforting

+comfortingly

+comforts

+comic

+comic's

+comical

+comically

+comics

+coming

+comings

+comma

+comma's

+command

+command's

+commandant

+commandant's

+commandants

+commanded

+commandeer

+commandeered

+commandeering

+commandeers

+commander

+commanders

+commanding

+commandingly

+commandment

+commandment's

+commandments

+commands

+commas

+commemorate

+commemorated

+commemorates

+commemorating

+commemoration

+commemorations

+commemorative

+commemoratively

+commemoratives

+commence

+commenced

+commencement

+commencement's

+commencements

+commencer

+commences

+commencing

+commend

+commendation

+commendation's

+commendations

+commended

+commender

+commending

+commends

+commensurate

+commensurately

+commensurates

+commensuration

+commensurations

+comment

+comment's

+commentaries

+commentary

+commentary's

+commentator

+commentator's

+commentators

+commented

+commenter

+commenting

+comments

+commerce

+commerced

+commercial

+commercially

+commercialness

+commercials

+commercing

+commission

+commissioned

+commissioner

+commissioners

+commissioning

+commissions

+commit

+commitment

+commitment's

+commitments

+commits

+committed

+committee

+committee's

+committees

+committing

+commodities

+commodity

+commodity's

+commodore

+commodore's

+commodores

+common

+commonalities

+commonality

+commoner

+commoner's

+commoners

+commonest

+commonly

+commonness

+commonplace

+commonplaceness

+commonplaces

+commons

+commonwealth

+commonwealths

+commotion

+commotions

+communal

+communally

+commune

+communed

+communes

+communicant

+communicant's

+communicants

+communicate

+communicated

+communicates

+communicating

+communication

+communications

+communicative

+communicatively

+communicativeness

+communicator

+communicator's

+communicators

+communing

+communion

+communist

+communist's

+communists

+communities

+community

+community's

+commutative

+commutatively

+commutativity

+commute

+commuted

+commuter

+commuters

+commutes

+commuting

+compact

+compacted

+compacter

+compacters

+compactest

+compacting

+compactly

+compactness

+compactor

+compactor's

+compactors

+compacts

+companies

+companion

+companion's

+companionable

+companionableness

+companions

+companionship

+company

+company's

+comparability

+comparable

+comparableness

+comparably

+comparative

+comparatively

+comparativeness

+comparatives

+comparator

+comparator's

+comparators

+compare

+compared

+comparer

+compares

+comparing

+comparison

+comparison's

+comparisons

+compartment

+compartmented

+compartmenting

+compartments

+compass

+compassed

+compasses

+compassing

+compassion

+compassionate

+compassionately

+compassionateness

+compatibilities

+compatibility

+compatibility's

+compatible

+compatibleness

+compatibles

+compatibly

+compel

+compelled

+compelling

+compellingly

+compels

+compendium

+compensate

+compensated

+compensates

+compensating

+compensation

+compensations

+compensative

+compensatory

+compete

+competed

+competence

+competences

+competent

+competently

+competes

+competing

+competition

+competition's

+competitions

+competitive

+competitively

+competitiveness

+competitor

+competitor's

+competitors

+compilable

+compilation

+compilation's

+compilations

+compile

+compiled

+compiler

+compiler's

+compilers

+compiles

+compiling

+complain

+complained

+complainer

+complainers

+complaining

+complainingly

+complains

+complaint

+complaint's

+complaints

+complement

+complementariness

+complementary

+complemented

+complementer

+complementers

+complementing

+complements

+complete

+completed

+completely

+completeness

+completer

+completes

+completing

+completion

+completions

+completive

+complex

+complexes

+complexion

+complexioned

+complexities

+complexity

+complexly

+complexness

+compliance

+compliances

+complicate

+complicated

+complicatedly

+complicatedness

+complicates

+complicating

+complication

+complications

+complicator

+complicator's

+complicators

+complicity

+complied

+complier

+compliers

+complies

+compliment

+complimentary

+complimented

+complimenter

+complimenters

+complimenting

+compliments

+comply

+complying

+component

+component's

+components

+compose

+composed

+composedly

+composedness

+composer

+composer's

+composers

+composes

+composing

+composite

+compositely

+composites

+composition

+compositional

+compositionally

+compositions

+composure

+compound

+compounded

+compounder

+compounding

+compounds

+comprehend

+comprehended

+comprehending

+comprehends

+comprehensibility

+comprehensible

+comprehensibleness

+comprehension

+comprehensive

+comprehensively

+comprehensiveness

+compress

+compressed

+compressedly

+compresses

+compressible

+compressing

+compression

+compressions

+compressive

+compressively

+comprise

+comprised

+comprises

+comprising

+compromise

+compromised

+compromiser

+compromisers

+compromises

+compromising

+compromisingly

+comptroller

+comptroller's

+comptrollers

+compulsion

+compulsion's

+compulsions

+compulsory

+compunction

+compunctions

+computability

+computable

+computation

+computation's

+computational

+computationally

+computations

+compute

+computed

+computer

+computer's

+computerese

+computers

+computes

+computing

+comrade

+comradeliness

+comradely

+comrades

+comradeship

+concatenate

+concatenated

+concatenates

+concatenating

+concatenation

+concatenations

+conceal

+concealed

+concealer

+concealers

+concealing

+concealingly

+concealment

+conceals

+concede

+conceded

+concededly

+conceder

+concedes

+conceding

+conceit

+conceited

+conceitedly

+conceitedness

+conceits

+conceivable

+conceivably

+conceive

+conceived

+conceiver

+conceives

+conceiving

+concentrate

+concentrated

+concentrates

+concentrating

+concentration

+concentrations

+concentrative

+concentrator

+concentrators

+concentric

+concept

+concept's

+conception

+conception's

+conceptions

+conceptive

+concepts

+conceptual

+conceptually

+concern

+concerned

+concernedly

+concerning

+concerns

+concert

+concerted

+concertedly

+concertedness

+concerts

+concession

+concession's

+concessioner

+concessions

+concise

+concisely

+conciseness

+concision

+concisions

+conclude

+concluded

+concluder

+concludes

+concluding

+conclusion

+conclusion's

+conclusions

+conclusive

+conclusively

+conclusiveness

+concomitant

+concomitantly

+concomitants

+concord

+concrete

+concreted

+concretely

+concreteness

+concretes

+concreting

+concretion

+concur

+concurred

+concurrence

+concurrencies

+concurrency

+concurrent

+concurrently

+concurring

+concurs

+condemn

+condemnation

+condemnations

+condemned

+condemner

+condemners

+condemning

+condemns

+condensation

+condense

+condensed

+condenser

+condensers

+condenses

+condensing

+condescend

+condescending

+condescendingly

+condescends

+condition

+conditional

+conditionally

+conditionals

+conditioned

+conditioner

+conditioners

+conditioning

+conditions

+condone

+condoned

+condoner

+condones

+condoning

+conducive

+conduciveness

+conduct

+conducted

+conducting

+conduction

+conductive

+conductively

+conductivities

+conductivity

+conductor

+conductor's

+conductors

+conducts

+conduit

+conduits

+cone

+cone's

+coned

+cones

+confederacy

+confederate

+confederates

+confederation

+confederations

+confederative

+confer

+conference

+conference's

+conferences

+conferencing

+conferred

+conferrer

+conferrer's

+conferrers

+conferring

+confers

+confess

+confessed

+confessedly

+confesses

+confessing

+confession

+confession's

+confessions

+confessor

+confessor's

+confessors

+confidant

+confidant's

+confidants

+confide

+confided

+confidence

+confidences

+confident

+confidential

+confidentiality

+confidentially

+confidentialness

+confidently

+confider

+confides

+confiding

+confidingly

+confidingness

+configurable

+configuration

+configuration's

+configurations

+configure

+configured

+configures

+configuring

+confine

+confined

+confinement

+confinement's

+confinements

+confiner

+confines

+confining

+confirm

+confirmation

+confirmation's

+confirmations

+confirmed

+confirmedly

+confirmedness

+confirming

+confirms

+confiscate

+confiscated

+confiscates

+confiscating

+confiscation

+confiscations

+conflict

+conflicted

+conflicting

+conflictingly

+conflictive

+conflicts

+conform

+conformed

+conformer

+conformers

+conforming

+conformity

+conforms

+confound

+confounded

+confoundedly

+confounder

+confounding

+confounds

+confront

+confrontation

+confrontation's

+confrontations

+confronted

+confronter

+confronters

+confronting

+confronts

+confuse

+confused

+confusedly

+confusedness

+confuser

+confusers

+confuses

+confusing

+confusingly

+confusion

+confusions

+congenial

+congenially

+congested

+congestion

+congratulate

+congratulated

+congratulates

+congratulation

+congratulations

+congregate

+congregated

+congregates

+congregating

+congregation

+congregations

+congress

+congress's

+congressed

+congresses

+congressing

+congressional

+congressionally

+congressman

+congruence

+congruent

+congruently

+coning

+conjecture

+conjectured

+conjecturer

+conjectures

+conjecturing

+conjoined

+conjunct

+conjuncted

+conjunction

+conjunction's

+conjunctions

+conjunctive

+conjunctively

+conjuncts

+conjure

+conjured

+conjurer

+conjurers

+conjures

+conjuring

+connect

+connected

+connectedly

+connectedness

+connecter

+connecters

+connecting

+connection

+connection's

+connections

+connective

+connective's

+connectively

+connectives

+connectivities

+connectivity

+connector

+connector's

+connectors

+connects

+connoisseur

+connoisseur's

+connoisseurs

+connote

+connoted

+connotes

+connoting

+conquer

+conquerable

+conquered

+conquerer

+conquerers

+conquering

+conqueror

+conqueror's

+conquerors

+conquers

+conquest

+conquest's

+conquests

+cons

+conscience

+conscience's

+consciences

+conscientious

+conscientiously

+conscientiousness

+conscious

+consciouses

+consciously

+consciousness

+consecrate

+consecrated

+consecrates

+consecrating

+consecration

+consecrations

+consecrative

+consecutive

+consecutively

+consecutiveness

+consensus

+consent

+consented

+consenter

+consenters

+consenting

+consentingly

+consents

+consequence

+consequence's

+consequences

+consequent

+consequential

+consequentialities

+consequentiality

+consequentially

+consequentialness

+consequently

+consequentness

+consequents

+conservation

+conservation's

+conservationist

+conservationist's

+conservationists

+conservations

+conservatism

+conservative

+conservatively

+conservativeness

+conservatives

+conserve

+conserved

+conserver

+conserves

+conserving

+consider

+considerable

+considerably

+considerate

+considerately

+considerateness

+consideration

+considerations

+considered

+considerer

+considering

+considers

+consign

+consigned

+consigning

+consigns

+consist

+consisted

+consistencies

+consistency

+consistent

+consistently

+consisting

+consists

+consolable

+consolation

+consolation's

+consolations

+console

+consoled

+consoler

+consolers

+consoles

+consolidate

+consolidated

+consolidates

+consolidating

+consolidation

+consolidations

+consoling

+consolingly

+consonant

+consonant's

+consonantly

+consonants

+consort

+consorted

+consorting

+consortium

+consorts

+conspicuous

+conspicuously

+conspicuousness

+conspiracies

+conspiracy

+conspiracy's

+conspirator

+conspirator's

+conspirators

+conspire

+conspired

+conspires

+conspiring

+constable

+constable's

+constables

+constancy

+constant

+constantly

+constants

+constellation

+constellation's

+constellations

+consternation

+constituencies

+constituency

+constituency's

+constituent

+constituent's

+constituently

+constituents

+constitute

+constituted

+constitutes

+constituting

+constitution

+constitutional

+constitutionality

+constitutionally

+constitutions

+constitutive

+constitutively

+constrain

+constrained

+constrainedly

+constraining

+constrains

+constraint

+constraint's

+constraints

+construct

+constructed

+constructibility

+constructible

+constructing

+construction

+construction's

+constructions

+constructive

+constructively

+constructiveness

+constructor

+constructor's

+constructors

+constructs

+construe

+construed

+construes

+construing

+consul

+consul's

+consulate

+consulate's

+consulates

+consuls

+consult

+consultant

+consultant's

+consultants

+consultation

+consultation's

+consultations

+consultative

+consulted

+consulter

+consulting

+consultive

+consults

+consumable

+consumables

+consume

+consumed

+consumedly

+consumer

+consumer's

+consumers

+consumes

+consuming

+consumingly

+consummate

+consummated

+consummately

+consummates

+consummating

+consummation

+consummations

+consummative

+consumption

+consumption's

+consumptions

+consumptive

+consumptively

+contact

+contacted

+contacting

+contacts

+contagion

+contagious

+contagiously

+contagiousness

+contain

+containable

+contained

+container

+containers

+containing

+containment

+containment's

+containments

+contains

+contaminate

+contaminated

+contaminates

+contaminating

+contamination

+contaminations

+contaminative

+contemplate

+contemplated

+contemplates

+contemplating

+contemplation

+contemplations

+contemplative

+contemplatively

+contemplativeness

+contemporaneous

+contemporaneously

+contemporaneousness

+contemporaries

+contemporariness

+contemporary

+contempt

+contemptible

+contemptibleness

+contemptuous

+contemptuously

+contemptuousness

+contend

+contended

+contender

+contenders

+contending

+contends

+content

+contented

+contentedly

+contentedness

+contenting

+contention

+contention's

+contentions

+contently

+contentment

+contents

+contest

+contestable

+contested

+contester

+contesters

+contesting

+contests

+context

+context's

+contexts

+contextual

+contextually

+contiguity

+contiguous

+contiguously

+contiguousness

+continent

+continent's

+continental

+continentally

+continently

+continents

+contingencies

+contingency

+contingency's

+contingent

+contingent's

+contingently

+contingents

+continual

+continually

+continuance

+continuance's

+continuances

+continuation

+continuation's

+continuations

+continue

+continued

+continuer

+continues

+continuing

+continuities

+continuity

+continuous

+continuously

+continuousness

+continuum

+contour

+contour's

+contoured

+contouring

+contours

+contract

+contracted

+contracting

+contraction

+contraction's

+contractions

+contractive

+contractor

+contractor's

+contractors

+contracts

+contractual

+contractually

+contradict

+contradicted

+contradicting

+contradiction

+contradiction's

+contradictions

+contradictoriness

+contradictory

+contradicts

+contradistinction

+contradistinctions

+contrapositive

+contrapositives

+contraption

+contraption's

+contraptions

+contrariness

+contrary

+contrast

+contrasted

+contraster

+contrasters

+contrasting

+contrastingly

+contrastive

+contrastively

+contrasts

+contribute

+contributed

+contributer

+contributers

+contributes

+contributing

+contribution

+contributions

+contributive

+contributively

+contributor

+contributor's

+contributorily

+contributors

+contributory

+contrivance

+contrivance's

+contrivances

+contrive

+contrived

+contriver

+contrives

+contriving

+control

+control's

+controllability

+controllable

+controllably

+controlled

+controller

+controller's

+controllers

+controlling

+controls

+controversial

+controversially

+controversies

+controversy

+controversy's

+conundrum

+conundrum's

+conundrums

+convalescence

+convene

+convened

+convener

+conveners

+convenes

+convenience

+convenience's

+conveniences

+convenient

+conveniently

+convening

+convent

+convent's

+convention

+convention's

+conventional

+conventionally

+conventions

+convents

+converge

+converged

+convergence

+convergences

+convergent

+converges

+converging

+conversant

+conversantly

+conversation

+conversation's

+conversational

+conversationally

+conversations

+converse

+conversed

+conversely

+converses

+conversing

+conversion

+conversioning

+conversions

+convert

+converted

+converter

+converters

+convertibility

+convertible

+convertibleness

+converting

+converts

+convex

+convey

+conveyance

+conveyance's

+conveyanced

+conveyancer

+conveyancers

+conveyances

+conveyancing

+conveyed

+conveyer

+conveyers

+conveying

+conveys

+convict

+convicted

+convicting

+conviction

+conviction's

+convictions

+convictive

+convicts

+convince

+convinced

+convincer

+convincers

+convinces

+convincing

+convincingly

+convincingness

+convoluted

+convoy

+convoyed

+convoying

+convoys

+convulsion

+convulsion's

+convulsions

+coo

+cooing

+cook

+cook's

+cooked

+cooker

+cookers

+cookery

+cookie

+cookie's

+cookies

+cooking

+cooks

+cooky

+cool

+cooled

+cooler

+cooler's

+coolers

+coolest

+coolie

+coolie's

+coolies

+cooling

+coolings

+coolly

+coolness

+coolnesses

+cools

+coon

+coon's

+coons

+coop

+cooped

+cooper

+cooperate

+cooperated

+cooperates

+cooperating

+cooperation

+cooperations

+cooperative

+cooperatively

+cooperativeness

+cooperatives

+cooperator

+cooperator's

+cooperators

+coopered

+coopering

+coopers

+coops

+coordinate

+coordinated

+coordinately

+coordinateness

+coordinates

+coordinating

+coordination

+coordinations

+coordinative

+coordinator

+coordinator's

+coordinators

+cop

+cop's

+cope

+coped

+coper

+copes

+copied

+copier

+copiers

+copies

+coping

+copings

+copious

+copiously

+copiousness

+copper

+copper's

+coppered

+coppering

+coppers

+cops

+copse

+copses

+copy

+copying

+copyright

+copyright's

+copyrighted

+copyrighter

+copyrighters

+copyrighting

+copyrights

+coral

+cord

+corded

+corder

+cordial

+cordially

+cordialness

+cording

+cords

+core

+cored

+corer

+corers

+cores

+coring

+cork

+corked

+corker

+corkers

+corking

+corks

+cormorant

+cormorants

+corn

+corned

+corner

+cornered

+cornering

+corners

+cornerstone

+cornerstone's

+cornerstones

+cornfield

+cornfield's

+cornfields

+corning

+corns

+corollaries

+corollary

+corollary's

+coronaries

+coronary

+coronation

+coronet

+coronet's

+coroneted

+coronets

+coroutine

+coroutine's

+coroutines

+corporal

+corporal's

+corporally

+corporals

+corporate

+corporately

+corporation

+corporation's

+corporations

+corporative

+corps

+corpse

+corpse's

+corpses

+corpus

+correct

+correctable

+corrected

+correcting

+correction

+corrections

+corrective

+correctively

+correctiveness

+correctives

+correctly

+correctness

+corrector

+corrects

+correlate

+correlated

+correlates

+correlating

+correlation

+correlations

+correlative

+correlatively

+correspond

+corresponded

+correspondence

+correspondence's

+correspondences

+correspondent

+correspondent's

+correspondents

+corresponding

+correspondingly

+corresponds

+corridor

+corridor's

+corridors

+corroborate

+corroborated

+corroborates

+corroborating

+corroboration

+corroborations

+corroborative

+corroboratively

+corrosion

+corrosions

+corrupt

+corrupted

+corrupter

+corrupting

+corruption

+corruptive

+corruptively

+corruptly

+corrupts

+corset

+corsets

+cosine

+cosines

+cosmetic

+cosmetics

+cosmology

+cosmopolitan

+cost

+costed

+costing

+costive

+costively

+costiveness

+costlier

+costliness

+costly

+costs

+costume

+costumed

+costumer

+costumers

+costumes

+costuming

+cot

+cot's

+cots

+cottage

+cottager

+cottagers

+cottages

+cotton

+cottoned

+cottoning

+cottons

+cotyledon

+cotyledon's

+cotyledons

+couch

+couched

+couches

+couching

+cough

+coughed

+cougher

+coughing

+coughs

+could

+couldest

+couldn't

+council

+council's

+councillor

+councillor's

+councillors

+councils

+counsel

+counsel's

+counsels

+count

+countable

+countably

+counted

+countenance

+countenancer

+counter

+counteract

+counteracted

+counteracting

+counteractive

+counteracts

+counterclockwise

+countered

+counterexample

+counterexamples

+counterfeit

+counterfeited

+counterfeiter

+counterfeiting

+counterfeits

+countering

+countermeasure

+countermeasure's

+countermeasures

+counterpart

+counterpart's

+counterparts

+counterpoint

+counterpointing

+counterproductive

+counterrevolution

+counters

+countess

+counties

+counting

+countless

+countlessly

+countries

+country

+country's

+countryman

+countryside

+counts

+county

+county's

+couple

+couple's

+coupled

+coupler

+couplers

+couples

+coupling

+couplings

+coupon

+coupon's

+coupons

+courage

+courageous

+courageously

+courageousness

+courier

+courier's

+couriers

+course

+coursed

+courser

+courses

+coursing

+court

+courted

+courteous

+courteously

+courteousness

+courter

+courters

+courtesies

+courtesy

+courtesy's

+courthouse

+courthouse's

+courthouses

+courtier

+courtier's

+courtiers

+courting

+courtliness

+courtly

+courtroom

+courtroom's

+courtrooms

+courts

+courtship

+courtyard

+courtyard's

+courtyards

+cousin

+cousin's

+cousins

+cove

+covenant

+covenant's

+covenanted

+covenanter

+covenanting

+covenants

+cover

+coverable

+coverage

+covered

+coverer

+covering

+coverings

+coverlet

+coverlet's

+coverlets

+covers

+covert

+covertly

+covertness

+coves

+covet

+coveted

+coveter

+coveting

+covetingly

+covetous

+covetously

+covetousness

+covets

+coving

+cow

+coward

+cowardice

+cowardliness

+cowardly

+cowards

+cowboy

+cowboy's

+cowboys

+cowed

+cowedly

+cower

+cowered

+cowerer

+cowerers

+cowering

+coweringly

+cowers

+cowgirl

+cowgirl's

+cowgirls

+cowing

+cowl

+cowled

+cowling

+cowls

+cows

+cowslip

+cowslip's

+cowslips

+coyote

+coyote's

+coyotes

+cozier

+cozies

+coziness

+cozy

+crab

+crab's

+crabs

+crack

+cracked

+cracker

+crackers

+cracking

+crackle

+crackled

+crackles

+crackling

+crackly

+cracks

+cradle

+cradled

+cradler

+cradles

+cradling

+craft

+crafted

+crafter

+craftier

+craftiness

+crafting

+crafts

+craftsman

+crafty

+crag

+crag's

+crags

+cram

+cramp

+cramp's

+cramped

+cramper

+cramps

+crams

+cranberries

+cranberry

+cranberry's

+crane

+crane's

+craned

+cranes

+craning

+crank

+cranked

+crankier

+crankiest

+crankily

+crankiness

+cranking

+cranks

+cranky

+crap

+craping

+craps

+crash

+crashed

+crasher

+crashers

+crashes

+crashing

+crate

+crater

+cratered

+craters

+crates

+crating

+cravat

+cravat's

+cravats

+crave

+craved

+craven

+cravenly

+cravenness

+craver

+craves

+craving

+crawl

+crawled

+crawler

+crawlers

+crawling

+crawls

+craze

+crazed

+crazes

+crazier

+craziest

+crazily

+craziness

+crazing

+crazy

+creak

+creaked

+creaking

+creaks

+cream

+creamed

+creamer

+creamers

+creaminess

+creaming

+creams

+creamy

+crease

+creased

+creaser

+creases

+creasing

+create

+created

+creates

+creating

+creation

+creations

+creative

+creatively

+creativeness

+creativity

+creator

+creator's

+creators

+creature

+creature's

+creatureliness

+creaturely

+creatures

+credence

+credibility

+credible

+credibly

+credit

+creditable

+creditableness

+creditably

+credited

+crediting

+creditor

+creditor's

+creditors

+credits

+credulity

+credulous

+credulously

+credulousness

+creed

+creed's

+creeds

+creek

+creek's

+creeks

+creep

+creeper

+creepers

+creeping

+creeps

+cremate

+cremated

+cremates

+cremating

+cremation

+cremations

+crepe

+crept

+crescent

+crescent's

+crescents

+crest

+crested

+cresting

+crests

+cretin

+cretins

+crevice

+crevice's

+crevices

+crew

+crewed

+crewing

+crews

+crib

+crib's

+cribs

+cricket

+cricket's

+cricketer

+cricketing

+crickets

+cried

+crier

+criers

+cries

+crime

+crime's

+crimes

+criminal

+criminally

+criminals

+crimson

+crimsoning

+cringe

+cringed

+cringer

+cringes

+cringing

+cripple

+crippled

+crippler

+cripples

+crippling

+crises

+crisis

+crisp

+crisper

+crisply

+crispness

+crisps

+criteria

+criterion

+critic

+critic's

+critical

+critically

+criticalness

+criticism

+criticism's

+criticisms

+critics

+critique

+critiqued

+critiques

+critiquing

+critter

+critter's

+critters

+croak

+croaked

+croaker

+croakers

+croaking

+croaks

+crochet

+crocheted

+crocheter

+crocheting

+crochets

+crook

+crooked

+crookedly

+crookedness

+crooks

+crop

+crop's

+cropped

+cropper

+cropper's

+croppers

+cropping

+crops

+cross

+crossable

+crossbar

+crossbar's

+crossbars

+crossed

+crosser

+crossers

+crosses

+crossing

+crossings

+crossly

+crossover

+crossover's

+crossovers

+crossword

+crossword's

+crosswords

+crouch

+crouched

+crouches

+crouching

+crow

+crowd

+crowded

+crowdedness

+crowder

+crowding

+crowds

+crowed

+crowing

+crown

+crowned

+crowner

+crowning

+crowns

+crows

+crucial

+crucially

+crucification

+crucified

+crucifies

+crucify

+crucifying

+crude

+crudely

+crudeness

+cruder

+crudest

+cruel

+crueler

+cruelest

+cruelly

+cruelness

+cruelty

+cruise

+cruised

+cruiser

+cruisers

+cruises

+cruising

+crumb

+crumble

+crumbled

+crumbles

+crumblier

+crumbliness

+crumbling

+crumblings

+crumbly

+crumbs

+crumple

+crumpled

+crumples

+crumpling

+crunch

+crunched

+cruncher

+crunchers

+crunches

+crunchier

+crunchiest

+crunchiness

+crunching

+crunchy

+crusade

+crusaded

+crusader

+crusaders

+crusades

+crusading

+crush

+crushable

+crushed

+crusher

+crushers

+crushes

+crushing

+crushingly

+crust

+crust's

+crustacean

+crustacean's

+crustaceans

+crusted

+crusting

+crusts

+crutch

+crutch's

+crutched

+crutches

+crux

+crux's

+cruxes

+cry

+crying

+cryptanalysis

+cryptic

+cryptographic

+cryptography

+cryptology

+crystal

+crystal's

+crystalline

+crystals

+cub

+cub's

+cube

+cubed

+cuber

+cubes

+cubic

+cubicly

+cubics

+cubing

+cubs

+cuckoo

+cuckoo's

+cuckoos

+cucumber

+cucumber's

+cucumbers

+cuddle

+cuddled

+cuddles

+cuddling

+cudgel

+cudgel's

+cudgels

+cue

+cued

+cues

+cuff

+cuff's

+cuffed

+cuffing

+cuffs

+cuing

+cull

+culled

+culler

+culling

+culls

+culminate

+culminated

+culminates

+culminating

+culmination

+culpability

+culprit

+culprit's

+culprits

+cult

+cult's

+cultivate

+cultivated

+cultivates

+cultivating

+cultivation

+cultivations

+cultivator

+cultivator's

+cultivators

+cults

+cultural

+culturally

+culture

+cultured

+cultures

+culturing

+cumbersome

+cumbersomely

+cumbersomeness

+cumulative

+cumulatively

+cunning

+cunningly

+cunningness

+cup

+cup's

+cupboard

+cupboard's

+cupboards

+cupful

+cupfuls

+cupped

+cupping

+cups

+cur

+curable

+curableness

+curably

+curb

+curbed

+curbing

+curbs

+curds

+cure

+cured

+curer

+cures

+curfew

+curfew's

+curfews

+curing

+curiosities

+curiosity

+curiosity's

+curious

+curiouser

+curiousest

+curiously

+curiousness

+curl

+curled

+curler

+curlers

+curlier

+curliness

+curling

+curls

+curly

+currant

+currant's

+currants

+currencies

+currency

+currency's

+current

+currently

+currentness

+currents

+curricular

+curriculum

+curriculum's

+curriculums

+curried

+currier

+curries

+curry

+currying

+curs

+curse

+cursed

+cursedly

+cursedness

+curses

+cursing

+cursive

+cursively

+cursiveness

+cursor

+cursor's

+cursorily

+cursoriness

+cursors

+cursory

+curt

+curtail

+curtailed

+curtailer

+curtailing

+curtails

+curtain

+curtained

+curtaining

+curtains

+curtly

+curtness

+curtsied

+curtsies

+curtsy

+curtsy's

+curtsying

+curvature

+curvatures

+curve

+curved

+curves

+curving

+cushion

+cushioned

+cushioning

+cushions

+cusp

+cusp's

+cusps

+cuss

+cussed

+cussedly

+cussedness

+cusser

+cusses

+custard

+custodian

+custodian's

+custodians

+custodies

+custody

+custom

+customarily

+customariness

+customary

+customer

+customer's

+customers

+customs

+cut

+cut's

+cute

+cutely

+cuteness

+cuter

+cutes

+cutest

+cutoff

+cutoffs

+cuts

+cutter

+cutter's

+cutters

+cutting

+cuttingly

+cuttings

+cybernetic

+cybernetics

+cycle

+cycled

+cycler

+cycles

+cyclic

+cyclically

+cyclicly

+cycling

+cycloid

+cycloid's

+cycloidal

+cycloids

+cyclone

+cyclone's

+cyclones

+cylinder

+cylinder's

+cylindered

+cylindering

+cylinders

+cylindrical

+cylindrically

+cymbal

+cymbal's

+cymbals

+cynical

+cynically

+cypress

+cyst

+cysts

+cytology

+czar

+dabble

+dabbled

+dabbler

+dabblers

+dabbles

+dabbling

+dad

+dad's

+daddies

+daddy

+dads

+daemon

+daemon's

+daemons

+daffodil

+daffodil's

+daffodils

+dagger

+daggers

+dailies

+daily

+daintier

+dainties

+daintily

+daintiness

+dainty

+dairies

+dairy

+dairying

+daisies

+daisy

+daisy's

+dale

+dale's

+dales

+daleth

+dam

+dam's

+damage

+damaged

+damager

+damagers

+damages

+damaging

+damagingly

+damask

+dame

+damed

+damn

+damnation

+damned

+damneder

+damnedest

+damning

+damningly

+damns

+damp

+damped

+dampen

+dampened

+dampener

+dampening

+dampens

+damper

+dampers

+damping

+damply

+dampness

+damps

+dams

+damsel

+damsel's

+damsels

+dance

+danced

+dancer

+dancers

+dances

+dancing

+dandelion

+dandelion's

+dandelions

+dandier

+dandies

+dandy

+danger

+danger's

+dangerous

+dangerously

+dangerousness

+dangers

+dangle

+dangled

+dangler

+dangler's

+danglers

+dangles

+dangling

+danglingly

+dare

+dared

+darer

+darers

+dares

+daring

+daringly

+daringness

+dark

+darken

+darkened

+darkener

+darkeners

+darkening

+darker

+darkest

+darkly

+darkness

+darks

+darling

+darling's

+darlingly

+darlingness

+darlings

+darn

+darned

+darner

+darning

+darns

+dart

+darted

+darter

+darting

+darts

+dash

+dashed

+dasher

+dashers

+dashes

+dashing

+dashingly

+data

+database

+database's

+databases

+date

+dated

+datedly

+datedness

+dater

+dates

+dating

+dative

+datum

+datums

+daughter

+daughter's

+daughterly

+daughters

+daunt

+daunted

+daunting

+dauntless

+dauntlessly

+dauntlessness

+daunts

+dawn

+dawned

+dawning

+dawns

+day

+day's

+daybreak

+daybreaks

+daydream

+daydreamed

+daydreamer

+daydreamers

+daydreaming

+daydreams

+daylight

+daylight's

+daylights

+days

+daytime

+daytimes

+daze

+dazed

+dazedness

+dazes

+dazing

+dazzle

+dazzled

+dazzler

+dazzlers

+dazzles

+dazzling

+dazzlingly

+deacon

+deacon's

+deacons

+dead

+deaden

+deadened

+deadener

+deadening

+deadeningly

+deadens

+deadlier

+deadliest

+deadline

+deadline's

+deadlines

+deadliness

+deadlock

+deadlocked

+deadlocking

+deadlocks

+deadly

+deadness

+deaf

+deafen

+deafened

+deafening

+deafeningly

+deafens

+deafer

+deafest

+deafly

+deafness

+deal

+dealer

+dealers

+dealing

+dealings

+deallocate

+deallocated

+deallocates

+deallocating

+deallocation

+deallocation's

+deallocations

+deallocator

+deals

+dealt

+dean

+dean's

+deans

+dear

+dearer

+dearest

+dearly

+dearness

+dears

+dearth

+dearths

+death

+deathly

+deaths

+debatable

+debate

+debated

+debater

+debaters

+debates

+debating

+debilitate

+debilitated

+debilitates

+debilitating

+debilitation

+debris

+debt

+debt's

+debtor

+debtors

+debts

+debug

+debugged

+debugger

+debugger's

+debuggers

+debugging

+debugs

+decade

+decade's

+decadence

+decadent

+decadently

+decades

+decay

+decayed

+decayer

+decaying

+decays

+decease

+deceased

+deceases

+deceasing

+deceit

+deceitful

+deceitfully

+deceitfulness

+deceive

+deceived

+deceiver

+deceivers

+deceives

+deceiving

+deceivingly

+decelerate

+decelerated

+decelerates

+decelerating

+deceleration

+decelerations

+decencies

+decency

+decency's

+decent

+decently

+deception

+deception's

+deceptions

+deceptive

+deceptively

+deceptiveness

+decidability

+decidable

+decide

+decided

+decidedly

+decidedness

+decider

+decides

+deciding

+decimal

+decimally

+decimals

+decimate

+decimated

+decimates

+decimating

+decimation

+decipher

+deciphered

+decipherer

+decipherers

+deciphering

+deciphers

+decision

+decision's

+decisions

+decisive

+decisively

+decisiveness

+deck

+decked

+decker

+decking

+deckings

+decks

+declaration

+declaration's

+declarations

+declarative

+declaratively

+declaratives

+declare

+declared

+declarer

+declarers

+declares

+declaring

+declination

+declination's

+declinations

+decline

+declined

+decliner

+decliners

+declines

+declining

+decode

+decoded

+decoder

+decoders

+decodes

+decoding

+decodings

+decompile

+decompiled

+decompiler

+decompilers

+decompiles

+decompiling

+decomposability

+decomposable

+decompose

+decomposed

+decomposer

+decomposes

+decomposing

+decomposition

+decomposition's

+decompositions

+decompression

+decorate

+decorated

+decorates

+decorating

+decoration

+decorations

+decorative

+decoratively

+decorativeness

+decorum

+decorums

+decouple

+decoupled

+decoupler

+decouples

+decoupling

+decoy

+decoy's

+decoys

+decrease

+decreased

+decreases

+decreasing

+decreasingly

+decree

+decreed

+decreeing

+decreer

+decrees

+decrement

+decremented

+decrementing

+decrements

+dedicate

+dedicated

+dedicatedly

+dedicates

+dedicating

+dedication

+dedications

+dedicative

+deduce

+deduced

+deducer

+deduces

+deducible

+deducing

+deduct

+deducted

+deducting

+deduction

+deduction's

+deductions

+deductive

+deductively

+deducts

+deed

+deeded

+deeding

+deeds

+deem

+deemed

+deeming

+deems

+deep

+deepen

+deepened

+deepening

+deepens

+deeper

+deepest

+deeply

+deepness

+deeps

+deer

+deers

+default

+defaulted

+defaulter

+defaulting

+defaults

+defeat

+defeated

+defeating

+defeatism

+defeatist

+defeatists

+defeats

+defect

+defected

+defecting

+defection

+defection's

+defections

+defective

+defectively

+defectiveness

+defectives

+defects

+defend

+defendant

+defendant's

+defendants

+defended

+defender

+defenders

+defending

+defends

+defenestrate

+defenestrated

+defenestrates

+defenestrating

+defenestration

+defenestrations

+defensive

+defensively

+defensiveness

+defer

+deference

+deferment

+deferment's

+deferments

+deferrable

+deferred

+deferrer

+deferrer's

+deferrers

+deferring

+defers

+defiance

+defiances

+defiant

+defiantly

+deficiencies

+deficiency

+deficient

+deficiently

+deficit

+deficit's

+deficits

+defied

+defier

+defies

+defile

+defiled

+defiler

+defiles

+defiling

+definable

+define

+defined

+definer

+definers

+defines

+defining

+definite

+definitely

+definiteness

+definition

+definition's

+definitional

+definitions

+definitive

+definitively

+definitiveness

+deformation

+deformation's

+deformations

+deformed

+deformities

+deformity

+deformity's

+deftly

+defy

+defying

+defyingly

+degenerate

+degenerated

+degenerately

+degenerateness

+degenerates

+degenerating

+degeneration

+degenerative

+degradable

+degradation

+degradation's

+degradations

+degrade

+degraded

+degradedly

+degradedness

+degrader

+degrades

+degrading

+degradingly

+degree

+degree's

+degreed

+degrees

+deign

+deigned

+deigning

+deigns

+deities

+deity

+deity's

+dejected

+dejectedly

+dejectedness

+delay

+delayed

+delayer

+delayers

+delaying

+delays

+delegate

+delegated

+delegates

+delegating

+delegation

+delegations

+delete

+deleted

+deleter

+deletes

+deleting

+deletion

+deletions

+deliberate

+deliberated

+deliberately

+deliberateness

+deliberates

+deliberating

+deliberation

+deliberations

+deliberative

+deliberatively

+deliberativeness

+deliberator

+deliberator's

+deliberators

+delicacies

+delicacy

+delicacy's

+delicate

+delicately

+delicateness

+delicates

+delicious

+deliciouses

+deliciously

+deliciousness

+delight

+delighted

+delightedly

+delightedness

+delighter

+delightful

+delightfully

+delightfulness

+delighting

+delights

+delimit

+delimited

+delimiter

+delimiters

+delimiting

+delimits

+delineate

+delineated

+delineates

+delineating

+delineation

+delineations

+delineative

+delinquency

+delinquent

+delinquent's

+delinquently

+delinquents

+delirious

+deliriously

+deliriousness

+deliver

+deliverable

+deliverables

+deliverance

+delivered

+deliverer

+deliverers

+deliveries

+delivering

+delivers

+delivery

+delivery's

+dell

+dell's

+dells

+delta

+delta's

+deltas

+delude

+deluded

+deluder

+deludes

+deluding

+deludingly

+deluge

+deluged

+deluges

+deluging

+delusion

+delusion's

+delusions

+delve

+delved

+delver

+delves

+delving

+demand

+demanded

+demander

+demanding

+demandingly

+demands

+demise

+demised

+demises

+demising

+demo

+democracies

+democracy

+democracy's

+democrat

+democrat's

+democratic

+democratically

+democrats

+demodulate

+demodulated

+demodulates

+demodulating

+demodulation

+demodulation's

+demodulations

+demodulator

+demodulator's

+demodulators

+demographic

+demographics

+demolish

+demolished

+demolisher

+demolishes

+demolishing

+demolition

+demolitions

+demon

+demon's

+demoness

+demons

+demonstrable

+demonstrableness

+demonstrate

+demonstrated

+demonstrates

+demonstrating

+demonstration

+demonstrations

+demonstrative

+demonstratively

+demonstrativeness

+demonstrator

+demonstrator's

+demonstrators

+demos

+demur

+demurs

+den

+den's

+deniable

+denial

+denial's

+denials

+denied

+denier

+denies

+denigrate

+denigrated

+denigrates

+denigrating

+denigration

+denigrative

+denizen

+denizens

+denomination

+denomination's

+denominations

+denominator

+denominator's

+denominators

+denotable

+denotation

+denotation's

+denotational

+denotationally

+denotations

+denotative

+denote

+denoted

+denotes

+denoting

+denounce

+denounced

+denouncer

+denouncers

+denounces

+denouncing

+dens

+dense

+densely

+denseness

+denser

+densest

+densities

+density

+density's

+dent

+dental

+dentally

+dentals

+dented

+denting

+dentist

+dentist's

+dentists

+dents

+deny

+denying

+denyingly

+depart

+departed

+departing

+department

+department's

+departmental

+departmentally

+departments

+departs

+departure

+departure's

+departures

+depend

+dependability

+dependable

+dependableness

+dependably

+depended

+dependence

+dependences

+dependencies

+dependency

+dependent

+dependently

+dependents

+depending

+depends

+depict

+depicted

+depicter

+depicting

+depicts

+deplete

+depleted

+depletes

+depleting

+depletion

+depletions

+depletive

+deplorable

+deplorableness

+deplore

+deplored

+deplorer

+deplores

+deploring

+deploringly

+deploy

+deployed

+deploying

+deployment

+deployment's

+deployments

+deploys

+deport

+deportation

+deported

+deportee

+deportee's

+deportees

+deporting

+deportment

+deports

+depose

+deposed

+deposes

+deposing

+deposit

+deposited

+depositing

+deposition

+deposition's

+depositions

+depositor

+depositor's

+depositors

+deposits

+depot

+depot's

+depots

+deprave

+depraved

+depravedly

+depravedness

+depraver

+depraves

+depraving

+depreciate

+depreciated

+depreciates

+depreciating

+depreciatingly

+depreciation

+depreciations

+depreciative

+depreciatively

+depress

+depressed

+depresses

+depressing

+depressingly

+depression

+depression's

+depressions

+depressive

+depressively

+deprivation

+deprivation's

+deprivations

+deprive

+deprived

+deprives

+depriving

+depth

+depths

+deputies

+deputy

+deputy's

+dequeue

+dequeued

+dequeues

+dequeuing

+derail

+derailed

+derailing

+derails

+derbies

+derby

+dereference

+dereferenced

+dereferencer

+dereferencers

+dereferences

+dereferencing

+deride

+derided

+derider

+derides

+deriding

+deridingly

+derision

+derivable

+derivation

+derivation's

+derivations

+derivative

+derivative's

+derivatively

+derivativeness

+derivatives

+derive

+derived

+deriver

+derives

+deriving

+descend

+descendant

+descendant's

+descendants

+descended

+descender

+descenders

+descending

+descends

+descent

+descent's

+descents

+describable

+describe

+described

+describer

+describers

+describes

+describing

+descried

+description

+description's

+descriptions

+descriptive

+descriptively

+descriptiveness

+descriptives

+descriptor

+descriptor's

+descriptors

+descry

+descrying

+desert

+deserted

+deserter

+deserters

+deserting

+desertion

+desertions

+deserts

+deserve

+deserved

+deservedly

+deservedness

+deserver

+deserves

+deserving

+deservingly

+deservings

+desiderata

+desideratum

+design

+designate

+designated

+designates

+designating

+designation

+designations

+designative

+designator

+designator's

+designators

+designed

+designedly

+designer

+designer's

+designers

+designing

+designs

+desirability

+desirable

+desirableness

+desirably

+desire

+desired

+desirer

+desires

+desiring

+desirous

+desirously

+desirousness

+desk

+desk's

+desks

+desktop

+desolate

+desolated

+desolately

+desolateness

+desolater

+desolates

+desolating

+desolatingly

+desolation

+desolations

+despair

+despaired

+despairer

+despairing

+despairingly

+despairs

+despatch

+despatched

+desperate

+desperately

+desperateness

+desperation

+despise

+despised

+despiser

+despises

+despising

+despite

+despited

+despot

+despot's

+despotic

+despots

+dessert

+dessert's

+desserts

+destination

+destination's

+destinations

+destine

+destined

+destinies

+destining

+destiny

+destiny's

+destitute

+destituteness

+destitution

+destroy

+destroyed

+destroyer

+destroyer's

+destroyers

+destroying

+destroys

+destruction

+destruction's

+destructions

+destructive

+destructively

+destructiveness

+detach

+detached

+detachedly

+detachedness

+detacher

+detaches

+detaching

+detachment

+detachment's

+detachments

+detail

+detailed

+detailedly

+detailedness

+detailer

+detailing

+details

+detain

+detained

+detainer

+detaining

+detains

+detect

+detectable

+detectably

+detected

+detecting

+detection

+detection's

+detections

+detective

+detectives

+detector

+detector's

+detectors

+detects

+detention

+deteriorate

+deteriorated

+deteriorates

+deteriorating

+deterioration

+deteriorative

+determinable

+determinableness

+determinacy

+determinant

+determinant's

+determinants

+determinate

+determinately

+determinateness

+determination

+determinations

+determinative

+determinatively

+determinativeness

+determine

+determined

+determinedly

+determinedness

+determiner

+determiners

+determines

+determining

+determinism

+deterministic

+deterministically

+detest

+detestable

+detestableness

+detested

+detesting

+detests

+detonate

+detonated

+detonates

+detonating

+detonation

+detonative

+detract

+detracted

+detracting

+detractive

+detractively

+detractor

+detractor's

+detractors

+detracts

+detriment

+detriments

+devastate

+devastated

+devastates

+devastating

+devastatingly

+devastation

+devastations

+devastative

+develop

+developed

+developer

+developer's

+developers

+developing

+development

+development's

+developmental

+developmentally

+developments

+develops

+deviant

+deviant's

+deviantly

+deviants

+deviate

+deviated

+deviates

+deviating

+deviation

+deviations

+device

+device's

+devices

+devil

+devil's

+devilish

+devilishly

+devilishness

+devils

+devise

+devised

+deviser

+devises

+devising

+devisings

+devision

+devisions

+devoid

+devote

+devoted

+devotedly

+devotee

+devotee's

+devotees

+devotes

+devoting

+devotion

+devotions

+devour

+devoured

+devourer

+devouring

+devours

+devout

+devoutly

+devoutness

+dew

+dewdrop

+dewdrop's

+dewdrops

+dewed

+dewier

+dewiness

+dewing

+dews

+dewy

+dexterity

+diabetes

+diadem

+diagnosable

+diagnose

+diagnosed

+diagnoses

+diagnosing

+diagnosis

+diagnostic

+diagnostic's

+diagnostics

+diagonal

+diagonally

+diagonals

+diagram

+diagram's

+diagramed

+diagraming

+diagrammable

+diagrammatic

+diagrammatically

+diagrammed

+diagrammer

+diagrammer's

+diagrammers

+diagramming

+diagrams

+dial

+dial's

+dialect

+dialect's

+dialects

+dialog

+dialog's

+dialogs

+dialogue

+dialogue's

+dialogues

+dials

+diameter

+diameter's

+diameters

+diametrically

+diamond

+diamond's

+diamonds

+diaper

+diaper's

+diapered

+diapering

+diapers

+diaphragm

+diaphragm's

+diaphragms

+diaries

+diary

+diary's

+diatribe

+diatribe's

+diatribes

+dice

+dicer

+dices

+dichotomies

+dichotomy

+dicing

+dickens

+dicky

+dictate

+dictated

+dictates

+dictating

+dictation

+dictations

+dictator

+dictator's

+dictators

+dictatorship

+dictatorships

+diction

+dictionaries

+dictionary

+dictionary's

+dictions

+dictum

+dictum's

+dictums

+did

+didn't

+die

+died

+dielectric

+dielectric's

+dielectrics

+dies

+diet

+dieter

+dieters

+dietitian

+dietitian's

+dietitians

+diets

+differ

+differed

+difference

+difference's

+differenced

+differences

+differencing

+different

+differential

+differential's

+differentially

+differentials

+differentiate

+differentiated

+differentiates

+differentiating

+differentiation

+differentiations

+differentiators

+differently

+differentness

+differer

+differers

+differing

+differs

+difficult

+difficulties

+difficultly

+difficulty

+difficulty's

+diffuse

+diffused

+diffusely

+diffuseness

+diffuser

+diffusers

+diffuses

+diffusing

+diffusion

+diffusions

+diffusive

+diffusively

+diffusiveness

+dig

+digest

+digested

+digester

+digestible

+digesting

+digestion

+digestions

+digestive

+digestively

+digestiveness

+digests

+digger

+digger's

+diggers

+digging

+diggings

+digit

+digit's

+digital

+digitally

+digits

+dignified

+dignify

+dignities

+dignity

+digress

+digressed

+digresses

+digressing

+digression

+digression's

+digressions

+digressive

+digressively

+digressiveness

+digs

+dike

+dike's

+diker

+dikes

+diking

+dilate

+dilated

+dilatedly

+dilatedness

+dilates

+dilating

+dilation

+dilative

+dilemma

+dilemma's

+dilemmas

+diligence

+diligences

+diligent

+diligently

+diligentness

+dilute

+diluted

+dilutely

+diluteness

+diluter

+dilutes

+diluting

+dilution

+dilutions

+dilutive

+dim

+dime

+dime's

+dimension

+dimensional

+dimensionality

+dimensionally

+dimensioned

+dimensioning

+dimensions

+dimer

+dimers

+dimes

+diminish

+diminished

+diminishes

+diminishing

+diminution

+diminutive

+diminutively

+diminutiveness

+dimly

+dimmed

+dimmer

+dimmer's

+dimmers

+dimmest

+dimming

+dimness

+dimple

+dimpled

+dimples

+dimpling

+dims

+din

+dine

+dined

+diner

+diners

+dines

+dingier

+dinginess

+dingy

+dining

+dinner

+dinner's

+dinners

+dint

+diode

+diode's

+diodes

+dioxide

+dioxides

+dip

+diphtheria

+diploma

+diploma's

+diplomacy

+diplomas

+diplomat

+diplomat's

+diplomatic

+diplomatics

+diplomats

+dipped

+dipper

+dipper's

+dippers

+dipping

+dippings

+dips

+dire

+direct

+directed

+directing

+direction

+direction's

+directional

+directionality

+directionally

+directions

+directive

+directive's

+directives

+directly

+directness

+director

+director's

+directories

+directors

+directory

+directory's

+directs

+direly

+direness

+direr

+direst

+dirge

+dirge's

+dirged

+dirges

+dirging

+dirt

+dirt's

+dirtied

+dirtier

+dirties

+dirtiest

+dirtily

+dirtiness

+dirts

+dirty

+dirtying

+disabilities

+disability

+disability's

+disable

+disabled

+disabler

+disablers

+disables

+disabling

+disabuse

+disadvantage

+disadvantage's

+disadvantaged

+disadvantagedness

+disadvantages

+disadvantaging

+disagree

+disagreeable

+disagreeableness

+disagreed

+disagreeing

+disagreement

+disagreement's

+disagreements

+disagrees

+disallow

+disallowed

+disallowing

+disallows

+disambiguate

+disambiguated

+disambiguates

+disambiguating

+disambiguation

+disambiguations

+disappear

+disappearance

+disappearance's

+disappearances

+disappeared

+disappearing

+disappears

+disappoint

+disappointed

+disappointedly

+disappointing

+disappointingly

+disappointment

+disappointment's

+disappointments

+disappoints

+disapproval

+disapprove

+disapproved

+disapprover

+disapproves

+disapproving

+disapprovingly

+disarm

+disarmament

+disarmed

+disarmer

+disarmers

+disarming

+disarmingly

+disarms

+disassemble

+disassembled

+disassembler

+disassembler's

+disassemblers

+disassembles

+disassembling

+disaster

+disaster's

+disasters

+disastrous

+disastrously

+disband

+disbanded

+disbanding

+disbands

+disbelieve

+disbelieved

+disbeliever

+disbelievers

+disbelieves

+disbelieving

+disburse

+disbursed

+disbursement

+disbursement's

+disbursements

+disburser

+disburses

+disbursing

+disc

+disc's

+discard

+discarded

+discarder

+discarding

+discards

+discern

+discerned

+discerner

+discernibility

+discernible

+discernibly

+discerning

+discerningly

+discernment

+discerns

+discharge

+discharged

+discharger

+discharges

+discharging

+disciple

+disciple's

+disciples

+disciplinary

+discipline

+disciplined

+discipliner

+disciplines

+disciplining

+disclaim

+disclaimed

+disclaimer

+disclaimers

+disclaiming

+disclaims

+disclose

+disclosed

+discloser

+discloses

+disclosing

+disclosure

+disclosure's

+disclosures

+discomfort

+discomforting

+discomfortingly

+disconcert

+disconcerted

+disconcerting

+disconcertingly

+disconcerts

+disconnect

+disconnected

+disconnectedly

+disconnectedness

+disconnecter

+disconnecting

+disconnection

+disconnections

+disconnects

+discontent

+discontented

+discontentedly

+discontinuance

+discontinue

+discontinued

+discontinues

+discontinuing

+discontinuities

+discontinuity

+discontinuity's

+discontinuous

+discontinuously

+discord

+discords

+discount

+discounted

+discounter

+discounting

+discounts

+discourage

+discouraged

+discouragement

+discourager

+discourages

+discouraging

+discouragingly

+discourse

+discourse's

+discoursed

+discourser

+discourses

+discoursing

+discover

+discovered

+discoverer

+discoverers

+discoveries

+discovering

+discovers

+discovery

+discovery's

+discredit

+discredited

+discrediting

+discredits

+discreet

+discreetly

+discreetness

+discrepancies

+discrepancy

+discrepancy's

+discrete

+discretely

+discreteness

+discretion

+discretions

+discriminate

+discriminated

+discriminates

+discriminating

+discriminatingly

+discrimination

+discriminations

+discriminative

+discriminatory

+discs

+discuss

+discussed

+discusser

+discusses

+discussing

+discussion

+discussion's

+discussions

+disdain

+disdaining

+disdains

+disease

+diseased

+diseases

+diseasing

+disenfranchise

+disenfranchised

+disenfranchisement

+disenfranchisement's

+disenfranchisements

+disenfranchiser

+disenfranchises

+disenfranchising

+disengage

+disengaged

+disengages

+disengaging

+disentangle

+disentangled

+disentangler

+disentangles

+disentangling

+disfigure

+disfigured

+disfigures

+disfiguring

+disgorge

+disgorger

+disgrace

+disgraced

+disgraceful

+disgracefully

+disgracefulness

+disgracer

+disgraces

+disgracing

+disgruntled

+disguise

+disguised

+disguisedly

+disguiser

+disguises

+disguising

+disgust

+disgusted

+disgustedly

+disgusting

+disgustingly

+disgusts

+dish

+dishearten

+disheartening

+dishearteningly

+dished

+dishes

+dishing

+dishonest

+dishonestly

+dishwasher

+dishwashers

+disillusion

+disillusioned

+disillusioning

+disillusionment

+disillusionment's

+disillusionments

+disinterested

+disinterestedly

+disinterestedness

+disjoint

+disjointed

+disjointedly

+disjointedness

+disjointly

+disjointness

+disjunct

+disjunction

+disjunctions

+disjunctive

+disjunctively

+disjuncts

+disk

+disk's

+disked

+disking

+disks

+dislike

+disliked

+disliker

+dislikes

+disliking

+dislocate

+dislocated

+dislocates

+dislocating

+dislocation

+dislocations

+dislodge

+dislodged

+dislodges

+dislodging

+dismal

+dismally

+dismalness

+dismay

+dismayed

+dismaying

+dismayingly

+dismays

+dismiss

+dismissal

+dismissal's

+dismissals

+dismissed

+dismisser

+dismissers

+dismisses

+dismissing

+dismissive

+dismount

+dismounted

+dismounting

+dismounts

+disobedience

+disobey

+disobeyed

+disobeyer

+disobeying

+disobeys

+disorder

+disordered

+disorderedly

+disorderedness

+disorderliness

+disorderly

+disorders

+disown

+disowned

+disowning

+disowns

+disparate

+disparately

+disparateness

+disparities

+disparity

+disparity's

+dispatch

+dispatched

+dispatcher

+dispatchers

+dispatches

+dispatching

+dispel

+dispelled

+dispelling

+dispels

+dispensation

+dispense

+dispensed

+dispenser

+dispensers

+dispenses

+dispensing

+disperse

+dispersed

+dispersedly

+disperser

+disperses

+dispersing

+dispersion

+dispersions

+dispersive

+dispersively

+dispersiveness

+displace

+displaced

+displacement

+displacement's

+displacements

+displacer

+displaces

+displacing

+display

+displayed

+displayer

+displaying

+displays

+displease

+displeased

+displeasedly

+displeases

+displeasing

+displeasure

+disposable

+disposal

+disposal's

+disposals

+dispose

+disposed

+disposer

+disposes

+disposing

+disposition

+disposition's

+dispositions

+disprove

+disproved

+disproves

+disproving

+dispute

+disputed

+disputer

+disputers

+disputes

+disputing

+disqualification

+disqualified

+disqualifies

+disqualify

+disqualifying

+disquiet

+disquieting

+disquietingly

+disquietly

+disregard

+disregarded

+disregarding

+disregards

+disrupt

+disrupted

+disrupter

+disrupting

+disruption

+disruption's

+disruptions

+disruptive

+disruptively

+disruptiveness

+disrupts

+dissatisfaction

+dissatisfaction's

+dissatisfactions

+dissatisfied

+disseminate

+disseminated

+disseminates

+disseminating

+dissemination

+dissension

+dissension's

+dissensions

+dissent

+dissented

+dissenter

+dissenters

+dissenting

+dissents

+dissertation

+dissertation's

+dissertations

+disservice

+dissident

+dissident's

+dissidents

+dissimilar

+dissimilarities

+dissimilarity

+dissimilarity's

+dissimilarly

+dissipate

+dissipated

+dissipatedly

+dissipatedness

+dissipater

+dissipates

+dissipating

+dissipation

+dissipations

+dissipative

+dissociate

+dissociated

+dissociates

+dissociating

+dissociation

+dissociative

+dissolution

+dissolution's

+dissolutions

+dissolve

+dissolved

+dissolver

+dissolves

+dissolving

+dissonance

+dissonance's

+dissonances

+distal

+distally

+distance

+distanced

+distances

+distancing

+distant

+distantly

+distantness

+distaste

+distasteful

+distastefully

+distastefulness

+distastes

+distemper

+distill

+distillation

+distilled

+distiller

+distillers

+distilling

+distills

+distinct

+distinction

+distinction's

+distinctions

+distinctive

+distinctively

+distinctiveness

+distinctly

+distinctness

+distinguish

+distinguishable

+distinguished

+distinguisher

+distinguishes

+distinguishing

+distort

+distorted

+distorter

+distorting

+distortion

+distortion's

+distortions

+distorts

+distract

+distracted

+distractedly

+distracting

+distractingly

+distraction

+distraction's

+distractions

+distractive

+distracts

+distraught

+distraughtly

+distress

+distressed

+distresses

+distressing

+distressingly

+distribute

+distributed

+distributer

+distributes

+distributing

+distribution

+distribution's

+distributional

+distributions

+distributive

+distributively

+distributiveness

+distributivity

+distributor

+distributor's

+distributors

+district

+district's

+districted

+districting

+districts

+distrust

+distrusted

+distrusts

+disturb

+disturbance

+disturbance's

+disturbances

+disturbed

+disturber

+disturbing

+disturbingly

+disturbs

+ditch

+ditch's

+ditched

+ditcher

+ditches

+ditching

+divan

+divan's

+divans

+dive

+dived

+diver

+diverge

+diverged

+divergence

+divergence's

+divergences

+divergent

+divergently

+diverges

+diverging

+divers

+diverse

+diversely

+diverseness

+diversification

+diversified

+diversifier

+diversifies

+diversify

+diversifying

+diversion

+diversions

+diversities

+diversity

+divert

+diverted

+diverting

+diverts

+dives

+divest

+divested

+divesting

+divests

+divide

+divided

+dividend

+dividend's

+dividends

+divider

+dividers

+divides

+dividing

+divine

+divined

+divinely

+diviner

+divines

+diving

+divining

+divinities

+divinity

+divinity's

+division

+division's

+divisions

+divisor

+divisor's

+divisors

+divorce

+divorced

+divorces

+divorcing

+divulge

+divulged

+divulges

+divulging

+dizzied

+dizzier

+dizziness

+dizzy

+dizzying

+dizzyingly

+do

+dock

+docked

+docker

+docking

+docks

+doctor

+doctor's

+doctoral

+doctorate

+doctorate's

+doctorates

+doctored

+doctoring

+doctors

+doctrine

+doctrine's

+doctrines

+document

+document's

+documentaries

+documentary

+documentary's

+documentation

+documentation's

+documentations

+documented

+documenter

+documenters

+documenting

+documents

+dodge

+dodged

+dodger

+dodgers

+dodges

+dodging

+doer

+doers

+does

+doesn't

+dog

+dog's

+dogged

+doggedly

+doggedness

+dogging

+dogma

+dogma's

+dogmas

+dogmatism

+dogs

+doing

+doings

+dole

+doled

+doleful

+dolefully

+dolefulness

+doles

+doling

+doll

+doll's

+dollar

+dollars

+dollied

+dollies

+dolls

+dolly

+dolly's

+dollying

+dolphin

+dolphin's

+dolphins

+domain

+domain's

+domains

+dome

+domed

+domes

+domestic

+domestically

+domesticate

+domesticated

+domesticates

+domesticating

+domestication

+dominance

+dominant

+dominantly

+dominate

+dominated

+dominates

+dominating

+domination

+dominations

+dominative

+doming

+dominion

+dominions

+don

+don't

+donate

+donated

+donates

+donating

+donation

+donations

+donative

+done

+donkey

+donkey's

+donkeys

+dons

+doom

+doomed

+dooming

+dooms

+door

+door's

+doors

+doorstep

+doorstep's

+doorsteps

+doorway

+doorway's

+doorways

+dope

+doped

+doper

+dopers

+dopes

+doping

+dormant

+dormitories

+dormitory

+dormitory's

+dorsal

+dorsally

+dose

+dosed

+doses

+dosing

+dot

+dot's

+dote

+doted

+doter

+dotes

+doth

+doting

+dotingly

+dots

+dotted

+dotting

+double

+doubled

+doubleness

+doubler

+doublers

+doubles

+doublet

+doublet's

+doublets

+doubling

+doubly

+doubt

+doubtable

+doubted

+doubter

+doubters

+doubtful

+doubtfully

+doubtfulness

+doubting

+doubtingly

+doubtless

+doubtlessly

+doubtlessness

+doubts

+dough

+doughnut

+doughnut's

+doughnuts

+douse

+doused

+douser

+douses

+dousing

+dove

+dover

+doves

+down

+downcast

+downed

+downer

+downers

+downfall

+downfallen

+downier

+downing

+downplay

+downplayed

+downplaying

+downplays

+downright

+downrightly

+downrightness

+downs

+downstairs

+downstream

+downtown

+downtowner

+downtowns

+downward

+downwardly

+downwardness

+downwards

+downy

+doze

+dozed

+dozen

+dozens

+dozenth

+dozer

+dozes

+dozing

+drab

+drably

+drabness

+drabs

+draft

+draft's

+drafted

+drafter

+drafters

+drafting

+drafts

+draftsmen

+drag

+dragged

+dragging

+draggingly

+dragon

+dragon's

+dragons

+dragoon

+dragooned

+dragoons

+drags

+drain

+drainage

+drainages

+drained

+drainer

+drainers

+draining

+drains

+drake

+drama

+drama's

+dramas

+dramatic

+dramatically

+dramatics

+dramatist

+dramatist's

+dramatists

+drank

+drape

+draped

+draper

+draperies

+drapers

+drapery

+drapery's

+drapes

+draping

+drastic

+drastically

+draw

+drawback

+drawback's

+drawbacks

+drawbridge

+drawbridge's

+drawbridges

+drawer

+drawers

+drawing

+drawings

+drawl

+drawled

+drawler

+drawling

+drawlingly

+drawls

+drawly

+drawn

+drawnly

+drawnness

+draws

+dread

+dreaded

+dreadful

+dreadfully

+dreadfulness

+dreading

+dreads

+dream

+dreamed

+dreamer

+dreamers

+dreamier

+dreamily

+dreaminess

+dreaming

+dreamingly

+dreams

+dreamy

+drearier

+dreariness

+dreary

+dredge

+dredge's

+dredged

+dredger

+dredgers

+dredges

+dredging

+dregs

+drench

+drenched

+drencher

+drenches

+drenching

+dress

+dressed

+dresser

+dressers

+dresses

+dressing

+dressings

+dressmaker

+dressmaker's

+dressmakers

+drew

+dried

+drier

+drier's

+driers

+dries

+driest

+drift

+drifted

+drifter

+drifters

+drifting

+driftingly

+drifts

+drill

+drilled

+driller

+drilling

+drills

+drily

+drink

+drinkable

+drinker

+drinkers

+drinking

+drinks

+drip

+drip's

+drips

+drive

+driven

+drivenness

+driver

+driver's

+drivers

+drives

+driveway

+driveway's

+driveways

+driving

+drone

+drone's

+droner

+drones

+droning

+droningly

+drool

+drooled

+drooler

+drooling

+drools

+droop

+drooped

+drooping

+droopingly

+droops

+drop

+drop's

+dropped

+dropper

+dropper's

+droppers

+dropping

+dropping's

+droppings

+drops

+drought

+drought's

+droughts

+drove

+drover

+drovers

+droves

+drown

+drowned

+drowner

+drowning

+drownings

+drowns

+drowsier

+drowsiest

+drowsiness

+drowsy

+drudgery

+drug

+drug's

+druggist

+druggist's

+druggists

+drugs

+drum

+drum's

+drummed

+drummer

+drummer's

+drummers

+drumming

+drums

+drunk

+drunk's

+drunkard

+drunkard's

+drunkards

+drunken

+drunkenly

+drunkenness

+drunker

+drunkly

+drunks

+dry

+drying

+dryly

+dual

+dualities

+duality

+duality's

+dually

+duals

+dub

+dubious

+dubiously

+dubiousness

+dubs

+duchess

+duchess's

+duchesses

+duchies

+duchy

+duck

+ducked

+ducker

+ducking

+ducks

+dude

+due

+duel

+duels

+dueness

+dues

+dug

+duke

+duke's

+dukes

+dull

+dulled

+duller

+dullest

+dulling

+dullness

+dulls

+dully

+duly

+dumb

+dumbbell

+dumbbell's

+dumbbells

+dumber

+dumbest

+dumbly

+dumbness

+dummied

+dummies

+dummy

+dummy's

+dummying

+dump

+dumped

+dumper

+dumpers

+dumping

+dumps

+dunce

+dunce's

+dunces

+dune

+dune's

+dunes

+dungeon

+dungeon's

+dungeons

+duplicate

+duplicated

+duplicates

+duplicating

+duplication

+duplications

+duplicative

+duplicator

+duplicator's

+duplicators

+durabilities

+durability

+durable

+durableness

+durables

+durably

+duration

+duration's

+durations

+during

+dusk

+duskier

+duskiness

+dusky

+dust

+dusted

+duster

+dusters

+dustier

+dustiest

+dustiness

+dusting

+dusts

+dusty

+duties

+dutiful

+dutifully

+dutifulness

+duty

+duty's

+dwarf

+dwarfed

+dwarfness

+dwarfs

+dwell

+dwelled

+dweller

+dwellers

+dwelling

+dwellings

+dwells

+dwindle

+dwindled

+dwindles

+dwindling

+dye

+dyed

+dyeing

+dyer

+dyers

+dyes

+dying

+dynamic

+dynamically

+dynamics

+dynamite

+dynamited

+dynamiter

+dynamites

+dynamiting

+dynasties

+dynasty

+dynasty's

+each

+eager

+eagerly

+eagerness

+eagle

+eagle's

+eagles

+ear

+eared

+earing

+earl

+earl's

+earlier

+earliest

+earliness

+earls

+early

+earmark

+earmarked

+earmarking

+earmarkings

+earmarks

+earn

+earned

+earner

+earner's

+earners

+earnest

+earnestly

+earnestness

+earning

+earnings

+earns

+earring

+earring's

+earrings

+ears

+earshot

+earth

+earth's

+earthed

+earthen

+earthenware

+earthliness

+earthly

+earthquake

+earthquake's

+earthquakes

+earths

+earthworm

+earthworm's

+earthworms

+ease

+eased

+easement

+easement's

+easements

+easer

+eases

+easier

+easiest

+easily

+easiness

+easing

+east

+easter

+easterly

+eastern

+easterner

+easterners

+easting

+easts

+eastward

+eastwards

+easy

+eat

+eaten

+eater

+eaters

+eating

+eatings

+eats

+eaves

+eavesdrop

+eavesdropped

+eavesdropper

+eavesdropper's

+eavesdroppers

+eavesdropping

+eavesdrops

+ebb

+ebbed

+ebbing

+ebbs

+ebony

+eccentric

+eccentric's

+eccentricities

+eccentricity

+eccentrics

+ecclesiastical

+ecclesiastically

+echo

+echoed

+echoes

+echoing

+echos

+eclipse

+eclipsed

+eclipses

+eclipsing

+ecology

+economic

+economical

+economically

+economics

+economies

+economist

+economist's

+economists

+economy

+economy's

+ecstasy

+eddied

+eddies

+eddy

+eddy's

+eddying

+edge

+edged

+edger

+edges

+edging

+edible

+edibleness

+edibles

+edict

+edict's

+edicts

+edifice

+edifice's

+edifices

+edit

+edited

+editing

+edition

+edition's

+editions

+editor

+editor's

+editorial

+editorially

+editorials

+editors

+edits

+educate

+educated

+educatedly

+educatedness

+educates

+educating

+education

+education's

+educational

+educationally

+educations

+educative

+educator

+educator's

+educators

+eel

+eel's

+eels

+eerie

+eerier

+effect

+effected

+effecting

+effective

+effectively

+effectiveness

+effectives

+effector

+effector's

+effectors

+effects

+effectually

+effeminate

+efficacy

+efficiencies

+efficiency

+efficient

+efficiently

+effigy

+effort

+effort's

+effortless

+effortlessly

+effortlessness

+efforts

+egg

+egged

+egger

+egging

+eggs

+ego

+egos

+eigenvalue

+eigenvalue's

+eigenvalues

+eight

+eighteen

+eighteens

+eighteenth

+eighth

+eighth's

+eighthes

+eighties

+eightieth

+eights

+eighty

+either

+ejaculate

+ejaculated

+ejaculates

+ejaculating

+ejaculation

+ejaculations

+eject

+ejected

+ejecting

+ejective

+ejects

+eke

+eked

+ekes

+eking

+el

+elaborate

+elaborated

+elaborately

+elaborateness

+elaborates

+elaborating

+elaboration

+elaborations

+elaborative

+elaborators

+elapse

+elapsed

+elapses

+elapsing

+elastic

+elastically

+elasticities

+elasticity

+elastics

+elate

+elated

+elatedly

+elatedness

+elater

+elates

+elating

+elation

+elbow

+elbowed

+elbowing

+elbows

+elder

+elderliness

+elderly

+elders

+eldest

+elect

+elected

+electing

+election

+election's

+elections

+elective

+electively

+electiveness

+electives

+elector

+elector's

+electoral

+electorally

+electors

+electric

+electrical

+electrically

+electricalness

+electricities

+electricity

+electrics

+electrification

+electrified

+electrify

+electrifying

+electrocute

+electrocuted

+electrocutes

+electrocuting

+electrocution

+electrocutions

+electrode

+electrode's

+electrodes

+electrolyte

+electrolyte's

+electrolytes

+electrolytic

+electron

+electron's

+electronic

+electronically

+electronics

+electrons

+elects

+elegance

+elegances

+elegant

+elegantly

+element

+element's

+elemental

+elementally

+elementals

+elementariness

+elementary

+elements

+elephant

+elephant's

+elephants

+elevate

+elevated

+elevates

+elevating

+elevation

+elevations

+elevator

+elevator's

+elevators

+eleven

+elevens

+elevenses

+eleventh

+elf

+elicit

+elicited

+eliciting

+elicits

+eligibilities

+eligibility

+eligible

+eligibles

+eliminate

+eliminated

+eliminately

+eliminates

+eliminating

+elimination

+eliminations

+eliminative

+eliminator

+eliminators

+elk

+elk's

+elks

+ellipse

+ellipse's

+ellipses

+ellipsis

+ellipsoid

+ellipsoid's

+ellipsoidal

+ellipsoids

+elliptic

+elliptical

+elliptically

+elm

+elmer

+elms

+elongate

+elongated

+elongates

+elongating

+elongation

+eloquence

+eloquent

+eloquently

+els

+else

+else's

+elsewhere

+elucidate

+elucidated

+elucidates

+elucidating

+elucidation

+elucidative

+elude

+eluded

+eludes

+eluding

+elusive

+elusively

+elusiveness

+elves

+emaciated

+emacs

+emacs's

+email

+email's

+emanating

+emancipation

+embark

+embarked

+embarking

+embarks

+embarrass

+embarrassed

+embarrassedly

+embarrasses

+embarrassing

+embarrassingly

+embarrassment

+embassies

+embassy

+embassy's

+embed

+embedded

+embedding

+embeds

+embellish

+embellished

+embellisher

+embellishes

+embellishing

+embellishment

+embellishment's

+embellishments

+ember

+embers

+embezzle

+embezzled

+embezzler

+embezzler's

+embezzlers

+embezzles

+embezzling

+emblem

+emblems

+embodied

+embodier

+embodies

+embodiment

+embodiment's

+embodiments

+embody

+embodying

+embrace

+embraced

+embracer

+embraces

+embracing

+embracingly

+embracive

+embroider

+embroidered

+embroiderer

+embroideries

+embroiders

+embroidery

+embryo

+embryo's

+embryology

+embryos

+emerald

+emerald's

+emeralds

+emerge

+emerged

+emergence

+emergencies

+emergency

+emergency's

+emergent

+emerges

+emerging

+emeries

+emery

+emigrant

+emigrant's

+emigrants

+emigrate

+emigrated

+emigrates

+emigrating

+emigration

+eminence

+eminent

+eminently

+emit

+emits

+emitted

+emotion

+emotion's

+emotional

+emotionally

+emotions

+empathy

+emperor

+emperor's

+emperors

+emphases

+emphasis

+emphatic

+emphatically

+empire

+empire's

+empires

+empirical

+empirically

+empiricist

+empiricist's

+empiricists

+employ

+employable

+employed

+employee

+employee's

+employees

+employer

+employer's

+employers

+employing

+employment

+employment's

+employments

+employs

+empower

+empowered

+empowering

+empowers

+empress

+emptied

+emptier

+empties

+emptiest

+emptily

+emptiness

+empty

+emptying

+emulate

+emulated

+emulates

+emulating

+emulation

+emulations

+emulative

+emulatively

+emulator

+emulator's

+emulators

+enable

+enabled

+enabler

+enablers

+enables

+enabling

+enact

+enacted

+enacting

+enactment

+enactments

+enacts

+enamel

+enamels

+encamp

+encamped

+encamping

+encamps

+encapsulate

+encapsulated

+encapsulates

+encapsulating

+encapsulation

+enchant

+enchanted

+enchanter

+enchanting

+enchantingly

+enchantment

+enchants

+encipher

+enciphered

+encipherer

+enciphering

+enciphers

+encircle

+encircled

+encircles

+encircling

+enclose

+enclosed

+encloses

+enclosing

+enclosure

+enclosure's

+enclosures

+encode

+encoded

+encoder

+encoders

+encodes

+encoding

+encodings

+encompass

+encompassed

+encompasses

+encompassing

+encounter

+encountered

+encountering

+encounters

+encourage

+encouraged

+encouragement

+encouragements

+encourager

+encourages

+encouraging

+encouragingly

+encrypt

+encrypted

+encrypting

+encryption

+encryption's

+encryptions

+encrypts

+encumber

+encumbered

+encumbering

+encumbers

+encyclopedia

+encyclopedia's

+encyclopedias

+encyclopedic

+end

+endanger

+endangered

+endangering

+endangers

+endear

+endeared

+endearing

+endearingly

+endears

+ended

+endemic

+ender

+enders

+ending

+endings

+endive

+endless

+endlessly

+endlessness

+endorse

+endorsed

+endorsement

+endorsement's

+endorsements

+endorser

+endorses

+endorsing

+endow

+endowed

+endowing

+endowment

+endowment's

+endowments

+endows

+ends

+endurable

+endurably

+endurance

+endure

+endured

+endures

+enduring

+enduringly

+enduringness

+enema

+enema's

+enemas

+enemies

+enemy

+enemy's

+energetic

+energetics

+energies

+energy

+enforce

+enforced

+enforcedly

+enforcement

+enforcer

+enforcers

+enforces

+enforcing

+enfranchise

+enfranchised

+enfranchisement

+enfranchiser

+enfranchises

+enfranchising

+engage

+engaged

+engagement

+engagement's

+engagements

+engages

+engaging

+engagingly

+engender

+engendered

+engendering

+engenders

+engine

+engine's

+engined

+engineer

+engineer's

+engineered

+engineering

+engineeringly

+engineerings

+engineers

+engines

+engining

+england

+englander

+englanders

+engrave

+engraved

+engraver

+engravers

+engraves

+engraving

+engravings

+engross

+engrossed

+engrossedly

+engrosser

+engrossing

+engrossingly

+enhance

+enhanced

+enhancement

+enhancement's

+enhancements

+enhances

+enhancing

+enigmatic

+enjoin

+enjoined

+enjoining

+enjoins

+enjoy

+enjoyable

+enjoyableness

+enjoyably

+enjoyed

+enjoying

+enjoyment

+enjoys

+enlarge

+enlarged

+enlargement

+enlargement's

+enlargements

+enlarger

+enlargers

+enlarges

+enlarging

+enlighten

+enlightened

+enlightening

+enlightenment

+enlightens

+enlist

+enlisted

+enlister

+enlisting

+enlistment

+enlistments

+enlists

+enliven

+enlivened

+enlivening

+enlivens

+enmities

+enmity

+ennoble

+ennobled

+ennobler

+ennobles

+ennobling

+ennui

+enormities

+enormity

+enormous

+enormously

+enormousness

+enough

+enqueue

+enqueued

+enqueues

+enquire

+enquired

+enquirer

+enquirers

+enquires

+enquiring

+enrage

+enraged

+enrages

+enraging

+enrich

+enriched

+enricher

+enriches

+enriching

+enrolled

+enrolling

+ensemble

+ensemble's

+ensembles

+ensign

+ensign's

+ensigns

+enslave

+enslaved

+enslaver

+enslavers

+enslaves

+enslaving

+ensnare

+ensnared

+ensnares

+ensnaring

+ensue

+ensued

+ensues

+ensuing

+ensure

+ensured

+ensurer

+ensurers

+ensures

+ensuring

+entail

+entailed

+entailer

+entailing

+entails

+entangle

+entangled

+entangler

+entangles

+entangling

+enter

+entered

+enterer

+entering

+enterprise

+enterpriser

+enterprises

+enterprising

+enterprisingly

+enters

+entertain

+entertained

+entertainer

+entertainers

+entertaining

+entertainingly

+entertainment

+entertainment's

+entertainments

+entertains

+enthusiasm

+enthusiasms

+enthusiast

+enthusiast's

+enthusiastic

+enthusiastically

+enthusiasts

+entice

+enticed

+enticer

+enticers

+entices

+enticing

+entire

+entirely

+entireties

+entirety

+entities

+entitle

+entitled

+entitles

+entitling

+entity

+entity's

+entrance

+entranced

+entrances

+entrancing

+entreat

+entreated

+entreaties

+entreating

+entreatingly

+entreats

+entreaty

+entrench

+entrenched

+entrenches

+entrenching

+entrepreneur

+entrepreneur's

+entrepreneurs

+entries

+entropies

+entropy

+entrust

+entrusted

+entrusting

+entrusts

+entry

+entry's

+enumerable

+enumerate

+enumerated

+enumerates

+enumerating

+enumeration

+enumerations

+enumerative

+enumerator

+enumerator's

+enumerators

+enunciation

+envelop

+envelope

+enveloped

+enveloper

+envelopes

+enveloping

+envelops

+enviably

+envied

+envier

+envies

+envious

+enviously

+enviousness

+environ

+environed

+environing

+environment

+environment's

+environmental

+environmentally

+environments

+environs

+envisage

+envisaged

+envisages

+envisaging

+envision

+envisioned

+envisioning

+envisions

+envoy

+envoy's

+envoys

+envy

+envying

+envyingly

+epaulet

+epaulet's

+epaulets

+ephemeral

+ephemerally

+ephemerals

+epic

+epic's

+epics

+epidemic

+epidemic's

+epidemics

+episcopal

+episcopally

+episode

+episode's

+episodes

+episodic

+epistemological

+epistemologically

+epistemology

+epistle

+epistle's

+epistler

+epistles

+epitaph

+epitaphed

+epitaphing

+epitaphs

+epitaxial

+epitaxially

+epithet

+epithet's

+epithets

+epoch

+epochs

+epsilon

+epsilons

+equal

+equalities

+equality

+equality's

+equally

+equals

+equate

+equated

+equates

+equating

+equation

+equations

+equator

+equator's

+equatorial

+equators

+equilibrium

+equilibriums

+equip

+equipment

+equipments

+equipped

+equipping

+equips

+equitable

+equitableness

+equitably

+equities

+equity

+equivalence

+equivalenced

+equivalences

+equivalencing

+equivalent

+equivalently

+equivalents

+era

+era's

+eradicate

+eradicated

+eradicates

+eradicating

+eradication

+eradicative

+eras

+erasable

+erase

+erased

+eraser

+erasers

+erases

+erasing

+erasion

+erasure

+ere

+erect

+erected

+erecting

+erection

+erection's

+erections

+erectly

+erectness

+erector

+erector's

+erectors

+erects

+ergo

+ermine

+ermine's

+ermined

+ermines

+err

+errand

+errands

+erratic

+erred

+erring

+erringly

+erroneous

+erroneously

+erroneousness

+error

+error's

+errors

+errs

+eruption

+eruptions

+escalate

+escalated

+escalates

+escalating

+escalation

+escapable

+escapade

+escapade's

+escapades

+escape

+escaped

+escapee

+escapee's

+escapees

+escaper

+escapes

+escaping

+eschew

+eschewed

+eschewing

+eschews

+escort

+escorted

+escorting

+escorts

+esoteric

+especial

+especially

+espied

+espies

+espionage

+espouse

+espoused

+espouser

+espouses

+espousing

+esprit

+esprits

+espy

+espying

+esquire

+esquires

+essay

+essayed

+essayer

+essays

+essence

+essence's

+essences

+essential

+essentially

+essentialness

+essentials

+establish

+established

+establisher

+establishes

+establishing

+establishment

+establishment's

+establishments

+estate

+estate's

+estates

+esteem

+esteemed

+esteeming

+esteems

+estimate

+estimated

+estimates

+estimating

+estimation

+estimations

+estimative

+etc

+eternal

+eternally

+eternalness

+eternities

+eternity

+ethereal

+ethereally

+etherealness

+ethic

+ethical

+ethically

+ethicalness

+ethics

+ethnic

+etiquette

+eunuch

+eunuchs

+euphemism

+euphemism's

+euphemisms

+euphoria

+evacuate

+evacuated

+evacuates

+evacuating

+evacuation

+evacuations

+evacuative

+evade

+evaded

+evader

+evades

+evading

+evaluate

+evaluated

+evaluates

+evaluating

+evaluation

+evaluations

+evaluative

+evaluator

+evaluator's

+evaluators

+evaporate

+evaporated

+evaporates

+evaporating

+evaporation

+evaporations

+evaporative

+evaporatively

+eve

+even

+evened

+evener

+evenhanded

+evenhandedly

+evenhandedness

+evening

+evening's

+evenings

+evenly

+evenness

+evens

+event

+event's

+eventful

+eventfully

+eventfulness

+events

+eventual

+eventualities

+eventuality

+eventually

+ever

+everest

+evergreen

+everlasting

+everlastingly

+everlastingness

+evermore

+every

+everybody

+everybody's

+everyday

+everydayness

+everyone

+everyone's

+everyones

+everything

+everywhere

+eves

+evict

+evicted

+evicting

+eviction

+eviction's

+evictions

+evicts

+evidence

+evidenced

+evidences

+evidencing

+evident

+evidently

+evil

+evilly

+evilness

+evils

+evince

+evinced

+evinces

+evincing

+evoke

+evoked

+evokes

+evoking

+evolute

+evolute's

+evolutes

+evolution

+evolution's

+evolutionary

+evolutions

+evolve

+evolved

+evolves

+evolving

+ewe

+ewe's

+ewer

+ewes

+exacerbate

+exacerbated

+exacerbates

+exacerbating

+exacerbation

+exacerbations

+exact

+exacted

+exacter

+exacting

+exactingly

+exactingness

+exaction

+exaction's

+exactions

+exactitude

+exactly

+exactness

+exacts

+exaggerate

+exaggerated

+exaggeratedly

+exaggeratedness

+exaggerates

+exaggerating

+exaggeration

+exaggerations

+exaggerative

+exaggeratively

+exalt

+exalted

+exaltedly

+exalter

+exalters

+exalting

+exalts

+exam

+exam's

+examen

+examination

+examination's

+examinations

+examine

+examined

+examiner

+examiners

+examines

+examining

+example

+example's

+exampled

+examples

+exampling

+exams

+exasperate

+exasperated

+exasperatedly

+exasperates

+exasperating

+exasperatingly

+exasperation

+exasperations

+excavate

+excavated

+excavates

+excavating

+excavation

+excavations

+exceed

+exceeded

+exceeder

+exceeding

+exceedingly

+exceeds

+excel

+excelled

+excellence

+excellences

+excellency

+excellent

+excellently

+excelling

+excels

+except

+excepted

+excepting

+exception

+exception's

+exceptional

+exceptionally

+exceptionalness

+exceptions

+exceptive

+excepts

+excerpt

+excerpted

+excerpter

+excerpts

+excess

+excesses

+excessive

+excessively

+excessiveness

+exchange

+exchangeable

+exchanged

+exchanger

+exchangers

+exchanges

+exchanging

+exchequer

+exchequer's

+exchequers

+excise

+excised

+excises

+excising

+excision

+excisions

+excitable

+excitableness

+excitation

+excitation's

+excitations

+excite

+excited

+excitedly

+excitement

+exciter

+excites

+exciting

+excitingly

+exclaim

+exclaimed

+exclaimer

+exclaimers

+exclaiming

+exclaims

+exclamation

+exclamation's

+exclamations

+exclude

+excluded

+excluder

+excludes

+excluding

+exclusion

+exclusioner

+exclusioners

+exclusions

+exclusive

+exclusively

+exclusiveness

+exclusivity

+excommunicate

+excommunicated

+excommunicates

+excommunicating

+excommunication

+excommunicative

+excrete

+excreted

+excreter

+excretes

+excreting

+excretion

+excretions

+excruciatingly

+excursion

+excursion's

+excursions

+excusable

+excusableness

+excusably

+excuse

+excused

+excuser

+excuses

+excusing

+executable

+executable's

+executables

+execute

+executed

+executer

+executers

+executes

+executing

+execution

+executional

+executioner

+executions

+executive

+executive's

+executives

+executor

+executor's

+executors

+exemplar

+exemplariness

+exemplars

+exemplary

+exemplification

+exemplified

+exemplifier

+exemplifiers

+exemplifies

+exemplify

+exemplifying

+exempt

+exempted

+exempting

+exempts

+exercise

+exercised

+exerciser

+exercisers

+exercises

+exercising

+exert

+exerted

+exerting

+exertion

+exertion's

+exertions

+exerts

+exhale

+exhaled

+exhales

+exhaling

+exhaust

+exhausted

+exhaustedly

+exhauster

+exhaustible

+exhausting

+exhaustingly

+exhaustion

+exhaustive

+exhaustively

+exhaustiveness

+exhausts

+exhibit

+exhibited

+exhibiting

+exhibition

+exhibition's

+exhibitioner

+exhibitions

+exhibitive

+exhibitor

+exhibitor's

+exhibitors

+exhibits

+exhortation

+exhortation's

+exhortations

+exigencies

+exigency

+exile

+exiled

+exiles

+exiling

+exist

+existed

+existence

+existences

+existent

+existential

+existentialism

+existentialist

+existentialist's

+existentialists

+existentially

+existing

+exists

+exit

+exited

+exiting

+exits

+exorbitant

+exorbitantly

+exoskeletons

+exotic

+exoticness

+expand

+expandable

+expanded

+expander

+expander's

+expanders

+expanding

+expands

+expanse

+expansed

+expanses

+expansing

+expansion

+expansionism

+expansions

+expansive

+expansively

+expansiveness

+expect

+expectancies

+expectancy

+expectant

+expectantly

+expectation

+expectation's

+expectations

+expected

+expectedly

+expectedness

+expecting

+expectingly

+expects

+expedient

+expediently

+expedite

+expedited

+expediter

+expedites

+expediting

+expedition

+expedition's

+expeditions

+expeditious

+expeditiously

+expeditiousness

+expel

+expelled

+expelling

+expels

+expend

+expendable

+expended

+expender

+expending

+expenditure

+expenditure's

+expenditures

+expends

+expense

+expensed

+expenses

+expensing

+expensive

+expensively

+expensiveness

+experience

+experienced

+experiences

+experiencing

+experiment

+experimental

+experimentally

+experimentation

+experimentation's

+experimentations

+experimented

+experimenter

+experimenters

+experimenting

+experiments

+expert

+expertise

+expertly

+expertness

+experts

+expiration

+expiration's

+expirations

+expire

+expired

+expires

+expiring

+explain

+explainable

+explained

+explainer

+explainers

+explaining

+explains

+explanation

+explanation's

+explanations

+explanatory

+explicit

+explicitly

+explicitness

+explode

+exploded

+exploder

+explodes

+exploding

+exploit

+exploitable

+exploitation

+exploitation's

+exploitations

+exploited

+exploiter

+exploiters

+exploiting

+exploitive

+exploits

+exploration

+exploration's

+explorations

+exploratory

+explore

+explored

+explorer

+explorers

+explores

+exploring

+explosion

+explosion's

+explosions

+explosive

+explosively

+explosiveness

+explosives

+exponent

+exponent's

+exponential

+exponentially

+exponentials

+exponentiate

+exponentiated

+exponentiates

+exponentiating

+exponentiation

+exponentiation's

+exponentiations

+exponents

+export

+exported

+exporter

+exporters

+exporting

+exports

+expose

+exposed

+exposer

+exposers

+exposes

+exposing

+exposition

+exposition's

+expositions

+expository

+exposure

+exposure's

+exposures

+expound

+expounded

+expounder

+expounding

+expounds

+express

+expressed

+expresser

+expresses

+expressibility

+expressible

+expressibly

+expressing

+expression

+expression's

+expressions

+expressive

+expressively

+expressiveness

+expressly

+expropriate

+expropriated

+expropriates

+expropriating

+expropriation

+expropriations

+expulsion

+expunge

+expunged

+expunger

+expunges

+expunging

+exquisite

+exquisitely

+exquisiteness

+extant

+extend

+extended

+extendedly

+extendedness

+extender

+extendible

+extendibles

+extending

+extends

+extensibility

+extensible

+extension

+extension's

+extensions

+extensive

+extensively

+extensiveness

+extent

+extent's

+extents

+extenuate

+extenuated

+extenuating

+extenuation

+exterior

+exterior's

+exteriorly

+exteriors

+exterminate

+exterminated

+exterminates

+exterminating

+extermination

+exterminations

+external

+externally

+externals

+extinct

+extinction

+extinctive

+extinguish

+extinguished

+extinguisher

+extinguishers

+extinguishes

+extinguishing

+extol

+extols

+extortion

+extortioner

+extortionist

+extortionist's

+extortionists

+extra

+extract

+extracted

+extracting

+extraction

+extraction's

+extractions

+extractive

+extractively

+extractor

+extractor's

+extractors

+extracts

+extracurricular

+extraneous

+extraneously

+extraneousness

+extraordinarily

+extraordinariness

+extraordinary

+extrapolate

+extrapolated

+extrapolates

+extrapolating

+extrapolation

+extrapolations

+extrapolative

+extras

+extravagance

+extravagant

+extravagantly

+extremal

+extreme

+extremed

+extremely

+extremeness

+extremer

+extremes

+extremest

+extremist

+extremist's

+extremists

+extremities

+extremity

+extremity's

+extrinsic

+exuberance

+exult

+exultation

+exulted

+exulting

+exultingly

+exults

+eye

+eyeball

+eyeballs

+eyebrow

+eyebrow's

+eyebrows

+eyed

+eyedness

+eyeglass

+eyeglasses

+eyeing

+eyelid

+eyelid's

+eyelids

+eyepiece

+eyepiece's

+eyepieces

+eyer

+eyers

+eyes

+eyesight

+eyewitness

+eyewitness's

+eyewitnesses

+eying

+fable

+fabled

+fabler

+fables

+fabling

+fabric

+fabric's

+fabricate

+fabricated

+fabricates

+fabricating

+fabrication

+fabrications

+fabrics

+fabulous

+fabulously

+fabulousness

+facade

+facaded

+facades

+facading

+face

+faced

+faceless

+facelessness

+facer

+faces

+facet

+faceted

+faceting

+facets

+facial

+facially

+facile

+facilely

+facileness

+facilitate

+facilitated

+facilitates

+facilitating

+facilitation

+facilitative

+facilities

+facility

+facility's

+facing

+facings

+facsimile

+facsimile's

+facsimiled

+facsimiles

+facsimiling

+fact

+fact's

+faction

+faction's

+factions

+factor

+factored

+factorial

+factories

+factoring

+factorings

+factors

+factory

+factory's

+facts

+factual

+factually

+factualness

+faculties

+faculty

+faculty's

+fade

+faded

+fadedly

+fader

+faders

+fades

+fading

+fag

+fags

+fail

+failed

+failing

+failingly

+failings

+fails

+failure

+failure's

+failures

+fain

+faint

+fainted

+fainter

+faintest

+fainting

+faintly

+faintness

+faints

+fair

+faired

+fairer

+fairest

+fairies

+fairing

+fairly

+fairness

+fairs

+fairy

+fairy's

+fairyland

+faith

+faithful

+faithfully

+faithfulness

+faithfuls

+faithless

+faithlessly

+faithlessness

+faiths

+fake

+faked

+faker

+fakes

+faking

+falcon

+falconer

+falcons

+fall

+fallacies

+fallacious

+fallaciously

+fallaciousness

+fallacy

+fallacy's

+fallen

+faller

+fallibility

+fallible

+falling

+falls

+false

+falsehood

+falsehood's

+falsehoods

+falsely

+falseness

+falser

+falsest

+falsification

+falsified

+falsifier

+falsifies

+falsify

+falsifying

+falsity

+falter

+faltered

+falterer

+faltering

+falteringly

+falters

+fame

+famed

+fames

+familiar

+familiarities

+familiarity

+familiarly

+familiarness

+familiars

+families

+family

+family's

+famine

+famine's

+famines

+faming

+famish

+famished

+famishes

+famishing

+famous

+famously

+famousness

+fan

+fan's

+fanatic

+fanatic's

+fanatically

+fanatics

+fancied

+fancier

+fancier's

+fanciers

+fancies

+fanciest

+fanciful

+fancifully

+fancifulness

+fancily

+fanciness

+fancy

+fancying

+fang

+fang's

+fanged

+fangs

+fanned

+fanning

+fans

+fantasied

+fantasies

+fantastic

+fantasy

+fantasy's

+far

+faraway

+farce

+farce's

+farces

+farcing

+fare

+fared

+farer

+fares

+farewell

+farewells

+faring

+farm

+farmed

+farmer

+farmer's

+farmers

+farmhouse

+farmhouse's

+farmhouses

+farming

+farms

+farmyard

+farmyard's

+farmyards

+farther

+farthest

+farthing

+fascinate

+fascinated

+fascinates

+fascinating

+fascinatingly

+fascination

+fascinations

+fashion

+fashionable

+fashionableness

+fashionably

+fashioned

+fashioner

+fashioners

+fashioning

+fashions

+fast

+fasted

+fasten

+fastened

+fastener

+fasteners

+fastening

+fastenings

+fastens

+faster

+fastest

+fasting

+fastness

+fasts

+fat

+fatal

+fatalities

+fatality

+fatality's

+fatally

+fatals

+fate

+fated

+fates

+father

+father's

+fathered

+fathering

+fatherland

+fatherliness

+fatherly

+fathers

+fathom

+fathomed

+fathoming

+fathoms

+fatigue

+fatigued

+fatigues

+fatiguing

+fatiguingly

+fating

+fatly

+fatness

+fats

+fatten

+fattened

+fattener

+fatteners

+fattening

+fattens

+fatter

+fattest

+fault

+faulted

+faultier

+faultiness

+faulting

+faultless

+faultlessly

+faultlessness

+faults

+faulty

+fawn

+fawned

+fawner

+fawning

+fawningly

+fawns

+fear

+feared

+fearer

+fearful

+fearfully

+fearfulness

+fearing

+fearless

+fearlessly

+fearlessness

+fears

+feasibility

+feasible

+feasibleness

+feast

+feasted

+feaster

+feasting

+feasts

+feat

+feat's

+feather

+feathered

+featherer

+featherers

+feathering

+feathers

+feating

+featly

+feats

+feature

+featured

+featureless

+features

+featuring

+fed

+federal

+federally

+federals

+federation

+feds

+fee

+feeble

+feebleness

+feebler

+feeblest

+feebly

+feed

+feedback

+feedbacks

+feeder

+feeders

+feeding

+feedings

+feeds

+feel

+feeler

+feelers

+feeling

+feelingly

+feelingness

+feelings

+feels

+fees

+feet

+feign

+feigned

+feigner

+feigning

+feigns

+felicities

+felicity

+fell

+felled

+feller

+fellers

+felling

+fellness

+fellow

+fellow's

+fellowly

+fellows

+fellowship

+fellowship's

+fellowships

+fells

+felt

+felted

+felting

+felts

+female

+female's

+femaleness

+females

+feminine

+femininely

+feminineness

+femininity

+feminist

+feminist's

+feminists

+femur

+femur's

+femurs

+fen

+fence

+fenced

+fencer

+fencers

+fences

+fencing

+ferment

+fermentation

+fermentation's

+fermentations

+fermented

+fermenter

+fermenting

+ferments

+fern

+fern's

+ferns

+ferocious

+ferociously

+ferociousness

+ferocity

+ferried

+ferries

+ferrite

+ferry

+ferrying

+fertile

+fertilely

+fertileness

+fertilities

+fertility

+fervent

+fervently

+festival

+festival's

+festivals

+festive

+festively

+festiveness

+festivities

+festivity

+fetch

+fetched

+fetcher

+fetches

+fetching

+fetchingly

+fetter

+fettered

+fettering

+fetters

+feud

+feud's

+feudal

+feudalism

+feudally

+feuds

+fever

+fevered

+fevering

+feverish

+feverishly

+feverishness

+fevers

+few

+fewer

+fewest

+fewness

+fews

+fibrous

+fibrously

+fibrousness

+fickle

+fickleness

+fiction

+fiction's

+fictional

+fictionally

+fictions

+fictitious

+fictitiously

+fictitiousness

+fiddle

+fiddled

+fiddler

+fiddles

+fiddling

+fidelity

+field

+fielded

+fielder

+fielders

+fielding

+fields

+fiend

+fiends

+fierce

+fiercely

+fierceness

+fiercer

+fiercest

+fieriness

+fiery

+fife

+fifteen

+fifteens

+fifteenth

+fifth

+fifthly

+fifties

+fiftieth

+fifty

+fig

+fig's

+fight

+fighter

+fighters

+fighting

+fights

+figs

+figurative

+figuratively

+figurativeness

+figure

+figured

+figurer

+figurers

+figures

+figuring

+figurings

+filament

+filament's

+filaments

+file

+file's

+filed

+filename

+filename's

+filenames

+filer

+filers

+files

+filial

+filially

+filing

+filings

+fill

+fillable

+filled

+filler

+fillers

+filling

+fillings

+fills

+film

+filmed

+filming

+films

+filter

+filter's

+filtered

+filterer

+filtering

+filters

+filth

+filthier

+filthiest

+filthiness

+filthy

+filtration

+filtration's

+fin

+fin's

+final

+finality

+finally

+finals

+finance

+financed

+finances

+financial

+financially

+financier

+financier's

+financiers

+financing

+find

+finder

+finders

+finding

+findings

+finds

+fine

+fined

+finely

+fineness

+finer

+fines

+finest

+finger

+fingered

+fingerer

+fingering

+fingerings

+fingers

+fining

+finish

+finished

+finisher

+finishers

+finishes

+finishing

+finishings

+finite

+finitely

+finiteness

+finites

+fins

+fir

+fire

+firearm

+firearm's

+firearms

+fired

+fireflies

+firefly

+firefly's

+firelight

+firelighting

+fireman

+fireplace

+fireplace's

+fireplaces

+firer

+firers

+fires

+fireside

+firewood

+fireworks

+firing

+firings

+firm

+firm's

+firmament

+firmed

+firmer

+firmest

+firming

+firmly

+firmness

+firms

+firmware

+firmwares

+first

+firsthand

+firstly

+firsts

+firth

+fiscal

+fiscally

+fiscals

+fish

+fished

+fisher

+fisheries

+fisherman

+fisherman's

+fishermen

+fishermen's

+fishers

+fishery

+fishes

+fishing

+fissure

+fissured

+fissures

+fissuring

+fist

+fisted

+fists

+fit

+fitful

+fitfully

+fitfulness

+fitly

+fitness

+fits

+fitted

+fitter

+fitter's

+fitters

+fitting

+fittingly

+fittingness

+fittings

+five

+fiver

+fives

+fix

+fixate

+fixated

+fixates

+fixating

+fixation

+fixations

+fixative

+fixed

+fixedly

+fixedness

+fixer

+fixers

+fixes

+fixing

+fixings

+fixture

+fixture's

+fixtures

+flab

+flabbier

+flabbiness

+flabby

+flag

+flag's

+flagged

+flagging

+flaggingly

+flagrant

+flagrantly

+flags

+flagship

+flagship's

+flagships

+flake

+flaked

+flaker

+flakes

+flaking

+flame

+flamed

+flamer

+flamers

+flames

+flaming

+flamingly

+flammable

+flammables

+flank

+flanked

+flanker

+flankers

+flanking

+flanks

+flannel

+flannel's

+flannels

+flap

+flap's

+flapping

+flaps

+flare

+flared

+flares

+flaring

+flaringly

+flash

+flashed

+flasher

+flashers

+flashes

+flashing

+flashlight

+flashlight's

+flashlights

+flask

+flat

+flatly

+flatness

+flatnesses

+flats

+flatten

+flattened

+flattener

+flattening

+flattens

+flatter

+flattered

+flatterer

+flattering

+flatteringly

+flatters

+flattery

+flattest

+flaunt

+flaunted

+flaunting

+flauntingly

+flaunts

+flaw

+flawed

+flawing

+flawless

+flawlessly

+flawlessness

+flaws

+flax

+flaxen

+flea

+flea's

+fleas

+fled

+fledged

+fledgling

+fledgling's

+fledglings

+flee

+fleece

+fleece's

+fleeced

+fleeces

+fleecier

+fleecy

+fleeing

+fleer

+flees

+fleet

+fleetest

+fleeting

+fleetingly

+fleetingness

+fleetly

+fleetness

+fleets

+flesh

+fleshed

+flesher

+fleshes

+fleshier

+fleshiness

+fleshing

+fleshings

+fleshly

+fleshy

+flew

+flews

+flexibilities

+flexibility

+flexible

+flexibly

+flick

+flicked

+flicker

+flickered

+flickering

+flickeringly

+flicking

+flicks

+flier

+fliers

+flies

+flight

+flight's

+flights

+flinch

+flinched

+flincher

+flinches

+flinching

+fling

+fling's

+flinger

+flinging

+flings

+flint

+flints

+flip

+flips

+flirt

+flirted

+flirter

+flirting

+flirts

+flit

+flits

+float

+floated

+floater

+floaters

+floating

+floats

+flock

+flocked

+flocking

+flocks

+flood

+flooded

+flooder

+flooding

+floods

+floor

+floored

+floorer

+flooring

+floorings

+floors

+flop

+flop's

+floppier

+floppies

+floppily

+floppiness

+floppy

+floppy's

+flops

+flora

+florin

+floss

+flossed

+flosses

+flossing

+flounder

+floundered

+floundering

+flounders

+flour

+floured

+flourish

+flourished

+flourisher

+flourishes

+flourishing

+flourishingly

+flours

+flow

+flowchart

+flowcharting

+flowcharts

+flowed

+flower

+flowered

+flowerer

+floweriness

+flowering

+flowers

+flowery

+flowing

+flowingly

+flown

+flows

+fluctuate

+fluctuated

+fluctuates

+fluctuating

+fluctuation

+fluctuations

+fluent

+fluently

+fluffier

+fluffiest

+fluffiness

+fluffy

+fluid

+fluidity

+fluidly

+fluidness

+fluids

+flung

+flunk

+flunked

+flunker

+flunking

+flunks

+fluorescence

+flurried

+flurries

+flurry

+flurrying

+flush

+flushed

+flushes

+flushing

+flushness

+flute

+flute's

+fluted

+fluter

+flutes

+fluting

+flutter

+fluttered

+flutterer

+fluttering

+flutters

+fly

+flyable

+flyer

+flyer's

+flyers

+flying

+foam

+foamed

+foamer

+foaming

+foams

+focal

+focally

+foci

+focus

+focusable

+focused

+focuser

+focuses

+focusing

+fodder

+foe

+foe's

+foes

+fog

+fog's

+fogged

+foggier

+foggiest

+foggily

+fogginess

+fogging

+foggy

+fogs

+foil

+foiled

+foiling

+foils

+fold

+folded

+folder

+folders

+folding

+foldings

+folds

+foliage

+foliaged

+foliages

+folk

+folk's

+folklore

+folks

+follies

+follow

+followed

+follower

+followers

+following

+followings

+follows

+folly

+fond

+fonder

+fondest

+fondle

+fondled

+fondler

+fondles

+fondling

+fondly

+fondness

+fonds

+font

+font's

+fonts

+food

+food's

+foods

+foodstuff

+foodstuff's

+foodstuffs

+fool

+fooled

+fooling

+foolish

+foolishly

+foolishness

+foolproof

+fools

+foot

+football

+football's

+footballed

+footballer

+footballers

+footballs

+footed

+footer

+footers

+foothold

+footholds

+footing

+footings

+footman

+footnote

+footnote's

+footnotes

+footprint

+footprint's

+footprints

+foots

+footstep

+footsteps

+for

+forage

+foraged

+forager

+forages

+foraging

+foray

+foray's

+forayer

+forays

+forbade

+forbear

+forbear's

+forbearance

+forbearer

+forbearing

+forbears

+forbid

+forbidden

+forbidding

+forbiddingly

+forbiddingness

+forbids

+force

+force's

+forced

+forcedly

+forcefield

+forcefield's

+forcefields

+forceful

+forcefully

+forcefulness

+forcer

+forces

+forcible

+forcibleness

+forcibly

+forcing

+ford

+fords

+fore

+forearm

+forearm's

+forearmed

+forearms

+foreboding

+forebodingly

+forebodingness

+forebodings

+forecast

+forecasted

+forecaster

+forecasters

+forecasting

+forecastle

+forecastles

+forecasts

+forefather

+forefather's

+forefathers

+forefinger

+forefinger's

+forefingers

+forego

+foregoer

+foregoes

+foregoing

+foregone

+foreground

+foregrounds

+forehead

+forehead's

+foreheads

+foreign

+foreigner

+foreigners

+foreignly

+foreignness

+foreigns

+foreman

+foremost

+forenoon

+foresee

+foreseeable

+foreseen

+foreseer

+foresees

+foresight

+foresighted

+foresightedly

+foresightedness

+forest

+forestall

+forestalled

+forestaller

+forestalling

+forestallment

+forestalls

+forested

+forester

+foresters

+forests

+foretell

+foreteller

+foretelling

+foretells

+forethought

+forethought's

+foretold

+forever

+foreverness

+forewarn

+forewarned

+forewarner

+forewarning

+forewarnings

+forewarns

+forfeit

+forfeited

+forfeiter

+forfeiters

+forfeiting

+forfeits

+forgave

+forge

+forged

+forger

+forgeries

+forgers

+forgery

+forgery's

+forges

+forget

+forgetful

+forgetfully

+forgetfulness

+forgetive

+forgets

+forgettable

+forgettably

+forgetting

+forging

+forgivable

+forgivably

+forgive

+forgiven

+forgiveness

+forgiver

+forgives

+forgiving

+forgivingly

+forgivingness

+forgot

+forgotten

+fork

+forked

+forker

+forking

+forks

+forlorn

+forlornly

+forlornness

+form

+formal

+formalism

+formalism's

+formalisms

+formalities

+formality

+formally

+formalness

+formals

+formant

+formants

+format

+formated

+formating

+formation

+formation's

+formations

+formative

+formatively

+formativeness

+formats

+formatted

+formatter

+formatter's

+formatters

+formatting

+formed

+former

+formerly

+formers

+formidable

+formidableness

+forming

+forms

+formula

+formula's

+formulae

+formulas

+formulate

+formulated

+formulates

+formulating

+formulation

+formulations

+formulator

+formulator's

+formulators

+fornication

+forsake

+forsaken

+forsakes

+forsaking

+fort

+fort's

+forte

+fortes

+forth

+forthcoming

+forthwith

+fortier

+forties

+fortieth

+fortification

+fortifications

+fortified

+fortifier

+fortifies

+fortify

+fortifying

+fortitude

+fortnight

+fortnightly

+fortress

+fortress's

+fortresses

+forts

+fortuitous

+fortuitously

+fortuitousness

+fortunate

+fortunately

+fortunateness

+fortunates

+fortune

+fortune's

+fortuned

+fortunes

+fortuning

+forty

+forum

+forum's

+forums

+forward

+forwarded

+forwarder

+forwarders

+forwarding

+forwardly

+forwardness

+forwards

+fossil

+fossils

+foster

+fostered

+fosterer

+fostering

+fosters

+fought

+foul

+fouled

+fouler

+foulest

+fouling

+foully

+foulness

+fouls

+found

+foundation

+foundation's

+foundations

+founded

+founder

+foundered

+foundering

+founders

+founding

+foundries

+foundry

+foundry's

+founds

+fount

+fount's

+fountain

+fountain's

+fountains

+founts

+four

+fours

+fourscore

+fourteen

+fourteener

+fourteens

+fourteenth

+fourth

+fourthly

+fowl

+fowler

+fowling

+fowls

+fox

+fox's

+foxed

+foxes

+foxing

+fractal

+fractal's

+fractals

+fraction

+fraction's

+fractional

+fractionally

+fractioned

+fractioning

+fractions

+fracture

+fractured

+fractures

+fracturing

+fragile

+fragilely

+fragment

+fragmentariness

+fragmentary

+fragmented

+fragmenting

+fragments

+fragrance

+fragrance's

+fragrances

+fragrant

+fragrantly

+frail

+frailer

+frailest

+frailly

+frailness

+frailties

+frailty

+frame

+frame's

+framed

+framer

+framers

+frames

+framework

+framework's

+frameworks

+framing

+framings

+franc

+franchise

+franchise's

+franchised

+franchiser

+franchises

+franchising

+francs

+frank

+franked

+franker

+frankest

+franking

+frankly

+frankness

+franks

+frantic

+frantically

+franticly

+franticness

+fraternal

+fraternally

+fraternities

+fraternity

+fraternity's

+fraud

+fraud's

+frauds

+fraudulently

+fraught

+fraughted

+fraughting

+fraughts

+fray

+frayed

+fraying

+frays

+freak

+freak's

+freaks

+freckle

+freckled

+freckles

+freckling

+free

+freed

+freedom

+freedom's

+freedoms

+freeing

+freeings

+freely

+freeman

+freeness

+freer

+frees

+freest

+freeway

+freeway's

+freeways

+freeze

+freezer

+freezers

+freezes

+freezing

+freight

+freighted

+freighter

+freighters

+freighting

+freights

+frenzied

+frenziedly

+frenzies

+frenzy

+frenzying

+frequencies

+frequency

+frequent

+frequented

+frequenter

+frequenters

+frequenting

+frequently

+frequentness

+frequents

+fresh

+freshen

+freshened

+freshener

+fresheners

+freshening

+freshens

+fresher

+freshers

+freshest

+freshly

+freshman

+freshmen

+freshness

+fret

+fretful

+fretfully

+fretfulness

+frets

+friar

+friar's

+friarly

+friars

+frication

+fricative

+fricatives

+friction

+friction's

+frictionless

+frictionlessly

+frictions

+fried

+friend

+friend's

+friendless

+friendlessness

+friendlier

+friendlies

+friendliest

+friendliness

+friendly

+friends

+friendship

+friendship's

+friendships

+frier

+fries

+frieze

+frieze's

+friezes

+frigate

+frigate's

+frigates

+fright

+frighten

+frightened

+frightening

+frighteningly

+frightens

+frightful

+frightfully

+frightfulness

+frill

+frill's

+frilled

+frills

+fringe

+fringed

+fringes

+fringing

+frisk

+frisked

+frisker

+frisking

+frisks

+frivolous

+frivolously

+frivolousness

+frock

+frock's

+frocked

+frocking

+frocks

+frog

+frog's

+frogs

+frolic

+frolics

+from

+front

+fronted

+frontier

+frontier's

+frontiers

+fronting

+fronts

+frost

+frosted

+frostier

+frostiness

+frosting

+frosts

+frosty

+froth

+frothing

+frown

+frowned

+frowner

+frowning

+frowningly

+frowns

+froze

+frozen

+frozenly

+frozenness

+frugal

+frugally

+fruit

+fruit's

+fruited

+fruiter

+fruiterer

+fruitful

+fruitfully

+fruitfulness

+fruition

+fruitless

+fruitlessly

+fruitlessness

+fruits

+frustrate

+frustrated

+frustrater

+frustrates

+frustrating

+frustratingly

+frustration

+frustrations

+fry

+frying

+fuel

+fuels

+fugitive

+fugitive's

+fugitively

+fugitiveness

+fugitives

+fulfilled

+fulfiller

+fulfilling

+full

+fuller

+fullest

+fullness

+fullword

+fullword's

+fullwords

+fully

+fumble

+fumbled

+fumbler

+fumbles

+fumbling

+fumblingly

+fume

+fumed

+fumes

+fuming

+fun

+function

+function's

+functional

+functionalities

+functionality

+functionally

+functionals

+functioned

+functioning

+functions

+functor

+functor's

+functors

+fund

+fundamental

+fundamentalist

+fundamentalist's

+fundamentalists

+fundamentally

+fundamentals

+funded

+funder

+funders

+funding

+funds

+funeral

+funeral's

+funerals

+fungus

+funguses

+funnel

+funnels

+funnier

+funnies

+funniest

+funnily

+funniness

+funny

+fur

+fur's

+furies

+furious

+furiouser

+furiously

+furiousness

+furnace

+furnace's

+furnaced

+furnaces

+furnacing

+furness

+furnish

+furnished

+furnisher

+furnishers

+furnishes

+furnishing

+furnishings

+furniture

+furrow

+furrowed

+furrowing

+furrows

+furs

+further

+furthered

+furtherer

+furtherest

+furthering

+furthermore

+furthers

+furtive

+furtively

+furtiveness

+fury

+fury's

+fuse

+fused

+fuses

+fusing

+fusion

+fusions

+fuss

+fusser

+fussing

+futile

+futilely

+futileness

+futility

+future

+future's

+futures

+fuzzier

+fuzziest

+fuzziness

+fuzzy

+gabardine

+gabardines

+gable

+gabled

+gabler

+gables

+gad

+gadget

+gadget's

+gadgets

+gag

+gaged

+gager

+gagged

+gagging

+gaging

+gags

+gaieties

+gaiety

+gaily

+gain

+gained

+gainer

+gainers

+gaining

+gainings

+gainly

+gains

+gait

+gaited

+gaiter

+gaiters

+gaits

+galaxies

+galaxy

+galaxy's

+gale

+gales

+gall

+gallant

+gallantly

+gallantry

+gallants

+galled

+galleried

+galleries

+gallery

+galley

+galley's

+galleys

+galling

+gallingly

+gallon

+gallon's

+gallons

+gallop

+galloped

+galloper

+gallopers

+galloping

+gallops

+gallows

+gallowses

+galls

+gamble

+gambled

+gambler

+gamblers

+gambles

+gambling

+game

+gamed

+gamely

+gameness

+games

+gaming

+gamma

+gammas

+gang

+gang's

+ganger

+ganglier

+gangly

+gangrene

+gangrened

+gangrenes

+gangrening

+gangs

+gangster

+gangster's

+gangsters

+gap

+gap's

+gape

+gaped

+gaper

+gapes

+gaping

+gapingly

+gaps

+garage

+garaged

+garages

+garaging

+garb

+garbage

+garbage's

+garbaged

+garbages

+garbaging

+garbed

+garble

+garbled

+garbler

+garbles

+garbling

+garden

+gardened

+gardener

+gardeners

+gardening

+gardens

+gargle

+gargled

+gargles

+gargling

+garland

+garlanded

+garlands

+garlic

+garlics

+garment

+garment's

+garmented

+garmenting

+garments

+garner

+garnered

+garnering

+garners

+garnish

+garnished

+garnishes

+garrison

+garrisoned

+garrisoning

+garrisons

+garter

+garter's

+gartered

+gartering

+garters

+gas

+gas's

+gaseous

+gaseously

+gaseousness

+gases

+gash

+gash's

+gashed

+gashes

+gashing

+gasoline

+gasolines

+gasp

+gasped

+gasper

+gaspers

+gasping

+gaspingly

+gasps

+gassed

+gasser

+gassers

+gassing

+gassings

+gastric

+gastrointestinal

+gate

+gated

+gates

+gateway

+gateway's

+gateways

+gather

+gathered

+gatherer

+gatherers

+gathering

+gatherings

+gathers

+gating

+gaudier

+gaudies

+gaudiness

+gaudy

+gauge

+gauged

+gauger

+gauges

+gauging

+gaunt

+gauntly

+gauntness

+gauze

+gauzed

+gauzes

+gauzing

+gave

+gay

+gayer

+gayest

+gayly

+gayness

+gaze

+gazed

+gazer

+gazers

+gazes

+gazing

+gear

+geared

+gearing

+gears

+geese

+gel

+gel's

+gelatin

+gelled

+gelling

+gels

+gem

+gem's

+gems

+gender

+gender's

+gendered

+gendering

+genders

+gene

+gene's

+general

+general's

+generalist

+generalist's

+generalists

+generalities

+generality

+generally

+generalness

+generals

+generate

+generated

+generates

+generating

+generation

+generations

+generative

+generatively

+generator

+generator's

+generators

+generic

+generically

+genericness

+generosities

+generosity

+generosity's

+generous

+generously

+generousness

+genes

+genetic

+genetically

+genetics

+genial

+genially

+genialness

+genius

+genius's

+geniuses

+genre

+genre's

+genres

+genteel

+genteeler

+genteelest

+genteelly

+genteelness

+gentle

+gentled

+gentleman

+gentlemanliness

+gentlemanly

+gentleness

+gentler

+gentlest

+gentlewoman

+gentling

+gently

+gentries

+gentry

+genuine

+genuinely

+genuineness

+genus

+geographic

+geographical

+geographically

+geographies

+geography

+geological

+geologist

+geologist's

+geologists

+geometric

+geometries

+geometry

+geranium

+germ

+germ's

+germane

+germen

+germinate

+germinated

+germinates

+germinating

+germination

+germinations

+germinative

+germinatively

+germs

+gestalt

+gesture

+gestured

+gestures

+gesturing

+get

+gets

+getter

+getter's

+gettered

+getters

+getting

+ghastlier

+ghastliness

+ghastly

+ghost

+ghosted

+ghosting

+ghostlier

+ghostliness

+ghostlinesses

+ghostly

+ghosts

+giant

+giant's

+giants

+gibberish

+giddied

+giddier

+giddiness

+giddy

+giddying

+gift

+gifted

+giftedly

+giftedness

+gifts

+gig

+gig's

+gigantic

+giganticness

+giggle

+giggled

+giggler

+giggles

+giggling

+gigglingly

+gigs

+gild

+gilded

+gilder

+gilding

+gilds

+gill

+gill's

+gilled

+giller

+gills

+gilt

+gimmick

+gimmick's

+gimmicks

+gin

+gin's

+ginger

+gingerbread

+gingered

+gingering

+gingerliness

+gingerly

+gingham

+ginghams

+gins

+giraffe

+giraffe's

+giraffes

+gird

+girded

+girder

+girder's

+girders

+girding

+girdle

+girdled

+girdler

+girdles

+girdling

+girds

+girl

+girl's

+girlfriend

+girlfriend's

+girlfriends

+girls

+girt

+girth

+give

+given

+givenness

+givens

+giver

+givers

+gives

+giveth

+giving

+givingly

+gizmo

+gizmo's

+gizmos

+glacial

+glacially

+glacier

+glacier's

+glaciers

+glad

+gladder

+gladdest

+glade

+glades

+gladly

+gladness

+glamour

+glamoured

+glamouring

+glamours

+glance

+glanced

+glances

+glancing

+glancingly

+gland

+gland's

+glanders

+glands

+glare

+glared

+glares

+glaring

+glaringly

+glaringness

+glass

+glassed

+glasses

+glassier

+glassies

+glassiness

+glassy

+glaze

+glazed

+glazer

+glazers

+glazes

+glazing

+gleam

+gleamed

+gleaming

+gleams

+glean

+gleaned

+gleaner

+gleaning

+gleanings

+gleans

+glee

+gleed

+gleeful

+gleefully

+gleefulness

+glees

+glen

+glen's

+glens

+glide

+glided

+glider

+gliders

+glides

+gliding

+glimmer

+glimmered

+glimmering

+glimmers

+glimpse

+glimpsed

+glimpser

+glimpsers

+glimpses

+glimpsing

+glint

+glinted

+glinting

+glints

+glisten

+glistened

+glistening

+glistens

+glitch

+glitch's

+glitches

+glitter

+glittered

+glittering

+glitteringly

+glitters

+global

+globally

+globals

+globe

+globe's

+globes

+globing

+globular

+globularity

+globularly

+globularness

+gloom

+gloomier

+gloomily

+gloominess

+glooms

+gloomy

+gloried

+glories

+glorification

+glorifications

+glorified

+glorifier

+glorifiers

+glorifies

+glorify

+glorious

+gloriously

+gloriousness

+glory

+glorying

+gloss

+glossaries

+glossary

+glossary's

+glossed

+glosses

+glossier

+glossies

+glossiness

+glossing

+glossy

+glottal

+glove

+gloved

+glover

+glovers

+gloves

+gloving

+glow

+glowed

+glower

+glowered

+glowering

+glowers

+glowing

+glowingly

+glows

+glucose

+glue

+glued

+gluer

+gluers

+glues

+gluing

+gnat

+gnat's

+gnats

+gnaw

+gnawed

+gnawer

+gnawing

+gnaws

+go

+goad

+goaded

+goading

+goads

+goal

+goal's

+goals

+goat

+goat's

+goatee

+goatee's

+goatees

+goats

+gobble

+gobbled

+gobbler

+gobblers

+gobbles

+gobbling

+goblet

+goblet's

+goblets

+goblin

+goblin's

+goblins

+god

+god's

+goddess

+goddess's

+goddesses

+godlier

+godlike

+godlikeness

+godliness

+godly

+godmother

+godmother's

+godmothers

+gods

+goer

+goering

+goes

+going

+goings

+gold

+golden

+goldenly

+goldenness

+golding

+golds

+goldsmith

+golf

+golfer

+golfers

+golfing

+golfs

+gone

+goner

+gong

+gong's

+gongs

+gonion

+good

+goodbye

+goodbye's

+goodbyes

+goodie

+goodie's

+goodies

+goodly

+goodness

+goods

+goody

+goody's

+goose

+gooses

+goosing

+gore

+gored

+gores

+gorge

+gorgeous

+gorgeously

+gorgeousness

+gorger

+gorges

+gorging

+gorilla

+gorilla's

+gorillas

+goring

+gosh

+gospel

+gospels

+gossip

+gossiper

+gossipers

+gossips

+got

+gotcha

+gotcha's

+gotchas

+goth

+goto

+gotten

+gouge

+gouged

+gouger

+gouges

+gouging

+govern

+governed

+governess

+governesses

+governing

+government

+government's

+governmental

+governmentally

+governments

+governor

+governor's

+governors

+governs

+gown

+gowned

+gowns

+grab

+grabbed

+grabber

+grabber's

+grabbers

+grabbing

+grabbings

+grabs

+grace

+graced

+graceful

+gracefully

+gracefulness

+graces

+gracing

+gracious

+graciously

+graciousness

+gradation

+gradation's

+gradations

+grade

+graded

+gradely

+grader

+graders

+grades

+gradient

+gradient's

+gradients

+grading

+gradings

+gradual

+gradually

+gradualness

+graduate

+graduated

+graduates

+graduating

+graduation

+graduations

+graft

+grafted

+grafter

+grafting

+grafts

+graham

+graham's

+grahams

+grain

+grained

+grainer

+graining

+grains

+grammar

+grammar's

+grammars

+grammatical

+grammatically

+grammaticalness

+granaries

+granary

+granary's

+grand

+grander

+grandest

+grandeur

+grandfather

+grandfather's

+grandfatherly

+grandfathers

+grandiose

+grandiosely

+grandioseness

+grandkid

+grandkid's

+grandkids

+grandly

+grandma

+grandma's

+grandmother

+grandmother's

+grandmotherly

+grandmothers

+grandness

+grandpa

+grandpa's

+grandparent

+grandparents

+grandpas

+grands

+grandson

+grandson's

+grandsons

+grange

+granger

+granges

+granite

+grannies

+granny

+grant

+grant's

+granted

+granter

+granting

+grants

+granularity

+granulate

+granulated

+granulates

+granulating

+granulation

+granulations

+granulative

+grape

+grape's

+grapes

+grapevine

+grapevine's

+grapevines

+graph

+graph's

+graphed

+graphic

+graphical

+graphically

+graphicness

+graphics

+graphing

+graphite

+graphs

+grapple

+grappled

+grappler

+grapples

+grappling

+grasp

+graspable

+grasped

+grasper

+grasping

+graspingly

+graspingness

+grasps

+grass

+grassed

+grassers

+grasses

+grassier

+grassiest

+grassing

+grassy

+grate

+grated

+grateful

+gratefully

+gratefulness

+grater

+grates

+gratification

+gratifications

+gratified

+gratify

+gratifying

+gratifyingly

+grating

+gratingly

+gratings

+gratitude

+gratuities

+gratuitous

+gratuitously

+gratuitousness

+gratuity

+gratuity's

+grave

+gravel

+gravelly

+gravels

+gravely

+graveness

+graver

+gravers

+graves

+gravest

+gravies

+graving

+gravitation

+gravitational

+gravitationally

+gravities

+gravity

+gravy

+gray

+grayed

+grayer

+grayest

+graying

+grayly

+grayness

+grays

+graze

+grazed

+grazer

+grazes

+grazing

+grease

+greased

+greaser

+greasers

+greases

+greasier

+greasiness

+greasing

+greasy

+great

+greaten

+greatened

+greatening

+greater

+greatest

+greatly

+greatness

+greats

+greed

+greedier

+greedily

+greediness

+greedy

+green

+greened

+greener

+greenest

+greenhouse

+greenhouse's

+greenhouses

+greening

+greenish

+greenishness

+greenly

+greenness

+greens

+greet

+greeted

+greeter

+greeting

+greetings

+greets

+grenade

+grenade's

+grenades

+grew

+grey

+greyest

+greying

+grid

+grid's

+grids

+grief

+grief's

+griefs

+grievance

+grievance's

+grievances

+grieve

+grieved

+griever

+grievers

+grieves

+grieving

+grievingly

+grievous

+grievously

+grievousness

+grill

+grilled

+griller

+grilling

+grills

+grim

+grimed

+griming

+grimly

+grimness

+grin

+grind

+grinder

+grinders

+grinding

+grindingly

+grindings

+grinds

+grindstone

+grindstone's

+grindstones

+grins

+grip

+gripe

+griped

+griper

+gripes

+griping

+gripped

+gripper

+gripper's

+grippers

+gripping

+grippingly

+grips

+grit

+grit's

+grits

+grizzlier

+grizzly

+groan

+groaned

+groaner

+groaners

+groaning

+groans

+grocer

+grocer's

+groceries

+grocers

+grocery

+groom

+groom's

+groomed

+groomer

+grooming

+grooms

+groove

+grooved

+groover

+grooves

+grooving

+grope

+groped

+groper

+gropes

+groping

+gross

+grossed

+grosser

+grosses

+grossest

+grossing

+grossly

+grossness

+grotesque

+grotesquely

+grotesqueness

+grotto

+grotto's

+grottos

+ground

+grounded

+grounder

+grounders

+grounding

+grounds

+groundwork

+group

+group's

+grouped

+grouper

+grouping

+groupings

+groups

+grouse

+groused

+grouser

+grouses

+grousing

+grove

+grovel

+grovels

+grover

+grovers

+groves

+grow

+grower

+growers

+growing

+growingly

+growl

+growled

+growler

+growlier

+growliness

+growling

+growlingly

+growls

+growly

+grown

+grownup

+grownup's

+grownups

+grows

+growth

+growths

+grub

+grub's

+grubs

+grudge

+grudge's

+grudged

+grudger

+grudges

+grudging

+grudgingly

+gruesome

+gruesomely

+gruesomeness

+gruff

+gruffly

+gruffness

+grumble

+grumbled

+grumbler

+grumbles

+grumbling

+grumblingly

+grunt

+grunted

+grunter

+grunting

+grunts

+guarantee

+guaranteed

+guaranteeing

+guaranteer

+guaranteers

+guarantees

+guaranty

+guard

+guarded

+guardedly

+guardedness

+guarder

+guardian

+guardian's

+guardians

+guardianship

+guarding

+guards

+guerrilla

+guerrilla's

+guerrillas

+guess

+guessed

+guesser

+guesses

+guessing

+guest

+guest's

+guested

+guesting

+guests

+guidance

+guidances

+guide

+guidebook

+guidebook's

+guidebooks

+guided

+guideline

+guideline's

+guidelines

+guider

+guides

+guiding

+guild

+guilder

+guile

+guilt

+guiltier

+guiltiest

+guiltily

+guiltiness

+guiltless

+guiltlessly

+guiltlessness

+guilts

+guilty

+guinea

+guineas

+guise

+guise's

+guised

+guises

+guising

+guitar

+guitar's

+guitars

+gulch

+gulch's

+gulches

+gulf

+gulf's

+gulfs

+gull

+gulled

+gullibility

+gullied

+gullies

+gulling

+gulls

+gully

+gully's

+gullying

+gulp

+gulped

+gulper

+gulps

+gum

+gum's

+gums

+gun

+gun's

+gunfire

+gunfires

+gunned

+gunner

+gunner's

+gunners

+gunning

+gunpowder

+gunpowders

+guns

+gurgle

+gurgled

+gurgles

+gurgling

+guru

+guru's

+gurus

+gush

+gushed

+gusher

+gushes

+gushing

+gust

+gust's

+gusts

+gut

+guts

+gutser

+gutter

+guttered

+guttering

+gutters

+guy

+guy's

+guyed

+guyer

+guyers

+guying

+guys

+gym

+gymnasium

+gymnasium's

+gymnasiums

+gymnast

+gymnast's

+gymnastic

+gymnastics

+gymnasts

+gyms

+gypsied

+gypsies

+gypsy

+gypsy's

+gypsying

+gyration

+gyrations

+gyroscope

+gyroscope's

+gyroscopes

+ha

+habit

+habit's

+habitable

+habitableness

+habitat

+habitat's

+habitation

+habitation's

+habitations

+habitats

+habits

+habitual

+habitually

+habitualness

+hack

+hacked

+hacker

+hacker's

+hackers

+hacking

+hacks

+had

+hadn't

+hag

+hagen

+haggard

+haggardly

+haggardness

+hail

+hailed

+hailer

+hailing

+hails

+hair

+hair's

+haircut

+haircut's

+haircuts

+hairdresser

+hairdresser's

+hairdressers

+haired

+hairier

+hairiness

+hairless

+hairlessness

+hairs

+hairy

+hale

+haler

+half

+halfness

+halfway

+halfword

+halfword's

+halfwords

+haling

+hall

+hall's

+haller

+hallmark

+hallmark's

+hallmarked

+hallmarking

+hallmarks

+hallow

+hallowed

+hallowing

+hallows

+halls

+hallway

+hallway's

+hallways

+halt

+halted

+halter

+haltered

+haltering

+halters

+halting

+haltingly

+halts

+halve

+halved

+halvers

+halves

+halving

+ham

+ham's

+hamburger

+hamburger's

+hamburgers

+hamlet

+hamlet's

+hamlets

+hammer

+hammered

+hammerer

+hammering

+hammers

+hammock

+hammock's

+hammocks

+hamper

+hampered

+hampering

+hampers

+hams

+hand

+handbag

+handbag's

+handbags

+handbook

+handbook's

+handbooks

+handcuff

+handcuffed

+handcuffing

+handcuffs

+handed

+handedly

+handedness

+hander

+handers

+handful

+handfuls

+handicap

+handicap's

+handicapped

+handicaps

+handier

+handiest

+handily

+handiness

+handing

+handiwork

+handkerchief

+handkerchief's

+handkerchiefs

+handle

+handled

+handler

+handlers

+handles

+handling

+hands

+handshake

+handshake's

+handshaker

+handshakes

+handshaking

+handsome

+handsomely

+handsomeness

+handsomer

+handsomest

+handwriting

+handwritten

+handy

+hang

+hangar

+hangar's

+hangars

+hanged

+hanger

+hangers

+hanging

+hangover

+hangover's

+hangovers

+hangs

+hap

+haphazard

+haphazardly

+haphazardness

+hapless

+haplessly

+haplessness

+haply

+happen

+happened

+happening

+happenings

+happens

+happier

+happiest

+happily

+happiness

+happy

+harass

+harassed

+harasser

+harasses

+harassing

+harassment

+harassments

+hard

+harden

+hardened

+hardener

+hardening

+hardens

+harder

+hardest

+hardier

+hardiness

+harding

+hardings

+hardly

+hardness

+hardnesses

+hards

+hardship

+hardship's

+hardships

+hardware

+hardwares

+hardy

+hare

+hare's

+hares

+hark

+harked

+harken

+harking

+harks

+harlot

+harlot's

+harlots

+harm

+harmed

+harmer

+harmful

+harmfully

+harmfulness

+harming

+harmless

+harmlessly

+harmlessness

+harmonies

+harmonious

+harmoniously

+harmoniousness

+harmony

+harms

+harness

+harnessed

+harnesser

+harnesses

+harnessing

+harp

+harped

+harper

+harpers

+harping

+harpings

+harps

+harried

+harrier

+harrow

+harrowed

+harrower

+harrowing

+harrows

+harry

+harrying

+harsh

+harshen

+harshened

+harshening

+harsher

+harshest

+harshly

+harshness

+hart

+harvest

+harvested

+harvester

+harvesters

+harvesting

+harvests

+has

+hash

+hashed

+hasher

+hashes

+hashing

+hasn't

+hassle

+hassled

+hassler

+hassles

+hassling

+haste

+hasted

+hasten

+hastened

+hastener

+hastening

+hastens

+hastes

+hastier

+hastiest

+hastily

+hastiness

+hasting

+hastings

+hasty

+hat

+hat's

+hatch

+hatched

+hatcher

+hatcheries

+hatchery

+hatchery's

+hatches

+hatchet

+hatchet's

+hatchets

+hatching

+hate

+hated

+hateful

+hatefully

+hatefulness

+hater

+hates

+hath

+hating

+hatred

+hats

+haughtier

+haughtily

+haughtiness

+haughty

+haul

+hauled

+hauler

+haulers

+hauling

+hauls

+haunch

+haunch's

+haunches

+haunt

+haunted

+haunter

+haunting

+hauntingly

+haunts

+have

+haven

+haven's

+haven't

+havens

+haver

+havering

+havers

+haves

+having

+havoc

+havocs

+hawk

+hawked

+hawker

+hawkers

+hawking

+hawks

+hay

+hayer

+haying

+hays

+hazard

+hazard's

+hazarded

+hazarding

+hazardous

+hazardously

+hazardousness

+hazards

+haze

+haze's

+hazed

+hazel

+hazer

+hazes

+hazier

+haziest

+haziness

+hazing

+hazy

+he

+he'd

+he'll

+he's

+head

+head's

+headache

+headache's

+headaches

+headed

+header

+headers

+headgear

+heading

+heading's

+headings

+headland

+headland's

+headlands

+headline

+headlined

+headliner

+headlines

+headlining

+headlong

+headphone

+headphone's

+headphones

+headquarters

+heads

+headway

+heal

+healed

+healer

+healers

+healing

+heals

+health

+healthful

+healthfully

+healthfulness

+healthier

+healthiest

+healthily

+healthiness

+healthy

+heap

+heaped

+heaping

+heaps

+hear

+heard

+hearer

+hearers

+hearest

+hearing

+hearings

+hearken

+hearkened

+hearkening

+hears

+hearsay

+hearses

+hearsing

+heart

+heart's

+heartache

+heartache's

+heartaches

+hearted

+heartedly

+hearten

+heartened

+heartening

+hearteningly

+heartens

+hearth

+heartier

+hearties

+heartiest

+heartily

+heartiness

+heartless

+heartlessly

+heartlessness

+hearts

+hearty

+heat

+heatable

+heated

+heatedly

+heater

+heaters

+heath

+heathen

+heather

+heating

+heats

+heave

+heaved

+heaven

+heaven's

+heavenliness

+heavenly

+heavens

+heaver

+heavers

+heaves

+heavier

+heavies

+heaviest

+heavily

+heaviness

+heaving

+heavy

+hedge

+hedged

+hedgehog

+hedgehog's

+hedgehogs

+hedger

+hedges

+hedging

+hedgingly

+heed

+heeded

+heeding

+heedless

+heedlessly

+heedlessness

+heeds

+heel

+heeled

+heeler

+heelers

+heeling

+heels

+heifer

+height

+heighten

+heightened

+heightening

+heightens

+heights

+heinous

+heinously

+heinousness

+heir

+heir's

+heiress

+heiress's

+heiresses

+heirs

+held

+hell

+hell's

+heller

+hello

+hellos

+hells

+helm

+helmet

+helmet's

+helmeted

+helmets

+help

+helped

+helper

+helpers

+helpful

+helpfully

+helpfulness

+helping

+helpless

+helplessly

+helplessness

+helps

+hem

+hem's

+hemisphere

+hemisphere's

+hemisphered

+hemispheres

+hemlock

+hemlock's

+hemlocks

+hemostat

+hemostats

+hemp

+hempen

+hems

+hen

+hen's

+hence

+henceforth

+henchman

+henchmen

+hens

+her

+herald

+heralded

+heralding

+heralds

+herb

+herb's

+herbivore

+herbivorous

+herbivorously

+herbs

+herd

+herded

+herder

+herding

+herds

+here

+here's

+hereabout

+hereabouts

+hereafter

+hereby

+hereditary

+heredity

+herein

+hereinafter

+heres

+heresy

+heretic

+heretic's

+heretics

+heretofore

+herewith

+heritage

+heritages

+hermit

+hermit's

+hermits

+hero

+hero's

+heroes

+heroic

+heroically

+heroics

+heroin

+heroine

+heroine's

+heroines

+heroism

+heron

+heron's

+herons

+heros

+herring

+herring's

+herrings

+hers

+herself

+hesitant

+hesitantly

+hesitate

+hesitated

+hesitater

+hesitates

+hesitating

+hesitatingly

+hesitation

+hesitations

+heterogeneous

+heterogeneously

+heterogeneousness

+heuristic

+heuristic's

+heuristically

+heuristics

+hew

+hewed

+hewer

+hewing

+hews

+hex

+hexagonal

+hexagonally

+hexer

+hey

+hickories

+hickory

+hid

+hidden

+hide

+hided

+hideous

+hideously

+hideousness

+hideout

+hideout's

+hideouts

+hider

+hides

+hiding

+hierarchical

+hierarchically

+hierarchies

+hierarchy

+hierarchy's

+high

+higher

+highest

+highland

+highlander

+highlands

+highlight

+highlighted

+highlighting

+highlights

+highly

+highness

+highness's

+highnesses

+highway

+highway's

+highways

+hijack

+hijacked

+hijacker

+hijackers

+hijacking

+hijacks

+hike

+hiked

+hiker

+hikers

+hikes

+hiking

+hilarious

+hilariously

+hilariousness

+hill

+hill's

+hilled

+hiller

+hilling

+hillock

+hillocks

+hills

+hillside

+hilltop

+hilltop's

+hilltops

+hilt

+hilt's

+hilts

+him

+hims

+himself

+hind

+hinder

+hindered

+hinderer

+hindering

+hinders

+hindrance

+hindrances

+hinds

+hindsight

+hinge

+hinged

+hinger

+hinges

+hinging

+hint

+hinted

+hinter

+hinting

+hints

+hip

+hip's

+hipness

+hips

+hire

+hired

+hirer

+hirers

+hires

+hiring

+hirings

+his

+hiss

+hissed

+hisser

+hisses

+hissing

+histogram

+histogram's

+histograms

+historian

+historian's

+historians

+historic

+historical

+historically

+historicalness

+histories

+history

+history's

+hit

+hit's

+hitch

+hitched

+hitcher

+hitches

+hitchhike

+hitchhiked

+hitchhiker

+hitchhikers

+hitchhikes

+hitchhiking

+hitching

+hither

+hitherto

+hits

+hitter

+hitter's

+hitters

+hitting

+hive

+hives

+hiving

+hoar

+hoard

+hoarded

+hoarder

+hoarding

+hoards

+hoarier

+hoariness

+hoarse

+hoarsely

+hoarseness

+hoarser

+hoarsest

+hoary

+hoax

+hoax's

+hoaxed

+hoaxer

+hoaxes

+hoaxing

+hobbies

+hobble

+hobbled

+hobbler

+hobbles

+hobbling

+hobby

+hobby's

+hobbyist

+hobbyist's

+hobbyists

+hockey

+hoe

+hoe's

+hoer

+hoes

+hog

+hog's

+hogs

+hoist

+hoisted

+hoister

+hoisting

+hoists

+hold

+holden

+holder

+holders

+holding

+holdings

+holds

+hole

+hole's

+holed

+holes

+holiday

+holiday's

+holidayer

+holidays

+holier

+holies

+holiness

+holing

+holistic

+hollies

+hollow

+hollowed

+hollower

+hollowest

+hollowing

+hollowly

+hollowness

+hollows

+holly

+holocaust

+hologram

+hologram's

+holograms

+holy

+homage

+homaged

+homager

+homages

+homaging

+home

+homebuilt

+homed

+homeless

+homelessness

+homelier

+homeliness

+homely

+homemade

+homemaker

+homemaker's

+homemakers

+homeomorphic

+homeomorphism

+homeomorphism's

+homeomorphisms

+homer

+homers

+homes

+homesick

+homesickness

+homespun

+homestead

+homesteader

+homesteaders

+homesteads

+homeward

+homewards

+homework

+homeworker

+homeworkers

+homing

+homogeneities

+homogeneity

+homogeneity's

+homogeneous

+homogeneously

+homogeneousness

+homomorphic

+homomorphism

+homomorphism's

+homomorphisms

+hone

+honed

+honer

+hones

+honest

+honestly

+honesty

+honey

+honeycomb

+honeycombed

+honeyed

+honeying

+honeymoon

+honeymooned

+honeymooner

+honeymooners

+honeymooning

+honeymoons

+honeys

+honeysuckle

+honing

+honorary

+hood

+hood's

+hooded

+hoodedness

+hooding

+hoods

+hoodwink

+hoodwinked

+hoodwinker

+hoodwinking

+hoodwinks

+hoof

+hoof's

+hoofed

+hoofer

+hoofs

+hook

+hooked

+hookedness

+hooker

+hookers

+hooking

+hooks

+hoop

+hooped

+hooper

+hooping

+hoops

+hooray

+hooray's

+hoorays

+hoot

+hooted

+hooter

+hooters

+hooting

+hoots

+hop

+hope

+hoped

+hopeful

+hopefully

+hopefulness

+hopefuls

+hopeless

+hopelessly

+hopelessness

+hoper

+hopes

+hoping

+hopped

+hopper

+hopper's

+hoppers

+hopping

+hops

+horde

+horde's

+hordes

+horizon

+horizon's

+horizons

+horizontal

+horizontally

+hormone

+hormone's

+hormones

+horn

+horned

+hornedness

+hornet

+hornet's

+hornets

+horns

+horrendous

+horrendously

+horrible

+horribleness

+horribly

+horrid

+horridly

+horridness

+horrified

+horrifies

+horrify

+horrifying

+horrifyingly

+horror

+horror's

+horrors

+horse

+horse's

+horseback

+horsely

+horseman

+horsepower

+horsepowers

+horses

+horseshoe

+horseshoer

+horseshoes

+horsing

+hose

+hose's

+hosed

+hoses

+hosing

+hospitable

+hospitably

+hospital

+hospital's

+hospitality

+hospitals

+host

+host's

+hostage

+hostage's

+hostages

+hosted

+hostess

+hostess's

+hostesses

+hostile

+hostilely

+hostilities

+hostility

+hosting

+hostly

+hosts

+hot

+hotel

+hotel's

+hotels

+hotly

+hotness

+hotter

+hottest

+hound

+hounded

+hounder

+hounding

+hounds

+hour

+hour's

+hourly

+hours

+house

+house's

+housed

+houseflies

+housefly

+housefly's

+household

+household's

+householder

+householders

+households

+housekeeper

+housekeeper's

+housekeepers

+housekeeping

+houser

+houses

+housetop

+housetop's

+housetops

+housewife

+housewife's

+housewifeliness

+housewifely

+housework

+houseworker

+houseworkers

+housing

+housings

+hovel

+hovel's

+hovels

+hover

+hovered

+hoverer

+hovering

+hovers

+how

+how's

+however

+howl

+howled

+howler

+howling

+howls

+hows

+hrs

+hub

+hub's

+hubris

+hubs

+huddle

+huddled

+huddler

+huddles

+huddling

+hue

+hue's

+hued

+hues

+hug

+huge

+hugely

+hugeness

+huger

+hugest

+hugs

+huh

+hull

+hull's

+hulled

+huller

+hulling

+hulls

+hum

+human

+humane

+humanely

+humaneness

+humanities

+humanity

+humanity's

+humanly

+humanness

+humans

+humble

+humbled

+humbleness

+humbler

+humbles

+humblest

+humbling

+humbly

+humid

+humidification

+humidifications

+humidified

+humidifier

+humidifiers

+humidifies

+humidify

+humidifying

+humidities

+humidity

+humidly

+humiliate

+humiliated

+humiliates

+humiliating

+humiliatingly

+humiliation

+humiliations

+humility

+hummed

+humming

+humorous

+humorously

+humorousness

+hump

+humped

+humping

+humps

+hums

+hunch

+hunched

+hunches

+hundred

+hundreds

+hundredth

+hung

+hunger

+hungered

+hungering

+hungers

+hungrier

+hungriest

+hungrily

+hungriness

+hungry

+hunk

+hunk's

+hunker

+hunkered

+hunkering

+hunkers

+hunks

+hunt

+hunted

+hunter

+hunters

+hunting

+hunts

+huntsman

+hurdle

+hurdled

+hurdler

+hurdles

+hurdling

+hurl

+hurled

+hurler

+hurlers

+hurling

+hurrah

+hurricane

+hurricane's

+hurricanes

+hurried

+hurriedly

+hurriedness

+hurrier

+hurries

+hurry

+hurrying

+hurt

+hurter

+hurting

+hurtingly

+hurts

+husband

+husband's

+husbander

+husbandly

+husbandry

+husbands

+hush

+hushed

+hushes

+hushing

+husk

+husked

+husker

+huskier

+huskies

+huskiness

+husking

+husks

+husky

+hustle

+hustled

+hustler

+hustlers

+hustles

+hustling

+hut

+hut's

+huts

+hyacinth

+hybrid

+hybrids

+hydraulic

+hydraulically

+hydraulics

+hydrodynamic

+hydrodynamics

+hydrogen

+hydrogen's

+hydrogens

+hygiene

+hymn

+hymn's

+hymning

+hymns

+hype

+hype's

+hyped

+hyper

+hyperbolic

+hypertext

+hypertext's

+hypes

+hyphen

+hyphen's

+hyphened

+hyphening

+hyphens

+hypocrisies

+hypocrisy

+hypocrite

+hypocrite's

+hypocrites

+hypodermic

+hypodermics

+hypotheses

+hypothesis

+hypothetical

+hypothetically

+hysteresis

+hysterical

+hysterically

+ice

+iceberg

+iceberg's

+icebergs

+iced

+ices

+icier

+iciest

+iciness

+icing

+icings

+icon

+icon's

+icons

+icy

+id

+id's

+idea

+idea's

+ideal

+idealism

+idealistic

+ideally

+ideals

+ideas

+identical

+identically

+identicalness

+identifiable

+identifiably

+identification

+identifications

+identified

+identifier

+identifiers

+identifies

+identify

+identifying

+identities

+identity

+identity's

+ideological

+ideologically

+ideologies

+ideology

+idiocies

+idiocy

+idiosyncrasies

+idiosyncrasy

+idiosyncrasy's

+idiosyncratic

+idiot

+idiot's

+idiotic

+idiots

+idle

+idled

+idleness

+idler

+idlers

+idles

+idlest

+idling

+idly

+idol

+idol's

+idolatry

+idols

+if

+ignition

+ignoble

+ignobleness

+ignorance

+ignorant

+ignorantly

+ignorantness

+ignore

+ignored

+ignorer

+ignores

+ignoring

+ii

+iii

+ill

+illegal

+illegalities

+illegality

+illegally

+illicit

+illicitly

+illiterate

+illiterately

+illiterateness

+illiterates

+illness

+illness's

+illnesses

+illogical

+illogically

+illogicalness

+ills

+illuminate

+illuminated

+illuminates

+illuminating

+illuminatingly

+illumination

+illuminations

+illuminative

+illusion

+illusion's

+illusions

+illusive

+illusively

+illusiveness

+illustrate

+illustrated

+illustrates

+illustrating

+illustration

+illustrations

+illustrative

+illustratively

+illustrator

+illustrator's

+illustrators

+illustrious

+illustriously

+illustriousness

+illy

+image

+imaged

+images

+imaginable

+imaginableness

+imaginably

+imaginariness

+imaginary

+imagination

+imagination's

+imaginations

+imaginative

+imaginatively

+imaginativeness

+imagine

+imagined

+imaginer

+imagines

+imaging

+imagining

+imaginings

+imbalance

+imbalances

+imitate

+imitated

+imitates

+imitating

+imitation

+imitations

+imitative

+imitatively

+imitativeness

+immaculate

+immaculately

+immaculateness

+immaterial

+immaterially

+immaterialness

+immature

+immaturely

+immatureness

+immaturity

+immediacies

+immediacy

+immediate

+immediately

+immediateness

+immemorial

+immemorially

+immense

+immensely

+immenseness

+immerse

+immersed

+immerser

+immerses

+immersing

+immersion

+immersions

+immigrant

+immigrant's

+immigrants

+immigrate

+immigrated

+immigrates

+immigrating

+immigration

+imminent

+imminently

+imminentness

+immoral

+immoralities

+immorality

+immorally

+immortal

+immortality

+immortally

+immortals

+immovability

+immovable

+immovableness

+immovably

+immune

+immunities

+immunity

+immunity's

+immunology

+immutable

+immutableness

+imp

+imp's

+impact

+impacted

+impacter

+impacting

+impaction

+impactions

+impactive

+impactor

+impactor's

+impactors

+impacts

+impair

+impaired

+impairer

+impairing

+impairs

+impart

+imparted

+impartial

+impartially

+imparting

+imparts

+impasse

+impasses

+impassion

+impassioned

+impassioning

+impassions

+impassive

+impassively

+impassiveness

+impatience

+impatient

+impatiently

+impeach

+impeached

+impeaches

+impeaching

+impedance

+impedance's

+impedances

+impede

+impeded

+impeder

+impedes

+impediment

+impediment's

+impediments

+impeding

+impel

+impels

+impending

+impenetrability

+impenetrable

+impenetrableness

+impenetrably

+imperative

+imperatively

+imperativeness

+imperatives

+imperfect

+imperfection

+imperfection's

+imperfections

+imperfective

+imperfectly

+imperfectness

+imperial

+imperialism

+imperialist

+imperialist's

+imperialists

+imperially

+imperil

+imperious

+imperiously

+imperiousness

+impermanence

+impermanent

+impermanently

+impermissible

+impersonal

+impersonally

+impersonate

+impersonated

+impersonates

+impersonating

+impersonation

+impersonations

+impertinent

+impertinently

+imperturbability

+impervious

+imperviously

+imperviousness

+impetuous

+impetuously

+impetuousness

+impetus

+impinge

+impinged

+impinges

+impinging

+impious

+impiously

+implant

+implanted

+implanter

+implanting

+implants

+implausible

+implement

+implementable

+implementation

+implementation's

+implementations

+implemented

+implementer

+implementers

+implementing

+implementor

+implementor's

+implementors

+implements

+implicant

+implicant's

+implicants

+implicate

+implicated

+implicates

+implicating

+implication

+implications

+implicative

+implicatively

+implicativeness

+implicit

+implicitly

+implicitness

+implied

+implies

+implore

+implored

+implores

+imploring

+imply

+implying

+import

+importance

+important

+importantly

+importation

+importations

+imported

+importer

+importers

+importing

+imports

+impose

+imposed

+imposer

+imposes

+imposing

+imposingly

+imposition

+imposition's

+impositions

+impossibilities

+impossibility

+impossible

+impossibleness

+impossibles

+impossibly

+impostor

+impostor's

+impostors

+impotence

+impotent

+impotently

+impoverish

+impoverished

+impoverisher

+impoverishes

+impoverishing

+impoverishment

+impracticable

+impracticableness

+impractical

+impracticality

+impractically

+impracticalness

+imprecise

+imprecisely

+impreciseness

+imprecision

+impregnable

+impregnableness

+impress

+impressed

+impresser

+impresses

+impressing

+impression

+impression's

+impressionable

+impressionableness

+impressionist

+impressionistic

+impressionists

+impressions

+impressive

+impressively

+impressiveness

+impressment

+imprint

+imprinted

+imprinting

+imprints

+imprison

+imprisoned

+imprisoning

+imprisonment

+imprisonment's

+imprisonments

+imprisons

+improbable

+improbableness

+impromptu

+improper

+improperly

+improperness

+improve

+improved

+improvement

+improvements

+improver

+improves

+improving

+improvisation

+improvisation's

+improvisational

+improvisations

+improvise

+improvised

+improviser

+improvisers

+improvises

+improvising

+imps

+impudent

+impudently

+impulse

+impulsed

+impulses

+impulsing

+impulsion

+impulsions

+impulsive

+impulsively

+impulsiveness

+impunity

+impure

+impurely

+impureness

+impurities

+impurity

+impurity's

+impute

+imputed

+imputes

+imputing

+in

+inabilities

+inability

+inaccessibility

+inaccessible

+inaccessibly

+inaccuracies

+inaccuracy

+inaccurate

+inaccurately

+inactions

+inactivation

+inactive

+inactively

+inactivity

+inadequacies

+inadequacy

+inadequate

+inadequately

+inadequateness

+inadmissibility

+inadmissible

+inadvertent

+inadvertently

+inadvisability

+inadvisable

+inalterable

+inalterableness

+inane

+inanely

+inaneness

+inaner

+inanest

+inanimate

+inanimately

+inanimateness

+inapparently

+inapplicability

+inapplicable

+inappreciable

+inappreciably

+inappreciative

+inappreciatively

+inappreciativeness

+inapproachable

+inappropriate

+inappropriately

+inappropriateness

+inapt

+inaptly

+inaptness

+inarguable

+inarguably

+inarticulable

+inartistic

+inartistically

+inasmuch

+inattentive

+inattentively

+inattentiveness

+inaudible

+inaudibly

+inaugural

+inaugurate

+inaugurated

+inaugurating

+inauguration

+inaugurations

+inauspicious

+inauspiciously

+inauspiciousness

+inauthentic

+inauthenticity

+inboards

+inborn

+inbounds

+inbred

+inbuilt

+incantation

+incantations

+incapable

+incapableness

+incapably

+incapacitating

+incarnation

+incarnation's

+incarnations

+incautious

+incautiously

+incautiousness

+incendiaries

+incendiary

+incense

+incensed

+incenses

+incensing

+incentive

+incentive's

+incentively

+incentives

+inception

+inceptions

+incessant

+incessantly

+inch

+inched

+inches

+inching

+incidence

+incidences

+incident

+incident's

+incidental

+incidentally

+incidentals

+incidents

+incipient

+incipiently

+incision

+incision's

+incisions

+incitations

+incite

+incited

+inciter

+incites

+inciting

+incivility

+inclination

+inclination's

+inclinations

+incline

+inclined

+incliner

+inclines

+inclining

+inclose

+inclosed

+incloses

+inclosing

+include

+included

+includes

+including

+inclusion

+inclusion's

+inclusions

+inclusive

+inclusively

+inclusiveness

+incoherence

+incoherences

+incoherent

+incoherently

+income

+incomer

+incomers

+incomes

+incoming

+incommensurate

+incomparability

+incomparable

+incomparably

+incompatibilities

+incompatibility

+incompatibility's

+incompatible

+incompatibly

+incompetence

+incompetent

+incompetent's

+incompetently

+incompetents

+incomplete

+incompletely

+incompleteness

+incompletion

+incomprehensibility

+incomprehensible

+incomprehensibleness

+incomprehensibly

+incomprehension

+incompressible

+incomputable

+inconceivable

+inconceivableness

+inconceivably

+inconclusive

+inconclusively

+inconclusiveness

+inconformity

+incongruence

+incongruent

+incongruently

+inconsequential

+inconsequentially

+inconsequently

+inconsiderable

+inconsiderableness

+inconsiderably

+inconsiderate

+inconsiderately

+inconsiderateness

+inconsideration

+inconsistencies

+inconsistency

+inconsistency's

+inconsistent

+inconsistently

+inconsolable

+inconsolableness

+inconspicuous

+inconspicuously

+inconspicuousness

+inconstancy

+inconstantly

+incontestable

+incontinently

+incontrollable

+inconvenience

+inconvenienced

+inconveniences

+inconveniencing

+inconvenient

+inconveniently

+inconvertibility

+inconvertible

+incorporate

+incorporated

+incorporates

+incorporating

+incorporation

+incorporative

+incorrect

+incorrectly

+incorrectness

+incorruption

+increase

+increased

+increaser

+increases

+increasing

+increasingly

+incredibility

+incredible

+incredibleness

+incredibly

+incredulity

+incredulous

+incredulously

+increment

+incremental

+incrementally

+incremented

+incrementing

+increments

+incubate

+incubated

+incubates

+incubating

+incubation

+incubative

+incubator

+incubator's

+incubators

+incur

+incurable

+incurableness

+incurables

+incurably

+incurred

+incurring

+incurs

+indebted

+indebtedness

+indecent

+indecently

+indecision

+indecisive

+indecisively

+indecisiveness

+indecomposable

+indeed

+indefinable

+indefinableness

+indefinite

+indefinitely

+indefiniteness

+indemnity

+indent

+indentation

+indentation's

+indentations

+indented

+indenter

+indenting

+indents

+independence

+independent

+independently

+independents

+indescribable

+indescribableness

+indeterminable

+indeterminableness

+indeterminacies

+indeterminacy

+indeterminacy's

+indeterminate

+indeterminately

+indeterminateness

+indetermination

+indeterminism

+indeterministic

+index

+indexable

+indexed

+indexer

+indexers

+indexes

+indexing

+indicate

+indicated

+indicates

+indicating

+indication

+indications

+indicative

+indicatively

+indicatives

+indicator

+indicator's

+indicators

+indices

+indictment

+indictment's

+indictments

+indifference

+indifferent

+indifferently

+indigenous

+indigenously

+indigenousness

+indigested

+indigestible

+indigestion

+indignant

+indignantly

+indignation

+indignities

+indignity

+indigo

+indirect

+indirected

+indirecting

+indirection

+indirections

+indirectly

+indirectness

+indirects

+indiscernible

+indiscipline

+indisciplined

+indiscreet

+indiscreetly

+indiscreetness

+indiscriminate

+indiscriminately

+indiscriminateness

+indiscriminating

+indiscriminatingly

+indiscrimination

+indispensability

+indispensable

+indispensableness

+indispensably

+indisposed

+indisposes

+indistinct

+indistinctive

+indistinctly

+indistinctness

+indistinguishable

+indistinguishableness

+individual

+individual's

+individualistic

+individuality

+individually

+individuals

+indivisibility

+indivisible

+indivisibleness

+indoctrinate

+indoctrinated

+indoctrinates

+indoctrinating

+indoctrination

+indolent

+indolently

+indomitable

+indomitableness

+indoor

+indoors

+induce

+induced

+inducement

+inducement's

+inducements

+inducer

+induces

+inducing

+induct

+inductance

+inductances

+inducted

+inducting

+induction

+induction's

+inductions

+inductive

+inductively

+inductiveness

+inductor

+inductor's

+inductors

+inducts

+indulge

+indulged

+indulgence

+indulgence's

+indulgences

+indulger

+indulges

+indulging

+industrial

+industrialist

+industrialist's

+industrialists

+industrially

+industrials

+industries

+industrious

+industriously

+industriousness

+industry

+industry's

+inedited

+ineffective

+ineffectively

+ineffectiveness

+inefficacy

+inefficiencies

+inefficiency

+inefficient

+inefficiently

+inelastically

+inelegant

+inelegantly

+ineloquent

+ineloquently

+inequalities

+inequality

+inequitably

+inequities

+inequity

+inert

+inertia

+inertias

+inertly

+inertness

+inescapable

+inescapably

+inessential

+inestimable

+inevitabilities

+inevitability

+inevitable

+inevitableness

+inevitably

+inexact

+inexactitude

+inexactly

+inexactness

+inexcusable

+inexcusableness

+inexcusably

+inexhaustible

+inexhaustibleness

+inexistent

+inexorable

+inexorableness

+inexorably

+inexpedient

+inexpediently

+inexpensive

+inexpensively

+inexpensiveness

+inexperience

+inexperienced

+inexplainable

+inexplicable

+inexplicableness

+inexplicably

+inexpressibility

+inexpressible

+inexpressibleness

+inexpressibly

+inexpressive

+inexpressively

+inexpressiveness

+inextensible

+infallibility

+infallible

+infallibly

+infamous

+infamously

+infancy

+infant

+infant's

+infantry

+infants

+infeasible

+infect

+infected

+infecting

+infection

+infection's

+infections

+infectious

+infectiously

+infectiousness

+infective

+infects

+infer

+inference

+inference's

+inferencer

+inferences

+inferencing

+inferential

+inferentially

+inferior

+inferior's

+inferiority

+inferiorly

+inferiors

+infernal

+infernally

+inferno

+inferno's

+infernos

+inferred

+inferring

+infers

+infertility

+infest

+infested

+infester

+infesting

+infests

+infidel

+infidel's

+infidelity

+infidels

+infields

+infighter

+infighter's

+infighters

+infighting

+infiltrate

+infiltrated

+infiltrates

+infiltrating

+infiltration

+infiltrative

+infinite

+infinitely

+infiniteness

+infinitesimal

+infinitesimally

+infinities

+infinitive

+infinitive's

+infinitively

+infinitives

+infinitum

+infinity

+infirmity

+infix

+infix's

+infixes

+inflame

+inflamed

+inflamer

+inflaming

+inflammable

+inflammableness

+inflatable

+inflate

+inflated

+inflater

+inflates

+inflating

+inflation

+inflationary

+inflexibility

+inflexible

+inflexibleness

+inflexibly

+inflict

+inflicted

+inflicter

+inflicting

+inflictive

+inflicts

+inflows

+influence

+influenced

+influencer

+influences

+influencing

+influent

+influential

+influentially

+influenza

+inform

+informal

+informality

+informally

+informant

+informant's

+informants

+information

+informational

+informations

+informative

+informatively

+informativeness

+informed

+informer

+informers

+informing

+informs

+infractions

+infrastructure

+infrastructures

+infrequent

+infrequently

+infringe

+infringed

+infringement

+infringement's

+infringements

+infringer

+infringes

+infringing

+infuriate

+infuriated

+infuriately

+infuriates

+infuriating

+infuriatingly

+infuriation

+infuse

+infused

+infuser

+infuses

+infusing

+infusion

+infusions

+ingenious

+ingeniously

+ingeniousness

+ingenuity

+inglorious

+ingloriously

+ingloriousness

+ingot

+ingrained

+ingrainedly

+ingrains

+ingratitude

+ingredient

+ingredient's

+ingredients

+ingrown

+ingrownness

+ingrowth

+ingrowths

+inhabit

+inhabitable

+inhabitance

+inhabitant

+inhabitant's

+inhabitants

+inhabited

+inhabiter

+inhabiting

+inhabits

+inhale

+inhaled

+inhaler

+inhales

+inhaling

+inharmonious

+inharmoniously

+inharmoniousness

+inhere

+inhered

+inherent

+inherently

+inheres

+inhering

+inherit

+inheritable

+inheritableness

+inheritance

+inheritance's

+inheritances

+inherited

+inheriting

+inheritor

+inheritor's

+inheritors

+inheritress

+inheritress's

+inheritresses

+inheritrices

+inheritrix

+inherits

+inhibit

+inhibited

+inhibiter

+inhibiting

+inhibition

+inhibition's

+inhibitions

+inhibitive

+inhibitors

+inhibits

+inholding

+inholdings

+inhomogeneities

+inhomogeneity

+inhospitable

+inhospitableness

+inhospitably

+inhospitality

+inhuman

+inhumane

+inhumanely

+inhumanities

+inhumanly

+inhumanness

+inion

+iniquities

+iniquity

+iniquity's

+initial

+initialness

+initials

+initiate

+initiated

+initiates

+initiating

+initiation

+initiations

+initiative

+initiative's

+initiatives

+initiator

+initiator's

+initiators

+inject

+injected

+injecting

+injection

+injection's

+injections

+injective

+injects

+injudicious

+injudiciously

+injudiciousness

+injunction

+injunction's

+injunctions

+injure

+injured

+injurer

+injures

+injuries

+injuring

+injurious

+injuriously

+injuriousness

+injury

+injury's

+injustice

+injustice's

+injustices

+ink

+inked

+inker

+inkers

+inking

+inkings

+inkling

+inkling's

+inklings

+inks

+inlaid

+inland

+inlander

+inlet

+inlet's

+inlets

+inlier

+inly

+inlying

+inmate

+inmate's

+inmates

+inn

+innards

+innate

+innately

+innateness

+inner

+innerly

+innermost

+inning

+innings

+innocence

+innocent

+innocently

+innocents

+innocuous

+innocuously

+innocuousness

+innovate

+innovated

+innovates

+innovating

+innovation

+innovation's

+innovations

+innovative

+innovativeness

+inns

+innumerability

+innumerable

+innumerableness

+innumerably

+inoperable

+inopportune

+inopportunely

+inopportuneness

+inordinate

+inordinately

+inordinateness

+inorganic

+input

+input's

+inputed

+inputer

+inputing

+inputs

+inputting

+inquietude

+inquire

+inquired

+inquirer

+inquirers

+inquires

+inquiries

+inquiring

+inquiringly

+inquiry

+inquiry's

+inquisition

+inquisition's

+inquisitions

+inquisitive

+inquisitively

+inquisitiveness

+inroad

+inroads

+ins

+insane

+insanely

+insaneness

+insanitary

+insanity

+inscribe

+inscribed

+inscriber

+inscribes

+inscribing

+inscription

+inscription's

+inscriptions

+insect

+insect's

+insects

+insecure

+insecurely

+insecureness

+insecurity

+insensible

+insensibleness

+insensibly

+insensitive

+insensitively

+insensitiveness

+insensitivity

+inseparable

+inseparableness

+insert

+inserted

+inserter

+inserting

+insertion

+insertion's

+insertions

+inserts

+insets

+insetting

+inside

+insider

+insiders

+insides

+insidious

+insidiously

+insidiousness

+insight

+insight's

+insightful

+insightfully

+insights

+insignia

+insignias

+insignificance

+insignificances

+insignificant

+insignificantly

+insincerity

+insinuate

+insinuated

+insinuates

+insinuating

+insinuatingly

+insinuation

+insinuations

+insinuative

+insist

+insisted

+insistence

+insistent

+insistently

+insisting

+insists

+insociability

+insociable

+insociably

+insofar

+insolence

+insolent

+insolently

+insolubility

+insoluble

+insolubleness

+insolvable

+inspect

+inspected

+inspecting

+inspection

+inspection's

+inspections

+inspective

+inspector

+inspector's

+inspectors

+inspects

+inspiration

+inspiration's

+inspirations

+inspire

+inspired

+inspirer

+inspires

+inspiring

+instabilities

+instability

+install

+installation

+installation's

+installations

+installed

+installer

+installers

+installing

+installment

+installment's

+installments

+installs

+instance

+instanced

+instances

+instancing

+instant

+instantaneous

+instantaneously

+instantaneousness

+instanter

+instantiate

+instantiated

+instantiates

+instantiating

+instantiation

+instantiation's

+instantiations

+instantly

+instantness

+instants

+instated

+instates

+instead

+insteps

+instigate

+instigated

+instigates

+instigating

+instigation

+instigative

+instigator

+instigator's

+instigators

+instills

+instinct

+instinct's

+instinctive

+instinctively

+instincts

+institute

+instituted

+instituter

+instituters

+institutes

+instituting

+institution

+institution's

+institutional

+institutionally

+institutions

+institutive

+instruct

+instructed

+instructing

+instruction

+instruction's

+instructional

+instructions

+instructive

+instructively

+instructiveness

+instructor

+instructor's

+instructors

+instructs

+instrument

+instrumental

+instrumentalist

+instrumentalist's

+instrumentalists

+instrumentally

+instrumentals

+instrumentation

+instrumented

+instrumenting

+instruments

+insufficiencies

+insufficiency

+insufficient

+insufficiently

+insulate

+insulated

+insulates

+insulating

+insulation

+insulations

+insulator

+insulator's

+insulators

+insult

+insulted

+insulter

+insulting

+insultingly

+insults

+insuperable

+insupportable

+insupportableness

+insurance

+insurances

+insure

+insured

+insurer

+insurers

+insures

+insurgent

+insurgent's

+insurgents

+insuring

+insurmountable

+insurrection

+insurrection's

+insurrections

+insusceptible

+intact

+intactness

+intakes

+intangible

+intangible's

+intangibleness

+intangibles

+intangibly

+integer

+integer's

+integers

+integral

+integral's

+integrally

+integrals

+integrate

+integrated

+integrates

+integrating

+integration

+integrations

+integrative

+integrity

+intellect

+intellect's

+intellective

+intellectively

+intellects

+intellectual

+intellectually

+intellectualness

+intellectuals

+intelligence

+intelligencer

+intelligences

+intelligent

+intelligently

+intelligibility

+intelligible

+intelligibleness

+intelligibly

+intemperance

+intemperate

+intemperately

+intemperateness

+intend

+intended

+intendedly

+intendedness

+intender

+intending

+intends

+intense

+intensely

+intenseness

+intensification

+intensified

+intensifier

+intensifiers

+intensifies

+intensify

+intensifying

+intension

+intensities

+intensity

+intensive

+intensively

+intensiveness

+intent

+intention

+intentional

+intentionally

+intentioned

+intentions

+intently

+intentness

+intents

+interact

+interacted

+interacting

+interaction

+interaction's

+interactions

+interactive

+interactively

+interactivity

+interacts

+intercept

+intercepted

+intercepter

+intercepting

+intercepts

+interchange

+interchangeability

+interchangeable

+interchangeableness

+interchangeably

+interchanged

+interchanger

+interchanges

+interchanging

+interchangings

+intercity

+intercommunicate

+intercommunicated

+intercommunicates

+intercommunicating

+intercommunication

+interconnect

+interconnected

+interconnectedness

+interconnecting

+interconnection

+interconnection's

+interconnections

+interconnectivity

+interconnects

+intercourse

+interdependence

+interdependencies

+interdependency

+interdependent

+interdependently

+interdisciplinary

+interest

+interested

+interestedly

+interesting

+interestingly

+interestingness

+interests

+interface

+interfaced

+interfacer

+interfaces

+interfacing

+interfere

+interfered

+interference

+interferences

+interferer

+interferes

+interfering

+interferingly

+interim

+interior

+interior's

+interiorly

+interiors

+interlace

+interlaced

+interlaces

+interlacing

+interleave

+interleaved

+interleaves

+interleaving

+interlink

+interlinked

+interlinking

+interlinks

+interlisp

+interlisp's

+intermediaries

+intermediary

+intermediate

+intermediate's

+intermediated

+intermediately

+intermediateness

+intermediates

+intermediating

+intermediation

+interminable

+intermingle

+intermingled

+intermingles

+intermingling

+intermittent

+intermittently

+intermix

+intermixed

+intermixer

+intermixes

+intermixing

+intermodule

+intern

+internal

+internally

+internals

+international

+internationality

+internationally

+internationals

+interned

+interning

+interns

+interpersonal

+interpersonally

+interplay

+interpolate

+interpolated

+interpolates

+interpolating

+interpolation

+interpolations

+interpolative

+interpose

+interposed

+interposer

+interposes

+interposing

+interpret

+interpretable

+interpretation

+interpretation's

+interpretations

+interpreted

+interpreter

+interpreters

+interpreting

+interpretive

+interpretively

+interprets

+interprocess

+interrelate

+interrelated

+interrelatedly

+interrelatedness

+interrelates

+interrelating

+interrelation

+interrelations

+interrelationship

+interrelationship's

+interrelationships

+interrogate

+interrogated

+interrogates

+interrogating

+interrogation

+interrogations

+interrogative

+interrogatively

+interrogatives

+interrupt

+interrupted

+interrupter

+interrupters

+interruptible

+interrupting

+interruption

+interruption's

+interruptions

+interruptive

+interrupts

+intersect

+intersected

+intersecting

+intersection

+intersection's

+intersections

+intersects

+intersperse

+interspersed

+intersperses

+interspersing

+interspersion

+interspersions

+interstage

+interstate

+intertask

+intertwine

+intertwined

+intertwines

+intertwining

+interval

+interval's

+intervals

+intervene

+intervened

+intervener

+intervenes

+intervening

+intervention

+intervention's

+interventions

+interview

+interviewed

+interviewee

+interviewee's

+interviewees

+interviewer

+interviewer's

+interviewers

+interviewing

+interviews

+interwoven

+intestinal

+intestinally

+intestine

+intestine's

+intestines

+intimacy

+intimate

+intimated

+intimately

+intimateness

+intimater

+intimates

+intimating

+intimation

+intimations

+intimidate

+intimidated

+intimidates

+intimidating

+intimidation

+into

+intolerability

+intolerable

+intolerableness

+intolerably

+intolerance

+intolerant

+intolerantly

+intolerantness

+intonation

+intonation's

+intonations

+intoned

+intoner

+intoxicate

+intoxicated

+intoxicatedly

+intoxicating

+intoxication

+intractability

+intractable

+intractableness

+intractably

+intramural

+intramurally

+intransigent

+intransigently

+intransigents

+intransitive

+intransitively

+intransitiveness

+intraprocess

+intricacies

+intricacy

+intricate

+intricately

+intricateness

+intrigue

+intrigued

+intriguer

+intrigues

+intriguing

+intriguingly

+intrinsic

+intrinsically

+intrinsics

+introduce

+introduced

+introducer

+introduces

+introducing

+introduction

+introduction's

+introductions

+introductory

+introspect

+introspection

+introspections

+introspective

+introspectively

+introspectiveness

+introvert

+introverted

+intrude

+intruded

+intruder

+intruder's

+intruders

+intrudes

+intruding

+intrusion

+intrusion's

+intrusions

+intrusive

+intrusively

+intrusiveness

+intrust

+intubate

+intubated

+intubates

+intubating

+intubation

+intuition

+intuition's

+intuitionist

+intuitions

+intuitive

+intuitively

+intuitiveness

+invade

+invaded

+invader

+invaders

+invades

+invading

+invalid

+invalidate

+invalidated

+invalidates

+invalidating

+invalidation

+invalidations

+invalidities

+invalidity

+invalidly

+invalidness

+invalids

+invaluable

+invaluableness

+invaluably

+invariability

+invariable

+invariableness

+invariably

+invariance

+invariant

+invariantly

+invariants

+invasion

+invasion's

+invasions

+invent

+invented

+inventing

+invention

+invention's

+inventions

+inventive

+inventively

+inventiveness

+inventor

+inventor's

+inventories

+inventors

+inventory

+inventory's

+invents

+inveracity

+inverse

+inversely

+inverses

+inversion

+inversions

+inversive

+invert

+invertebrate

+invertebrate's

+invertebrates

+inverted

+inverter

+inverters

+invertible

+inverting

+inverts

+invest

+invested

+investigate

+investigated

+investigates

+investigating

+investigation

+investigations

+investigative

+investigator

+investigator's

+investigators

+investing

+investment

+investment's

+investments

+investor

+investor's

+investors

+invests

+inviability

+inviable

+invincible

+invincibleness

+invisibility

+invisible

+invisibleness

+invisibly

+invitation

+invitation's

+invitations

+invite

+invited

+inviter

+invites

+inviting

+invitingly

+invocation

+invocation's

+invocations

+invoice

+invoiced

+invoices

+invoicing

+invokable

+invoke

+invoked

+invoker

+invokers

+invokes

+invoking

+involuntarily

+involuntariness

+involuntary

+involve

+involved

+involvedly

+involvement

+involvement's

+involvements

+involver

+involves

+involving

+invulnerable

+invulnerableness

+inward

+inwardly

+inwardness

+inwards

+inwrought

+ioctl

+iodine

+ion

+ions

+irate

+irately

+irateness

+ire

+ire's

+ires

+iris

+irises

+irk

+irked

+irking

+irks

+irksome

+irksomely

+irksomeness

+iron

+ironed

+ironer

+ironical

+ironically

+ironicalness

+ironies

+ironing

+ironings

+ironness

+irons

+ironwork

+ironwork's

+ironworker

+ironworks

+irony

+irrational

+irrationality

+irrationally

+irrationalness

+irrationals

+irrecoverable

+irrecoverableness

+irreducible

+irreducibly

+irreflexive

+irrefutable

+irregular

+irregularities

+irregularity

+irregularly

+irregulars

+irrelevance

+irrelevances

+irrelevant

+irrelevantly

+irrepressible

+irresistible

+irresistibleness

+irrespective

+irrespectively

+irresponsible

+irresponsibleness

+irresponsibly

+irreversible

+irrigate

+irrigated

+irrigates

+irrigating

+irrigation

+irrigations

+irritate

+irritated

+irritates

+irritating

+irritatingly

+irritation

+irritations

+irritative

+is

+island

+islander

+islanders

+islands

+isle

+isle's

+isles

+islet

+islet's

+islets

+isling

+isn't

+isolate

+isolated

+isolates

+isolating

+isolation

+isolations

+isometric

+isometrics

+isomorphic

+isomorphically

+isomorphism

+isomorphism's

+isomorphisms

+isotope

+isotope's

+isotopes

+ispell

+ispell's

+issuance

+issue

+issued

+issuer

+issuers

+issues

+issuing

+isthmus

+it

+it'd

+it'll

+it's

+italic

+italics

+itch

+itches

+itching

+item

+item's

+items

+iterate

+iterated

+iterates

+iterating

+iteration

+iterations

+iterative

+iteratively

+iterator

+iterator's

+iterators

+itineraries

+itinerary

+its

+itself

+iv

+ivied

+ivies

+ivories

+ivory

+ivy

+ivy's

+ix

+jab

+jab's

+jabbed

+jabbing

+jabs

+jack

+jacked

+jacker

+jacket

+jacketed

+jackets

+jacking

+jacks

+jade

+jaded

+jadedly

+jadedness

+jades

+jading

+jail

+jailed

+jailer

+jailers

+jailing

+jails

+jam

+jammed

+jamming

+jams

+janitor

+janitor's

+janitors

+jar

+jar's

+jargon

+jarred

+jarring

+jarringly

+jars

+jaunt

+jaunt's

+jaunted

+jauntier

+jauntiness

+jaunting

+jaunts

+jaunty

+javelin

+javelin's

+javelins

+jaw

+jaw's

+jawed

+jaws

+jay

+jazz

+jealous

+jealousies

+jealously

+jealousness

+jealousy

+jean

+jean's

+jeans

+jeep

+jeep's

+jeeped

+jeepers

+jeeping

+jeeps

+jeer

+jeer's

+jeerer

+jeers

+jellied

+jellies

+jelly

+jelly's

+jellyfish

+jellying

+jenny

+jerk

+jerked

+jerker

+jerkier

+jerkiness

+jerking

+jerkings

+jerks

+jerky

+jersey

+jersey's

+jerseys

+jest

+jested

+jester

+jesting

+jests

+jet

+jet's

+jets

+jetted

+jetting

+jewel

+jewelries

+jewelry

+jewels

+jig

+jig's

+jigs

+jingle

+jingled

+jingler

+jingles

+jingling

+job

+job's

+jobs

+jocks

+jocund

+jocundly

+jog

+jogs

+john

+john's

+johns

+join

+joined

+joiner

+joiners

+joining

+joins

+joint

+joint's

+jointed

+jointedly

+jointedness

+jointer

+jointing

+jointly

+jointness

+joints

+joke

+joked

+joker

+jokers

+jokes

+joking

+jokingly

+jollied

+jollier

+jollies

+jolly

+jollying

+jolt

+jolted

+jolter

+jolting

+jolts

+jostle

+jostled

+jostles

+jostling

+jot

+jots

+jotted

+jotting

+journal

+journal's

+journalism

+journalist

+journalist's

+journalistic

+journalists

+journals

+journey

+journeyed

+journeying

+journeyings

+journeys

+joust

+jousted

+jouster

+jousting

+jousts

+joy

+joy's

+joyful

+joyfully

+joyfulness

+joyous

+joyously

+joyousness

+joys

+jubilee

+judge

+judged

+judger

+judges

+judging

+judicable

+judicial

+judicially

+judiciaries

+judiciary

+judicious

+judiciously

+judiciousness

+jug

+jug's

+juggle

+juggled

+juggler

+jugglers

+juggles

+juggling

+jugs

+juice

+juice's

+juiced

+juicer

+juicers

+juices

+juicier

+juiciest

+juiciness

+juicing

+juicy

+jumble

+jumbled

+jumbles

+jumbling

+jump

+jumped

+jumper

+jumpers

+jumpier

+jumpiness

+jumping

+jumps

+jumpy

+junction

+junction's

+junctions

+juncture

+juncture's

+junctures

+jungle

+jungle's

+jungled

+jungles

+junior

+junior's

+juniors

+juniper

+junk

+junker

+junkers

+junkie

+junkies

+junks

+junky

+juries

+jurisdiction

+jurisdiction's

+jurisdictions

+juror

+juror's

+jurors

+jury

+jury's

+just

+juster

+justice

+justice's

+justices

+justifiable

+justifiably

+justification

+justifications

+justified

+justifier

+justifier's

+justifiers

+justifies

+justify

+justifying

+justing

+justly

+justness

+jut

+juvenile

+juvenile's

+juveniles

+juxtapose

+juxtaposed

+juxtaposes

+juxtaposing

+kHz

+keel

+keeled

+keeler

+keeling

+keels

+keen

+keener

+keenest

+keening

+keenly

+keenness

+keep

+keeper

+keepers

+keeping

+keeps

+ken

+kennel

+kennel's

+kennels

+kept

+kerchief

+kerchief's

+kerchiefed

+kerchiefs

+kernel

+kernel's

+kernels

+kerosene

+ketchup

+kettle

+kettle's

+kettles

+key

+keyboard

+keyboard's

+keyboarder

+keyboarding

+keyboards

+keyclick

+keyclick's

+keyclicks

+keyed

+keying

+keypad

+keypad's

+keypads

+keys

+keystroke

+keystroke's

+keystrokes

+keyword

+keyword's

+keywords

+kick

+kicked

+kicker

+kickers

+kicking

+kicks

+kid

+kid's

+kidded

+kidding

+kiddingly

+kidnap

+kidnap's

+kidnaps

+kidney

+kidney's

+kidneys

+kids

+kill

+killed

+killer

+killers

+killing

+killingly

+killings

+kills

+kilobit

+kilobits

+kilobyte

+kilobytes

+kin

+kind

+kinder

+kindergarten

+kindest

+kindhearted

+kindheartedly

+kindheartedness

+kindle

+kindled

+kindler

+kindles

+kindlier

+kindliness

+kindling

+kindly

+kindness

+kindnesses

+kindred

+kinds

+king

+kingdom

+kingdom's

+kingdoms

+kinglier

+kingliness

+kingly

+kings

+kinkier

+kinkiness

+kinky

+kinship

+kinsman

+kiss

+kissed

+kisser

+kissers

+kisses

+kissing

+kissings

+kit

+kit's

+kitchen

+kitchen's

+kitchener

+kitchens

+kite

+kited

+kiter

+kites

+kiting

+kits

+kitsch

+kitten

+kitten's

+kittened

+kittening

+kittens

+kitties

+kitty

+kludge

+kludge's

+kludged

+kludger

+kludger's

+kludgers

+kludges

+kludgey

+kludging

+klutz

+klutz's

+klutzes

+klutziness

+klutzy

+knack

+knacker

+knacks

+knapsack

+knapsack's

+knapsacks

+knave

+knave's

+knaves

+knead

+kneaded

+kneader

+kneading

+kneads

+knee

+kneed

+kneeing

+kneel

+kneeled

+kneeler

+kneeling

+kneels

+knees

+knell

+knell's

+knells

+knelt

+knew

+knife

+knifed

+knifes

+knifing

+knight

+knighted

+knighthood

+knighting

+knightliness

+knightly

+knights

+knit

+knits

+knives

+knob

+knob's

+knobs

+knock

+knocked

+knocker

+knockers

+knocking

+knocks

+knoll

+knoll's

+knolls

+knot

+knot's

+knots

+knotted

+knotting

+know

+knowable

+knower

+knowhow

+knowing

+knowingly

+knowledge

+knowledgeable

+knowledgeableness

+knowledges

+known

+knows

+knuckle

+knuckled

+knuckles

+knuckling

+kudos

+lab

+lab's

+label

+label's

+labels

+laboratories

+laboratory

+laboratory's

+labs

+labyrinth

+labyrinths

+lace

+laced

+lacer

+lacerate

+lacerated

+lacerates

+lacerating

+laceration

+lacerations

+lacerative

+laces

+lacing

+lack

+lackadaisical

+lackadaisically

+lacked

+lacker

+lacking

+lacks

+lacquer

+lacquered

+lacquerer

+lacquerers

+lacquering

+lacquers

+lad

+ladder

+ladders

+laded

+laden

+ladened

+ladening

+ladies

+lading

+lads

+lady

+lady's

+lag

+lager

+lagers

+lagged

+lagoon

+lagoon's

+lagoons

+lags

+laid

+lain

+lair

+lair's

+lairs

+lake

+lake's

+laker

+lakes

+laking

+lamb

+lamb's

+lambda

+lambda's

+lambdas

+lamber

+lambs

+lame

+lamed

+lamely

+lameness

+lament

+lamentable

+lamentableness

+lamentation

+lamentation's

+lamentations

+lamented

+lamenting

+laments

+lamer

+lames

+lamest

+laminar

+laming

+lamp

+lamp's

+lamper

+lamps

+lance

+lanced

+lancer

+lancers

+lances

+lancing

+land

+landed

+lander

+landers

+landing

+landings

+landladies

+landlady

+landlady's

+landlord

+landlord's

+landlords

+landmark

+landmark's

+landmarks

+landowner

+landowner's

+landowners

+lands

+landscape

+landscaped

+landscaper

+landscapes

+landscaping

+lane

+lane's

+lanes

+language

+language's

+languages

+languid

+languidly

+languidness

+languish

+languished

+languisher

+languishes

+languishing

+languishingly

+lantern

+lantern's

+lanterns

+lap

+lap's

+lapel

+lapel's

+lapels

+laps

+lapse

+lapsed

+lapser

+lapses

+lapsing

+lard

+larded

+larder

+larding

+lards

+large

+largely

+largeness

+larger

+largest

+lark

+lark's

+larker

+larks

+larva

+larvae

+larvas

+laser

+laser's

+lasers

+lash

+lashed

+lasher

+lashes

+lashing

+lashings

+lass

+lass's

+lasses

+last

+lasted

+laster

+lasting

+lastingly

+lastingness

+lastly

+lasts

+latch

+latched

+latches

+latching

+late

+lated

+lately

+latencies

+latency

+latency's

+lateness

+latent

+latently

+latents

+later

+lateral

+laterally

+latest

+latex

+latex's

+latexes

+lath

+lather

+lathered

+latherer

+lathering

+lathes

+lathing

+latitude

+latitude's

+latitudes

+latrine

+latrine's

+latrines

+latter

+latter's

+latterly

+lattice

+lattice's

+latticed

+lattices

+latticing

+laugh

+laughable

+laughableness

+laughably

+laughed

+laugher

+laughers

+laughing

+laughingly

+laughs

+laughter

+laughters

+launch

+launched

+launcher

+launchers

+launches

+launching

+launchings

+launder

+laundered

+launderer

+laundering

+launderings

+launders

+laundries

+laundry

+laurel

+laurel's

+laurels

+lava

+lavatories

+lavatory

+lavatory's

+lavender

+lavendered

+lavendering

+lavish

+lavished

+lavishing

+lavishly

+lavishness

+law

+law's

+lawful

+lawfully

+lawfulness

+lawless

+lawlessly

+lawlessness

+lawn

+lawn's

+lawns

+laws

+lawsuit

+lawsuit's

+lawsuits

+lawyer

+lawyer's

+lawyerly

+lawyers

+lay

+layer

+layered

+layering

+layers

+laying

+layman

+laymen

+layoffs

+layout

+layout's

+layouts

+lays

+lazed

+lazied

+lazier

+laziest

+lazily

+laziness

+lazing

+lazy

+lazying

+lead

+leaded

+leaden

+leadenly

+leadenness

+leader

+leader's

+leaders

+leadership

+leadership's

+leaderships

+leading

+leadings

+leads

+leaf

+leafed

+leafier

+leafiest

+leafing

+leafless

+leaflet

+leaflet's

+leaflets

+leafs

+leafy

+league

+leagued

+leaguer

+leaguers

+leagues

+leaguing

+leak

+leakage

+leakage's

+leakages

+leaked

+leaker

+leaking

+leaks

+lean

+leaned

+leaner

+leanest

+leaning

+leanings

+leanly

+leanness

+leans

+leap

+leaped

+leaper

+leaping

+leaps

+leapt

+learn

+learned

+learnedly

+learnedness

+learner

+learners

+learning

+learnings

+learns

+lease

+leased

+leases

+leash

+leash's

+leashes

+leasing

+least

+leather

+leathered

+leathering

+leathern

+leathers

+leave

+leaved

+leaven

+leavened

+leavening

+leaver

+leavers

+leaves

+leaving

+leavings

+lecture

+lectured

+lecturer

+lecturers

+lectures

+lecturing

+led

+ledge

+ledger

+ledgers

+ledges

+lee

+leech

+leech's

+leeches

+leer

+leered

+leering

+leers

+lees

+left

+leftist

+leftist's

+leftists

+leftmost

+leftover

+leftover's

+leftovers

+lefts

+leftward

+leftwards

+leg

+legacies

+legacy

+legacy's

+legal

+legalities

+legality

+legally

+legals

+legend

+legend's

+legendary

+legends

+legged

+leggings

+legibility

+legible

+legibly

+legion

+legion's

+legions

+legislate

+legislated

+legislates

+legislating

+legislation

+legislations

+legislative

+legislatively

+legislator

+legislator's

+legislators

+legislature

+legislature's

+legislatures

+legitimacy

+legitimate

+legitimated

+legitimately

+legitimates

+legitimating

+legitimation

+legs

+leisure

+leisured

+leisureliness

+leisurely

+lemma

+lemma's

+lemmas

+lemon

+lemon's

+lemonade

+lemons

+lend

+lender

+lenders

+lending

+lends

+length

+lengthen

+lengthened

+lengthener

+lengthening

+lengthens

+lengthier

+lengthiness

+lengthly

+lengths

+lengthwise

+lengthy

+leniency

+lenient

+leniently

+lens

+lens's

+lensed

+lenser

+lensers

+lenses

+lensing

+lensings

+lent

+lentil

+lentil's

+lentils

+leopard

+leopard's

+leopards

+leprosy

+less

+lessen

+lessened

+lessening

+lessens

+lesser

+lesses

+lessing

+lesson

+lesson's

+lessoned

+lessoning

+lessons

+lest

+lester

+let

+let's

+lets

+letter

+lettered

+letterer

+lettering

+letters

+letting

+lettuce

+levee

+levee's

+leveed

+levees

+level

+levelly

+levelness

+levels

+lever

+lever's

+leverage

+leveraged

+leverages

+leveraging

+levered

+levering

+levers

+levied

+levier

+levies

+levy

+levying

+lewd

+lewdly

+lewdness

+lexical

+lexically

+lexicographic

+lexicographical

+lexicographically

+lexicon

+lexicon's

+lexicons

+liabilities

+liability

+liability's

+liable

+liableness

+liaison

+liaison's

+liaisons

+liar

+liar's

+liars

+liberal

+liberally

+liberalness

+liberals

+liberate

+liberated

+liberates

+liberating

+liberation

+liberator

+liberator's

+liberators

+liberties

+liberty

+liberty's

+libido

+librarian

+librarian's

+librarians

+libraries

+library

+library's

+libretti

+license

+licensed

+licensee

+licensee's

+licensees

+licenser

+licenses

+licensing

+lichen

+lichen's

+lichened

+lichens

+lick

+licked

+licker

+licking

+licks

+lid

+lid's

+lids

+lie

+lied

+lieder

+liege

+lien

+lien's

+liens

+lier

+lies

+lieu

+lieutenant

+lieutenant's

+lieutenants

+life

+life's

+lifeless

+lifelessly

+lifelessness

+lifelike

+lifelikeness

+lifelong

+lifer

+lifers

+lifestyle

+lifestyles

+lifetime

+lifetime's

+lifetimes

+lift

+lifted

+lifter

+lifters

+lifting

+lifts

+light

+lighted

+lighten

+lightened

+lightener

+lightening

+lightens

+lighter

+lighter's

+lighters

+lightest

+lighthouse

+lighthouse's

+lighthouses

+lighting

+lightly

+lightness

+lightning

+lightning's

+lightninged

+lightnings

+lights

+lightweight

+lightweights

+like

+liked

+likelier

+likeliest

+likelihood

+likelihoods

+likeliness

+likely

+liken

+likened

+likeness

+likeness's

+likenesses

+likening

+likens

+liker

+likes

+likest

+likewise

+liking

+likings

+lilac

+lilac's

+lilacs

+lilied

+lilies

+lily

+lily's

+limb

+limbed

+limber

+limbered

+limbering

+limberly

+limberness

+limbers

+limbs

+lime

+lime's

+limed

+limes

+limestone

+liming

+limit

+limitability

+limitably

+limitation

+limitation's

+limitations

+limited

+limitedly

+limitedness

+limiteds

+limiter

+limiters

+limiting

+limits

+limp

+limped

+limper

+limping

+limply

+limpness

+limps

+linden

+line

+line's

+linear

+linearities

+linearity

+linearly

+lined

+linen

+linen's

+linens

+liner

+liners

+lines

+linger

+lingered

+lingerer

+lingering

+lingeringly

+lingers

+linguist

+linguist's

+linguistic

+linguistically

+linguistics

+linguists

+lining

+linings

+link

+linkage

+linkage's

+linkages

+linked

+linker

+linkers

+linking

+linkings

+links

+linoleum

+linseed

+lint

+linter

+lints

+lion

+lion's

+lioness

+lioness's

+lionesses

+lions

+lip

+lip's

+lips

+lipstick

+liquefied

+liquefier

+liquefiers

+liquefies

+liquefy

+liquefying

+liquid

+liquid's

+liquidation

+liquidation's

+liquidations

+liquidity

+liquidly

+liquidness

+liquids

+liquor

+liquor's

+liquored

+liquoring

+liquors

+lisp

+lisp's

+lisped

+lisper

+lisping

+lisps

+list

+listed

+listen

+listened

+listener

+listeners

+listening

+listens

+lister

+listers

+listing

+listing's

+listings

+lists

+lit

+literacy

+literal

+literally

+literalness

+literals

+literariness

+literary

+literate

+literately

+literateness

+literation

+literature

+literature's

+literatures

+lithe

+lithely

+litheness

+litigate

+litigated

+litigates

+litigating

+litigation

+litigator

+litter

+littered

+litterer

+littering

+litters

+little

+littleness

+littler

+littlest

+livable

+livableness

+livably

+live

+lived

+livelier

+liveliest

+livelihood

+liveliness

+lively

+liven

+livened

+liveness

+livening

+liver

+liveried

+livers

+livery

+lives

+livest

+liveth

+living

+livingly

+livingness

+livings

+lizard

+lizard's

+lizards

+load

+loaded

+loader

+loaders

+loading

+loadings

+loads

+loaf

+loafed

+loafer

+loafers

+loafing

+loafs

+loan

+loaned

+loaner

+loaning

+loans

+loath

+loathe

+loathed

+loather

+loathes

+loathing

+loathly

+loathness

+loathsome

+loathsomely

+loathsomeness

+loaves

+lobbied

+lobbies

+lobby

+lobbying

+lobe

+lobe's

+lobed

+lobes

+lobster

+lobster's

+lobsters

+local

+localities

+locality

+locality's

+locally

+locals

+locate

+located

+locater

+locates

+locating

+location

+locations

+locative

+locatives

+locator

+locator's

+locators

+loci

+lock

+locked

+locker

+lockers

+locking

+lockings

+lockout

+lockout's

+lockouts

+locks

+lockup

+lockup's

+lockups

+locomotion

+locomotive

+locomotive's

+locomotively

+locomotives

+locus

+locus's

+locust

+locust's

+locusts

+lodge

+lodged

+lodger

+lodger's

+lodgers

+lodges

+lodging

+lodgings

+loft

+loft's

+lofter

+loftier

+loftiness

+lofts

+lofty

+log

+log's

+logarithm

+logarithm's

+logarithmically

+logarithms

+logged

+logger

+logger's

+loggers

+logging

+logic

+logic's

+logical

+logically

+logicalness

+logicals

+logician

+logician's

+logicians

+logics

+login

+logins

+logistic

+logistics

+logout

+logs

+loin

+loin's

+loins

+loiter

+loitered

+loiterer

+loitering

+loiters

+lone

+lonelier

+loneliest

+loneliness

+lonely

+loneness

+loner

+loners

+lonesome

+lonesomely

+lonesomeness

+long

+longed

+longer

+longest

+longing

+longingly

+longings

+longitude

+longitude's

+longitudes

+longly

+longness

+longs

+longword

+longword's

+longwords

+look

+lookahead

+looked

+looker

+lookers

+looking

+lookout

+lookouts

+looks

+lookup

+lookup's

+lookups

+loom

+loomed

+looming

+looms

+loon

+loop

+looped

+looper

+loophole

+loophole's

+loopholed

+loopholes

+loopholing

+looping

+loops

+loose

+loosed

+loosely

+loosen

+loosened

+loosener

+looseness

+loosening

+loosens

+looser

+looses

+loosest

+loosing

+loot

+looted

+looter

+looting

+loots

+lord

+lord's

+lording

+lordlier

+lordliness

+lordly

+lords

+lordship

+lore

+lorries

+lorry

+lose

+loser

+losers

+loses

+losing

+losings

+loss

+loss's

+losses

+lossier

+lossiest

+lossy

+lost

+lostness

+lot

+lot's

+lots

+lotteries

+lottery

+lotus

+loud

+louden

+loudened

+loudening

+louder

+loudest

+loudly

+loudness

+loudspeaker

+loudspeaker's

+loudspeakers

+lounge

+lounged

+lounger

+loungers

+lounges

+lounging

+lousier

+lousiness

+lousy

+lovable

+lovableness

+lovably

+love

+love's

+loved

+lovelier

+lovelies

+loveliest

+loveliness

+lovely

+lover

+lover's

+lovering

+loverly

+lovers

+loves

+loving

+lovingly

+lovingness

+low

+lower

+lowered

+lowering

+lowers

+lowest

+lowing

+lowland

+lowlander

+lowlands

+lowlier

+lowliest

+lowliness

+lowly

+lowness

+lows

+loyal

+loyally

+loyalties

+loyalty

+loyalty's

+lubricant

+lubricant's

+lubricants

+lubrication

+luck

+lucked

+luckier

+luckiest

+luckily

+luckiness

+luckless

+lucks

+lucky

+ludicrous

+ludicrously

+ludicrousness

+luggage

+lukewarm

+lukewarmly

+lukewarmness

+lull

+lullaby

+lulled

+lulls

+lumber

+lumbered

+lumberer

+lumbering

+lumbers

+luminous

+luminously

+luminousness

+lump

+lumped

+lumpen

+lumper

+lumping

+lumps

+lunar

+lunatic

+lunatics

+lunch

+lunched

+luncheon

+luncheon's

+luncheons

+luncher

+lunches

+lunching

+lung

+lunged

+lunger

+lunging

+lungs

+lurch

+lurched

+lurcher

+lurches

+lurching

+lure

+lured

+lurer

+lures

+luring

+lurk

+lurked

+lurker

+lurkers

+lurking

+lurks

+luscious

+lusciously

+lusciousness

+lust

+lustier

+lustily

+lustiness

+lusting

+lustrous

+lustrously

+lustrousness

+lusts

+lusty

+lute

+lute's

+luted

+lutes

+luting

+luxuriant

+luxuriantly

+luxuries

+luxurious

+luxuriously

+luxuriousness

+luxury

+luxury's

+lying

+lyingly

+lyings

+lymph

+lynch

+lynched

+lyncher

+lynches

+lynx

+lynx's

+lynxes

+lyre

+lyre's

+lyres

+lyric

+lyrics

+ma'am

+macaroni

+macaroni's

+mace

+maced

+macer

+maces

+machine

+machine's

+machined

+machineries

+machinery

+machines

+machining

+macing

+macro

+macro's

+macroeconomics

+macromolecule

+macromolecule's

+macromolecules

+macros

+macroscopic

+mad

+madam

+madams

+madden

+maddened

+maddening

+maddeningly

+madder

+maddest

+made

+mademoiselle

+mademoiselles

+madly

+madman

+madness

+madras

+magazine

+magazine's

+magazined

+magazines

+magazining

+maggot

+maggot's

+maggots

+magic

+magical

+magically

+magician

+magician's

+magicians

+magistrate

+magistrate's

+magistrates

+magnesium

+magnesiums

+magnet

+magnet's

+magnetic

+magnetically

+magnetics

+magnetism

+magnetism's

+magnetisms

+magnets

+magnification

+magnifications

+magnificence

+magnificent

+magnificently

+magnified

+magnifier

+magnifiers

+magnifies

+magnify

+magnifying

+magnitude

+magnitude's

+magnitudes

+mahogany

+maid

+maid's

+maiden

+maidenliness

+maidenly

+maidens

+maids

+mail

+mailable

+mailbox

+mailbox's

+mailboxes

+mailed

+mailer

+mailer's

+mailers

+mailing

+mailings

+mails

+maim

+maimed

+maimedness

+maimer

+maimers

+maiming

+maims

+main

+mainframe

+mainframe's

+mainframes

+mainland

+mainlander

+mainlanders

+mainly

+mains

+mainstay

+maintain

+maintainability

+maintainable

+maintained

+maintainer

+maintainer's

+maintainers

+maintaining

+maintains

+maintenance

+maintenance's

+maintenances

+majestic

+majesties

+majesty

+majesty's

+major

+majored

+majoring

+majorities

+majority

+majority's

+majors

+makable

+make

+makefile

+makefiles

+maker

+makers

+makes

+makeshift

+makeshifts

+makeup

+makeups

+making

+makings

+maladies

+malady

+malady's

+malaria

+male

+male's

+malefactor

+malefactor's

+malefactors

+maleness

+males

+malfunction

+malfunctioned

+malfunctioning

+malfunctions

+malice

+malicious

+maliciously

+maliciousness

+malignant

+malignantly

+mall

+mall's

+mallet

+mallet's

+mallets

+malls

+malnutrition

+malt

+malted

+malting

+malts

+mama

+mamma

+mamma's

+mammal

+mammal's

+mammals

+mammas

+mammoth

+man

+man's

+manage

+manageable

+manageableness

+managed

+management

+management's

+managements

+manager

+manager's

+managerial

+managerially

+managers

+manages

+managing

+mandate

+mandated

+mandates

+mandating

+mandatories

+mandatory

+mandible

+mandolin

+mandolin's

+mandolins

+mane

+mane's

+maned

+manes

+manger

+manger's

+mangers

+mangle

+mangled

+mangler

+mangles

+mangling

+manhood

+maniac

+maniac's

+maniacs

+manicure

+manicured

+manicures

+manicuring

+manifest

+manifestation

+manifestation's

+manifestations

+manifested

+manifesting

+manifestly

+manifestness

+manifests

+manifold

+manifold's

+manifolder

+manifoldly

+manifoldness

+manifolds

+manipulability

+manipulable

+manipulatable

+manipulate

+manipulated

+manipulates

+manipulating

+manipulation

+manipulations

+manipulative

+manipulativeness

+manipulator

+manipulator's

+manipulators

+manipulatory

+mankind

+manlier

+manliest

+manliness

+manly

+manned

+manner

+mannered

+mannerliness

+mannerly

+manners

+manning

+manometer

+manometer's

+manometers

+manor

+manor's

+manors

+manpower

+mans

+mansion

+mansion's

+mansions

+mantel

+mantel's

+mantels

+mantissa

+mantissa's

+mantissas

+mantle

+mantle's

+mantled

+mantles

+mantling

+manual

+manual's

+manually

+manuals

+manufacture

+manufactured

+manufacturer

+manufacturer's

+manufacturers

+manufactures

+manufacturing

+manure

+manured

+manurer

+manurers

+manures

+manuring

+manuscript

+manuscript's

+manuscripts

+many

+map

+map's

+maple

+maple's

+maples

+mappable

+mapped

+mapping

+mapping's

+mappings

+maps

+mar

+marble

+marbled

+marbler

+marbles

+marbling

+march

+marched

+marcher

+marches

+marching

+mare

+mare's

+mares

+margin

+margin's

+marginal

+marginally

+marginals

+margined

+margining

+margins

+marigold

+marigold's

+marigolds

+marijuana

+marijuana's

+marinate

+marinated

+marinates

+marinating

+marine

+mariner

+marines

+maritime

+maritimer

+mark

+markable

+marked

+markedly

+marker

+markers

+market

+marketability

+marketable

+marketed

+marketer

+marketing

+marketings

+marketplace

+marketplace's

+marketplaces

+markets

+marking

+markings

+marks

+marquis

+marquises

+marriage

+marriage's

+marriages

+married

+marries

+marrow

+marrows

+marry

+marrying

+mars

+marsh

+marsh's

+marshal

+marshaled

+marshaler

+marshalers

+marshaling

+marshals

+marshes

+mart

+marten

+martens

+martial

+martially

+marts

+martyr

+martyr's

+martyrdom

+martyrs

+marvel

+marvels

+masculine

+masculinely

+masculineness

+masculinity

+mash

+mashed

+masher

+mashers

+mashes

+mashing

+mashings

+mask

+masked

+masker

+masking

+maskings

+masks

+masochist

+masochist's

+masochists

+mason

+mason's

+masoned

+masoning

+masonry

+masons

+masquerade

+masquerader

+masquerades

+masquerading

+mass

+massacre

+massacred

+massacrer

+massacres

+massacring

+massage

+massaged

+massager

+massages

+massaging

+massed

+masses

+massing

+massinger

+massive

+massively

+massiveness

+mast

+masted

+master

+master's

+mastered

+masterful

+masterfully

+masterfulness

+mastering

+masterings

+masterliness

+masterly

+masterpiece

+masterpiece's

+masterpieces

+masters

+mastery

+masts

+masturbate

+masturbated

+masturbates

+masturbating

+masturbation

+mat

+mat's

+match

+matchable

+matched

+matcher

+matchers

+matches

+matching

+matchings

+matchless

+matchlessly

+matchmaker

+matchmaker's

+matchmakers

+matchmaking

+matchmaking's

+mate

+mate's

+mated

+mater

+material

+materialism

+materialism's

+materially

+materialness

+materials

+maternal

+maternally

+mates

+math

+mathematical

+mathematically

+mathematician

+mathematician's

+mathematicians

+mathematics

+mating

+matings

+matrices

+matriculation

+matrimony

+matrix

+matrixes

+matron

+matronly

+mats

+matted

+matter

+mattered

+mattering

+matters

+mattress

+mattress's

+mattresses

+maturation

+mature

+matured

+maturely

+matureness

+maturer

+matures

+maturing

+maturities

+maturity

+max

+maxim

+maxim's

+maximal

+maximally

+maxims

+maximum

+maximumly

+maximums

+may

+maybe

+mayer

+mayest

+mayhap

+mayhem

+maying

+mayonnaise

+mayor

+mayor's

+mayoral

+mayors

+mays

+maze

+maze's

+mazed

+mazedly

+mazedness

+mazednesses

+mazer

+mazes

+mazing

+me

+mead

+meadow

+meadow's

+meadows

+meads

+meager

+meagerly

+meagerness

+meal

+meal's

+meals

+mean

+meander

+meandered

+meandering

+meanderings

+meanders

+meaner

+meanest

+meaning

+meaning's

+meaningful

+meaningfully

+meaningfulness

+meaningless

+meaninglessly

+meaninglessness

+meanings

+meanly

+meanness

+means

+meant

+meantime

+meanwhile

+measles

+measurable

+measurably

+measure

+measured

+measuredly

+measurement

+measurement's

+measurements

+measurer

+measures

+measuring

+meat

+meat's

+meats

+mechanic

+mechanic's

+mechanical

+mechanically

+mechanicals

+mechanics

+mechanism

+mechanism's

+mechanisms

+med

+medal

+medal's

+medallion

+medallion's

+medallions

+medals

+meddle

+meddled

+meddler

+meddles

+meddling

+media

+median

+median's

+medianly

+medians

+medias

+mediate

+mediated

+mediately

+mediateness

+mediates

+mediating

+mediation

+mediations

+mediative

+medic

+medic's

+medical

+medically

+medicinal

+medicinally

+medicine

+medicine's

+medicines

+medics

+medieval

+medieval's

+medievally

+medievals

+meditate

+meditated

+meditates

+meditating

+meditation

+meditations

+meditative

+meditatively

+meditativeness

+medium

+medium's

+mediums

+meek

+meeker

+meekest

+meekly

+meekness

+meet

+meeter

+meeting

+meetings

+meetly

+meets

+megabit

+megabits

+megabyte

+megabytes

+megaword

+megawords

+melancholy

+meld

+melding

+melds

+mellow

+mellowed

+mellowing

+mellowly

+mellowness

+mellows

+melodies

+melodious

+melodiously

+melodiousness

+melodrama

+melodrama's

+melodramas

+melody

+melody's

+melon

+melon's

+melons

+melt

+melted

+melter

+melting

+meltingly

+melts

+member

+member's

+membered

+members

+membership

+membership's

+memberships

+membrane

+membrane's

+membraned

+membranes

+memo

+memo's

+memoir

+memoirs

+memorability

+memorable

+memorableness

+memoranda

+memorandum

+memorandums

+memorial

+memorially

+memorials

+memories

+memory

+memory's

+memoryless

+memos

+men

+men's

+menace

+menaced

+menaces

+menacing

+menacingly

+menagerie

+menageries

+mend

+mended

+mender

+mending

+mends

+menial

+menially

+menials

+mens

+mensed

+menses

+mensing

+mental

+mentalities

+mentality

+mentally

+mention

+mentionable

+mentioned

+mentioner

+mentioners

+mentioning

+mentions

+mentor

+mentor's

+mentors

+menu

+menu's

+menus

+mer

+mercenaries

+mercenariness

+mercenary

+mercenary's

+merchandise

+merchandised

+merchandiser

+merchandises

+merchandising

+merchant

+merchant's

+merchants

+mercies

+merciful

+mercifully

+mercifulness

+merciless

+mercilessly

+mercilessness

+mercuries

+mercury

+mercy

+mere

+merely

+merest

+merge

+merged

+merger

+mergers

+merges

+merging

+meridian

+meridians

+merit

+merited

+meriting

+meritorious

+meritoriously

+meritoriousness

+merits

+merrier

+merriest

+merrily

+merriment

+merriments

+merriness

+merry

+mesh

+meshed

+meshes

+meshing

+mess

+message

+message's

+messaged

+messages

+messaging

+messed

+messenger

+messenger's

+messengers

+messes

+messiah

+messiahs

+messier

+messiest

+messieurs

+messily

+messiness

+messing

+messy

+met

+meta

+metacircular

+metacircularity

+metal

+metal's

+metalanguage

+metalanguages

+metallic

+metallurgy

+metals

+metamathematical

+metamorphosis

+metaphor

+metaphor's

+metaphorical

+metaphorically

+metaphors

+metaphysical

+metaphysically

+metaphysics

+metavariable

+mete

+meted

+meteor

+meteor's

+meteoric

+meteorology

+meteors

+meter

+meter's

+metered

+metering

+meters

+metes

+method

+method's

+methodical

+methodically

+methodicalness

+methodist

+methodist's

+methodists

+methodological

+methodologically

+methodologies

+methodologists

+methodology

+methodology's

+methods

+meting

+metric

+metric's

+metrical

+metrically

+metrics

+metropolis

+metropolitan

+mets

+mew

+mewed

+mews

+mica

+mice

+microbicidal

+microbicide

+microcode

+microcoded

+microcodes

+microcoding

+microcomputer

+microcomputer's

+microcomputers

+microeconomics

+microfilm

+microfilm's

+microfilmed

+microfilmer

+microfilms

+microinstruction

+microinstruction's

+microinstructions

+microphone

+microphones

+microphoning

+microprocessing

+microprocessor

+microprocessor's

+microprocessors

+microprogram

+microprogram's

+microprogrammed

+microprogramming

+microprograms

+microscope

+microscope's

+microscopes

+microscopic

+microsecond

+microsecond's

+microseconds

+microstore

+microwave

+microwave's

+microwaves

+microword

+microwords

+mid

+midday

+middle

+middled

+middler

+middles

+middling

+middlingly

+middlings

+midnight

+midnightly

+midnights

+midpoint

+midpoint's

+midpoints

+midst

+midsts

+midsummer

+midway

+midways

+midwinter

+midwinterly

+mien

+miens

+mies

+miff

+miffed

+miffing

+miffs

+might

+mightier

+mightiest

+mightily

+mightiness

+mights

+mighty

+migrate

+migrated

+migrates

+migrating

+migration

+migrations

+migrative

+mild

+milden

+milder

+mildest

+mildew

+mildews

+mildly

+mildness

+mile

+mile's

+mileage

+mileages

+miler

+miles

+milestone

+milestone's

+milestones

+militant

+militantly

+militantness

+militants

+militaries

+militarily

+militarism

+militarisms

+military

+militia

+militias

+milk

+milked

+milker

+milkers

+milkier

+milkiness

+milking

+milkmaid

+milkmaid's

+milkmaids

+milks

+milky

+mill

+milled

+miller

+millers

+millet

+milling

+million

+millionaire

+millionaire's

+millionaires

+millioned

+millions

+millionth

+millipede

+millipede's

+millipedes

+millisecond

+milliseconds

+mills

+millstone

+millstone's

+millstones

+mimic

+mimicked

+mimicking

+mimics

+mince

+minced

+mincer

+mincers

+minces

+mincing

+mincingly

+mind

+minded

+mindedness

+minder

+minders

+mindful

+mindfully

+mindfulness

+minding

+mindless

+mindlessly

+mindlessness

+minds

+mine

+mined

+miner

+mineral

+mineral's

+minerals

+miners

+mines

+ming

+mingle

+mingled

+mingles

+mingling

+miniature

+miniature's

+miniatured

+miniatures

+miniaturing

+minicomputer

+minicomputer's

+minicomputers

+minimal

+minimally

+minimum

+minimums

+mining

+minion

+minions

+minister

+minister's

+ministered

+ministering

+ministers

+ministries

+ministry

+ministry's

+mink

+mink's

+minks

+minnow

+minnow's

+minnows

+minor

+minor's

+minored

+minoring

+minorities

+minority

+minority's

+minors

+minstrel

+minstrel's

+minstrels

+mint

+minted

+minter

+minting

+mints

+minus

+minuses

+minute

+minuted

+minutely

+minuteness

+minuter

+minutes

+minutest

+minuting

+miracle

+miracle's

+miracles

+miraculous

+miraculously

+miraculousness

+mire

+mired

+mires

+miring

+mirror

+mirrored

+mirroring

+mirrors

+mirth

+misapplication

+misapplied

+misapplier

+misapplies

+misapply

+misapplying

+misbehaving

+miscalculation

+miscalculation's

+miscalculations

+miscellaneous

+miscellaneously

+miscellaneousness

+mischief

+mischievous

+mischievously

+mischievousness

+miscommunicate

+miscommunicated

+miscommunicates

+miscommunication

+misconception

+misconception's

+misconceptions

+misconstrue

+misconstrued

+misconstrues

+misconstruing

+misdirect

+misdirected

+misdirection

+misdirects

+miser

+miserable

+miserableness

+miserably

+miseries

+miserliness

+miserly

+misers

+misery

+misery's

+misfeature

+misfit

+misfit's

+misfits

+misfortune

+misfortune's

+misfortunes

+misgiving

+misgivingly

+misgivings

+misguide

+misguided

+misguidedly

+misguidedness

+misguider

+misguides

+misguiding

+mishap

+mishap's

+mishaps

+misinform

+misinformation

+misinformed

+misinforming

+misinforms

+misinterpret

+misinterpreted

+misinterpreter

+misinterpreters

+misinterpreting

+misinterprets

+mislead

+misleader

+misleading

+misleadingly

+misleadings

+misleads

+misled

+mismatch

+mismatched

+mismatches

+mismatching

+misnomer

+misnomered

+misperceive

+misperceived

+misperceives

+misplace

+misplaced

+misplaces

+misplacing

+misread

+misreader

+misreading

+misreads

+misrepresentation

+misrepresentation's

+misrepresentations

+miss

+missed

+misses

+missile

+missile's

+missiles

+missing

+mission

+missionaries

+missionary

+missionary's

+missioned

+missioner

+missioning

+missions

+missive

+missives

+misspell

+misspelled

+misspelling

+misspellings

+misspells

+misstate

+misstated

+misstater

+misstates

+misstating

+mist

+mistakable

+mistake

+mistaken

+mistakenly

+mistaker

+mistakes

+mistaking

+mistakingly

+misted

+mister

+mistered

+mistering

+misters

+mistier

+mistiest

+mistiness

+misting

+mistreat

+mistreated

+mistreating

+mistreats

+mistress

+mistressly

+mistrust

+mistrusted

+mistruster

+mistrusting

+mistrusts

+mists

+misty

+mistype

+mistyped

+mistypes

+mistyping

+misunderstand

+misunderstander

+misunderstanders

+misunderstanding

+misunderstanding's

+misunderstandings

+misunderstands

+misunderstood

+misuse

+misused

+misuser

+misuses

+misusing

+mite

+mites

+mitigate

+mitigated

+mitigates

+mitigating

+mitigation

+mitigations

+mitigative

+mitten

+mitten's

+mittens

+mix

+mixed

+mixer

+mixers

+mixes

+mixing

+mixture

+mixture's

+mixtures

+ml

+mnemonic

+mnemonic's

+mnemonically

+mnemonics

+moan

+moaned

+moaning

+moans

+moat

+moat's

+moats

+mob

+mob's

+mobility

+mobs

+moccasin

+moccasin's

+moccasins

+mock

+mocked

+mocker

+mockers

+mockery

+mocking

+mockingly

+mocks

+modal

+modalities

+modality

+modality's

+modally

+mode

+model

+model's

+models

+modem

+modems

+moderate

+moderated

+moderately

+moderateness

+moderates

+moderating

+moderation

+moderations

+moderator

+moderator's

+moderators

+modern

+modernity

+modernly

+modernness

+moderns

+modes

+modest

+modestly

+modesty

+modifiability

+modifiable

+modifiableness

+modification

+modifications

+modified

+modifier

+modifiers

+modifies

+modify

+modifying

+modular

+modularities

+modularity

+modularly

+modulate

+modulated

+modulates

+modulating

+modulation

+modulations

+modulator

+modulator's

+modulators

+module

+module's

+modules

+modulo

+modulus

+modus

+moist

+moisten

+moistened

+moistener

+moistening

+moistly

+moistness

+moisture

+moistures

+molasses

+mold

+molded

+molder

+moldered

+moldering

+molders

+moldier

+moldiness

+molding

+molds

+moldy

+mole

+molecular

+molecularly

+molecule

+molecule's

+molecules

+moles

+molest

+molested

+molester

+molesters

+molesting

+molests

+molten

+mom

+mom's

+moment

+moment's

+momentarily

+momentariness

+momentary

+momently

+momentous

+momentously

+momentousness

+moments

+momentum

+momentums

+moms

+monarch

+monarchies

+monarchs

+monarchy

+monarchy's

+monasteries

+monastery

+monastery's

+monastic

+monetary

+money

+money's

+moneyed

+moneyer

+moneys

+monitor

+monitored

+monitoring

+monitors

+monk

+monk's

+monkey

+monkeyed

+monkeying

+monkeys

+monks

+mono

+mono's

+monochrome

+monochromes

+monograph

+monograph's

+monographes

+monographs

+monolithic

+monopolies

+monopoly

+monopoly's

+monotheism

+monotone

+monotonic

+monotonically

+monotonicity

+monotonous

+monotonously

+monotonousness

+monotony

+monster

+monster's

+monsters

+monstrous

+monstrously

+monstrousness

+month

+month's

+monthlies

+monthly

+months

+monument

+monument's

+monumental

+monumentally

+monuments

+mood

+mood's

+moodier

+moodiness

+moods

+moody

+moon

+mooned

+mooning

+moonlight

+moonlighted

+moonlighter

+moonlighting

+moonlights

+moonlit

+moons

+moonshine

+moonshiner

+moor

+moor's

+moored

+mooring

+moorings

+moors

+moose

+moot

+mooted

+mop

+moped

+moper

+moping

+mops

+moral

+moral's

+morale

+morales

+moralities

+morality

+morally

+morals

+morass

+morasses

+morbid

+morbidly

+morbidness

+more

+mored

+moreover

+mores

+morion

+morn

+morning

+mornings

+morphological

+morphologically

+morphology

+morrow

+morsel

+morsel's

+morsels

+mortal

+mortality

+mortally

+mortals

+mortar

+mortared

+mortaring

+mortars

+mortgage

+mortgage's

+mortgaged

+mortgager

+mortgages

+mortgaging

+mortification

+mortifications

+mortified

+mortifiedly

+mortifier

+mortifies

+mortify

+mortifying

+mosaic

+mosaic's

+mosaics

+mosquito

+mosquitoes

+mosquitos

+moss

+moss's

+mosses

+mossier

+mossy

+most

+mostly

+motel

+motel's

+motels

+moth

+mother

+mother's

+motherboard

+motherboard's

+motherboards

+mothered

+motherer

+motherers

+mothering

+motherliness

+motherly

+mothers

+motif

+motif's

+motifs

+motion

+motioned

+motioner

+motioning

+motionless

+motionlessly

+motionlessness

+motions

+motivate

+motivated

+motivates

+motivating

+motivation

+motivational

+motivationally

+motivations

+motivative

+motive

+motived

+motives

+motiving

+motley

+motor

+motorcar

+motorcar's

+motorcars

+motorcycle

+motorcycle's

+motorcycles

+motored

+motoring

+motorist

+motorist's

+motorists

+motors

+motto

+mottoes

+mottos

+mould

+moulded

+moulder

+mouldering

+moulding

+moulds

+mound

+mounded

+mounds

+mount

+mountain

+mountain's

+mountaineer

+mountaineering

+mountaineers

+mountainous

+mountainously

+mountainousness

+mountains

+mounted

+mounter

+mounting

+mountings

+mounts

+mourn

+mourned

+mourner

+mourners

+mournful

+mournfully

+mournfulness

+mourning

+mourningly

+mourns

+mouse

+mouser

+mouses

+mousing

+mouth

+mouthed

+mouther

+mouthes

+mouthful

+mouthing

+mouths

+movable

+movableness

+move

+moved

+movement

+movement's

+movements

+mover

+movers

+moves

+movie

+movie's

+movies

+moving

+movingly

+movings

+mow

+mowed

+mower

+mowers

+mowing

+mows

+much

+muchness

+muck

+mucked

+mucker

+mucking

+mucks

+mud

+muddied

+muddier

+muddiness

+muddle

+muddled

+muddler

+muddlers

+muddles

+muddling

+muddy

+muddying

+muds

+muff

+muff's

+muffin

+muffin's

+muffins

+muffle

+muffled

+muffler

+mufflers

+muffles

+muffling

+muffs

+mug

+mug's

+mugs

+mulberries

+mulberry

+mulberry's

+mule

+mule's

+mules

+muling

+multicellular

+multicomponent

+multidimensional

+multilevel

+multinational

+multiple

+multiple's

+multiples

+multiplex

+multiplexed

+multiplexer

+multiplexers

+multiplexes

+multiplexing

+multiplexor

+multiplexor's

+multiplexors

+multiplicand

+multiplicand's

+multiplicands

+multiplication

+multiplications

+multiplicative

+multiplicatively

+multiplicatives

+multiplicity

+multiplied

+multiplier

+multipliers

+multiplies

+multiply

+multiplying

+multiprocess

+multiprocessing

+multiprocessor

+multiprocessor's

+multiprocessors

+multiprogram

+multiprogrammed

+multiprogramming

+multiprogrammings

+multistage

+multitasking

+multitude

+multitude's

+multitudes

+multiuser

+multivariate

+mumble

+mumbled

+mumbler

+mumblers

+mumbles

+mumbling

+mumblings

+mummies

+mummy

+mummy's

+munch

+munched

+muncher

+munches

+munching

+mundane

+mundanely

+mundaneness

+municipal

+municipalities

+municipality

+municipality's

+municipally

+munition

+munitions

+mural

+murals

+murder

+murdered

+murderer

+murderers

+murdering

+murderous

+murderously

+murderousness

+murders

+murkier

+murkiness

+murky

+murmur

+murmured

+murmurer

+murmuring

+murmurs

+muscle

+muscled

+muscles

+muscling

+muscular

+muscularly

+muse

+mused

+muser

+muses

+museum

+museum's

+museums

+mushier

+mushiness

+mushroom

+mushroomed

+mushrooming

+mushrooms

+mushy

+music

+musical

+musically

+musicals

+musician

+musicianly

+musicians

+musics

+musing

+musingly

+musings

+musk

+musket

+musket's

+muskets

+muskrat

+muskrat's

+muskrats

+musks

+muslin

+mussel

+mussel's

+mussels

+must

+mustard

+mustards

+muster

+mustered

+mustering

+musters

+mustier

+mustiness

+musts

+musty

+mutability

+mutable

+mutableness

+mutate

+mutated

+mutates

+mutating

+mutation

+mutations

+mutative

+mutator

+mutators

+mute

+muted

+mutedly

+mutely

+muteness

+muter

+mutes

+mutest

+mutilate

+mutilated

+mutilates

+mutilating

+mutilation

+mutilations

+muting

+mutinies

+mutiny

+mutiny's

+mutter

+muttered

+mutterer

+mutterers

+muttering

+mutters

+mutton

+mutual

+mutually

+muzzle

+muzzle's

+muzzled

+muzzler

+muzzles

+muzzling

+my

+myriad

+myrtle

+myself

+mysteries

+mysterious

+mysteriously

+mysteriousness

+mystery

+mystery's

+mystic

+mystic's

+mystical

+mystically

+mysticism

+mysticisms

+mystics

+myth

+myth's

+mythes

+mythical

+mythically

+mythologies

+mythology

+mythology's

+nag

+nag's

+nags

+nail

+nailed

+nailer

+nailing

+nails

+naive

+naively

+naiveness

+naiver

+naivete

+naked

+nakedly

+nakedness

+name

+name's

+nameable

+named

+nameless

+namelessly

+namelessness

+namely

+namer

+namers

+names

+namesake

+namesake's

+namesakes

+naming

+nanosecond

+nanoseconds

+nap

+nap's

+napkin

+napkin's

+napkins

+naps

+narcissistic

+narcissus

+narcissuses

+narcotic

+narcotics

+narrative

+narrative's

+narratively

+narratives

+narrow

+narrowed

+narrower

+narrowest

+narrowing

+narrowingness

+narrowly

+narrowness

+narrows

+nasal

+nasally

+nastier

+nasties

+nastiest

+nastily

+nastiness

+nasty

+nation

+nation's

+national

+nationalist

+nationalist's

+nationalists

+nationalities

+nationality

+nationality's

+nationally

+nationals

+nations

+nationwide

+native

+natively

+nativeness

+natives

+nativity

+natural

+naturalism

+naturalist

+naturally

+naturalness

+naturals

+nature

+nature's

+natured

+natures

+naught

+naught's

+naughtier

+naughtiness

+naughts

+naughty

+naval

+navally

+navies

+navigable

+navigableness

+navigate

+navigated

+navigates

+navigating

+navigation

+navigations

+navigator

+navigator's

+navigators

+navy

+navy's

+nay

+near

+nearby

+neared

+nearer

+nearest

+nearing

+nearly

+nearness

+nears

+neat

+neaten

+neater

+neatest

+neatly

+neatness

+neats

+nebula

+necessaries

+necessarily

+necessary

+necessitate

+necessitated

+necessitates

+necessitating

+necessitation

+necessitations

+necessities

+necessity

+neck

+necked

+necker

+necking

+necklace

+necklace's

+necklaces

+necks

+necktie

+necktie's

+neckties

+need

+needed

+needer

+needful

+needfully

+needfulness

+needier

+neediness

+needing

+needle

+needled

+needler

+needlers

+needles

+needless

+needlessly

+needlessness

+needlework

+needleworker

+needling

+needly

+needn't

+needs

+needy

+negate

+negated

+negater

+negates

+negating

+negation

+negations

+negative

+negatived

+negatively

+negativeness

+negatives

+negativing

+negator

+negators

+neglect

+neglected

+neglecter

+neglecting

+neglects

+negligence

+negligible

+negotiable

+negotiate

+negotiated

+negotiates

+negotiating

+negotiation

+negotiations

+neigh

+neither

+neophyte

+neophytes

+nephew

+nephew's

+nephews

+nerve

+nerve's

+nerved

+nerves

+nerving

+nervous

+nervously

+nervousness

+nest

+nested

+nester

+nesting

+nestle

+nestled

+nestler

+nestles

+nestling

+nests

+net

+net's

+nether

+nets

+netted

+netting

+nettle

+nettled

+nettles

+nettling

+network

+network's

+networked

+networking

+networks

+neural

+neurally

+neurobiology

+neurobiology's

+neurological

+neurologically

+neurologists

+neuron

+neuron's

+neurons

+neutral

+neutralities

+neutrality

+neutrally

+neutralness

+neutrals

+neutrino

+neutrino's

+neutrinos

+never

+nevertheless

+new

+newborn

+newborns

+newcomer

+newcomer's

+newcomers

+newer

+newest

+newline

+newline's

+newlines

+newly

+newness

+news

+newsgroup

+newsgroup's

+newsgroups

+newsletter

+newsletter's

+newsletters

+newsman

+newsmen

+newspaper

+newspaper's

+newspapers

+newswire

+newt

+newts

+next

+nibble

+nibbled

+nibbler

+nibblers

+nibbles

+nibbling

+nice

+nicely

+niceness

+nicer

+nicest

+niceties

+nicety

+niche

+niches

+niching

+nick

+nicked

+nickel

+nickel's

+nickels

+nicker

+nickered

+nickering

+nicking

+nickname

+nicknamed

+nicknamer

+nicknames

+nicks

+nicotine

+niece

+niece's

+nieces

+niftier

+nifties

+nifty

+nigh

+night

+night's

+nighted

+nighters

+nightfall

+nightgown

+nightingale

+nightingale's

+nightingales

+nightly

+nightmare

+nightmare's

+nightmares

+nights

+nil

+nilly

+nimble

+nimbleness

+nimbler

+nimblest

+nimbly

+nine

+nines

+nineteen

+nineteens

+nineteenth

+nineties

+ninetieth

+ninety

+ninth

+nip

+nips

+nitrogen

+nix

+nixed

+nixer

+nixes

+nixing

+no

+nobilities

+nobility

+noble

+nobleman

+nobleness

+nobler

+nobles

+noblest

+nobly

+nobodies

+nobody

+nobody's

+nocturnal

+nocturnally

+nod

+nod's

+nodded

+nodding

+node

+node's

+nodes

+nods

+noise

+noised

+noiseless

+noiselessly

+noises

+noisier

+noisily

+noisiness

+noising

+noisy

+nomenclature

+nomenclatures

+nominal

+nominally

+nominate

+nominated

+nominates

+nominating

+nomination

+nomination's

+nominations

+nominative

+nominatively

+non

+nonblocking

+nonconservative

+noncyclic

+nondecreasing

+nondescript

+nondescriptly

+nondestructively

+nondeterminacy

+nondeterminate

+nondeterminately

+nondeterminism

+nondeterministic

+nondeterministically

+nondisclosure

+nondisclosures

+none

+nonempty

+nones

+nonetheless

+nonexistence

+nonexistent

+nonextensible

+nonfunctional

+noninteracting

+noninterference

+nonintuitive

+nonlinear

+nonlinearities

+nonlinearity

+nonlinearity's

+nonlinearly

+nonlocal

+nonnegative

+nonorthogonal

+nonorthogonality

+nonperishable

+nonprocedural

+nonprocedurally

+nonprogrammable

+nonprogrammer

+nonsense

+nonsensical

+nonsensically

+nonsensicalness

+nonspecialist

+nonspecialist's

+nonspecialists

+nonstandard

+nontechnical

+nontechnically

+nonterminal

+nonterminal's

+nonterminals

+nonterminating

+nontermination

+nontrivial

+nonuniform

+nonzero

+nook

+nook's

+nooks

+noon

+noonday

+nooning

+noons

+noontide

+nope

+nor

+norm

+norm's

+normal

+normalcy

+normality

+normally

+normals

+normed

+norms

+north

+north's

+northeast

+northeaster

+northeasterly

+northeastern

+norther

+northerly

+northern

+northerner

+northerners

+northernly

+northers

+northing

+northward

+northwards

+northwest

+northwester

+northwesterly

+northwestern

+nose

+nosed

+noses

+nosing

+nostril

+nostril's

+nostrils

+not

+notable

+notableness

+notables

+notably

+notation

+notation's

+notational

+notationally

+notations

+notch

+notched

+notches

+notching

+note

+notebook

+notebook's

+notebooks

+noted

+notedly

+notedness

+noter

+notes

+noteworthiness

+noteworthy

+nothing

+nothingness

+nothings

+notice

+noticeable

+noticeably

+noticed

+notices

+noticing

+notification

+notifications

+notified

+notifier

+notifiers

+notifies

+notify

+notifying

+noting

+notion

+notions

+notorious

+notoriously

+notoriousness

+notwithstanding

+noun

+noun's

+nouns

+nourish

+nourished

+nourisher

+nourishes

+nourishing

+nourishment

+novel

+novel's

+novelist

+novelist's

+novelists

+novels

+novelties

+novelty

+novelty's

+novice

+novice's

+novices

+now

+nowadays

+nowhere

+nowheres

+nows

+nroff

+nroff's

+nuances

+nuclear

+nucleotide

+nucleotide's

+nucleotides

+nucleus

+nucleuses

+nuisance

+nuisance's

+nuisances

+null

+nulled

+nullification

+nullified

+nullifier

+nullifiers

+nullifies

+nullify

+nullifying

+nulls

+numb

+numbed

+number

+numbered

+numberer

+numbering

+numberless

+numbers

+numbing

+numbingly

+numbly

+numbness

+numbs

+numeral

+numeral's

+numerally

+numerals

+numerator

+numerator's

+numerators

+numeric

+numerical

+numerically

+numerics

+numerous

+numerously

+numerousness

+nun

+nun's

+nuns

+nuptial

+nuptials

+nurse

+nurse's

+nursed

+nurser

+nurseries

+nursery

+nursery's

+nurses

+nursing

+nurture

+nurtured

+nurturer

+nurtures

+nurturing

+nut

+nut's

+nutrition

+nutrition's

+nuts

+nymph

+nymphs

+o'clock

+oak

+oaken

+oaks

+oar

+oar's

+oared

+oaring

+oars

+oasis

+oat

+oaten

+oater

+oath

+oaths

+oatmeal

+oats

+obedience

+obediences

+obedient

+obediently

+obey

+obeyed

+obeyer

+obeying

+obeys

+obfuscate

+obfuscated

+obfuscater

+obfuscates

+obfuscating

+obfuscation

+obfuscations

+object

+object's

+objected

+objecting

+objection

+objection's

+objectionable

+objectionableness

+objections

+objective

+objectively

+objectiveness

+objectives

+objector

+objector's

+objectors

+objects

+oblate

+oblately

+oblateness

+oblation

+oblations

+obligate

+obligated

+obligately

+obligates

+obligating

+obligation

+obligation's

+obligations

+obligatory

+oblige

+obliged

+obliger

+obliges

+obliging

+obligingly

+obligingness

+oblique

+obliquely

+obliqueness

+obliterate

+obliterated

+obliterates

+obliterating

+obliteration

+obliterations

+obliterative

+obliteratively

+oblivion

+oblivions

+oblivious

+obliviously

+obliviousness

+oblong

+oblongly

+oblongness

+obscene

+obscenely

+obscure

+obscured

+obscurely

+obscureness

+obscurer

+obscures

+obscuring

+obscurities

+obscurity

+observable

+observance

+observance's

+observances

+observant

+observantly

+observation

+observation's

+observations

+observatories

+observatory

+observe

+observed

+observer

+observers

+observes

+observing

+observingly

+obsession

+obsession's

+obsessions

+obsolescence

+obsolete

+obsoleted

+obsoletely

+obsoleteness

+obsoletes

+obsoleting

+obstacle

+obstacle's

+obstacles

+obstinacy

+obstinate

+obstinately

+obstinateness

+obstruct

+obstructed

+obstructer

+obstructing

+obstruction

+obstruction's

+obstructionist

+obstructions

+obstructive

+obstructively

+obstructiveness

+obstructs

+obtain

+obtainable

+obtainably

+obtained

+obtainer

+obtaining

+obtains

+obviate

+obviated

+obviates

+obviating

+obviation

+obviations

+obvious

+obviously

+obviousness

+occasion

+occasional

+occasionally

+occasioned

+occasioning

+occasionings

+occasions

+occlude

+occluded

+occludes

+occluding

+occlusion

+occlusion's

+occlusions

+occupancies

+occupancy

+occupant

+occupant's

+occupants

+occupation

+occupation's

+occupational

+occupationally

+occupations

+occupied

+occupier

+occupiers

+occupies

+occupy

+occupying

+occur

+occurred

+occurrence

+occurrence's

+occurrences

+occurring

+occurs

+ocean

+ocean's

+oceans

+octal

+octals

+octave

+octaves

+octopus

+odd

+odder

+oddest

+oddities

+oddity

+oddity's

+oddly

+oddness

+odds

+ode

+ode's

+oded

+oder

+odes

+odious

+odiously

+odiousness

+odorous

+odorously

+odorousness

+of

+off

+offend

+offended

+offender

+offenders

+offending

+offends

+offensive

+offensively

+offensiveness

+offensives

+offer

+offered

+offerer

+offerers

+offering

+offerings

+offers

+office

+office's

+officer

+officer's

+officered

+officers

+offices

+official

+official's

+officially

+officials

+officiate

+officiated

+officiates

+officiating

+officiation

+officiations

+officio

+officious

+officiously

+officiousness

+offing

+offs

+offset

+offset's

+offsets

+offspring

+offsprings

+oft

+often

+oftener

+oftentimes

+oh

+oil

+oilcloth

+oiled

+oiler

+oilers

+oilier

+oiliest

+oiliness

+oiling

+oils

+oily

+ointment

+ointments

+okay

+okay's

+okays

+old

+olden

+older

+oldest

+oldness

+olive

+olive's

+oliver

+olives

+omen

+omen's

+omens

+ominous

+ominously

+ominousness

+omission

+omission's

+omissions

+omit

+omits

+omitted

+omitting

+omnipresent

+omnipresently

+omniscient

+omnisciently

+omnivore

+on

+onanism

+once

+oncer

+one

+one's

+oneness

+oner

+onerous

+onerously

+onerousness

+ones

+oneself

+ongoing

+onion

+onions

+online

+onliness

+only

+ons

+onset

+onset's

+onsets

+onto

+onward

+onwards

+oops

+ooze

+oozed

+oozes

+oozing

+opacities

+opacity

+opal

+opal's

+opals

+opaque

+opaquely

+opaqueness

+opcode

+opcode's

+opcodes

+open

+opened

+opener

+openers

+openest

+opening

+opening's

+openings

+openly

+openness

+opens

+opera

+opera's

+operable

+operand

+operand's

+operandi

+operands

+operas

+operate

+operated

+operates

+operating

+operation

+operational

+operationally

+operations

+operative

+operatively

+operativeness

+operatives

+operator

+operator's

+operators

+opiate

+opiates

+opinion

+opinion's

+opinions

+opium

+opponent

+opponent's

+opponents

+opportune

+opportunely

+opportunism

+opportunistic

+opportunistically

+opportunities

+opportunity

+opportunity's

+oppose

+opposed

+opposer

+opposes

+opposing

+opposite

+oppositely

+oppositeness

+opposites

+opposition

+oppositions

+oppress

+oppressed

+oppresses

+oppressing

+oppression

+oppressive

+oppressively

+oppressiveness

+oppressor

+oppressor's

+oppressors

+opt

+opted

+optic

+optical

+optically

+optics

+optimal

+optimality

+optimally

+optimism

+optimistic

+optimistically

+optimum

+opting

+option

+option's

+optional

+optionally

+options

+opts

+or

+or's

+oracle

+oracle's

+oracles

+oral

+orally

+orals

+orange

+orange's

+oranges

+oration

+oration's

+orations

+orator

+orator's

+oratories

+orators

+oratory

+oratory's

+orb

+orbit

+orbital

+orbitally

+orbitals

+orbited

+orbiter

+orbiters

+orbiting

+orbits

+orchard

+orchard's

+orchards

+orchestra

+orchestra's

+orchestras

+orchid

+orchid's

+orchids

+ordain

+ordained

+ordainer

+ordaining

+ordains

+ordeal

+ordeals

+order

+ordered

+orderer

+ordering

+orderings

+orderlies

+orderliness

+orderly

+orders

+ordinal

+ordinance

+ordinance's

+ordinances

+ordinaries

+ordinarily

+ordinariness

+ordinary

+ordinate

+ordinated

+ordinates

+ordinating

+ordination

+ordinations

+ore

+ore's

+ores

+organ

+organ's

+organic

+organics

+organism

+organism's

+organisms

+organist

+organist's

+organists

+organs

+orgies

+orgy

+orgy's

+orient

+orientation

+orientation's

+orientations

+oriented

+orienting

+orients

+orifice

+orifice's

+orifices

+origin

+origin's

+original

+originality

+originally

+originals

+originate

+originated

+originates

+originating

+origination

+originations

+originative

+originatively

+originator

+originator's

+originators

+origins

+orion

+orly

+ornament

+ornamental

+ornamentally

+ornamentation

+ornamentations

+ornamented

+ornamenting

+ornaments

+orphan

+orphaned

+orphaning

+orphans

+orthodox

+orthodoxes

+orthodoxly

+orthogonal

+orthogonality

+orthogonally

+oscillate

+oscillated

+oscillates

+oscillating

+oscillation

+oscillation's

+oscillations

+oscillator

+oscillator's

+oscillators

+oscillatory

+oscilloscope

+oscilloscope's

+oscilloscopes

+ostrich

+ostrich's

+ostriches

+other

+other's

+otherness

+others

+otherwise

+otter

+otter's

+otters

+ought

+oughts

+ounce

+ounces

+our

+ours

+ourself

+ourselves

+out

+outbreak

+outbreak's

+outbreaks

+outburst

+outburst's

+outbursts

+outcast

+outcast's

+outcasts

+outcome

+outcome's

+outcomes

+outcries

+outcry

+outdoor

+outdoors

+outed

+outer

+outermost

+outfit

+outfit's

+outfits

+outgoing

+outgoingness

+outgoings

+outgrew

+outgrow

+outgrowing

+outgrown

+outgrows

+outgrowth

+outing

+outing's

+outings

+outlast

+outlasts

+outlaw

+outlawed

+outlawing

+outlaws

+outlay

+outlay's

+outlays

+outlet

+outlet's

+outlets

+outline

+outlined

+outlines

+outlining

+outlive

+outlived

+outlives

+outliving

+outlook

+outness

+outperform

+outperformed

+outperforming

+outperforms

+outpost

+outpost's

+outposts

+output

+output's

+outputs

+outputting

+outrage

+outraged

+outrageous

+outrageously

+outrageousness

+outrages

+outraging

+outright

+outrightly

+outrun

+outruns

+outs

+outset

+outside

+outsider

+outsider's

+outsiderness

+outsiders

+outskirts

+outstanding

+outstandingly

+outstretched

+outstrip

+outstripped

+outstripping

+outstrips

+outvote

+outvoted

+outvotes

+outvoting

+outward

+outwardly

+outwardness

+outwards

+outweigh

+outweighed

+outweighing

+outweighs

+outwit

+outwits

+outwitted

+outwitting

+oval

+oval's

+ovally

+ovalness

+ovals

+ovaries

+ovary

+ovary's

+oven

+oven's

+ovens

+over

+overall

+overall's

+overalls

+overblown

+overboard

+overcame

+overcast

+overcasting

+overcoat

+overcoat's

+overcoating

+overcoats

+overcome

+overcomer

+overcomes

+overcoming

+overcrowd

+overcrowded

+overcrowding

+overcrowds

+overdone

+overdose

+overdose's

+overdosed

+overdoses

+overdosing

+overdraft

+overdraft's

+overdrafts

+overdraw

+overdrawing

+overdrawn

+overdraws

+overdrew

+overdue

+overemphasis

+overestimate

+overestimated

+overestimates

+overestimating

+overestimation

+overestimations

+overflow

+overflowed

+overflowing

+overflows

+overhang

+overhanging

+overhangs

+overhaul

+overhauled

+overhauler

+overhauling

+overhaulings

+overhauls

+overhead

+overheads

+overhear

+overheard

+overhearer

+overhearing

+overhears

+overing

+overjoy

+overjoyed

+overkill

+overkill's

+overlaid

+overland

+overlap

+overlap's

+overlapped

+overlapping

+overlaps

+overlay

+overlaying

+overlays

+overload

+overloaded

+overloading

+overloads

+overlook

+overlooked

+overlooking

+overlooks

+overly

+overlying

+overnight

+overnighter

+overnighters

+overnights

+overpower

+overpowered

+overpowering

+overpoweringly

+overpowers

+overprint

+overprinted

+overprinting

+overprints

+overproduction

+overridden

+override

+overrider

+overrides

+overriding

+overrode

+overrule

+overruled

+overrules

+overruling

+overrun

+overruns

+overs

+overseas

+oversee

+overseeing

+overseer

+overseers

+oversees

+overshadow

+overshadowed

+overshadowing

+overshadows

+overshoot

+overshooting

+overshoots

+overshot

+oversight

+oversight's

+oversights

+oversimplification

+oversimplifications

+oversimplified

+oversimplifies

+oversimplify

+oversimplifying

+overstate

+overstated

+overstatement

+overstatement's

+overstatements

+overstates

+overstating

+overstocks

+overt

+overtake

+overtaken

+overtaker

+overtakers

+overtakes

+overtaking

+overthrew

+overthrow

+overthrowing

+overthrown

+overthrows

+overtime

+overtly

+overtness

+overtone

+overtone's

+overtones

+overtook

+overture

+overture's

+overtures

+overturn

+overturned

+overturning

+overturns

+overuse

+overview

+overview's

+overviews

+overweight

+overwhelm

+overwhelmed

+overwhelming

+overwhelmingly

+overwhelms

+overwork

+overworked

+overworking

+overworks

+overwrite

+overwrites

+overwriting

+overwritten

+overwrote

+overzealous

+overzealousness

+ovum

+owe

+owed

+owes

+owing

+owl

+owl's

+owler

+owls

+own

+owned

+owner

+owner's

+owners

+ownership

+ownerships

+owning

+owns

+ox

+oxen

+oxidation

+oxide

+oxide's

+oxides

+oxygen

+oxygens

+oyster

+oyster's

+oystering

+oysters

+pa

+pace

+pace's

+paced

+pacer

+pacers

+paces

+pacific

+pacification

+pacifications

+pacified

+pacifier

+pacifies

+pacify

+pacifying

+pacing

+pack

+package

+packaged

+packager

+packagers

+packages

+packaging

+packagings

+packed

+packer

+packers

+packet

+packet's

+packeted

+packeting

+packets

+packing

+packs

+pact

+pact's

+pacts

+pad

+pad's

+padded

+paddies

+padding

+paddings

+paddle

+paddled

+paddler

+paddles

+paddling

+paddy

+pads

+pagan

+pagan's

+pagans

+page

+page's

+pageant

+pageant's

+pageants

+paged

+pager

+pager's

+pagers

+pages

+paginate

+paginated

+paginates

+paginating

+pagination

+paginations

+paging

+paid

+pail

+pail's

+pails

+pain

+pained

+painful

+painfully

+painfulness

+paining

+painless

+painlessly

+painlessness

+pains

+painstaking

+painstakingly

+paint

+painted

+painter

+painterliness

+painterly

+painters

+painting

+paintings

+paints

+pair

+paired

+pairing

+pairings

+pairs

+pairwise

+pal

+pal's

+palace

+palace's

+palaces

+palate

+palate's

+palates

+pale

+paled

+palely

+paleness

+paler

+pales

+palest

+palfrey

+paling

+pall

+palliate

+palliation

+palliative

+palliatively

+palliatives

+pallid

+pallidly

+pallidness

+palling

+pally

+palm

+palmed

+palmer

+palming

+palms

+pals

+pamphlet

+pamphlet's

+pamphlets

+pan

+pan's

+panacea

+panacea's

+panaceas

+pancake

+pancake's

+pancaked

+pancakes

+pancaking

+pancreas

+panda

+panda's

+pandas

+pandemonium

+pander

+pandered

+panderer

+pandering

+panders

+pane

+pane's

+panel

+panelist

+panelist's

+panelists

+panels

+panes

+pang

+pang's

+pangs

+panic

+panic's

+panics

+panned

+panning

+pans

+pansies

+pansy

+pansy's

+pant

+panted

+panther

+panther's

+panthers

+panties

+panting

+pantries

+pantry

+pantry's

+pants

+panty

+papa

+papal

+papally

+paper

+paper's

+paperback

+paperback's

+paperbacks

+papered

+paperer

+paperers

+papering

+paperings

+papers

+paperwork

+paprika

+par

+parachute

+parachute's

+parachuted

+parachuter

+parachutes

+parachuting

+parade

+paraded

+parader

+parades

+paradigm

+paradigm's

+paradigms

+parading

+paradise

+paradox

+paradox's

+paradoxes

+paradoxical

+paradoxically

+paradoxicalness

+paraffin

+paraffins

+paragon

+paragon's

+paragons

+paragraph

+paragraphed

+paragrapher

+paragraphing

+paragraphs

+parallax

+parallax's

+parallel

+parallelism

+parallelogram

+parallelogram's

+parallelograms

+parallels

+paralysis

+parameter

+parameter's

+parameterless

+parameters

+parametric

+paramilitary

+paramount

+paranoia

+paranoid

+parapet

+parapet's

+parapeted

+parapets

+paraphrase

+paraphrased

+paraphraser

+paraphrases

+paraphrasing

+parasite

+parasite's

+parasites

+parasitic

+parasitics

+parcel

+parcels

+parch

+parched

+parchment

+pardon

+pardonable

+pardonableness

+pardonably

+pardoned

+pardoner

+pardoners

+pardoning

+pardons

+pare

+parent

+parent's

+parentage

+parental

+parentally

+parentheses

+parenthesis

+parenthetical

+parenthetically

+parenthood

+parenting

+parents

+parer

+pares

+paring

+parings

+parish

+parish's

+parishes

+parities

+parity

+park

+parked

+parker

+parkers

+parking

+parks

+parliament

+parliament's

+parliamentary

+parliaments

+parole

+paroled

+paroles

+paroling

+parried

+parrot

+parroting

+parrots

+parry

+parrying

+pars

+parse

+parsed

+parser

+parser's

+parsers

+parses

+parsimony

+parsing

+parsings

+parsley

+parson

+parson's

+parsons

+part

+partake

+partaker

+partakes

+partaking

+parted

+parter

+parters

+partial

+partiality

+partially

+partials

+participant

+participant's

+participants

+participate

+participated

+participates

+participating

+participation

+participations

+participative

+participatory

+particle

+particle's

+particles

+particular

+particularly

+particulars

+partied

+parties

+parting

+partings

+partisan

+partisan's

+partisans

+partition

+partitioned

+partitioner

+partitioning

+partitions

+partly

+partner

+partner's

+partnered

+partnering

+partners

+partnership

+partnerships

+partridge

+partridge's

+partridges

+parts

+party

+party's

+partying

+pas

+pass

+passage

+passage's

+passaged

+passages

+passageway

+passaging

+passe

+passed

+passenger

+passenger's

+passengerly

+passengers

+passer

+passers

+passes

+passing

+passion

+passionate

+passionately

+passionateness

+passions

+passive

+passively

+passiveness

+passives

+passivity

+passport

+passport's

+passports

+password

+password's

+passworded

+passwords

+past

+past's

+paste

+pasted

+pastes

+pastime

+pastime's

+pastimes

+pasting

+pastness

+pastor

+pastor's

+pastoral

+pastorally

+pastoralness

+pastors

+pastries

+pastry

+pasts

+pasture

+pasture's

+pastured

+pasturer

+pastures

+pasturing

+pat

+pat's

+patch

+patched

+patcher

+patches

+patching

+patchwork

+patchworker

+patchworkers

+pated

+paten

+patent

+patentable

+patented

+patenter

+patenters

+patenting

+patently

+patents

+pater

+paternal

+paternally

+path

+pathetic

+pathname

+pathname's

+pathnames

+pathological

+pathologically

+pathologies

+pathologist

+pathologist's

+pathologists

+pathology

+pathos

+paths

+pathway

+pathway's

+pathways

+patience

+patient

+patient's

+patiently

+patients

+patriarch

+patriarchs

+patrician

+patrician's

+patricians

+patriot

+patriot's

+patriotic

+patriotism

+patriots

+patrol

+patrol's

+patrols

+patron

+patron's

+patronage

+patronly

+patrons

+pats

+patter

+pattered

+patterer

+pattering

+patterings

+pattern

+patterned

+patterning

+patterns

+patters

+patties

+patty

+patty's

+paucity

+pause

+paused

+pauses

+pausing

+pave

+paved

+pavement

+pavement's

+pavements

+paver

+paves

+pavilion

+pavilion's

+pavilions

+paving

+paw

+pawed

+pawing

+pawn

+pawn's

+pawned

+pawner

+pawning

+pawns

+paws

+pay

+payable

+paycheck

+paycheck's

+paychecks

+payed

+payer

+payer's

+payers

+paying

+payment

+payment's

+payments

+payoff

+payoff's

+payoffs

+payroll

+payrolls

+pays

+pea

+pea's

+peace

+peaceable

+peaceableness

+peaceful

+peacefully

+peacefulness

+peaces

+peach

+peach's

+peaches

+peacock

+peacock's

+peacocks

+peak

+peaked

+peakedness

+peaking

+peaks

+peal

+pealed

+pealing

+peals

+peanut

+peanut's

+peanuts

+pear

+pearl

+pearl's

+pearler

+pearlier

+pearls

+pearly

+pears

+peas

+peasant

+peasant's

+peasantry

+peasants

+peat

+pebble

+pebble's

+pebbled

+pebbles

+pebbling

+peck

+pecked

+pecker

+pecking

+pecks

+peculiar

+peculiarities

+peculiarity

+peculiarity's

+peculiarly

+peculiars

+pedagogic

+pedagogical

+pedagogically

+pedagogics

+pedantic

+peddler

+peddler's

+peddlers

+pedestal

+pedestals

+pedestrian

+pedestrian's

+pedestrians

+pediatric

+pediatrics

+peek

+peeked

+peeking

+peeks

+peel

+peeled

+peeler

+peeler's

+peeling

+peels

+peep

+peeped

+peeper

+peepers

+peeping

+peeps

+peer

+peered

+peering

+peerless

+peerlessly

+peerlessness

+peers

+peeve

+peeve's

+peeved

+peevers

+peeves

+peeving

+peg

+peg's

+pegs

+pellet

+pellet's

+pelleted

+pelleting

+pellets

+pelt

+pelter

+pelting

+pelts

+pen

+penalties

+penalty

+penalty's

+penance

+penanced

+penances

+penancing

+pence

+pencil

+pencils

+pend

+pended

+pending

+pends

+pendulum

+pendulum's

+pendulums

+penetrate

+penetrated

+penetrates

+penetrating

+penetratingly

+penetration

+penetrations

+penetrative

+penetratively

+penetrativeness

+penetrator

+penetrator's

+penetrators

+penguin

+penguin's

+penguins

+peninsula

+peninsula's

+peninsulas

+penitent

+penitentiary

+penitently

+penned

+pennies

+penniless

+penning

+penny

+penny's

+pens

+pension

+pensioned

+pensioner

+pensioners

+pensioning

+pensions

+pensive

+pensively

+pensiveness

+pent

+pentagon

+pentagon's

+pentagons

+penthouse

+penthouse's

+penthouses

+people

+people's

+peopled

+peoples

+peopling

+pep

+pepper

+peppercorn

+peppercorn's

+peppercorns

+peppered

+pepperer

+peppering

+peppers

+per

+perceivable

+perceivably

+perceive

+perceived

+perceiver

+perceivers

+perceives

+perceiving

+percent

+percentage

+percentages

+percentile

+percentiles

+percents

+perceptible

+perceptibly

+perception

+perceptions

+perceptive

+perceptively

+perceptiveness

+perceptual

+perceptually

+perch

+perchance

+perched

+perches

+perching

+percolate

+percolated

+percolates

+percolating

+percolation

+percutaneous

+percutaneously

+peremptoriness

+peremptory

+perennial

+perennially

+perennials

+perfect

+perfected

+perfecter

+perfecting

+perfection

+perfectionist

+perfectionist's

+perfectionists

+perfections

+perfective

+perfectively

+perfectiveness

+perfectly

+perfectness

+perfects

+perforce

+perform

+performance

+performance's

+performances

+performed

+performer

+performers

+performing

+performs

+perfume

+perfumed

+perfumer

+perfumes

+perfuming

+perhaps

+peril

+peril's

+perilous

+perilously

+perilousness

+perils

+period

+period's

+periodic

+periodical

+periodically

+periodicals

+periods

+peripheral

+peripherally

+peripherals

+peripheries

+periphery

+periphery's

+perish

+perishable

+perishable's

+perishables

+perished

+perisher

+perishers

+perishes

+perishing

+perishingly

+permanence

+permanent

+permanently

+permanentness

+permanents

+permeate

+permeated

+permeates

+permeating

+permeation

+permeations

+permeative

+permissibility

+permissible

+permissibleness

+permissibly

+permission

+permissions

+permissive

+permissively

+permissiveness

+permit

+permit's

+permits

+permitted

+permitting

+permutation

+permutation's

+permutations

+permute

+permuted

+permutes

+permuting

+perpendicular

+perpendicularly

+perpendiculars

+perpetrate

+perpetrated

+perpetrates

+perpetrating

+perpetration

+perpetrations

+perpetrator

+perpetrator's

+perpetrators

+perpetual

+perpetually

+perpetuate

+perpetuated

+perpetuates

+perpetuating

+perpetuation

+perplex

+perplexed

+perplexedly

+perplexes

+perplexing

+perplexities

+perplexity

+persecute

+persecuted

+persecutes

+persecuting

+persecution

+persecutive

+persecutor

+persecutor's

+persecutors

+perseverance

+persevere

+persevered

+perseveres

+persevering

+persist

+persisted

+persistence

+persistent

+persistently

+persister

+persisting

+persists

+person

+person's

+personable

+personableness

+personage

+personage's

+personages

+personal

+personalities

+personality

+personality's

+personally

+personals

+personification

+personifications

+personified

+personifier

+personifies

+personify

+personifying

+personnel

+persons

+perspective

+perspective's

+perspectively

+perspectives

+perspicuous

+perspicuously

+perspicuousness

+perspiration

+perspirations

+persuadable

+persuade

+persuaded

+persuader

+persuaders

+persuades

+persuading

+persuasion

+persuasion's

+persuasions

+persuasive

+persuasively

+persuasiveness

+pertain

+pertained

+pertaining

+pertains

+pertinent

+pertinently

+perturb

+perturbation

+perturbation's

+perturbations

+perturbed

+perturbing

+perusal

+peruse

+perused

+peruser

+perusers

+peruses

+perusing

+pervade

+pervaded

+pervades

+pervading

+pervasive

+pervasively

+pervasiveness

+pervert

+perverted

+pervertedly

+pervertedness

+perverter

+perverting

+perverts

+pessimistic

+pest

+pester

+pestered

+pestering

+pesters

+pestilence

+pestilences

+pests

+pet

+petal

+petal's

+petals

+peter

+petered

+peters

+petition

+petitioned

+petitioner

+petitioning

+petitions

+petroleum

+pets

+petted

+petter

+petter's

+petters

+petticoat

+petticoat's

+petticoated

+petticoats

+pettier

+pettiest

+pettiness

+pettinesses

+petting

+petty

+pew

+pew's

+pews

+pewter

+pewterer

+phantom

+phantom's

+phantoms

+phase

+phased

+phaser

+phasers

+phases

+phasing

+pheasant

+pheasant's

+pheasants

+phenomena

+phenomenal

+phenomenally

+phenomenological

+phenomenologically

+phenomenologies

+phenomenology

+phenomenon

+philosopher

+philosopher's

+philosophers

+philosophic

+philosophical

+philosophically

+philosophies

+philosophy

+philosophy's

+phone

+phone's

+phoned

+phoneme

+phoneme's

+phonemes

+phonemic

+phonemics

+phones

+phonetic

+phonetics

+phoning

+phonograph

+phonographer

+phonographs

+phosphate

+phosphate's

+phosphates

+phosphoric

+photo

+photo's

+photocopied

+photocopier

+photocopies

+photocopy

+photocopying

+photograph

+photographed

+photographer

+photographers

+photographic

+photographing

+photographs

+photography

+photos

+phrase

+phrased

+phrases

+phrasing

+phrasings

+phyla

+phylum

+physic

+physical

+physically

+physicalness

+physicals

+physician

+physician's

+physicians

+physicist

+physicist's

+physicists

+physics

+physiological

+physiologically

+physiology

+physique

+physiqued

+pi

+piano

+piano's

+pianos

+piazza

+piazza's

+piazzas

+picayune

+pick

+picked

+picker

+pickering

+pickers

+picket

+picketed

+picketer

+picketers

+picketing

+pickets

+picking

+pickings

+pickle

+pickled

+pickles

+pickling

+picks

+pickup

+pickup's

+pickups

+picnic

+picnic's

+picnics

+pictorial

+pictorially

+pictorialness

+picture

+pictured

+pictures

+picturesque

+picturesquely

+picturesqueness

+picturing

+pie

+piece

+pieced

+piecemeal

+piecer

+pieces

+piecewise

+piecing

+pied

+pier

+pierce

+pierced

+pierces

+piercing

+piercingly

+piers

+pies

+pieties

+piety

+pig

+pig's

+pigeon

+pigeon's

+pigeons

+pigment

+pigmented

+pigments

+pigs

+pike

+pike's

+piked

+piker

+pikes

+piking

+pile

+piled

+pilers

+piles

+pilferage

+pilgrim

+pilgrim's

+pilgrimage

+pilgrimage's

+pilgrimages

+pilgrims

+piling

+pilings

+pill

+pill's

+pillage

+pillaged

+pillager

+pillages

+pillaging

+pillar

+pillared

+pillars

+pillow

+pillow's

+pillows

+pills

+pilot

+pilot's

+piloted

+piloting

+pilots

+pin

+pin's

+pinch

+pinched

+pincher

+pinches

+pinching

+pine

+pineapple

+pineapple's

+pineapples

+pined

+pines

+ping

+pinger

+pinging

+pining

+pinion

+pinioned

+pinions

+pink

+pinked

+pinker

+pinkest

+pinking

+pinkly

+pinkness

+pinks

+pinnacle

+pinnacle's

+pinnacled

+pinnacles

+pinnacling

+pinned

+pinning

+pinnings

+pinpoint

+pinpointed

+pinpointing

+pinpoints

+pins

+pint

+pint's

+pinter

+pints

+pioneer

+pioneered

+pioneering

+pioneers

+pious

+piously

+piousness

+pipe

+piped

+pipeline

+pipelined

+pipelines

+pipelining

+piper

+pipers

+pipes

+piping

+pipingly

+pipings

+pique

+piqued

+piquing

+pirate

+pirate's

+pirated

+pirates

+pirating

+piss

+pissed

+pisser

+pisses

+pissing

+pistil

+pistil's

+pistils

+pistol

+pistol's

+pistols

+piston

+piston's

+pistons

+pit

+pit's

+pitch

+pitched

+pitcher

+pitchers

+pitches

+pitching

+piteous

+piteously

+piteousness

+pitfall

+pitfall's

+pitfalls

+pith

+pithed

+pithes

+pithier

+pithiest

+pithiness

+pithing

+pithy

+pitiable

+pitiableness

+pitied

+pitier

+pitiers

+pities

+pitiful

+pitifully

+pitifulness

+pitiless

+pitilessly

+pitilessness

+pits

+pitted

+pity

+pitying

+pityingly

+pivot

+pivotal

+pivotally

+pivoted

+pivoting

+pivots

+pixel

+pixel's

+pixels

+placard

+placard's

+placards

+place

+placed

+placement

+placement's

+placements

+placer

+places

+placid

+placidly

+placidness

+placing

+plague

+plagued

+plaguer

+plagues

+plaguing

+plaid

+plaid's

+plaided

+plaids

+plain

+plainer

+plainest

+plainly

+plainness

+plains

+plaintiff

+plaintiff's

+plaintiffs

+plaintive

+plaintively

+plaintiveness

+plait

+plait's

+plaiter

+plaiting

+plaits

+plan

+plan's

+planar

+planarity

+plane

+plane's

+planed

+planer

+planers

+planes

+planet

+planet's

+planetary

+planets

+planing

+plank

+planking

+planks

+planned

+planner

+planner's

+planners

+planning

+plans

+plant

+plantation

+plantation's

+plantations

+planted

+planter

+planters

+planting

+plantings

+plants

+plasma

+plaster

+plastered

+plasterer

+plasterers

+plastering

+plasters

+plastic

+plasticity

+plasticly

+plastics

+plate

+plateau

+plateau's

+plateaus

+plated

+platelet

+platelet's

+platelets

+platen

+platen's

+platens

+plater

+platers

+plates

+platform

+platform's

+platforms

+plating

+platings

+platinum

+platter

+platter's

+platters

+plausibility

+plausible

+plausibleness

+play

+playable

+played

+player

+player's

+players

+playful

+playfully

+playfulness

+playground

+playground's

+playgrounds

+playing

+playmate

+playmate's

+playmates

+plays

+plaything

+plaything's

+playthings

+playwright

+playwright's

+playwrights

+plea

+plea's

+plead

+pleaded

+pleader

+pleading

+pleadingly

+pleadings

+pleads

+pleas

+pleasant

+pleasantly

+pleasantness

+please

+pleased

+pleasely

+pleaser

+pleases

+pleasing

+pleasingly

+pleasingness

+pleasurable

+pleasurableness

+pleasure

+pleasured

+pleasures

+pleasuring

+plebeian

+plebeianly

+plebiscite

+plebiscite's

+plebiscites

+pledge

+pledged

+pledger

+pledges

+pledging

+plenary

+plenteous

+plenteously

+plenteousness

+plenties

+plentiful

+plentifully

+plentifulness

+plenty

+pleurisy

+plication

+plied

+plier

+pliers

+plies

+plight

+plighter

+plod

+plods

+plot

+plot's

+plots

+plotted

+plotter

+plotter's

+plotters

+plotting

+ploy

+ploy's

+ploys

+pluck

+plucked

+plucker

+pluckier

+pluckiness

+plucking

+plucky

+plug

+plug's

+plugged

+plugging

+plugs

+plum

+plum's

+plumage

+plumaged

+plumages

+plumb

+plumb's

+plumbed

+plumber

+plumbers

+plumbing

+plumbs

+plume

+plumed

+plumes

+pluming

+plummeting

+plump

+plumped

+plumpen

+plumper

+plumply

+plumpness

+plums

+plunder

+plundered

+plunderer

+plunderers

+plundering

+plunders

+plunge

+plunged

+plunger

+plungers

+plunges

+plunging

+plural

+plurality

+plurally

+plurals

+plus

+pluses

+plush

+plushly

+plushness

+ply

+plying

+pneumonia

+poach

+poached

+poacher

+poachers

+poaches

+poaching

+pocket

+pocketbook

+pocketbook's

+pocketbooks

+pocketed

+pocketing

+pockets

+pod

+pod's

+pods

+poem

+poem's

+poems

+poet

+poet's

+poetic

+poetical

+poetically

+poeticalness

+poetics

+poetries

+poetry

+poetry's

+poets

+point

+pointed

+pointedly

+pointedness

+pointer

+pointers

+pointier

+pointiest

+pointing

+pointless

+pointlessly

+pointlessness

+points

+pointy

+poise

+poised

+poises

+poising

+poison

+poisoned

+poisoner

+poisoning

+poisonous

+poisonously

+poisonousness

+poisons

+poke

+poked

+poker

+pokes

+poking

+polar

+polarities

+polarity

+polarity's

+pole

+poled

+polemic

+polemics

+poler

+poles

+police

+police's

+policed

+policeman

+policeman's

+policemen

+policemen's

+polices

+policies

+policing

+policy

+policy's

+poling

+polish

+polished

+polisher

+polishers

+polishes

+polishing

+polite

+politely

+politeness

+politer

+politest

+politic

+political

+politically

+politician

+politician's

+politicians

+politics

+poll

+polled

+pollen

+poller

+polling

+polls

+pollute

+polluted

+polluter

+pollutes

+polluting

+pollution

+pollutive

+polo

+polygon

+polygon's

+polygons

+polymer

+polymer's

+polymers

+polynomial

+polynomial's

+polynomials

+polyphonic

+pomp

+pompous

+pompously

+pompousness

+pond

+ponder

+pondered

+ponderer

+pondering

+ponderous

+ponderously

+ponderousness

+ponders

+ponds

+ponies

+pony

+pony's

+poof

+pool

+pooled

+pooling

+pools

+poor

+poorer

+poorest

+poorly

+poorness

+pop

+pop's

+pope

+pope's

+popes

+poplar

+popped

+poppied

+poppies

+popping

+poppy

+poppy's

+pops

+populace

+popular

+popularity

+popularly

+populate

+populated

+populates

+populating

+population

+populations

+populous

+populously

+populousness

+porcelain

+porch

+porch's

+porches

+porcupine

+porcupine's

+porcupines

+pore

+pored

+pores

+poring

+pork

+porker

+porn

+pornographic

+porridge

+port

+portability

+portable

+portables

+portably

+portal

+portal's

+portals

+portamento

+portamento's

+ported

+portend

+portended

+portending

+portends

+porter

+portering

+porters

+porting

+portion

+portion's

+portioned

+portioning

+portions

+portlier

+portliness

+portly

+portrait

+portrait's

+portraits

+portray

+portrayed

+portrayer

+portraying

+portrays

+ports

+pose

+posed

+poser

+posers

+poses

+posing

+posit

+posited

+positing

+position

+positional

+positioned

+positioning

+positions

+positive

+positively

+positiveness

+positives

+posits

+possess

+possessed

+possessedly

+possessedness

+possesses

+possessing

+possession

+possession's

+possessional

+possessions

+possessive

+possessive's

+possessively

+possessiveness

+possessives

+possessor

+possessor's

+possessors

+possibilities

+possibility

+possibility's

+possible

+possibles

+possibly

+possum

+possum's

+possums

+post

+postage

+postal

+postcard

+postcard's

+postcards

+postcondition

+postconditions

+posted

+poster

+poster's

+posterior

+posteriorly

+posterity

+posters

+posting

+postings

+postman

+postmaster

+postmaster's

+postmasters

+postpone

+postponed

+postponer

+postpones

+postponing

+posts

+postscript

+postscript's

+postscripts

+postulate

+postulated

+postulates

+postulating

+postulation

+postulations

+posture

+posture's

+postured

+posturer

+postures

+posturing

+pot

+pot's

+potash

+potassium

+potato

+potatoes

+potent

+potentate

+potentate's

+potentates

+potential

+potentialities

+potentiality

+potentially

+potentials

+potentiating

+potentiometer

+potentiometer's

+potentiometers

+potently

+pots

+potted

+potter

+potter's

+potterer

+potteries

+potters

+pottery

+potting

+pouch

+pouch's

+pouched

+pouches

+poultry

+pounce

+pounced

+pounces

+pouncing

+pound

+pounded

+pounder

+pounders

+pounding

+pounds

+pour

+poured

+pourer

+pourers

+pouring

+pouringly

+pours

+pout

+pouted

+pouter

+pouting

+pouts

+poverty

+powder

+powdered

+powderer

+powdering

+powders

+power

+powered

+powerful

+powerfully

+powerfulness

+powering

+powerless

+powerlessly

+powerlessness

+powers

+pox

+poxes

+practicable

+practicableness

+practicably

+practical

+practicalities

+practicality

+practically

+practicalness

+practice

+practice's

+practices

+practitioner

+practitioner's

+practitioners

+pragmatic

+pragmatically

+pragmatics

+prairie

+prairies

+praise

+praised

+praiser

+praisers

+praises

+praising

+praisingly

+prance

+pranced

+prancer

+prances

+prancing

+prancingly

+prank

+prank's

+pranks

+prate

+prated

+prater

+prates

+prating

+pratingly

+pray

+prayed

+prayer

+prayer's

+prayers

+praying

+prays

+preach

+preached

+preacher

+preachers

+preaches

+preaching

+preachingly

+preallocate

+preallocated

+preallocates

+preallocating

+preallocation

+preallocation's

+preallocations

+preallocator

+preallocators

+preassign

+preassigned

+preassigning

+preassigns

+precarious

+precariously

+precariousness

+precaution

+precaution's

+precautioned

+precautioning

+precautions

+precede

+preceded

+precedence

+precedence's

+precedences

+precedent

+precedented

+precedents

+precedes

+preceding

+precept

+precept's

+preceptive

+preceptively

+precepts

+precinct

+precinct's

+precincts

+precious

+preciously

+preciousness

+precipice

+precipitate

+precipitated

+precipitately

+precipitateness

+precipitates

+precipitating

+precipitation

+precipitative

+precipitous

+precipitously

+precipitousness

+precise

+precisely

+preciseness

+precision

+precisions

+preclude

+precluded

+precludes

+precluding

+precocious

+precociously

+precociousness

+preconceive

+preconceived

+preconception

+preconception's

+preconceptions

+precondition

+preconditioned

+preconditions

+precursor

+precursor's

+precursors

+predate

+predated

+predates

+predating

+predation

+predecessor

+predecessor's

+predecessors

+predefine

+predefined

+predefines

+predefining

+predefinition

+predefinition's

+predefinitions

+predetermine

+predetermined

+predeterminer

+predetermines

+predetermining

+predicament

+predicate

+predicated

+predicates

+predicating

+predication

+predications

+predicative

+predict

+predictability

+predictable

+predictably

+predicted

+predicting

+prediction

+prediction's

+predictions

+predictive

+predictively

+predictor

+predictors

+predicts

+predominant

+predominantly

+predominate

+predominated

+predominately

+predominates

+predominating

+predomination

+preempt

+preempted

+preempting

+preemption

+preemptive

+preemptively

+preempts

+preface

+prefaced

+prefacer

+prefaces

+prefacing

+prefer

+preferable

+preferableness

+preferably

+preference

+preference's

+preferences

+preferential

+preferentially

+preferred

+preferring

+prefers

+prefix

+prefixed

+prefixes

+prefixing

+pregnant

+pregnantly

+prehistoric

+prejudge

+prejudged

+prejudger

+prejudice

+prejudiced

+prejudices

+prejudicing

+prelate

+preliminaries

+preliminary

+prelude

+prelude's

+preluded

+preluder

+preludes

+preluding

+premature

+prematurely

+prematureness

+prematurity

+premeditated

+premeditatedly

+premier

+premier's

+premiere

+premiered

+premieres

+premiering

+premiers

+premise

+premise's

+premised

+premises

+premising

+premium

+premium's

+premiums

+preoccupation

+preoccupations

+preoccupied

+preoccupies

+preoccupy

+preparation

+preparation's

+preparations

+preparative

+preparative's

+preparatively

+preparatives

+preparatory

+prepare

+prepared

+preparedly

+preparedness

+preparer

+prepares

+preparing

+prepend

+prepended

+prepender

+prependers

+prepending

+prepends

+preposition

+preposition's

+prepositional

+prepositionally

+prepositions

+preposterous

+preposterously

+preposterousness

+preprint

+preprinted

+preprinting

+preprints

+preprocessor

+preprocessors

+preproduction

+preprogrammed

+prerequisite

+prerequisite's

+prerequisites

+prerogative

+prerogative's

+prerogatived

+prerogatives

+prescribe

+prescribed

+prescriber

+prescribes

+prescribing

+prescription

+prescription's

+prescriptions

+prescriptive

+prescriptively

+preselect

+preselected

+preselecting

+preselects

+presence

+presence's

+presences

+present

+presentation

+presentation's

+presentations

+presented

+presenter

+presenters

+presenting

+presently

+presentness

+presents

+preservation

+preservations

+preservative

+preservative's

+preservatives

+preserve

+preserved

+preserver

+preservers

+preserves

+preserving

+preset

+presets

+preside

+presided

+presidency

+president

+president's

+presidential

+presidentially

+presidents

+presider

+presides

+presiding

+press

+pressed

+presser

+presses

+pressing

+pressingly

+pressings

+pressure

+pressured

+pressures

+pressuring

+prestige

+presumably

+presume

+presumed

+presumer

+presumes

+presuming

+presumingly

+presumption

+presumption's

+presumptions

+presumptuous

+presumptuously

+presumptuousness

+presuppose

+presupposed

+presupposes

+presupposing

+pretend

+pretended

+pretendedly

+pretender

+pretenders

+pretending

+pretends

+pretentious

+pretentiously

+pretentiousness

+pretext

+pretext's

+pretexts

+prettied

+prettier

+pretties

+prettiest

+prettily

+prettiness

+pretty

+prettying

+prevail

+prevailed

+prevailing

+prevailingly

+prevails

+prevalence

+prevalent

+prevalently

+prevent

+preventable

+preventably

+prevented

+preventer

+preventing

+prevention

+preventions

+preventive

+preventively

+preventiveness

+preventives

+prevents

+preview

+previewed

+previewer

+previewers

+previewing

+previews

+previous

+previously

+previousness

+prey

+preyed

+preyer

+preying

+preys

+price

+priced

+priceless

+pricer

+pricers

+prices

+pricing

+prick

+pricked

+pricker

+pricking

+pricklier

+prickliness

+prickly

+pricks

+pride

+prided

+prides

+priding

+pried

+prier

+pries

+priest

+priestliness

+priestly

+priests

+primacy

+primaries

+primarily

+primary

+primary's

+prime

+primed

+primely

+primeness

+primer

+primers

+primes

+primeval

+primevally

+priming

+primitive

+primitively

+primitiveness

+primitives

+primrose

+prince

+princelier

+princeliness

+princely

+princes

+princess

+princess's

+princesses

+principal

+principalities

+principality

+principality's

+principally

+principals

+principle

+principled

+principles

+print

+printable

+printably

+printed

+printer

+printers

+printing

+printout

+printouts

+prints

+prior

+priori

+priorities

+priority

+priority's

+priorly

+priors

+priory

+prism

+prism's

+prisms

+prison

+prisoner

+prisoner's

+prisoners

+prisons

+privacies

+privacy

+private

+privately

+privateness

+privates

+privation

+privations

+privative

+privatively

+privies

+privilege

+privileged

+privileges

+privy

+privy's

+prize

+prized

+prizer

+prizers

+prizes

+prizing

+pro

+pro's

+probabilistic

+probabilistically

+probabilities

+probability

+probable

+probably

+probate

+probated

+probates

+probating

+probation

+probationer

+probationers

+probative

+probe

+probed

+prober

+probes

+probing

+probings

+problem

+problem's

+problematic

+problematical

+problematically

+problems

+procedural

+procedurally

+procedure

+procedure's

+procedures

+proceed

+proceeded

+proceeder

+proceeding

+proceedings

+proceeds

+process

+process's

+processed

+processes

+processing

+procession

+processor

+processor's

+processors

+proclaim

+proclaimed

+proclaimer

+proclaimers

+proclaiming

+proclaims

+proclamation

+proclamation's

+proclamations

+proclivities

+proclivity

+proclivity's

+procrastinate

+procrastinated

+procrastinates

+procrastinating

+procrastination

+procrastinator

+procrastinator's

+procrastinators

+procure

+procured

+procurement

+procurement's

+procurements

+procurer

+procurers

+procures

+procuring

+prodigal

+prodigally

+prodigious

+prodigiously

+prodigiousness

+produce

+produced

+producer

+producers

+produces

+producible

+producing

+product

+product's

+production

+production's

+productions

+productive

+productively

+productiveness

+productivities

+productivity

+products

+profane

+profaned

+profanely

+profaneness

+profaner

+profaning

+profess

+professed

+professedly

+professes

+professing

+profession

+profession's

+professional

+professionalism

+professionalisms

+professionally

+professionals

+professions

+professor

+professor's

+professors

+proffer

+proffered

+proffering

+proffers

+proficiencies

+proficiency

+proficient

+proficiently

+profile

+profiled

+profiler

+profiler's

+profilers

+profiles

+profiling

+profit

+profit's

+profitability

+profitable

+profitableness

+profitably

+profited

+profiteer

+profiteer's

+profiteers

+profiter

+profiters

+profiting

+profits

+profound

+profoundest

+profoundly

+profoundness

+progeny

+program

+program's

+programmability

+programmable

+programmed

+programmer

+programmer's

+programmers

+programming

+programs

+progress

+progressed

+progresses

+progressing

+progression

+progression's

+progressions

+progressive

+progressively

+progressiveness

+prohibit

+prohibited

+prohibiter

+prohibiting

+prohibition

+prohibition's

+prohibitions

+prohibitive

+prohibitively

+prohibitiveness

+prohibits

+project

+project's

+projected

+projecting

+projection

+projection's

+projections

+projective

+projectively

+projector

+projector's

+projectors

+projects

+prolegomena

+proletariat

+proliferate

+proliferated

+proliferates

+proliferating

+proliferation

+proliferative

+prolific

+prolificness

+prolog

+prolog's

+prologs

+prologue

+prologue's

+prologues

+prolong

+prolonged

+prolonger

+prolonging

+prolongs

+promenade

+promenade's

+promenader

+promenades

+promenading

+prominence

+prominent

+prominently

+promiscuity

+promiscuity's

+promiscuous

+promiscuously

+promiscuousness

+promise

+promised

+promiser

+promises

+promising

+promisingly

+promontories

+promontory

+promote

+promoted

+promoter

+promoters

+promotes

+promoting

+promotion

+promotional

+promotions

+promotive

+promotiveness

+prompt

+prompted

+prompter

+prompters

+promptest

+prompting

+promptings

+promptly

+promptness

+prompts

+promulgate

+promulgated

+promulgates

+promulgating

+promulgation

+promulgations

+prone

+pronely

+proneness

+prong

+pronged

+prongs

+pronoun

+pronoun's

+pronounce

+pronounceable

+pronounced

+pronouncedly

+pronouncement

+pronouncement's

+pronouncements

+pronouncer

+pronounces

+pronouncing

+pronouns

+pronunciation

+pronunciation's

+pronunciations

+proof

+proof's

+proofed

+proofer

+proofing

+proofs

+prop

+propaganda

+propagate

+propagated

+propagates

+propagating

+propagation

+propagations

+propagative

+propel

+propelled

+propeller

+propeller's

+propellers

+propels

+propensities

+propensity

+proper

+properly

+properness

+propertied

+properties

+property

+prophecies

+prophecy

+prophecy's

+prophesied

+prophesier

+prophesies

+prophesy

+prophesying

+prophet

+prophet's

+prophetic

+prophets

+propitious

+propitiously

+propitiousness

+proponent

+proponent's

+proponents

+proportion

+proportional

+proportionally

+proportionately

+proportioned

+proportioner

+proportioning

+proportionment

+proportions

+proposal

+proposal's

+proposals

+propose

+proposed

+proposer

+proposers

+proposes

+proposing

+proposition

+propositional

+propositionally

+propositioned

+propositioning

+propositions

+propound

+propounded

+propounder

+propounding

+propounds

+proprietary

+proprietor

+proprietor's

+proprietors

+propriety

+props

+propulsion

+propulsion's

+propulsions

+pros

+prose

+prosecute

+prosecuted

+prosecutes

+prosecuting

+prosecution

+prosecutions

+proser

+prosing

+prosodic

+prosodics

+prospect

+prospected

+prospecting

+prospection

+prospection's

+prospections

+prospective

+prospectively

+prospectiveness

+prospectives

+prospector

+prospector's

+prospectors

+prospects

+prospectus

+prosper

+prospered

+prospering

+prosperity

+prosperous

+prosperously

+prosperousness

+prospers

+prostitution

+prostrate

+prostrated

+prostration

+protect

+protected

+protectedly

+protecting

+protection

+protection's

+protections

+protective

+protectively

+protectiveness

+protector

+protector's

+protectorate

+protectors

+protects

+protege

+protege's

+proteges

+protein

+protein's

+proteins

+protest

+protest's

+protestants

+protestation

+protestations

+protested

+protester

+protester's

+protesters

+protesting

+protestingly

+protests

+protocol

+protocol's

+protocols

+proton

+proton's

+protons

+protoplasm

+prototype

+prototype's

+prototyped

+prototypes

+prototypical

+prototypically

+prototyping

+protrude

+protruded

+protrudes

+protruding

+protrusion

+protrusion's

+protrusions

+proud

+prouder

+proudest

+proudly

+provability

+provable

+provableness

+provably

+prove

+proved

+proven

+provenly

+prover

+proverb

+proverb's

+proverbs

+provers

+proves

+provide

+provided

+providence

+provider

+providers

+provides

+providing

+province

+province's

+provinces

+provincial

+provincially

+proving

+provision

+provisional

+provisionally

+provisioned

+provisioner

+provisioning

+provisions

+provocation

+provoke

+provoked

+provokes

+provoking

+provokingly

+prow

+prow's

+prowess

+prowl

+prowled

+prowler

+prowlers

+prowling

+prowls

+prows

+proximal

+proximally

+proximate

+proximately

+proximateness

+proximity

+prudence

+prudent

+prudently

+prune

+pruned

+pruner

+pruners

+prunes

+pruning

+pry

+prying

+pryingly

+psalm

+psalm's

+psalms

+pseudo

+psyche

+psyche's

+psyches

+psychiatrist

+psychiatrist's

+psychiatrists

+psychiatry

+psychological

+psychologically

+psychologist

+psychologist's

+psychologists

+psychology

+psychosocial

+psychosocially

+pub

+pub's

+public

+publication

+publication's

+publications

+publicity

+publicly

+publicness

+publics

+publish

+published

+publisher

+publishers

+publishes

+publishing

+pubs

+pucker

+puckered

+puckering

+puckers

+pudding

+pudding's

+puddings

+puddle

+puddled

+puddler

+puddles

+puddling

+puff

+puffed

+puffer

+puffers

+puffing

+puffs

+pull

+pulled

+puller

+pulley

+pulley's

+pulleys

+pulling

+pullings

+pulls

+pulp

+pulper

+pulping

+pulpit

+pulpit's

+pulpits

+pulse

+pulsed

+pulser

+pulses

+pulsing

+pump

+pumped

+pumper

+pumping

+pumpkin

+pumpkin's

+pumpkins

+pumps

+pun

+pun's

+punch

+punched

+puncher

+puncher's

+punchers

+punches

+punching

+punchings

+punctual

+punctually

+punctualness

+punctuation

+puncture

+puncture's

+punctured

+punctures

+puncturing

+punier

+puniness

+punish

+punishable

+punished

+punisher

+punishes

+punishing

+punishment

+punishment's

+punishments

+punitive

+punitively

+punitiveness

+puns

+punt

+punted

+punter

+punters

+punting

+punts

+puny

+pup

+pup's

+pupa

+pupas

+pupil

+pupil's

+pupils

+puppet

+puppet's

+puppets

+puppies

+puppy

+puppy's

+pups

+purchasable

+purchase

+purchased

+purchaser

+purchasers

+purchases

+purchasing

+pure

+purely

+pureness

+purer

+purest

+purge

+purged

+purger

+purges

+purging

+purification

+purifications

+purified

+purifier

+purifiers

+purifies

+purify

+purifying

+purity

+purple

+purpled

+purpler

+purples

+purplest

+purpling

+purport

+purported

+purportedly

+purporter

+purporters

+purporting

+purports

+purpose

+purposed

+purposeful

+purposefully

+purposefulness

+purposely

+purposes

+purposing

+purposive

+purposively

+purposiveness

+purr

+purred

+purring

+purringly

+purrs

+purse

+pursed

+purser

+pursers

+purses

+pursing

+pursue

+pursued

+pursuer

+pursuers

+pursues

+pursuing

+pursuit

+pursuit's

+pursuits

+purview

+push

+pushbutton

+pushbuttons

+pushdown

+pushed

+pusher

+pushers

+pushes

+pushing

+puss

+pussier

+pussies

+pussy

+put

+puts

+putter

+putterer

+puttering

+putters

+putting

+puzzle

+puzzled

+puzzlement

+puzzler

+puzzlers

+puzzles

+puzzling

+puzzlings

+pygmies

+pygmy

+pygmy's

+pyramid

+pyramid's

+pyramids

+quack

+quacked

+quacking

+quacks

+quadrant

+quadrant's

+quadrants

+quadratic

+quadratical

+quadratically

+quadratics

+quadrature

+quadrature's

+quadratures

+quadruple

+quadrupled

+quadruples

+quadrupling

+quadword

+quadword's

+quadwords

+quagmire

+quagmire's

+quagmires

+quail

+quail's

+quails

+quaint

+quaintly

+quaintness

+quake

+quaked

+quaker

+quakers

+quakes

+quaking

+qualification

+qualifications

+qualified

+qualifiedly

+qualifier

+qualifiers

+qualifies

+qualify

+qualifying

+qualitative

+qualitatively

+qualities

+quality

+quality's

+qualm

+qualms

+quandaries

+quandary

+quandary's

+quanta

+quantifiable

+quantification

+quantifications

+quantified

+quantifier

+quantifiers

+quantifies

+quantify

+quantifying

+quantitative

+quantitatively

+quantitativeness

+quantities

+quantity

+quantity's

+quantum

+quarantine

+quarantine's

+quarantined

+quarantines

+quarantining

+quarrel

+quarrels

+quarrelsome

+quarrelsomely

+quarrelsomeness

+quarried

+quarrier

+quarries

+quarry

+quarry's

+quarrying

+quart

+quarter

+quartered

+quarterer

+quartering

+quarterlies

+quarterly

+quarters

+quartet

+quartet's

+quartets

+quarts

+quartz

+quash

+quashed

+quashes

+quashing

+quasi

+quaver

+quavered

+quavering

+quaveringly

+quavers

+quay

+quays

+queen

+queen's

+queenly

+queens

+queer

+queerer

+queerest

+queerly

+queerness

+queers

+quell

+quelled

+queller

+quelling

+quells

+quench

+quenched

+quencher

+quenches

+quenching

+queried

+querier

+queries

+query

+querying

+quest

+quested

+quester

+questers

+questing

+question

+questionable

+questionableness

+questionably

+questioned

+questioner

+questioners

+questioning

+questioningly

+questionings

+questionnaire

+questionnaire's

+questionnaires

+questions

+quests

+queue

+queue's

+queued

+queuer

+queuer's

+queuers

+queues

+quick

+quicken

+quickened

+quickener

+quickening

+quickens

+quicker

+quickest

+quickly

+quickness

+quicksilver

+quiet

+quieted

+quieten

+quietened

+quietening

+quietens

+quieter

+quietest

+quieting

+quietly

+quietness

+quiets

+quietude

+quill

+quills

+quilt

+quilted

+quilter

+quilting

+quilts

+quinine

+quit

+quite

+quits

+quitter

+quitter's

+quitters

+quitting

+quiver

+quivered

+quivering

+quivers

+quiz

+quizzed

+quizzes

+quizzing

+quo

+quota

+quota's

+quotas

+quotation

+quotation's

+quotations

+quote

+quoted

+quotes

+quoth

+quotient

+quotients

+quoting

+rabbit

+rabbit's

+rabbited

+rabbiter

+rabbiting

+rabbits

+rabble

+rabbled

+rabbler

+rabbling

+raccoon

+raccoon's

+raccoons

+race

+raced

+racehorse

+racehorse's

+racehorses

+racer

+racers

+races

+racial

+racially

+racing

+rack

+racked

+racker

+racket

+racket's

+racketeer

+racketeering

+racketeers

+rackets

+racking

+racks

+radar

+radar's

+radars

+radial

+radially

+radiance

+radiant

+radiantly

+radiate

+radiated

+radiately

+radiates

+radiating

+radiation

+radiations

+radiative

+radiatively

+radiator

+radiator's

+radiators

+radical

+radically

+radicalness

+radicals

+radio

+radioed

+radioing

+radiology

+radios

+radish

+radish's

+radishes

+radius

+radiuses

+radix

+radixes

+raft

+rafter

+raftered

+rafters

+rafts

+rag

+rag's

+rage

+raged

+rages

+ragged

+raggedly

+raggedness

+raging

+rags

+raid

+raided

+raider

+raiders

+raiding

+raids

+rail

+railed

+railer

+railers

+railing

+railroad

+railroaded

+railroader

+railroaders

+railroading

+railroads

+rails

+railway

+railway's

+railways

+raiment

+rain

+rain's

+rainbow

+rainbows

+raincoat

+raincoat's

+raincoats

+raindrop

+raindrop's

+raindrops

+rained

+rainfall

+rainier

+rainiest

+raining

+rains

+rainy

+raise

+raised

+raiser

+raisers

+raises

+raisin

+raising

+raisins

+rake

+raked

+raker

+rakes

+raking

+rallied

+rallies

+rally

+rallying

+ram

+ram's

+ramble

+rambled

+rambler

+ramblers

+rambles

+rambling

+ramblingly

+ramblings

+ramification

+ramification's

+ramifications

+ramp

+ramp's

+rampart

+ramparts

+ramped

+ramping

+ramps

+rams

+ramses

+ran

+ranch

+ranched

+rancher

+ranchers

+ranches

+ranching

+random

+randomly

+randomness

+rang

+range

+ranged

+ranger

+rangers

+ranges

+ranging

+rank

+ranked

+ranker

+ranker's

+rankers

+rankest

+ranking

+ranking's

+rankings

+rankle

+rankled

+rankles

+rankling

+rankly

+rankness

+ranks

+ransack

+ransacked

+ransacker

+ransacking

+ransacks

+ransom

+ransomer

+ransoming

+ransoms

+rant

+ranted

+ranter

+ranters

+ranting

+rantingly

+rants

+rap

+rap's

+rape

+raped

+raper

+rapes

+rapid

+rapidity

+rapidly

+rapidness

+rapids

+raping

+raps

+rapt

+raptly

+raptness

+rapture

+rapture's

+raptured

+raptures

+rapturing

+rapturous

+rapturously

+rapturousness

+rare

+rarely

+rareness

+rarer

+rarest

+raring

+rarities

+rarity

+rarity's

+rascal

+rascally

+rascals

+rash

+rasher

+rashes

+rashly

+rashness

+rasp

+raspberry

+rasped

+rasper

+rasping

+raspingly

+raspings

+rasps

+raster

+rasters

+rat

+rat's

+rate

+rated

+rater

+raters

+rates

+rather

+ratification

+ratifications

+ratified

+ratifies

+ratify

+ratifying

+rating

+ratings

+ratio

+ratio's

+ration

+rational

+rationale

+rationale's

+rationales

+rationalities

+rationality

+rationally

+rationalness

+rationed

+rationing

+rations

+ratios

+rats

+rattle

+rattled

+rattler

+rattlers

+rattles

+rattlesnake

+rattlesnake's

+rattlesnakes

+rattling

+rattlingly

+ravage

+ravaged

+ravager

+ravagers

+ravages

+ravaging

+rave

+raved

+raven

+ravened

+ravener

+ravening

+ravenous

+ravenously

+ravenousness

+ravens

+raver

+raves

+ravine

+ravine's

+ravined

+ravines

+raving

+ravings

+raw

+rawer

+rawest

+rawly

+rawness

+raws

+ray

+ray's

+rayed

+rays

+razor

+razor's

+razors

+re

+reabbreviate

+reabbreviated

+reabbreviates

+reabbreviating

+reach

+reachable

+reachably

+reached

+reacher

+reaches

+reaching

+reacquainted

+react

+reacted

+reacting

+reaction

+reaction's

+reactionaries

+reactionary

+reactionary's

+reactions

+reactivate

+reactivated

+reactivates

+reactivating

+reactivation

+reactive

+reactively

+reactiveness

+reactivity

+reactor

+reactor's

+reactors

+reacts

+read

+readability

+readable

+readableness

+readapting

+reader

+reader's

+readers

+readied

+readier

+readies

+readiest

+readily

+readiness

+reading

+readings

+readjustable

+readjusted

+readjustments

+readjusts

+readout

+readout's

+readouts

+reads

+ready

+readying

+reaffirm

+reaffirmed

+reaffirming

+reaffirms

+reagents

+real

+realest

+realign

+realigned

+realigning

+realignment

+realignments

+realigns

+realism

+realist

+realist's

+realistic

+realistically

+realists

+realities

+reality

+realizable

+realizable's

+realizableness

+realizables

+realizablies

+realizably

+realization

+realization's

+realizations

+realize

+realized

+realizer

+realizers

+realizes

+realizing

+realizing's

+realizingly

+realizings

+reallocate

+reallocated

+reallocates

+reallocating

+reallocation

+reallocation's

+reallocations

+reallocator

+reallocator's

+reallocators

+reallotments

+reallots

+reallotted

+reallotting

+really

+realm

+realm's

+realms

+realness

+reals

+ream

+ream's

+reamed

+reamer

+reaming

+reams

+reanalysis

+reap

+reaped

+reaper

+reaping

+reappear

+reappeared

+reappearing

+reappears

+reapplying

+reapportioned

+reappraisal

+reappraisals

+reappraised

+reappraises

+reaps

+rear

+reared

+rearer

+rearing

+rearmed

+rearms

+rearrange

+rearrangeable

+rearranged

+rearrangement

+rearrangement's

+rearrangements

+rearranges

+rearranging

+rearrest

+rearrested

+rears

+reason

+reasonable

+reasonableness

+reasonably

+reasoned

+reasoner

+reasoning

+reasonings

+reasons

+reassemble

+reassembled

+reassembler

+reassembles

+reassembling

+reasserts

+reassess

+reassessed

+reassesses

+reassessing

+reassessment

+reassessment's

+reassessments

+reassign

+reassignable

+reassigned

+reassigning

+reassignment

+reassignment's

+reassignments

+reassigns

+reassurances

+reassure

+reassured

+reassures

+reassuring

+reassuringly

+reawaken

+reawakened

+reawakening

+reawakens

+rebate

+rebate's

+rebated

+rebater

+rebates

+rebating

+rebel

+rebel's

+rebelled

+rebelling

+rebellion

+rebellion's

+rebellions

+rebellious

+rebelliously

+rebelliousness

+rebells

+rebels

+rebidding

+rebids

+rebirth

+rebirth's

+rebonds

+reboot

+rebooted

+rebooter

+rebooters

+rebooting

+reboots

+reborn

+rebound

+rebounded

+rebounder

+rebounding

+rebounds

+rebroadcast

+rebroadcasts

+rebuff

+rebuffed

+rebuffing

+rebuffs

+rebuild

+rebuilding

+rebuilds

+rebuilt

+rebuke

+rebuked

+rebuker

+rebukes

+rebuking

+rebut

+rebuttal

+rebuttals

+rebutted

+rebutting

+recalculate

+recalculated

+recalculates

+recalculating

+recalculation

+recalculations

+recall

+recalled

+recaller

+recalling

+recalls

+recapitulate

+recapitulated

+recapitulates

+recapitulating

+recapitulation

+recapped

+recapping

+recapture

+recaptured

+recaptures

+recapturing

+recast

+recasting

+recasts

+recede

+receded

+recedes

+receding

+receipt

+receipt's

+receipted

+receipting

+receipts

+receivable

+receivables

+receive

+received

+receiver

+receiver's

+receivers

+receives

+receiving

+recent

+recently

+recentness

+receptacle

+receptacle's

+receptacles

+reception

+reception's

+receptions

+receptive

+receptively

+receptiveness

+receptivity

+receptor

+receptor's

+receptors

+recess

+recessed

+recesses

+recessing

+recession

+recession's

+recessions

+recessive

+recessively

+recessiveness

+recharged

+recharges

+rechartering

+rechecked

+rechecks

+recipe

+recipe's

+recipes

+recipient

+recipient's

+recipients

+reciprocal

+reciprocally

+reciprocals

+reciprocate

+reciprocated

+reciprocates

+reciprocating

+reciprocation

+reciprocative

+reciprocity

+recirculate

+recirculated

+recirculates

+recirculating

+recirculation

+recital

+recital's

+recitals

+recitation

+recitation's

+recitations

+recite

+recited

+reciter

+recites

+reciting

+reckless

+recklessly

+recklessness

+reckon

+reckoned

+reckoner

+reckoning

+reckonings

+reckons

+reclaim

+reclaimable

+reclaimed

+reclaimer

+reclaimers

+reclaiming

+reclaims

+reclamation

+reclamations

+reclassification

+reclassified

+reclassifies

+reclassify

+reclassifying

+recline

+reclined

+reclines

+reclining

+reclustered

+reclusters

+recode

+recoded

+recodes

+recoding

+recognition

+recognition's

+recognitions

+recoil

+recoiled

+recoiling

+recoils

+recoinage

+recollect

+recollected

+recollecting

+recollection

+recollection's

+recollections

+recollects

+recombination

+recombination's

+recombinational

+recombinations

+recombine

+recombined

+recombines

+recombining

+recommenced

+recommences

+recommend

+recommendation

+recommendation's

+recommendations

+recommended

+recommender

+recommending

+recommends

+recompense

+recompilations

+recompile

+recompiled

+recompiles

+recompiling

+recompute

+recomputed

+recomputes

+recomputing

+reconcile

+reconciled

+reconciler

+reconciles

+reconciliation

+reconciliation's

+reconciliations

+reconciling

+reconditioned

+reconfigurable

+reconfiguration

+reconfiguration's

+reconfigurations

+reconfigure

+reconfigured

+reconfigurer

+reconfigures

+reconfiguring

+reconnect

+reconnected

+reconnecter

+reconnecting

+reconnection

+reconnects

+reconsider

+reconsideration

+reconsidered

+reconsidering

+reconsiders

+reconsolidated

+reconsolidates

+reconstituted

+reconstitutes

+reconstruct

+reconstructed

+reconstructible

+reconstructing

+reconstruction

+reconstructions

+reconstructive

+reconstructs

+recontacted

+reconvened

+reconvenes

+reconverts

+record

+recorded

+recorder

+recorders

+recording

+recordings

+records

+recored

+recount

+recounted

+recounter

+recounting

+recounts

+recourse

+recourses

+recover

+recoverability

+recoverable

+recovered

+recoverer

+recoveries

+recovering

+recovers

+recovery

+recovery's

+recreate

+recreated

+recreates

+recreating

+recreation

+recreational

+recreations

+recreative

+recruit

+recruit's

+recruited

+recruiter

+recruiter's

+recruiters

+recruiting

+recruits

+recta

+rectangle

+rectangle's

+rectangles

+rectangular

+rectangularly

+rector

+rector's

+rectors

+rectum

+rectum's

+rectums

+recur

+recurrence

+recurrence's

+recurrences

+recurrent

+recurrently

+recurring

+recurs

+recurse

+recursed

+recurses

+recursing

+recursion

+recursion's

+recursions

+recursive

+recursively

+recursiveness

+recurved

+recyclable

+recycle

+recycled

+recycles

+recycling

+red

+redbreast

+redden

+reddened

+reddening

+redder

+reddest

+reddish

+reddishness

+redeclare

+redeclared

+redeclares

+redeclaring

+redecorated

+redecorates

+redeem

+redeemed

+redeemer

+redeemers

+redeeming

+redeems

+redefine

+redefined

+redefines

+redefining

+redefinition

+redefinition's

+redefinitions

+redemption

+redemptioner

+redeploys

+redeposit

+redeposit's

+redeposited

+redepositing

+redepositor

+redepositor's

+redepositors

+redeposits

+redesign

+redesigned

+redesigning

+redesigns

+redetermination

+redetermines

+redevelop

+redeveloped

+redeveloper

+redevelopers

+redeveloping

+redevelopment

+redevelops

+redials

+redirect

+redirected

+redirecting

+redirection

+redirections

+redirector

+redirector's

+redirectors

+redirects

+rediscovered

+rediscovers

+redisplay

+redisplayed

+redisplaying

+redisplays

+redistribute

+redistributed

+redistributes

+redistributing

+redistribution

+redistribution's

+redistributions

+redistributive

+redly

+redness

+redoing

+redone

+redouble

+redoubled

+redoubles

+redoubling

+redoubtable

+redraw

+redrawing

+redrawn

+redraws

+redress

+redressed

+redresser

+redresses

+redressing

+reds

+reduce

+reduced

+reducer

+reducers

+reduces

+reducibility

+reducible

+reducibly

+reducing

+reduction

+reduction's

+reductions

+redundancies

+redundancy

+redundant

+redundantly

+reduplicated

+reed

+reed's

+reeder

+reeding

+reeds

+reeducation

+reef

+reefer

+reefing

+reefs

+reel

+reelect

+reelected

+reelecting

+reelects

+reeled

+reeler

+reeling

+reels

+reemerged

+reenactment

+reenforcement

+reenlists

+reenter

+reentered

+reentering

+reenters

+reentrant

+reestablish

+reestablished

+reestablishes

+reestablishing

+reestimating

+reevaluate

+reevaluated

+reevaluates

+reevaluating

+reevaluation

+reeves

+reexamine

+reexamined

+reexamines

+reexamining

+refaced

+refaces

+refelled

+refelling

+refer

+referee

+referee's

+refereed

+refereeing

+referees

+reference

+referenced

+referencer

+references

+referencing

+referendum

+referent

+referent's

+referential

+referentiality

+referentially

+referents

+referral

+referral's

+referrals

+referred

+referrer

+referring

+refers

+refill

+refillable

+refilled

+refilling

+refills

+refine

+refined

+refinement

+refinement's

+refinements

+refiner

+refines

+refining

+refinished

+reflect

+reflected

+reflecting

+reflection

+reflection's

+reflections

+reflective

+reflectively

+reflectiveness

+reflectivity

+reflector

+reflector's

+reflectors

+reflects

+reflex

+reflex's

+reflexed

+reflexes

+reflexive

+reflexively

+reflexiveness

+reflexivity

+reflexly

+refluent

+refocus

+refocused

+refocuses

+refocusing

+refolded

+reform

+reformable

+reformat

+reformation

+reformative

+reformats

+reformatted

+reformatter

+reformatting

+reformed

+reformer

+reformers

+reforming

+reforms

+reformulate

+reformulated

+reformulates

+reformulating

+reformulation

+refractoriness

+refractory

+refrain

+refrained

+refraining

+refrains

+refresh

+refreshed

+refreshen

+refresher

+refreshers

+refreshes

+refreshing

+refreshingly

+refreshment

+refreshment's

+refreshments

+refried

+refries

+refrigerator

+refrigerator's

+refrigerators

+refry

+refrying

+refuel

+refuels

+refuge

+refuged

+refugee

+refugee's

+refugees

+refuges

+refuging

+refund

+refund's

+refunded

+refunder

+refunders

+refunding

+refunds

+refusal

+refusals

+refuse

+refused

+refuser

+refuses

+refusing

+refutable

+refutation

+refute

+refuted

+refuter

+refutes

+refuting

+regain

+regained

+regaining

+regains

+regal

+regaled

+regaling

+regally

+regard

+regarded

+regarding

+regardless

+regardlessly

+regardlessness

+regards

+regenerate

+regenerated

+regenerately

+regenerateness

+regenerates

+regenerating

+regeneration

+regenerative

+regeneratively

+regenerators

+regent

+regent's

+regents

+regime

+regime's

+regimen

+regiment

+regimented

+regiments

+regimes

+region

+region's

+regional

+regionally

+regions

+register

+registered

+registering

+registers

+registration

+registration's

+registrations

+regreets

+regress

+regressed

+regresses

+regressing

+regression

+regression's

+regressions

+regressive

+regressively

+regressiveness

+regret

+regretful

+regretfully

+regretfulness

+regrets

+regrettable

+regrettably

+regretted

+regretting

+regrids

+regroup

+regrouped

+regrouping

+regular

+regularities

+regularity

+regularly

+regulars

+regulate

+regulated

+regulates

+regulating

+regulation

+regulations

+regulative

+regulator

+regulator's

+regulators

+rehash

+rehashed

+rehashes

+rehashing

+rehearsal

+rehearsal's

+rehearsals

+rehearse

+rehearsed

+rehearser

+rehearses

+rehearsing

+rehoused

+rehouses

+reign

+reigned

+reigning

+reigns

+reimbursed

+reimbursement

+reimbursement's

+reimbursements

+rein

+reincarnate

+reincarnated

+reincarnation

+reincorporating

+reincorporation

+reindeer

+reined

+reinforce

+reinforced

+reinforcement

+reinforcement's

+reinforcements

+reinforcer

+reinforces

+reinforcing

+reining

+reins

+reinsert

+reinserted

+reinserting

+reinsertions

+reinserts

+reinstall

+reinstalled

+reinstaller

+reinstalling

+reinstalls

+reinstate

+reinstated

+reinstatement

+reinstates

+reinstating

+reintegrated

+reinterpret

+reinterpretations

+reinterpreted

+reinterpreting

+reinterprets

+reinterviewed

+reintroduce

+reintroduced

+reintroduces

+reintroducing

+reinvent

+reinvented

+reinventing

+reinvention

+reinvents

+reinvested

+reinvoked

+reinvokes

+reissue

+reissued

+reissuer

+reissuer's

+reissuers

+reissues

+reissuing

+reiterate

+reiterated

+reiterates

+reiterating

+reiteration

+reiterations

+reiterative

+reiteratively

+reiterativeness

+reject

+rejected

+rejecter

+rejecting

+rejectingly

+rejection

+rejection's

+rejections

+rejective

+rejector

+rejector's

+rejectors

+rejects

+rejoice

+rejoiced

+rejoicer

+rejoices

+rejoicing

+rejoicingly

+rejoin

+rejoined

+rejoining

+rejoins

+rekindle

+rekindled

+rekindler

+rekindles

+rekindling

+reknit

+relabel

+relabels

+relapse

+relapsed

+relapser

+relapses

+relapsing

+relate

+related

+relatedly

+relatedness

+relater

+relates

+relating

+relation

+relational

+relationally

+relations

+relationship

+relationship's

+relationships

+relative

+relatively

+relativeness

+relatives

+relativism

+relativistic

+relativistically

+relativity

+relativity's

+relax

+relaxation

+relaxation's

+relaxations

+relaxed

+relaxedly

+relaxedness

+relaxer

+relaxes

+relaxing

+relay

+relayed

+relaying

+relays

+relearns

+release

+released

+releaser

+releases

+releasing

+relegate

+relegated

+relegates

+relegating

+relegation

+relent

+relented

+relenting

+relentless

+relentlessly

+relentlessness

+relents

+relevance

+relevances

+relevant

+relevantly

+reliabilities

+reliability

+reliable

+reliableness

+reliably

+reliance

+relic

+relic's

+relicense

+relicensed

+relicenser

+relicenses

+relicensing

+relics

+relied

+relief

+reliefs

+relier

+relies

+relieve

+relieved

+relievedly

+reliever

+relievers

+relieves

+relieving

+religion

+religion's

+religions

+religious

+religiously

+religiousness

+relinking

+relinquish

+relinquished

+relinquishes

+relinquishing

+relish

+relished

+relishes

+relishing

+relive

+relives

+reliving

+reload

+reloaded

+reloader

+reloading

+reloads

+relocate

+relocated

+relocates

+relocating

+relocation

+relocations

+reluctance

+reluctances

+reluctant

+reluctantly

+rely

+relying

+remade

+remain

+remainder

+remainder's

+remaindered

+remaindering

+remainders

+remained

+remaining

+remains

+remark

+remarkable

+remarkableness

+remarkably

+remarked

+remarking

+remarks

+remarriages

+remarried

+remedied

+remedies

+remedy

+remedying

+remember

+remembered

+rememberer

+remembering

+remembers

+remembrance

+remembrance's

+remembrancer

+remembrances

+remind

+reminded

+reminder

+reminders

+reminding

+reminds

+reminiscence

+reminiscence's

+reminiscences

+reminiscent

+reminiscently

+remissions

+remittance

+remittances

+remixed

+remnant

+remnant's

+remnants

+remodel

+remodels

+remodulate

+remodulated

+remodulates

+remodulating

+remodulation

+remodulator

+remodulator's

+remodulators

+remolding

+remonstrate

+remonstrated

+remonstrates

+remonstrating

+remonstration

+remonstrative

+remonstratively

+remorse

+remote

+remotely

+remoteness

+remotest

+remotion

+remoulds

+removable

+removableness

+removal

+removal's

+removals

+remove

+removed

+remover

+removes

+removing

+renaissance

+renal

+rename

+renamed

+renames

+renaming

+renatured

+renatures

+rend

+render

+rendered

+renderer

+rendering

+renderings

+renders

+rendezvous

+rendezvoused

+rendezvouses

+rendezvousing

+rending

+rendition

+rendition's

+renditions

+rends

+renegotiable

+renegotiated

+renegotiates

+renew

+renewal

+renewals

+renewed

+renewer

+renewing

+renews

+reno

+renominated

+renominates

+renounce

+renounced

+renouncer

+renounces

+renouncing

+renown

+renowned

+rent

+rental

+rental's

+rentals

+rented

+renter

+renter's

+renters

+renting

+rents

+renumber

+renumbered

+renumbering

+renumbers

+reopen

+reopened

+reopening

+reopens

+reorder

+reordered

+reordering

+reorders

+reoriented

+repackage

+repackaged

+repackager

+repackages

+repackaging

+repacks

+repaid

+repaint

+repainted

+repainter

+repainters

+repainting

+repaints

+repair

+repaired

+repairer

+repairers

+repairing

+repairman

+repairs

+reparable

+reparation

+reparation's

+reparations

+repartition

+repartitioned

+repartitioner

+repartitioners

+repartitioning

+repartitions

+repast

+repast's

+repasts

+repaving

+repay

+repayable

+repaying

+repayments

+repays

+repeal

+repealed

+repealer

+repealing

+repeals

+repeat

+repeatable

+repeated

+repeatedly

+repeater

+repeaters

+repeating

+repeats

+repel

+repels

+repent

+repentance

+repented

+repenter

+repenting

+repents

+repercussion

+repercussion's

+repercussions

+repertoire

+repetition

+repetition's

+repetitions

+repetitive

+repetitively

+repetitiveness

+rephrase

+rephrased

+rephrases

+rephrasing

+repine

+repined

+repiner

+repining

+replace

+replaceable

+replaced

+replacement

+replacement's

+replacements

+replacer

+replaces

+replacing

+replanted

+replay

+replayed

+replaying

+replays

+repleader

+replenish

+replenished

+replenisher

+replenishes

+replenishing

+replete

+repleteness

+repletion

+replica

+replica's

+replicas

+replicate

+replicated

+replicates

+replicating

+replication

+replications

+replicative

+replied

+replier

+replies

+reply

+replying

+report

+reported

+reportedly

+reporter

+reporters

+reporting

+reports

+repose

+reposed

+reposes

+reposing

+reposition

+repositioned

+repositioning

+repositions

+repositories

+repository

+repository's

+repost

+reposted

+reposter

+reposting

+repostings

+reposts

+represent

+representable

+representably

+representation

+representation's

+representational

+representationally

+representations

+representative

+representatively

+representativeness

+representatives

+represented

+representer

+representing

+represents

+repress

+repressed

+represses

+repressing

+repression

+repression's

+repressions

+repressive

+repressively

+repressiveness

+reprieve

+reprieved

+reprieves

+reprieving

+reprint

+reprinted

+reprinter

+reprinting

+reprints

+reprisal

+reprisal's

+reprisals

+reproach

+reproached

+reproacher

+reproaches

+reproaching

+reproachingly

+reprobates

+reprocessed

+reproduce

+reproduced

+reproducer

+reproducers

+reproduces

+reproducibilities

+reproducibility

+reproducible

+reproducibly

+reproducing

+reproduction

+reproduction's

+reproductions

+reproductive

+reproductively

+reproductivity

+reprogrammed

+reprogrammer

+reprogrammer's

+reprogrammers

+reprogramming

+reproof

+reprove

+reproved

+reprover

+reproving

+reprovingly

+reptile

+reptile's

+reptiles

+republic

+republic's

+republican

+republican's

+republicans

+republication

+republics

+republish

+republished

+republisher

+republisher's

+republishers

+republishes

+republishing

+repudiate

+repudiated

+repudiates

+repudiating

+repudiation

+repudiations

+repulse

+repulsed

+repulses

+repulsing

+repulsion

+repulsions

+repulsive

+repulsively

+repulsiveness

+reputable

+reputably

+reputation

+reputation's

+reputations

+repute

+reputed

+reputedly

+reputes

+reputing

+request

+requested

+requester

+requesters

+requesting

+requestioned

+requests

+requiem

+requiem's

+requiems

+require

+required

+requirement

+requirement's

+requirements

+requirer

+requires

+requiring

+requisite

+requisiteness

+requisites

+requisition

+requisitioned

+requisitioner

+requisitioning

+requisitions

+requite

+requited

+requiter

+requiting

+reran

+reread

+rereading

+rereads

+reroute

+rerouted

+rerouter

+rerouters

+reroutes

+reroutings

+rerun

+rerunning

+reruns

+res

+resalable

+resaturated

+resaturates

+rescaled

+rescan

+rescanned

+rescanning

+rescans

+reschedule

+rescheduled

+rescheduler

+reschedules

+rescheduling

+rescue

+rescued

+rescuer

+rescuers

+rescues

+rescuing

+resealed

+research

+researched

+researcher

+researcher's

+researchers

+researches

+researching

+reselect

+reselected

+reselecting

+reselects

+resell

+reseller

+resellers

+reselling

+resells

+resemblance

+resemblance's

+resemblances

+resemble

+resembled

+resembles

+resembling

+resends

+resent

+resented

+resentful

+resentfully

+resentfulness

+resenting

+resentment

+resents

+resequenced

+reservation

+reservation's

+reservations

+reserve

+reserved

+reservedly

+reservedness

+reserver

+reserves

+reserving

+reservoir

+reservoir's

+reservoirs

+reset

+reseted

+reseter

+reseting

+resets

+resetting

+resettings

+resettled

+resettles

+resettling

+reshape

+reshaped

+reshaper

+reshapes

+reshaping

+reside

+resided

+residence

+residence's

+residences

+resident

+resident's

+residential

+residentially

+residents

+resider

+resides

+residing

+residue

+residue's

+residues

+resifted

+resign

+resignation

+resignation's

+resignations

+resigned

+resignedly

+resignedness

+resigner

+resigning

+resigns

+resin

+resin's

+resined

+resining

+resins

+resist

+resistance

+resistances

+resistant

+resistantly

+resisted

+resister

+resistible

+resistibly

+resisting

+resistive

+resistively

+resistiveness

+resistivity

+resistor

+resistor's

+resistors

+resists

+resize

+resized

+resizes

+resizing

+resold

+resoluble

+resolute

+resolutely

+resoluteness

+resolution

+resolutions

+resolutive

+resolvable

+resolve

+resolved

+resolver

+resolvers

+resolves

+resolving

+resonance

+resonances

+resonant

+resonantly

+resort

+resorted

+resorter

+resorting

+resorts

+resound

+resounding

+resoundingly

+resounds

+resource

+resource's

+resourced

+resourceful

+resourcefully

+resourcefulness

+resources

+resourcing

+respecified

+respect

+respectability

+respectable

+respectableness

+respectably

+respected

+respecter

+respectful

+respectfully

+respectfulness

+respecting

+respective

+respectively

+respectiveness

+respects

+respiration

+respirations

+respired

+respires

+respite

+respited

+respiting

+resplendent

+resplendently

+respond

+responded

+respondent

+respondent's

+respondents

+responder

+responders

+responding

+responds

+response

+responser

+responses

+responsibilities

+responsibility

+responsible

+responsibleness

+responsibly

+responsions

+responsive

+responsively

+responsiveness

+rest

+restart

+restarted

+restarter

+restarting

+restarts

+restate

+restated

+restatement

+restates

+restating

+restaurant

+restaurant's

+restaurants

+rested

+rester

+restful

+restfully

+restfulness

+resting

+restive

+restively

+restiveness

+restless

+restlessly

+restlessness

+restoration

+restoration's

+restorations

+restore

+restored

+restorer

+restorers

+restores

+restoring

+restrain

+restrained

+restrainedly

+restrainer

+restrainers

+restraining

+restrains

+restraint

+restraint's

+restraints

+restrict

+restricted

+restrictedly

+restricting

+restriction

+restriction's

+restrictions

+restrictive

+restrictively

+restrictiveness

+restricts

+restroom

+restroom's

+restrooms

+restructure

+restructured

+restructures

+restructuring

+rests

+resubmit

+resubmits

+resubmitted

+resubmitting

+result

+resultant

+resultantly

+resultants

+resulted

+resulting

+results

+resumable

+resume

+resumed

+resumes

+resuming

+resumption

+resumption's

+resumptions

+resupplier

+resupplier's

+resuppliers

+resurface

+resurfaced

+resurfacer

+resurfacer's

+resurfacers

+resurfaces

+resurfacing

+resurged

+resurges

+resurrect

+resurrected

+resurrecting

+resurrection

+resurrection's

+resurrections

+resurrects

+resuspended

+retail

+retailed

+retailer

+retailers

+retailing

+retails

+retain

+retained

+retainer

+retainers

+retaining

+retainment

+retains

+retaliation

+retard

+retarded

+retarder

+retarding

+retention

+retentions

+retentive

+retentively

+retentiveness

+rethinks

+rethreading

+reticence

+reticent

+reticently

+reticle

+reticle's

+reticles

+reticular

+reticulate

+reticulated

+reticulately

+reticulates

+reticulating

+reticulation

+retied

+retina

+retina's

+retinal

+retinas

+retinue

+retinues

+retire

+retired

+retiredly

+retiredness

+retirement

+retirement's

+retirements

+retires

+retiring

+retiringly

+retiringness

+retitled

+retold

+retort

+retorted

+retorting

+retorts

+retrace

+retraced

+retraces

+retracing

+retract

+retractable

+retracted

+retracting

+retraction

+retractions

+retractor

+retractor's

+retractors

+retracts

+retrain

+retrained

+retraining

+retrains

+retranslated

+retransmission

+retransmission's

+retransmissions

+retransmit

+retransmits

+retransmitted

+retransmitting

+retreat

+retreated

+retreater

+retreating

+retreats

+retried

+retrier

+retriers

+retries

+retrievable

+retrieval

+retrieval's

+retrievals

+retrieve

+retrieved

+retriever

+retrievers

+retrieves

+retrieving

+retroactively

+retrospect

+retrospection

+retrospective

+retrospectively

+retry

+retrying

+return

+returnable

+returned

+returner

+returners

+returning

+returns

+retype

+retyped

+retypes

+retyping

+reunion

+reunion's

+reunions

+reunite

+reunited

+reuniting

+reupholstering

+reusable

+reuse

+reused

+reuses

+reusing

+revalidated

+revalidates

+revalidation

+revalued

+revalues

+revamp

+revamped

+revamping

+revamps

+reveal

+revealed

+revealer

+revealing

+reveals

+revel

+revelation

+revelation's

+revelations

+revelry

+revels

+revenge

+revenge's

+revenged

+revenger

+revenges

+revenging

+revenue

+revenuer

+revenuers

+revenues

+revere

+revered

+reverence

+reverencer

+reverend

+reverend's

+reverends

+reverently

+reveres

+reverified

+reverifies

+reverify

+reverifying

+revering

+reversal

+reversal's

+reversals

+reverse

+reversed

+reversely

+reverser

+reverses

+reversible

+reversing

+reversion

+reversioner

+reversions

+revert

+reverted

+reverter

+reverting

+revertive

+reverts

+revetting

+review

+reviewed

+reviewer

+reviewers

+reviewing

+reviews

+revile

+reviled

+reviler

+reviling

+revise

+revised

+reviser

+revises

+revising

+revision

+revision's

+revisions

+revisit

+revisited

+revisiting

+revisits

+revival

+revival's

+revivals

+revive

+revived

+reviver

+revives

+reviving

+revocation

+revocations

+revoke

+revoked

+revoker

+revokes

+revoking

+revolt

+revolted

+revolter

+revolting

+revoltingly

+revolts

+revolution

+revolution's

+revolutionaries

+revolutionariness

+revolutionary

+revolutionary's

+revolutions

+revolve

+revolved

+revolver

+revolvers

+revolves

+revolving

+reward

+rewarded

+rewarder

+rewarding

+rewardingly

+rewards

+rewind

+rewinded

+rewinder

+rewinding

+rewinds

+rewired

+rewires

+reword

+reworded

+rewording

+rewording's

+rewordings

+rewords

+rework

+reworked

+reworking

+reworks

+rewound

+rewrite

+rewriter

+rewrites

+rewriting

+rewritings

+rewritten

+rewrote

+rhetoric

+rheumatism

+rhinoceros

+rhubarb

+rhyme

+rhymed

+rhymer

+rhymes

+rhyming

+rhythm

+rhythm's

+rhythmic

+rhythmical

+rhythmically

+rhythmics

+rhythms

+rib

+rib's

+ribbed

+ribbing

+ribbon

+ribbon's

+ribbons

+ribs

+rice

+ricer

+rices

+rich

+richen

+richened

+richening

+richer

+riches

+richest

+richly

+richness

+rickshaw

+rickshaw's

+rickshaws

+rid

+ridden

+riddle

+riddled

+riddler

+riddles

+riddling

+ride

+rider

+rider's

+riders

+rides

+ridge

+ridge's

+ridged

+ridges

+ridging

+ridicule

+ridiculed

+ridiculer

+ridicules

+ridiculing

+ridiculous

+ridiculously

+ridiculousness

+riding

+ridings

+rids

+rifle

+rifled

+rifleman

+rifler

+rifles

+rifling

+rift

+rig

+rig's

+rigged

+rigging

+right

+righted

+righten

+righteous

+righteously

+righteousness

+righter

+rightful

+rightfully

+rightfulness

+righting

+rightly

+rightmost

+rightness

+rights

+rightward

+rightwards

+rigid

+rigidities

+rigidity

+rigidly

+rigidness

+rigorous

+rigorously

+rigorousness

+rigs

+rill

+rim

+rim's

+rime

+rimer

+riming

+rims

+rind

+rind's

+rinded

+rinds

+ring

+ringed

+ringer

+ringers

+ringing

+ringingly

+ringings

+rings

+rinse

+rinsed

+rinser

+rinses

+rinsing

+riot

+rioted

+rioter

+rioters

+rioting

+riotous

+riotously

+riotousness

+riots

+rip

+ripe

+ripely

+ripen

+ripened

+ripener

+ripeness

+ripening

+ripens

+riper

+ripest

+ripped

+ripping

+ripple

+rippled

+rippler

+ripples

+rippling

+rips

+rise

+risen

+riser

+risers

+rises

+rising

+risings

+risk

+risked

+risker

+risking

+risks

+rite

+rite's

+rited

+rites

+ritual

+ritually

+rituals

+rival

+rivalries

+rivalry

+rivalry's

+rivals

+rive

+rived

+riven

+river

+river's

+rivers

+riverside

+rivet

+riveted

+riveter

+riveting

+rivets

+riving

+rivulet

+rivulet's

+rivulets

+road

+road's

+roads

+roadside

+roadsides

+roadster

+roadster's

+roadsters

+roadway

+roadway's

+roadways

+roam

+roamed

+roamer

+roaming

+roams

+roar

+roared

+roarer

+roaring

+roaringest

+roars

+roast

+roasted

+roaster

+roasting

+roasts

+rob

+robbed

+robber

+robber's

+robberies

+robbers

+robbery

+robbery's

+robbing

+robe

+robed

+robes

+robin

+robin's

+robing

+robins

+robot

+robot's

+robotic

+robotics

+robots

+robs

+robust

+robustly

+robustness

+rock

+rocked

+rocker

+rockers

+rocket

+rocket's

+rocketed

+rocketing

+rockets

+rockier

+rockies

+rockiness

+rocking

+rocks

+rocky

+rod

+rod's

+rode

+rods

+roe

+roes

+rogue

+rogue's

+rogues

+roguing

+role

+role's

+roles

+roll

+rolled

+roller

+rollers

+rolling

+rolls

+romance

+romanced

+romancer

+romancers

+romances

+romancing

+romantic

+romantic's

+romantically

+romantics

+romp

+romped

+romper

+rompers

+romping

+romps

+roof

+roofed

+roofer

+roofers

+roofing

+roofs

+rook

+rooks

+room

+roomed

+roomer

+roomers

+rooming

+rooms

+roost

+rooster

+roosters

+root

+root's

+rooted

+rootedness

+rooter

+rooting

+roots

+rope

+roped

+roper

+ropers

+ropes

+roping

+rose

+rose's

+rosebud

+rosebud's

+rosebuds

+roses

+rosier

+rosiness

+rosy

+rot

+rotary

+rotate

+rotated

+rotates

+rotating

+rotation

+rotational

+rotationally

+rotations

+rotative

+rotatively

+rotator

+rotator's

+rotators

+rots

+rotten

+rottenly

+rottenness

+rouge

+rough

+roughed

+roughen

+roughened

+roughening

+roughens

+rougher

+roughest

+roughly

+roughness

+rouging

+round

+roundabout

+roundaboutness

+rounded

+roundedness

+rounder

+rounders

+roundest

+rounding

+roundly

+roundness

+roundoff

+rounds

+roundup

+roundup's

+roundups

+rouse

+roused

+rouser

+rouses

+rousing

+rout

+route

+routed

+router

+routers

+routes

+routine

+routinely

+routines

+routing

+routings

+rove

+roved

+rover

+roves

+roving

+row

+rowed

+rowen

+rower

+rowers

+rowing

+rows

+royal

+royalist

+royalist's

+royalists

+royally

+royalties

+royalty

+royalty's

+rub

+rubbed

+rubber

+rubber's

+rubbers

+rubbing

+rubbish

+rubbishes

+rubble

+rubbled

+rubbling

+rubies

+rubout

+rubs

+ruby

+ruby's

+rudder

+rudder's

+rudders

+ruddier

+ruddiness

+ruddy

+rude

+rudely

+rudeness

+ruder

+rudest

+rudiment

+rudiment's

+rudimentariness

+rudimentary

+rudiments

+rue

+ruefully

+rues

+ruffian

+ruffianly

+ruffians

+ruffle

+ruffled

+ruffler

+ruffles

+ruffling

+rug

+rug's

+rugged

+ruggedly

+ruggedness

+rugs

+ruin

+ruination

+ruination's

+ruinations

+ruined

+ruiner

+ruing

+ruining

+ruinous

+ruinously

+ruinousness

+ruins

+rule

+ruled

+ruler

+rulers

+rules

+ruling

+rulings

+rum

+rumble

+rumbled

+rumbler

+rumbles

+rumbling

+rumen

+rumens

+rump

+rumple

+rumpled

+rumples

+rumplier

+rumpling

+rumply

+rumps

+run

+runaway

+runaways

+rung

+rung's

+rungs

+runnable

+runner

+runner's

+runners

+running

+runs

+runtime

+rupture

+ruptured

+ruptures

+rupturing

+rural

+rurally

+rush

+rushed

+rusher

+rushes

+rushing

+russet

+russeted

+russeting

+russets

+rust

+rusted

+rustic

+rusticate

+rusticated

+rusticates

+rusticating

+rustication

+rustier

+rustiness

+rusting

+rustle

+rustled

+rustler

+rustlers

+rustles

+rustling

+rusts

+rusty

+rut

+rut's

+ruthless

+ruthlessly

+ruthlessness

+ruts

+rye

+rye's

+sable

+sable's

+sables

+sabotage

+sabotaged

+sabotages

+sabotaging

+sack

+sacked

+sacker

+sacking

+sacks

+sacred

+sacredly

+sacredness

+sacrifice

+sacrificed

+sacrificer

+sacrificers

+sacrifices

+sacrificial

+sacrificially

+sacrificing

+sad

+sadden

+saddened

+saddening

+saddens

+sadder

+saddest

+saddle

+saddled

+saddler

+saddles

+saddling

+sadism

+sadist

+sadist's

+sadistic

+sadistically

+sadists

+sadly

+sadness

+safe

+safeguard

+safeguarded

+safeguarding

+safeguards

+safely

+safeness

+safer

+safes

+safest

+safetied

+safeties

+safety

+safetying

+sag

+sagacious

+sagaciously

+sagaciousness

+sagacity

+sage

+sagely

+sageness

+sages

+sags

+said

+sail

+sailed

+sailer

+sailing

+sailor

+sailorly

+sailors

+sails

+saint

+sainted

+saintliness

+saintly

+saints

+sake

+saker

+sakes

+salable

+salad

+salad's

+salads

+salaried

+salaries

+salary

+sale

+sale's

+sales

+salesman

+salesmen

+salespeople

+salespeople's

+salesperson

+salesperson's

+salient

+saliently

+saline

+saliva

+sallied

+sallies

+sallow

+sallowness

+sally

+sallying

+salmon

+salmons

+salon

+salon's

+salons

+saloon

+saloon's

+saloons

+salt

+salted

+salter

+salters

+saltier

+saltiest

+saltiness

+salting

+saltness

+salts

+salty

+salutariness

+salutary

+salutation

+salutation's

+salutations

+salute

+saluted

+saluter

+salutes

+saluting

+salvage

+salvaged

+salvager

+salvages

+salvaging

+salvation

+salve

+salver

+salves

+salving

+same

+sameness

+sample

+sample's

+sampled

+sampler

+samplers

+samples

+sampling

+samplings

+sanctification

+sanctified

+sanctifier

+sanctify

+sanction

+sanctioned

+sanctioning

+sanctions

+sanctities

+sanctity

+sanctuaries

+sanctuary

+sanctuary's

+sand

+sandal

+sandal's

+sandals

+sanded

+sander

+sanders

+sandier

+sandiness

+sanding

+sandpaper

+sands

+sandstone

+sandstones

+sandwich

+sandwiched

+sandwiches

+sandwiching

+sandy

+sane

+sanely

+saneness

+saner

+sanest

+sang

+sanguine

+sanguinely

+sanguineness

+sanitarium

+sanitariums

+sanitary

+sanitation

+sanity

+sank

+sap

+sap's

+sapling

+sapling's

+saplings

+sapphire

+saps

+sarcasm

+sarcasm's

+sarcasms

+sarcastic

+sash

+sashed

+sashes

+sat

+satchel

+satchel's

+satchels

+sate

+sated

+satellite

+satellite's

+satellites

+sates

+satin

+sating

+satire

+satire's

+satires

+satirist

+satirist's

+satirists

+satisfaction

+satisfaction's

+satisfactions

+satisfactorily

+satisfactoriness

+satisfactory

+satisfiability

+satisfiable

+satisfied

+satisfier

+satisfiers

+satisfies

+satisfy

+satisfying

+satisfyingly

+saturate

+saturated

+saturater

+saturates

+saturating

+saturation

+saturations

+satyr

+sauce

+saucepan

+saucepan's

+saucepans

+saucer

+saucers

+sauces

+saucier

+sauciness

+saucing

+saucy

+saunter

+sauntered

+saunterer

+sauntering

+saunters

+sausage

+sausage's

+sausages

+savage

+savaged

+savagely

+savageness

+savager

+savagers

+savages

+savaging

+save

+saved

+saver

+savers

+saves

+saving

+savings

+saw

+sawed

+sawer

+sawing

+sawmill

+sawmill's

+sawmills

+saws

+sawtooth

+say

+sayer

+sayers

+saying

+sayings

+says

+scabbard

+scabbard's

+scabbards

+scaffold

+scaffolding

+scaffoldings

+scaffolds

+scalable

+scalar

+scalar's

+scalars

+scald

+scalded

+scalding

+scalds

+scale

+scaled

+scaler

+scalers

+scales

+scalier

+scaliness

+scaling

+scalings

+scallop

+scalloped

+scalloper

+scalloping

+scallops

+scalp

+scalp's

+scalper

+scalping

+scalps

+scaly

+scam

+scam's

+scamper

+scampered

+scampering

+scampers

+scams

+scan

+scandal

+scandal's

+scandalous

+scandalously

+scandalousness

+scandals

+scanned

+scanner

+scanner's

+scanners

+scanning

+scans

+scant

+scantier

+scanties

+scantiest

+scantily

+scantiness

+scantly

+scantness

+scanty

+scar

+scar's

+scarce

+scarcely

+scarceness

+scarcer

+scarcest

+scarcity

+scare

+scared

+scarer

+scares

+scarf

+scarfs

+scarier

+scaring

+scarlet

+scars

+scary

+scatter

+scattered

+scatterer

+scattering

+scatteringly

+scatters

+scavenger

+scavenger's

+scavengers

+scenario

+scenario's

+scenarios

+scene

+scene's

+sceneries

+scenery

+scenes

+scenic

+scenics

+scent

+scented

+scents

+schedule

+schedule's

+scheduled

+scheduler

+scheduler's

+schedulers

+schedules

+scheduling

+schema

+schema's

+schemas

+schemata

+schematic

+schematically

+schematics

+scheme

+scheme's

+schemed

+schemer

+schemers

+schemes

+scheming

+schizophrenia

+scholar

+scholarly

+scholars

+scholarship

+scholarship's

+scholarships

+scholastic

+scholastically

+scholastics

+school

+schoolboy

+schoolboy's

+schoolboys

+schooled

+schooler

+schoolers

+schoolhouse

+schoolhouse's

+schoolhouses

+schooling

+schoolmaster

+schoolmaster's

+schoolmasters

+schoolroom

+schoolroom's

+schoolrooms

+schools

+schoolyard

+schoolyard's

+schoolyards

+schooner

+science

+science's

+sciences

+scientific

+scientifically

+scientist

+scientist's

+scientists

+scissor

+scissored

+scissoring

+scissors

+scoff

+scoffed

+scoffer

+scoffing

+scoffs

+scold

+scolded

+scolder

+scolding

+scolds

+scoop

+scooped

+scooper

+scooping

+scoops

+scope

+scoped

+scopes

+scoping

+scorch

+scorched

+scorcher

+scorches

+scorching

+scorchingly

+score

+score's

+scored

+scorer

+scorers

+scores

+scoring

+scorings

+scorn

+scorned

+scorner

+scornful

+scornfully

+scornfulness

+scorning

+scorns

+scorpion

+scorpion's

+scorpions

+scoundrel

+scoundrel's

+scoundrelly

+scoundrels

+scour

+scoured

+scourer

+scourge

+scourger

+scourging

+scouring

+scourings

+scours

+scout

+scouted

+scouter

+scouting

+scouts

+scow

+scowl

+scowled

+scowler

+scowling

+scowls

+scramble

+scrambled

+scrambler

+scrambles

+scrambling

+scrap

+scrap's

+scrape

+scraped

+scraper

+scrapers

+scrapes

+scraping

+scrapings

+scrapped

+scraps

+scratch

+scratched

+scratcher

+scratchers

+scratches

+scratching

+scrawl

+scrawled

+scrawler

+scrawling

+scrawls

+scream

+screamed

+screamer

+screamers

+screaming

+screamingly

+screams

+screech

+screeched

+screecher

+screeches

+screeching

+screen

+screened

+screener

+screening

+screenings

+screens

+screw

+screwed

+screwer

+screwing

+screws

+scribble

+scribbled

+scribbler

+scribbles

+scribbling

+scribe

+scriber

+scribes

+scribing

+script

+script's

+scripted

+scripting

+scripts

+scripture

+scriptures

+scroll

+scrolled

+scrolling

+scrolls

+scrooge

+scrooge's

+scrooges

+scrub

+scrubs

+scruple

+scrupled

+scruples

+scrupling

+scrupulous

+scrupulously

+scrupulousness

+scrutiny

+scuffle

+scuffled

+scuffles

+scuffling

+sculpt

+sculpted

+sculpting

+sculptor

+sculptor's

+sculptors

+sculpts

+sculpture

+sculptured

+sculptures

+sculpturing

+scum

+scum's

+scums

+scurried

+scurry

+scurrying

+scuttle

+scuttled

+scuttles

+scuttling

+scythe

+scythe's

+scythes

+scything

+sea

+seaboard

+seacoast

+seacoast's

+seacoasts

+seal

+sealed

+sealer

+sealing

+seals

+sealy

+seam

+seaman

+seamanly

+seamed

+seamen

+seamer

+seaming

+seams

+seaport

+seaport's

+seaports

+sear

+search

+searched

+searcher

+searcher's

+searchers

+searches

+searching

+searchingly

+searchings

+seared

+searing

+searingly

+sears

+seas

+seashore

+seashore's

+seashores

+seaside

+season

+season's

+seasonable

+seasonableness

+seasonably

+seasonal

+seasonally

+seasoned

+seasoner

+seasoners

+seasoning

+seasonings

+seasonly

+seasons

+seat

+seated

+seater

+seating

+seats

+seaward

+seawards

+seaweed

+seaweeds

+secede

+seceded

+seceder

+secedes

+seceding

+secluded

+secludedly

+secludedness

+seclusion

+second

+secondaries

+secondarily

+secondariness

+secondary

+seconded

+seconder

+seconders

+secondhand

+seconding

+secondly

+seconds

+secrecy

+secret

+secretarial

+secretaries

+secretary

+secretary's

+secrete

+secreted

+secretes

+secreting

+secretion

+secretions

+secretive

+secretively

+secretiveness

+secretly

+secrets

+sect

+sect's

+section

+sectional

+sectionally

+sectioned

+sectioning

+sections

+sector

+sector's

+sectored

+sectoring

+sectors

+sects

+secular

+secularly

+secure

+secured

+securely

+secureness

+securer

+secures

+securing

+securings

+securities

+security

+sedge

+sediment

+sediment's

+sediments

+seduce

+seduced

+seducer

+seducers

+seduces

+seducing

+seductive

+seductively

+seductiveness

+see

+seed

+seeded

+seeder

+seeders

+seeding

+seedings

+seedling

+seedling's

+seedlings

+seeds

+seeing

+seek

+seeker

+seekers

+seeking

+seekingly

+seeks

+seem

+seemed

+seeming

+seemingly

+seemlier

+seemliness

+seemly

+seems

+seen

+seep

+seeped

+seeping

+seeps

+seer

+seers

+sees

+seethe

+seethed

+seethes

+seething

+segment

+segmentation

+segmentation's

+segmentations

+segmented

+segmenting

+segments

+segregate

+segregated

+segregates

+segregating

+segregation

+segregative

+seismic

+seizable

+seize

+seized

+seizer

+seizers

+seizes

+seizin

+seizing

+seizings

+seizins

+seizor

+seizors

+seizure

+seizure's

+seizures

+seldom

+select

+selected

+selecting

+selection

+selection's

+selections

+selective

+selectively

+selectiveness

+selectivity

+selectness

+selector

+selector's

+selectors

+selects

+self

+selfish

+selfishly

+selfishness

+selfness

+selfsame

+selfsameness

+sell

+seller

+sellers

+selling

+sells

+selves

+semantic

+semantical

+semantically

+semanticist

+semanticist's

+semanticists

+semantics

+semaphore

+semaphore's

+semaphores

+semblance

+semester

+semester's

+semesters

+semiautomated

+semicolon

+semicolon's

+semicolons

+semiconductor

+semiconductor's

+semiconductors

+seminal

+seminally

+seminar

+seminar's

+seminaries

+seminars

+seminary

+seminary's

+semipermanent

+semipermanently

+senate

+senate's

+senates

+senator

+senator's

+senators

+send

+sender

+senders

+sending

+sends

+senior

+senior's

+seniority

+seniors

+sensation

+sensation's

+sensational

+sensationally

+sensations

+sense

+sensed

+senseless

+senselessly

+senselessness

+senses

+sensibilities

+sensibility

+sensible

+sensibleness

+sensibly

+sensing

+sensitive

+sensitively

+sensitiveness

+sensitives

+sensitivities

+sensitivity

+sensor

+sensor's

+sensors

+sensory

+sent

+sentence

+sentenced

+sentences

+sentencing

+sentential

+sententially

+sentiment

+sentiment's

+sentimental

+sentimentally

+sentiments

+sentinel

+sentinel's

+sentinels

+sentries

+sentry

+sentry's

+separable

+separableness

+separate

+separated

+separately

+separateness

+separates

+separating

+separation

+separations

+separative

+separator

+separator's

+separators

+sequel

+sequel's

+sequels

+sequence

+sequenced

+sequencer

+sequencers

+sequences

+sequencing

+sequencings

+sequential

+sequentiality

+sequentially

+sequester

+sequestered

+sequestering

+serendipitous

+serendipitously

+serendipity

+serene

+serenely

+sereneness

+serenity

+serf

+serf's

+serfs

+sergeant

+sergeant's

+sergeants

+serial

+serially

+serials

+series

+serious

+seriously

+seriousness

+sermon

+sermon's

+sermons

+serpent

+serpent's

+serpentine

+serpentinely

+serpents

+serum

+serum's

+serums

+servant

+servant's

+servants

+serve

+served

+server

+server's

+servers

+serves

+service

+serviceable

+serviceableness

+serviced

+servicer

+services

+servicing

+servile

+servilely

+servileness

+serving

+servings

+servitude

+session

+session's

+sessions

+set

+set's

+sets

+setter

+setter's

+setters

+setting

+settings

+settle

+settled

+settlement

+settlement's

+settlements

+settler

+settlers

+settles

+settling

+settlings

+setup

+setups

+seven

+sevens

+seventeen

+seventeens

+seventeenth

+seventh

+seventies

+seventieth

+seventy

+sever

+several

+severally

+severals

+severance

+severe

+severed

+severely

+severeness

+severer

+severest

+severing

+severities

+severity

+severity's

+severs

+sew

+sewed

+sewer

+sewers

+sewing

+sews

+sex

+sexed

+sexes

+sexism

+sexism's

+sexist

+sexist's

+sexists

+sexual

+sexuality

+sexually

+shabbier

+shabbiness

+shabby

+shack

+shacked

+shackle

+shackled

+shackler

+shackles

+shackling

+shacks

+shade

+shaded

+shader

+shades

+shadier

+shadiest

+shadily

+shadiness

+shading

+shadings

+shadow

+shadowed

+shadower

+shadowiness

+shadowing

+shadows

+shadowy

+shady

+shaft

+shaft's

+shafted

+shafting

+shafts

+shaggier

+shagginess

+shaggy

+shakable

+shakably

+shake

+shaken

+shaker

+shakers

+shakes

+shakier

+shakiness

+shaking

+shaky

+shale

+shales

+shall

+shallow

+shallower

+shallowly

+shallowness

+shallows

+sham

+sham's

+shambles

+shame

+shamed

+shameful

+shamefully

+shamefulness

+shameless

+shamelessly

+shamelessness

+shames

+shaming

+shams

+shan't

+shanties

+shanty

+shanty's

+shape

+shaped

+shapeless

+shapelessly

+shapelessness

+shapelier

+shapeliness

+shapely

+shaper

+shapers

+shapes

+shaping

+sharable

+share

+sharecropper

+sharecropper's

+sharecroppers

+shared

+shareholder

+shareholder's

+shareholders

+sharer

+sharers

+shares

+sharing

+shark

+shark's

+sharks

+sharp

+sharped

+sharpen

+sharpened

+sharpener

+sharpening

+sharpens

+sharper

+sharpest

+sharping

+sharply

+sharpness

+sharps

+shatter

+shattered

+shattering

+shatteringly

+shatters

+shave

+shaved

+shaven

+shaver

+shaves

+shaving

+shavings

+shawl

+shawl's

+shawls

+she

+she'd

+she'll

+she's

+sheaf

+shear

+sheared

+shearer

+shearers

+shearing

+shears

+sheath

+sheather

+sheathing

+sheaths

+sheaves

+shed

+sheds

+sheep

+sheer

+sheered

+sheerly

+sheerness

+sheet

+sheeted

+sheeter

+sheeting

+sheets

+shelf

+shelfs

+shell

+shell's

+shelled

+sheller

+shelling

+shells

+shelter

+sheltered

+shelterer

+sheltering

+shelters

+shelve

+shelved

+shelver

+shelves

+shelving

+shepherd

+shepherd's

+shepherded

+shepherding

+shepherds

+sheriff

+sheriff's

+sheriffs

+shied

+shield

+shielded

+shielder

+shielding

+shields

+shier

+shies

+shiest

+shift

+shifted

+shifter

+shifters

+shiftier

+shiftiest

+shiftily

+shiftiness

+shifting

+shifts

+shifty

+shilling

+shillings

+shimmer

+shimmered

+shimmering

+shin

+shine

+shined

+shiner

+shiners

+shines

+shingle

+shingle's

+shingled

+shingler

+shingles

+shingling

+shinier

+shininess

+shining

+shiningly

+shiny

+ship

+ship's

+shipboard

+shipboards

+shipbuilding

+shipment

+shipment's

+shipments

+shippable

+shipped

+shipper

+shipper's

+shippers

+shipping

+ships

+shipwreck

+shipwrecked

+shipwrecks

+shirk

+shirker

+shirking

+shirks

+shirt

+shirting

+shirts

+shit

+shiver

+shivered

+shiverer

+shivering

+shivers

+shoal

+shoal's

+shoals

+shock

+shocked

+shocker

+shockers

+shocking

+shockingly

+shocks

+shod

+shoe

+shoed

+shoeing

+shoemaker

+shoer

+shoes

+shone

+shook

+shoot

+shooter

+shooters

+shooting

+shootings

+shoots

+shop

+shop's

+shopkeeper

+shopkeeper's

+shopkeepers

+shopped

+shopper

+shopper's

+shoppers

+shopping

+shops

+shore

+shore's

+shored

+shores

+shoring

+shorn

+short

+shortage

+shortage's

+shortages

+shortcoming

+shortcoming's

+shortcomings

+shortcut

+shortcut's

+shortcuts

+shorted

+shorten

+shortened

+shortener

+shortening

+shortens

+shorter

+shortest

+shorthand

+shorthanded

+shorthands

+shorting

+shortly

+shortness

+shorts

+shot

+shot's

+shotgun

+shotgun's

+shotguns

+shots

+should

+shoulder

+shouldered

+shouldering

+shoulders

+shouldest

+shouldn't

+shout

+shouted

+shouter

+shouters

+shouting

+shouts

+shove

+shoved

+shovel

+shovels

+shover

+shoves

+shoving

+show

+showed

+shower

+showered

+showering

+showers

+showing

+showings

+shown

+shows

+shrank

+shred

+shred's

+shredder

+shredder's

+shredders

+shreds

+shrew

+shrew's

+shrewd

+shrewdest

+shrewdly

+shrewdness

+shrews

+shriek

+shrieked

+shrieking

+shrieks

+shrill

+shrilled

+shrilling

+shrillness

+shrilly

+shrimp

+shrine

+shrine's

+shrines

+shrink

+shrinkable

+shrinker

+shrinking

+shrinks

+shrivel

+shrivels

+shroud

+shrouded

+shrouding

+shrouds

+shrub

+shrub's

+shrubbery

+shrubs

+shrug

+shrugs

+shrunk

+shrunken

+shudder

+shuddered

+shuddering

+shudders

+shuffle

+shuffled

+shuffler

+shuffles

+shuffling

+shun

+shuns

+shut

+shutdown

+shutdown's

+shutdowns

+shuts

+shutter

+shuttered

+shuttering

+shutters

+shutting

+shuttle

+shuttled

+shuttles

+shuttling

+shy

+shying

+shyly

+shyness

+sibling

+sibling's

+siblings

+sick

+sicken

+sickened

+sickener

+sickening

+sickeningly

+sicker

+sickerly

+sickest

+sicking

+sickle

+sickled

+sicklied

+sickliness

+sickling

+sickly

+sicklying

+sickness

+sickness's

+sicknesses

+sicks

+side

+sideboard

+sideboard's

+sideboards

+sideburns

+sided

+sidedness

+sidelight

+sidelight's

+sidelights

+sides

+sidetrack

+sidetracked

+sidetracking

+sidetracks

+sidewalk

+sidewalk's

+sidewalks

+sideways

+sidewise

+siding

+sidings

+siege

+siege's

+sieges

+sieging

+sierra

+sierras

+sieve

+sieve's

+sievers

+sieves

+sieving

+sift

+sifted

+sifter

+sifting

+siftings

+sifts

+sigh

+sighed

+sigher

+sighing

+sighs

+sight

+sighted

+sighter

+sighting

+sightings

+sightliness

+sightly

+sights

+sign

+signal

+signally

+signals

+signature

+signature's

+signatures

+signed

+signer

+signers

+signet

+significance

+significances

+significant

+significantly

+significants

+signification

+signified

+signifier

+signifies

+signify

+signifying

+signing

+signs

+silence

+silenced

+silencer

+silencers

+silences

+silencing

+silent

+silently

+silentness

+silents

+silhouette

+silhouetted

+silhouettes

+silicon

+silicone

+silicons

+silk

+silken

+silkier

+silkiest

+silkily

+silkiness

+silks

+silky

+sill

+sill's

+sillier

+silliest

+silliness

+sills

+silly

+silt

+silted

+silting

+silts

+silver

+silvered

+silverer

+silveriness

+silvering

+silverly

+silvers

+silvery

+similar

+similarities

+similarity

+similarly

+similitude

+simmer

+simmered

+simmering

+simmers

+simple

+simpleness

+simpler

+simples

+simplest

+simplex

+simplexes

+simplicities

+simplicity

+simplicity's

+simplification

+simplifications

+simplified

+simplifier

+simplifiers

+simplifies

+simplify

+simplifying

+simplistic

+simply

+simulate

+simulated

+simulates

+simulating

+simulation

+simulations

+simulative

+simulator

+simulator's

+simulators

+simultaneity

+simultaneous

+simultaneously

+simultaneousness

+sin

+sin's

+since

+sincere

+sincerely

+sincereness

+sincerest

+sincerity

+sine

+sines

+sinew

+sinew's

+sinews

+sinful

+sinfully

+sinfulness

+sing

+singable

+singed

+singer

+singer's

+singers

+singing

+singingly

+single

+singled

+singleness

+singles

+singleton

+singleton's

+singletons

+singling

+singly

+sings

+singular

+singularities

+singularity

+singularity's

+singularly

+sining

+sinister

+sinisterly

+sinisterness

+sink

+sinked

+sinker

+sinkers

+sinkhole

+sinkholes

+sinking

+sinks

+sinned

+sinner

+sinner's

+sinners

+sinning

+sins

+sinusoidal

+sinusoidally

+sinusoids

+sip

+sips

+sir

+sire

+sired

+siren

+sirens

+sires

+siring

+sirs

+sirup

+sister

+sister's

+sistered

+sistering

+sisterly

+sisters

+sit

+site

+site's

+sited

+sites

+siting

+sits

+sitter

+sitter's

+sitters

+sitting

+sittings

+situate

+situated

+situates

+situating

+situation

+situational

+situationally

+situations

+six

+sixes

+sixpence

+sixpences

+sixteen

+sixteens

+sixteenth

+sixth

+sixthly

+sixties

+sixtieth

+sixty

+sizable

+sizableness

+size

+sized

+sizer

+sizers

+sizes

+sizing

+sizings

+skate

+skated

+skater

+skater's

+skaters

+skates

+skating

+skeletal

+skeletally

+skeleton

+skeleton's

+skeletons

+skeptic

+skeptic's

+skeptical

+skeptically

+skeptics

+sketch

+sketched

+sketcher

+sketches

+sketchier

+sketchily

+sketchiness

+sketching

+sketchy

+skew

+skewed

+skewer

+skewered

+skewering

+skewers

+skewing

+skewness

+skews

+ski

+skied

+skien

+skier

+skies

+skiing

+skill

+skilled

+skillful

+skillfully

+skillfulness

+skilling

+skills

+skim

+skim's

+skimmed

+skimmer

+skimmer's

+skimmers

+skimming

+skimmings

+skimp

+skimped

+skimping

+skimps

+skims

+skin

+skin's

+skinned

+skinner

+skinner's

+skinners

+skinning

+skins

+skip

+skipped

+skipper

+skipper's

+skippered

+skippering

+skippers

+skipping

+skips

+skirmish

+skirmished

+skirmisher

+skirmishers

+skirmishes

+skirmishing

+skirt

+skirted

+skirter

+skirting

+skirts

+skis

+skulk

+skulked

+skulker

+skulking

+skulks

+skull

+skull's

+skulled

+skulls

+skunk

+skunk's

+skunks

+sky

+sky's

+skying

+skylark

+skylarker

+skylarking

+skylarks

+skylight

+skylight's

+skylights

+skyscraper

+skyscraper's

+skyscrapers

+slab

+slabs

+slack

+slacked

+slacken

+slackened

+slackening

+slackens

+slacker

+slackest

+slacking

+slackly

+slackness

+slacks

+slain

+slam

+slammed

+slamming

+slams

+slander

+slandered

+slanderer

+slandering

+slanders

+slang

+slanging

+slant

+slanted

+slanting

+slantingly

+slants

+slap

+slapped

+slapping

+slaps

+slash

+slashed

+slasher

+slashes

+slashing

+slashingly

+slat

+slat's

+slate

+slated

+slater

+slaters

+slates

+slating

+slats

+slaughter

+slaughtered

+slaughterer

+slaughtering

+slaughters

+slave

+slaved

+slaver

+slavered

+slavering

+slavery

+slaves

+slaving

+slay

+slayer

+slayers

+slaying

+slays

+sled

+sled's

+sledge

+sledge's

+sledges

+sledging

+sleds

+sleek

+sleekly

+sleekness

+sleep

+sleeper

+sleepers

+sleepier

+sleepily

+sleepiness

+sleeping

+sleepless

+sleeplessly

+sleeplessness

+sleeps

+sleepy

+sleet

+sleeve

+sleeve's

+sleeved

+sleeves

+sleeving

+sleigh

+sleighs

+sleken

+slekened

+slekening

+slender

+slenderer

+slenderly

+slenderness

+slept

+slew

+slewed

+slewing

+slice

+sliced

+slicer

+slicers

+slices

+slicing

+slick

+slicker

+slickers

+slickly

+slickness

+slicks

+slid

+slide

+slider

+sliders

+slides

+sliding

+slier

+sliest

+slight

+slighted

+slighter

+slightest

+slighting

+slightingly

+slightly

+slightness

+slights

+slim

+slime

+slimed

+slimes

+slimier

+sliminess

+sliming

+slimly

+slimness

+slimy

+sling

+slinger

+slinging

+slings

+slip

+slip's

+slippage

+slipped

+slipper

+slipper's

+slipperier

+slipperiness

+slippers

+slippery

+slipping

+slips

+slit

+slit's

+slits

+slogan

+slogan's

+slogans

+slop

+slope

+sloped

+sloper

+slopers

+slopes

+sloping

+slopped

+sloppier

+sloppiness

+slopping

+sloppy

+slops

+slot

+slot's

+sloth

+sloths

+slots

+slotted

+slouch

+slouched

+sloucher

+slouches

+slouching

+slow

+slowed

+slower

+slowest

+slowing

+slowly

+slowness

+slows

+slug

+sluggish

+sluggishly

+sluggishness

+slugs

+slum

+slum's

+slumber

+slumber's

+slumbered

+slumberer

+slumbering

+slumbers

+slump

+slumped

+slumps

+slums

+slung

+slur

+slur's

+slurs

+sly

+slyly

+smack

+smacked

+smacker

+smacking

+smacks

+small

+smaller

+smallest

+smallness

+smallpox

+smart

+smarted

+smarten

+smartened

+smartening

+smarter

+smartest

+smarting

+smartly

+smartness

+smarts

+smash

+smashed

+smasher

+smashers

+smashes

+smashing

+smashingly

+smear

+smeared

+smearer

+smearing

+smears

+smell

+smelled

+smeller

+smellier

+smelling

+smells

+smelly

+smelt

+smelter

+smelts

+smile

+smiled

+smiler

+smiles

+smiling

+smilingly

+smite

+smiter

+smith

+smith's

+smithies

+smiths

+smithy

+smiting

+smitten

+smock

+smocking

+smocks

+smog

+smokable

+smoke

+smoked

+smoker

+smoker's

+smokers

+smokes

+smokier

+smokies

+smokiness

+smoking

+smoky

+smolder

+smoldered

+smoldering

+smolderingly

+smolders

+smooth

+smoothed

+smoothen

+smoothened

+smoothening

+smoother

+smoothers

+smoothes

+smoothest

+smoothing

+smoothly

+smoothness

+smote

+smother

+smothered

+smothering

+smothers

+smug

+smuggle

+smuggled

+smuggler

+smugglers

+smuggles

+smuggling

+smugly

+smugness

+snail

+snail's

+snails

+snake

+snaked

+snakes

+snaking

+snap

+snapped

+snapper

+snapper's

+snappers

+snappier

+snappiest

+snappily

+snappiness

+snapping

+snappy

+snaps

+snapshot

+snapshot's

+snapshots

+snare

+snared

+snarer

+snares

+snarf

+snarfed

+snarfing

+snarfings

+snarfs

+snaring

+snarl

+snarled

+snarler

+snarling

+snarls

+snatch

+snatched

+snatcher

+snatches

+snatching

+sneak

+sneaked

+sneaker

+sneakered

+sneakers

+sneakier

+sneakiest

+sneakily

+sneakiness

+sneaking

+sneakingly

+sneaks

+sneaky

+sneer

+sneered

+sneerer

+sneering

+sneers

+sneeze

+sneezed

+sneezer

+sneezes

+sneezing

+sniff

+sniffed

+sniffer

+sniffing

+sniffs

+snoop

+snooped

+snooper

+snooping

+snoops

+snore

+snored

+snorer

+snores

+snoring

+snort

+snorted

+snorter

+snorting

+snorts

+snout

+snout's

+snouted

+snouts

+snow

+snowed

+snowier

+snowiest

+snowily

+snowiness

+snowing

+snowman

+snowmen

+snows

+snowshoe

+snowshoe's

+snowshoed

+snowshoer

+snowshoes

+snowy

+snuff

+snuffed

+snuffer

+snuffing

+snuffs

+snug

+snuggle

+snuggled

+snuggles

+snuggling

+snugly

+snugness

+snugs

+so

+soak

+soaked

+soaker

+soaking

+soaks

+soap

+soaped

+soaping

+soaps

+soar

+soared

+soarer

+soaring

+soars

+sob

+sober

+sobered

+soberer

+soberest

+sobering

+soberly

+soberness

+sobers

+sobs

+soccer

+sociability

+sociable

+sociably

+social

+socialism

+socialist

+socialist's

+socialists

+socially

+societal

+societally

+societies

+society

+society's

+sociological

+sociologically

+sociology

+sock

+socked

+socket

+socket's

+sockets

+socking

+socks

+sod

+sod's

+soda

+sodium

+sodomy

+sods

+sofa

+sofa's

+sofas

+soft

+soften

+softened

+softener

+softening

+softens

+softer

+softest

+softly

+softness

+software

+software's

+softwares

+soil

+soiled

+soiling

+soils

+sojourn

+sojourner

+sojourners

+solace

+solaced

+solacer

+solacing

+solar

+sold

+solder

+soldered

+solderer

+soldering

+solders

+soldier

+soldiered

+soldiering

+soldierly

+soldiers

+sole

+soled

+solely

+solemn

+solemnity

+solemnly

+solemnness

+soleness

+soles

+solicit

+solicited

+soliciting

+solicitor

+solicitors

+solicits

+solid

+solidification

+solidified

+solidifies

+solidify

+solidifying

+solidity

+solidly

+solidness

+solids

+soling

+solingen

+solitaire

+solitariness

+solitary

+solitude

+solitude's

+solitudes

+solo

+solo's

+soloed

+soloing

+solos

+solubility

+soluble

+solution

+solution's

+solutions

+solvable

+solve

+solved

+solvent

+solvent's

+solvently

+solvents

+solver

+solvers

+solves

+solving

+somber

+somberly

+somberness

+some

+somebody

+somebody's

+someday

+somehow

+someone

+someone's

+someplace

+someplace's

+somers

+something

+sometime

+sometimes

+somewhat

+somewhere

+somewheres

+son

+son's

+sonar

+sonars

+song

+song's

+songs

+sonly

+sonnet

+sonnet's

+sonnets

+sons

+soon

+sooner

+soonest

+soot

+sooth

+soothe

+soothed

+soother

+soothes

+soothing

+soothingly

+soothingness

+soothly

+sophisticated

+sophisticatedly

+sophistication

+sophomore

+sophomore's

+sophomores

+sorcerer

+sorcerer's

+sorcerers

+sorcery

+sordid

+sordidly

+sordidness

+sore

+sorely

+soreness

+sorer

+sores

+sorest

+sorrier

+sorriest

+sorriness

+sorrow

+sorrow's

+sorrower

+sorrowful

+sorrowfully

+sorrowfulness

+sorrows

+sorry

+sort

+sorted

+sorter

+sorters

+sorting

+sorts

+sos

+sought

+soul

+soul's

+souled

+souls

+sound

+sounded

+sounder

+soundest

+sounding

+sounding's

+soundingly

+soundings

+soundly

+soundness

+sounds

+soup

+soup's

+soups

+sour

+source

+source's

+sources

+soured

+sourer

+sourest

+souring

+sourly

+sourness

+sours

+south

+souther

+southerly

+southern

+southerner

+southerners

+southernly

+southernness

+southing

+sovereign

+sovereign's

+sovereignly

+sovereigns

+soviet

+soviet's

+soviets

+space

+spaced

+spacer

+spacers

+spaces

+spaceship

+spaceship's

+spaceships

+spacing

+spacings

+spade

+spaded

+spader

+spades

+spading

+spaghetti

+span

+span's

+spank

+spanked

+spanker

+spanking

+spanks

+spanned

+spanner

+spanner's

+spanners

+spanning

+spans

+spare

+spared

+sparely

+spareness

+sparer

+spares

+sparest

+sparing

+sparingly

+spark

+sparked

+sparker

+sparking

+sparks

+sparrow

+sparrow's

+sparrows

+sparse

+sparsely

+sparseness

+sparser

+sparsest

+spat

+spate

+spate's

+spates

+spatial

+spatially

+spats

+spatter

+spattered

+spawn

+spawned

+spawner

+spawning

+spawns

+speak

+speakable

+speaker

+speaker's

+speakers

+speaking

+speaks

+spear

+speared

+spearer

+spearing

+spears

+special

+specialist

+specialist's

+specialists

+specially

+specialness

+specials

+species

+specifiable

+specific

+specifically

+specification

+specifications

+specificities

+specificity

+specifics

+specified

+specifier

+specifiers

+specifies

+specify

+specifying

+specimen

+specimen's

+specimens

+speck

+speck's

+speckle

+speckled

+speckles

+speckling

+specks

+spectacle

+spectacled

+spectacles

+spectacular

+spectacularly

+spectator

+spectator's

+spectators

+spectra

+spectrogram

+spectrogram's

+spectrograms

+spectroscopically

+spectrum

+spectrums

+speculate

+speculated

+speculates

+speculating

+speculation

+speculations

+speculative

+speculatively

+speculator

+speculator's

+speculators

+sped

+speech

+speech's

+speeches

+speechless

+speechlessly

+speechlessness

+speed

+speeded

+speeder

+speeders

+speedier

+speedily

+speediness

+speeding

+speeds

+speedup

+speedup's

+speedups

+speedy

+spell

+spelled

+speller

+spellers

+spelling

+spellings

+spells

+spend

+spender

+spenders

+spending

+spends

+spent

+sphere

+sphere's

+spheres

+spherical

+spherically

+sphering

+spice

+spiced

+spices

+spicier

+spiciness

+spicing

+spicy

+spider

+spider's

+spiders

+spied

+spier

+spies

+spike

+spiked

+spiker

+spikes

+spiking

+spill

+spilled

+spiller

+spilling

+spills

+spin

+spinach

+spinal

+spinally

+spindle

+spindled

+spindler

+spindles

+spindling

+spine

+spines

+spinner

+spinner's

+spinners

+spinning

+spins

+spiral

+spirally

+spirals

+spire

+spire's

+spired

+spires

+spiring

+spirit

+spirited

+spiritedly

+spiritedness

+spiriting

+spirits

+spiritual

+spiritually

+spiritualness

+spirituals

+spit

+spite

+spited

+spiteful

+spitefully

+spitefulness

+spites

+spiting

+spits

+spitting

+splash

+splashed

+splasher

+splashers

+splashes

+splashing

+spleen

+splendid

+splendidly

+splendidness

+splice

+spliced

+splicer

+splicers

+splices

+splicing

+splicings

+spline

+spline's

+splined

+splines

+splinter

+splintered

+splintering

+splinters

+split

+split's

+splits

+splitter

+splitter's

+splitters

+splitting

+splittings

+spoil

+spoiled

+spoiler

+spoilers

+spoiling

+spoils

+spoke

+spoked

+spoken

+spokes

+spokesman

+spokesmen

+spoking

+sponge

+sponged

+sponger

+spongers

+sponges

+sponging

+sponsor

+sponsored

+sponsoring

+sponsors

+sponsorship

+spontaneous

+spontaneously

+spontaneousness

+spook

+spookier

+spookiness

+spooky

+spool

+spooled

+spooler

+spoolers

+spooling

+spools

+spoon

+spooned

+spooning

+spoons

+spore

+spore's

+spored

+spores

+sporing

+sport

+sported

+sporting

+sportingly

+sportive

+sportively

+sportiveness

+sports

+sportsman

+sportsmanly

+spot

+spot's

+spotless

+spotlessly

+spotlessness

+spotlight

+spotlight's

+spotlighted

+spotlighting

+spotlights

+spots

+spotted

+spotter

+spotter's

+spotters

+spotting

+spouse

+spouse's

+spouses

+spousing

+spout

+spouted

+spouter

+spouting

+spouts

+sprang

+sprawl

+sprawled

+sprawling

+sprawls

+spray

+sprayed

+sprayer

+spraying

+sprays

+spread

+spreader

+spreaders

+spreading

+spreadings

+spreads

+spreadsheet

+spreadsheets

+spree

+spree's

+sprees

+sprig

+sprightlier

+sprightliness

+sprightly

+spring

+springer

+springers

+springier

+springiest

+springiness

+springing

+springs

+springtime

+springy

+sprinkle

+sprinkled

+sprinkler

+sprinklered

+sprinkles

+sprinkling

+sprint

+sprinted

+sprinter

+sprinters

+sprinting

+sprints

+sprite

+sprout

+sprouted

+sprouting

+sprouts

+spruce

+spruced

+sprucely

+spruceness

+sprucer

+sprucest

+sprucing

+sprung

+spun

+spur

+spur's

+spurious

+spuriously

+spuriousness

+spurn

+spurned

+spurner

+spurning

+spurns

+spurs

+spurt

+spurted

+spurting

+spurts

+sputter

+sputtered

+sputterer

+spy

+spying

+squabble

+squabbled

+squabbler

+squabbles

+squabbling

+squad

+squad's

+squadron

+squadron's

+squadrons

+squads

+squall

+squall's

+squaller

+squalls

+square

+squared

+squarely

+squareness

+squarer

+squares

+squarest

+squaring

+squash

+squashed

+squasher

+squashes

+squashing

+squat

+squatly

+squatness

+squats

+squawk

+squawked

+squawker

+squawking

+squawks

+squeak

+squeaked

+squeaker

+squeaking

+squeaks

+squeal

+squealed

+squealer

+squealing

+squeals

+squeeze

+squeezed

+squeezer

+squeezes

+squeezing

+squid

+squids

+squint

+squinted

+squinter

+squinting

+squintingly

+squints

+squire

+squire's

+squires

+squiring

+squirm

+squirmed

+squirming

+squirms

+squirrel

+squirrelly

+squirrels

+stab

+stabbed

+stabbing

+stabilities

+stability

+stability's

+stable

+stabled

+stableness

+stabler

+stables

+stablest

+stabling

+stably

+stabs

+stack

+stack's

+stacked

+stacker

+stacking

+stacks

+staff

+staff's

+staffed

+staffer

+staffers

+staffing

+staffs

+stag

+stag's

+stage

+stagecoach

+staged

+stager

+stagers

+stages

+stagger

+staggered

+staggerer

+staggering

+staggeringly

+staggers

+staging

+stagnant

+stagnantly

+stags

+staid

+staidly

+staidness

+stain

+stained

+stainer

+staining

+stainless

+stainlessly

+stains

+stair

+stair's

+staircase

+staircase's

+staircases

+stairs

+stairway

+stairway's

+stairways

+stake

+staked

+stakes

+staking

+stale

+staled

+stalely

+staleness

+staler

+stales

+stalest

+staling

+stalk

+stalked

+stalker

+stalking

+stalks

+stall

+stalled

+stalling

+stallings

+stalls

+stalwart

+stalwartly

+stalwartness

+stamen

+stamen's

+stamens

+stamina

+stammer

+stammered

+stammerer

+stammering

+stammers

+stamp

+stamped

+stampede

+stampeded

+stampeder

+stampedes

+stampeding

+stamper

+stampers

+stamping

+stamps

+stance

+stance's

+stances

+stanch

+stancher

+stanchest

+stand

+standard

+standardly

+standards

+standby

+stander

+standing

+standings

+standpoint

+standpoint's

+standpoints

+stands

+standstill

+stanza

+stanza's

+stanzas

+staple

+stapled

+stapler

+staplers

+staples

+stapling

+star

+star's

+starboard

+starboarded

+starboarding

+starboards

+starch

+starched

+starches

+starching

+stare

+stared

+starer

+stares

+starfish

+staring

+stark

+starkest

+starkly

+starkness

+starlet

+starlet's

+starlets

+starlight

+starred

+starrier

+starring

+starry

+stars

+start

+started

+starter

+starters

+starting

+startle

+startled

+startles

+startling

+startlingly

+startlingness

+starts

+startup

+startup's

+startups

+starvation

+starve

+starved

+starver

+starves

+starving

+state

+state's

+stated

+statelier

+stateliness

+stately

+statement

+statement's

+statements

+stater

+states

+statesman

+statesman's

+statesmanly

+static

+statically

+statics

+stating

+station

+stationaries

+stationary

+stationed

+stationer

+stationing

+stations

+statistic

+statistic's

+statistical

+statistically

+statistician

+statistician's

+statisticians

+statistics

+stative

+statue

+statue's

+statued

+statues

+statuesque

+statuesquely

+statuesqueness

+stature

+status

+statuses

+statute

+statute's

+statutes

+statutorily

+statutoriness

+statutory

+staunch

+staunchest

+staunchly

+staunchness

+stave

+staved

+staves

+staving

+stay

+stayed

+stayer

+stayers

+staying

+stays

+stdio

+stead

+steadfast

+steadfastly

+steadfastness

+steadied

+steadier

+steadies

+steadiest

+steadily

+steadiness

+steading

+steady

+steadying

+steak

+steak's

+steaks

+steal

+stealer

+stealing

+steals

+stealth

+stealthier

+stealthily

+stealthiness

+stealthy

+steam

+steamboat

+steamboat's

+steamboats

+steamed

+steamer

+steamers

+steaming

+steams

+steamship

+steamship's

+steamships

+steed

+steeds

+steel

+steeled

+steelers

+steeling

+steels

+steep

+steeped

+steepen

+steepened

+steepening

+steeper

+steepest

+steeping

+steeple

+steeple's

+steeples

+steeply

+steepness

+steeps

+steer

+steered

+steerer

+steering

+steers

+stellar

+stem

+stem's

+stemmed

+stemming

+stems

+stench

+stench's

+stenches

+stencil

+stencil's

+stencils

+stenographer

+stenographer's

+stenographers

+step

+step's

+stepmother

+stepmother's

+stepmothers

+stepped

+stepper

+stepping

+steps

+stepwise

+stereo

+stereo's

+stereos

+stereotype

+stereotyped

+stereotyper

+stereotypers

+stereotypes

+stereotypical

+stereotypically

+stereotyping

+sterile

+sterling

+sterlingly

+sterlingness

+stern

+sternly

+sternness

+sterns

+stew

+steward

+steward's

+stewards

+stewed

+stewing

+stews

+stick

+sticked

+sticker

+stickers

+stickier

+stickiest

+stickily

+stickiness

+sticking

+sticks

+sticky

+stiff

+stiffen

+stiffened

+stiffener

+stiffeners

+stiffening

+stiffens

+stiffer

+stiffest

+stiffly

+stiffness

+stiffnesses

+stiffs

+stifle

+stifled

+stifler

+stifles

+stifling

+stiflingly

+stigma

+stigmas

+stile

+stile's

+stiles

+still

+stilled

+stiller

+stillest

+stilling

+stillness

+stills

+stimulant

+stimulant's

+stimulants

+stimulate

+stimulated

+stimulates

+stimulating

+stimulation

+stimulations

+stimulative

+stimuli

+stimulus

+sting

+stinger

+stinging

+stingingly

+stings

+stink

+stinker

+stinkers

+stinking

+stinkingly

+stinks

+stint

+stint's

+stinted

+stinter

+stinting

+stints

+stipend

+stipend's

+stipends

+stipple

+stippled

+stippler

+stipples

+stippling

+stipulate

+stipulated

+stipulates

+stipulating

+stipulation

+stipulations

+stir

+stirred

+stirrer

+stirrer's

+stirrers

+stirring

+stirringly

+stirrings

+stirrup

+stirrups

+stirs

+stitch

+stitched

+stitcher

+stitches

+stitching

+stochastic

+stochastically

+stock

+stockade

+stockade's

+stockaded

+stockades

+stockading

+stocked

+stocker

+stockers

+stockholder

+stockholder's

+stockholders

+stocking

+stockinged

+stockings

+stocks

+stole

+stole's

+stoled

+stolen

+stoles

+stomach

+stomached

+stomacher

+stomaches

+stomaching

+stone

+stone's

+stoned

+stoner

+stones

+stonier

+stoniness

+stoning

+stony

+stood

+stool

+stools

+stoop

+stooped

+stooping

+stoops

+stop

+stop's

+stopcock

+stopcocks

+stopgap

+stopgap's

+stopgaps

+stoppable

+stoppage

+stoppages

+stopped

+stopper

+stopper's

+stoppered

+stoppering

+stoppers

+stopping

+stops

+storage

+storage's

+storages

+store

+stored

+storehouse

+storehouse's

+storehouses

+stores

+storied

+stories

+storing

+stork

+stork's

+storks

+storm

+stormed

+stormier

+stormiest

+storminess

+storming

+storms

+stormy

+story

+story's

+storying

+stout

+stouten

+stoutened

+stoutening

+stouter

+stoutest

+stoutly

+stoutness

+stove

+stove's

+stover

+stoves

+stow

+stowed

+stowing

+stows

+straggle

+straggled

+straggler

+stragglers

+straggles

+straggling

+straight

+straighten

+straightened

+straightener

+straighteners

+straightening

+straightens

+straighter

+straightest

+straightforward

+straightforwardly

+straightforwardness

+straightforwards

+straightly

+straightness

+straightway

+strain

+strained

+strainer

+strainers

+straining

+strains

+strait

+straiten

+straitened

+straitening

+straitly

+straitness

+straits

+strand

+stranded

+strandedness

+strander

+stranding

+strands

+strange

+strangely

+strangeness

+stranger

+stranger's

+strangers

+strangest

+strangle

+strangled

+strangler

+stranglers

+strangles

+strangling

+stranglings

+strangulation

+strangulation's

+strangulations

+strap

+strap's

+straps

+stratagem

+stratagem's

+stratagems

+strategic

+strategics

+strategies

+strategy

+strategy's

+stratification

+stratifications

+stratified

+stratifies

+stratify

+stratifying

+stratum

+straw

+straw's

+strawberries

+strawberry

+strawberry's

+straws

+stray

+stray's

+strayed

+strayer

+straying

+strays

+streak

+streaked

+streaking

+streaks

+stream

+streamed

+streamer

+streamers

+streaming

+streamline

+streamlined

+streamliner

+streamlines

+streamlining

+streams

+street

+streetcar

+streetcar's

+streetcars

+streeters

+streets

+strength

+strengthen

+strengthened

+strengthener

+strengthening

+strengthens

+strengths

+strenuous

+strenuously

+strenuousness

+stress

+stressed

+stresses

+stressing

+stretch

+stretched

+stretcher

+stretchers

+stretches

+stretching

+strew

+strewing

+strewn

+strews

+strewth

+stricken

+strict

+stricter

+strictest

+strictly

+strictness

+stride

+strider

+strides

+striding

+strife

+strike

+striker

+strikers

+strikes

+striking

+strikingly

+string

+string's

+stringed

+stringent

+stringently

+stringer

+stringers

+stringier

+stringiest

+stringiness

+stringing

+strings

+stringy

+strip

+strip's

+stripe

+striped

+striper

+stripes

+striping

+stripped

+stripper

+stripper's

+strippers

+stripping

+strips

+strive

+striver

+strives

+striving

+strivings

+strobe

+strobe's

+strobed

+strobes

+strobing

+stroboscopic

+strode

+stroke

+stroked

+stroker

+strokers

+strokes

+stroking

+stroll

+strolled

+stroller

+strolling

+strolls

+strong

+stronger

+strongest

+stronghold

+strongly

+strove

+struck

+structural

+structurally

+structure

+structured

+structurer

+structures

+structuring

+struggle

+struggled

+struggler

+struggles

+struggling

+strung

+strut

+struts

+strutted

+strutter

+strutting

+stub

+stub's

+stubbed

+stubbing

+stubble

+stubborn

+stubbornly

+stubbornness

+stubs

+stuck

+stud

+stud's

+student

+student's

+students

+studied

+studiedly

+studiedness

+studier

+studies

+studio

+studio's

+studios

+studious

+studiously

+studiousness

+studs

+study

+studying

+stuff

+stuffed

+stuffer

+stuffier

+stuffiest

+stuffiness

+stuffing

+stuffings

+stuffs

+stuffy

+stumble

+stumbled

+stumbler

+stumbles

+stumbling

+stumblingly

+stump

+stumped

+stumper

+stumping

+stumps

+stun

+stung

+stunning

+stunningly

+stuns

+stunt

+stunt's

+stunted

+stuntedness

+stunting

+stunts

+stupefy

+stupefying

+stupendous

+stupendously

+stupendousness

+stupid

+stupider

+stupidest

+stupidities

+stupidity

+stupidly

+stupidness

+stupor

+sturdier

+sturdiness

+sturdy

+style

+styled

+styler

+stylers

+styles

+styling

+stylish

+stylishly

+stylishness

+stylistic

+stylistically

+stylistics

+sub

+subatomic

+subclass

+subclass's

+subclasses

+subcommittee

+subcommittee's

+subcommittees

+subcomponent

+subcomponent's

+subcomponents

+subcomputation

+subcomputation's

+subcomputations

+subconscious

+subconsciously

+subconsciousness

+subculture

+subculture's

+subcultures

+subdivide

+subdivided

+subdivider

+subdivides

+subdividing

+subdivision

+subdivision's

+subdivisions

+subdue

+subdued

+subduedly

+subduer

+subdues

+subduing

+subexpression

+subexpression's

+subexpressions

+subfield

+subfield's

+subfields

+subfile

+subfile's

+subfiles

+subgoal

+subgoal's

+subgoals

+subgraph

+subgraphs

+subgroup

+subgroup's

+subgrouping

+subgroups

+subinterval

+subinterval's

+subintervals

+subject

+subject's

+subjected

+subjecting

+subjection

+subjective

+subjectively

+subjectiveness

+subjectivity

+subjects

+sublimation

+sublimations

+sublime

+sublimed

+sublimely

+sublimeness

+sublimer

+subliming

+sublist

+sublist's

+sublists

+submarine

+submarined

+submariner

+submariners

+submarines

+submarining

+submerge

+submerged

+submerges

+submerging

+submission

+submission's

+submissions

+submit

+submits

+submitted

+submitting

+submode

+submodes

+submodule

+submodule's

+submodules

+subnetwork

+subnetwork's

+subnetworks

+subordinate

+subordinated

+subordinately

+subordinateness

+subordinates

+subordinating

+subordination

+subordinative

+subproblem

+subproblem's

+subproblems

+subprocess

+subprocess's

+subprocesses

+subprogram

+subprogram's

+subprograms

+subproject

+subproof

+subproof's

+subproofs

+subrange

+subrange's

+subranges

+subroutine

+subroutine's

+subroutines

+subs

+subschema

+subschema's

+subschemas

+subscribe

+subscribed

+subscriber

+subscribers

+subscribes

+subscribing

+subscript

+subscripted

+subscripting

+subscription

+subscription's

+subscriptions

+subscripts

+subsection

+subsection's

+subsections

+subsegment

+subsegment's

+subsegments

+subsequence

+subsequence's

+subsequences

+subsequent

+subsequently

+subsequentness

+subset

+subset's

+subsets

+subside

+subsided

+subsides

+subsidiaries

+subsidiary

+subsidiary's

+subsidies

+subsiding

+subsidy

+subsidy's

+subsist

+subsisted

+subsistence

+subsisting

+subsists

+subspace

+subspace's

+subspaces

+substance

+substance's

+substances

+substantial

+substantially

+substantialness

+substantiate

+substantiated

+substantiates

+substantiating

+substantiation

+substantiations

+substantiative

+substantive

+substantively

+substantiveness

+substantivity

+substitutability

+substitutable

+substitute

+substituted

+substituter

+substitutes

+substituting

+substitution

+substitutions

+substitutive

+substitutively

+substrate

+substrate's

+substrates

+substring

+substrings

+substructure

+substructure's

+substructures

+subsume

+subsumed

+subsumes

+subsuming

+subsystem

+subsystem's

+subsystems

+subtask

+subtask's

+subtasks

+subterranean

+subterraneanly

+subtitle

+subtitle's

+subtitled

+subtitles

+subtitling

+subtle

+subtleness

+subtler

+subtlest

+subtleties

+subtlety

+subtly

+subtopic

+subtopic's

+subtopics

+subtract

+subtracted

+subtracter

+subtracter's

+subtracters

+subtracting

+subtraction

+subtractions

+subtractive

+subtracts

+subtrahend

+subtrahend's

+subtrahends

+subtree

+subtree's

+subtrees

+subunit

+subunit's

+subunits

+suburb

+suburb's

+suburban

+suburbs

+subversion

+subvert

+subverted

+subverter

+subverting

+subverts

+subway

+subway's

+subways

+succeed

+succeeded

+succeeder

+succeeding

+succeeds

+success

+successes

+successful

+successfully

+successfulness

+succession

+succession's

+successions

+successive

+successively

+successiveness

+successor

+successor's

+successors

+succinct

+succinctly

+succinctness

+succumb

+succumbed

+succumbing

+succumbs

+such

+suck

+sucked

+sucker

+suckered

+suckering

+suckers

+sucking

+suckle

+suckled

+suckles

+suckling

+sucks

+suction

+sudden

+suddenly

+suddenness

+suds

+sudser

+sudsing

+sue

+sued

+sueded

+sueding

+suer

+sues

+suffer

+sufferance

+suffered

+sufferer

+sufferers

+suffering

+sufferings

+suffers

+suffice

+sufficed

+sufficer

+suffices

+sufficiency

+sufficient

+sufficiently

+sufficing

+suffix

+suffixed

+suffixer

+suffixes

+suffixing

+suffocate

+suffocated

+suffocates

+suffocating

+suffocatingly

+suffocation

+suffocative

+suffrage

+sugar

+sugared

+sugaring

+sugarings

+sugars

+suggest

+suggested

+suggester

+suggestible

+suggesting

+suggestion

+suggestion's

+suggestions

+suggestive

+suggestively

+suggestiveness

+suggests

+suicidal

+suicidally

+suicide

+suicide's

+suicided

+suicides

+suiciding

+suing

+suit

+suit's

+suitability

+suitable

+suitableness

+suitably

+suitcase

+suitcase's

+suitcases

+suite

+suited

+suiters

+suites

+suiting

+suitor

+suitor's

+suitors

+suits

+sulk

+sulked

+sulkies

+sulkiness

+sulking

+sulks

+sulky

+sullen

+sullenly

+sullenness

+sulphate

+sulphates

+sulphur

+sulphured

+sulphuric

+sultan

+sultan's

+sultans

+sultrier

+sultriness

+sultry

+sum

+sum's

+sumer

+summand

+summand's

+summands

+summaries

+summary

+summary's

+summation

+summation's

+summations

+summed

+summer

+summer's

+summered

+summering

+summers

+summing

+summit

+summon

+summoned

+summoner

+summoners

+summoning

+summons

+summonses

+sumptuous

+sumptuously

+sumptuousness

+sums

+sun

+sun's

+sunbeam

+sunbeam's

+sunbeams

+sunburn

+sundown

+sundowner

+sundowners

+sundries

+sundry

+sung

+sunglass

+sunglasses

+sunk

+sunken

+sunlight

+sunlights

+sunned

+sunnier

+sunniness

+sunning

+sunny

+sunrise

+sunrises

+suns

+sunset

+sunsets

+sunshine

+sunshines

+sup

+super

+superb

+superbly

+superbness

+superclass

+superclass's

+supercomputer

+supercomputer's

+supercomputers

+supered

+superego

+superego's

+superegos

+superficial

+superficially

+superficialness

+superfluities

+superfluity

+superfluity's

+superfluous

+superfluously

+superfluousness

+superhuman

+superhumanly

+superhumanness

+superimpose

+superimposed

+superimposes

+superimposing

+supering

+superintend

+superintendent

+superintendent's

+superintendents

+superior

+superior's

+superiority

+superiorly

+superiors

+superlative

+superlatively

+superlativeness

+superlatives

+supermarket

+supermarket's

+supermarkets

+superpose

+superposed

+superposes

+superposing

+superscript

+superscripted

+superscripting

+superscripts

+supersede

+superseded

+superseder

+supersedes

+superseding

+superset

+superset's

+supersets

+superstition

+superstition's

+superstitions

+superstitious

+superstitiously

+superstitiousness

+supertitle

+supertitle's

+supertitled

+supertitles

+supertitling

+superuser

+superuser's

+superusers

+supervise

+supervised

+supervises

+supervising

+supervision

+supervisions

+supervisor

+supervisor's

+supervisors

+supervisory

+supper

+supper's

+suppers

+supplant

+supplanted

+supplanter

+supplanting

+supplants

+supple

+suppled

+supplely

+supplement

+supplemental

+supplementaries

+supplementary

+supplemented

+supplementer

+supplementing

+supplements

+suppleness

+suppler

+supplication

+supplied

+supplier

+supplier's

+suppliers

+supplies

+suppling

+supply

+supply's

+supplying

+support

+supportable

+supported

+supporter

+supporters

+supporting

+supportingly

+supportive

+supportively

+supports

+suppose

+supposed

+supposedly

+supposer

+supposes

+supposing

+supposition

+supposition's

+suppositions

+suppress

+suppressed

+suppresses

+suppressing

+suppression

+suppressions

+suppressive

+suppressiveness

+supremacy

+supreme

+supremely

+supremeness

+sure

+sured

+surely

+sureness

+surer

+surest

+sureties

+surety

+surf

+surface

+surfaced

+surfaceness

+surfacer

+surfacers

+surfaces

+surfacing

+surfer

+surfer's

+surfers

+surfing

+surge

+surged

+surgely

+surgeon

+surgeon's

+surgeons

+surgeries

+surgery

+surges

+surgical

+surgically

+surging

+surlier

+surliness

+surly

+surmise

+surmised

+surmiser

+surmises

+surmising

+surmount

+surmounted

+surmounting

+surmounts

+surname

+surname's

+surnamed

+surnames

+surpass

+surpassed

+surpasses

+surpassing

+surpassingly

+surplus

+surplus's

+surpluses

+surprise

+surprise's

+surprised

+surpriser

+surprises

+surprising

+surprisingly

+surrender

+surrendered

+surrenderer

+surrendering

+surrenders

+surrogate

+surrogate's

+surrogates

+surrogation

+surround

+surrounded

+surrounding

+surroundings

+surrounds

+survey

+surveyed

+surveying

+surveyor

+surveyor's

+surveyors

+surveys

+survival

+survivals

+survive

+survived

+surviver

+survives

+surviving

+survivor

+survivor's

+survivors

+susceptible

+suspect

+suspected

+suspecter

+suspecting

+suspects

+suspend

+suspended

+suspender

+suspender's

+suspenders

+suspending

+suspends

+suspense

+suspenses

+suspension

+suspensions

+suspensive

+suspensively

+suspicion

+suspicion's

+suspicioned

+suspicioning

+suspicions

+suspicious

+suspiciously

+suspiciousness

+sustain

+sustained

+sustainer

+sustaining

+sustains

+suture

+sutured

+sutures

+suturing

+swagger

+swaggered

+swaggering

+swain

+swain's

+swains

+swallow

+swallowed

+swallower

+swallowing

+swallows

+swam

+swamp

+swamped

+swamper

+swampier

+swampiness

+swamping

+swamps

+swampy

+swan

+swan's

+swans

+swap

+swapped

+swapper

+swapper's

+swappers

+swapping

+swaps

+swarm

+swarmed

+swarmer

+swarming

+swarms

+swarthier

+swarthiness

+swarthy

+swatted

+sway

+swayed

+swayer

+swaying

+sways

+swear

+swearer

+swearing

+swears

+sweat

+sweated

+sweater

+sweaters

+sweating

+sweats

+sweep

+sweeper

+sweepers

+sweeping

+sweepingly

+sweepingness

+sweepings

+sweeps

+sweet

+sweeten

+sweetened

+sweetener

+sweeteners

+sweetening

+sweetenings

+sweetens

+sweeter

+sweetest

+sweetheart

+sweetheart's

+sweethearts

+sweetie

+sweetie's

+sweeties

+sweeting

+sweetly

+sweetness

+sweets

+swell

+swelled

+swelling

+swellings

+swells

+swept

+swerve

+swerved

+swerves

+swerving

+swift

+swifter

+swiftest

+swiftly

+swiftness

+swim

+swimmer

+swimmer's

+swimmers

+swimming

+swimmingly

+swims

+swimsuit

+swimsuit's

+swimsuits

+swine

+swing

+swinger

+swingers

+swinging

+swingingly

+swings

+swipe

+swiped

+swipes

+swiping

+swirl

+swirled

+swirler

+swirling

+swirlingly

+swirls

+swish

+swished

+swisher

+switch

+switch's

+switchboard

+switchboard's

+switchboards

+switched

+switcher

+switchers

+switches

+switching

+switchings

+swollen

+swoon

+swooned

+swooner

+swooning

+swooningly

+swoons

+swoop

+swooped

+swooper

+swooping

+swoops

+sword

+sword's

+swords

+swore

+sworn

+swum

+swung

+sycamore

+syllabi

+syllable

+syllable's

+syllabled

+syllables

+syllabling

+syllabus

+syllogism

+syllogism's

+syllogisms

+symbiosis

+symbiotic

+symbol

+symbol's

+symbolic

+symbolic's

+symbolically

+symbolics

+symbolism

+symbolisms

+symbols

+symmetric

+symmetrical

+symmetrically

+symmetricalness

+symmetries

+symmetry

+symmetry's

+sympathetic

+sympathies

+sympathy

+sympathy's

+symphonies

+symphony

+symphony's

+symposium

+symposiums

+symptom

+symptom's

+symptomatic

+symptoms

+synapse

+synapse's

+synapsed

+synapses

+synapsing

+synchronous

+synchronously

+synchronousness

+synchrony

+syndicate

+syndicated

+syndicates

+syndicating

+syndication

+syndrome

+syndrome's

+syndromes

+synergism

+synergistic

+synonym

+synonym's

+synonymous

+synonymously

+synonyms

+synopses

+synopsis

+syntactic

+syntactical

+syntactically

+syntacticly

+syntactics

+syntax

+syntaxes

+syntheses

+synthesis

+synthetic

+synthetics

+syringe

+syringed

+syringes

+syringing

+syrup

+system

+system's

+systematic

+systematically

+systematicness

+systematics

+systems

+tab

+tabernacle

+tabernacle's

+tabernacled

+tabernacles

+tabernacling

+table

+tableau

+tableau's

+tableaus

+tablecloth

+tablecloths

+tabled

+tables

+tablespoon

+tablespoon's

+tablespoonful

+tablespoonful's

+tablespoonfuls

+tablespoons

+tablet

+tablet's

+tablets

+tabling

+taboo

+taboo's

+taboos

+tabs

+tabular

+tabularly

+tabulate

+tabulated

+tabulates

+tabulating

+tabulation

+tabulations

+tabulator

+tabulator's

+tabulators

+tachometer

+tachometer's

+tachometers

+tachometry

+tacit

+tacitly

+tacitness

+tack

+tacked

+tacker

+tacking

+tackle

+tackle's

+tackled

+tackler

+tackles

+tackling

+tacks

+tact

+tactics

+tactile

+tactilely

+tag

+tag's

+tagged

+tagging

+tags

+tail

+tailed

+tailer

+tailing

+tailings

+tailor

+tailored

+tailoring

+tailors

+tails

+taint

+tainted

+taints

+take

+taken

+taker

+takers

+takes

+taketh

+taking

+takings

+tale

+tale's

+talent

+talented

+talents

+taler

+tales

+talion

+talk

+talkative

+talkatively

+talkativeness

+talked

+talker

+talkers

+talkie

+talking

+talks

+tall

+taller

+tallest

+tallness

+tallow

+tame

+tamed

+tamely

+tameness

+tamer

+tames

+tamest

+taming

+tamper

+tampered

+tamperer

+tampering

+tampers

+tan

+tandem

+tang

+tanged

+tangent

+tangent's

+tangential

+tangentially

+tangents

+tangible

+tangibleness

+tangibly

+tangier

+tangle

+tangled

+tangles

+tangling

+tangly

+tangy

+tank

+tanked

+tanker

+tankers

+tanking

+tanks

+tanner

+tanner's

+tanners

+tans

+tantamount

+tantrum

+tantrum's

+tantrums

+tap

+tap's

+tape

+taped

+taper

+tapered

+taperer

+tapering

+tapers

+tapes

+tapestried

+tapestries

+tapestry

+tapestry's

+taping

+tapings

+tapped

+tapper

+tapper's

+tappers

+tapping

+taproot

+taproot's

+taproots

+taps

+tar

+tardier

+tardies

+tardiness

+tardy

+target

+targeted

+targeting

+targets

+tariff

+tariff's

+tariffs

+taring

+tarried

+tarries

+tarry

+tarrying

+tars

+tart

+tartly

+tartness

+tarts

+task

+tasked

+tasking

+tasks

+taste

+tasted

+tasteful

+tastefully

+tastefulness

+tasteless

+tastelessly

+tastelessness

+taster

+tasters

+tastes

+tasting

+tatter

+tattered

+tattoo

+tattooed

+tattooer

+tattoos

+tau

+taught

+taunt

+taunted

+taunter

+taunting

+tauntingly

+taunts

+taut

+tauten

+tautened

+tautening

+tautly

+tautness

+tautological

+tautologically

+tautologies

+tautology

+tautology's

+tavern

+tavern's

+taverner

+taverns

+tawnier

+tawnies

+tawniness

+tawny

+tax

+taxable

+taxation

+taxed

+taxer

+taxes

+taxi

+taxi's

+taxicab

+taxicab's

+taxicabs

+taxied

+taxiing

+taxing

+taxingly

+taxis

+taxonomic

+taxonomically

+taxonomy

+taxpayer

+taxpayer's

+taxpayers

+tea

+teach

+teachable

+teachableness

+teacher

+teacher's

+teachers

+teaches

+teaching

+teachings

+team

+team's

+teamed

+teaming

+teams

+tear

+tear's

+teared

+tearer

+tearful

+tearfully

+tearfulness

+tearing

+tears

+teas

+tease

+teased

+teaser

+teases

+teasing

+teasingly

+teaspoon

+teaspoon's

+teaspoonful

+teaspoonful's

+teaspoonfuls

+teaspoons

+technical

+technicalities

+technicality

+technicality's

+technically

+technicalness

+technician

+technician's

+technicians

+technique

+technique's

+techniques

+technological

+technologically

+technologies

+technologist

+technologist's

+technologists

+technology

+technology's

+tedious

+tediously

+tediousness

+tedium

+teem

+teemed

+teeming

+teemingly

+teemingness

+teems

+teen

+teenage

+teenaged

+teenager

+teenagers

+teener

+teens

+teeth

+teethe

+teethed

+teether

+teethes

+teething

+telecommunication

+telecommunications

+teleconference

+teleconference's

+teleconferenced

+teleconferences

+teleconferencing

+telegram

+telegram's

+telegrams

+telegraph

+telegraphed

+telegrapher

+telegraphers

+telegraphic

+telegraphing

+telegraphs

+teleological

+teleologically

+teleology

+telephone

+telephoned

+telephoner

+telephoners

+telephones

+telephonic

+telephoning

+telephony

+telescope

+telescoped

+telescopes

+telescoping

+teletype

+teletype's

+teletypes

+televise

+televised

+televises

+televising

+television

+televisions

+televisor

+televisor's

+televisors

+tell

+teller

+tellers

+telling

+tellingly

+tellings

+tells

+temper

+temperament

+temperamental

+temperamentally

+temperaments

+temperance

+temperate

+temperately

+temperateness

+temperature

+temperature's

+temperatures

+tempered

+temperer

+tempering

+tempers

+tempest

+tempests

+tempestuous

+tempestuously

+tempestuousness

+template

+template's

+templates

+temple

+temple's

+templed

+temples

+temporal

+temporally

+temporaries

+temporarily

+temporariness

+temporary

+tempt

+temptation

+temptation's

+temptations

+tempted

+tempter

+tempters

+tempting

+temptingly

+tempts

+ten

+ten's

+tenacious

+tenaciously

+tenaciousness

+tenant

+tenant's

+tenants

+tend

+tended

+tendencies

+tendency

+tender

+tendered

+tendering

+tenderly

+tenderness

+tenders

+tending

+tends

+tenement

+tenement's

+tenements

+tennis

+tenor

+tenor's

+tenors

+tens

+tense

+tensed

+tensely

+tenseness

+tenser

+tenses

+tensest

+tensing

+tension

+tensioned

+tensioner

+tensioning

+tensions

+tensive

+tensor

+tensor's

+tensors

+tent

+tentacle

+tentacled

+tentacles

+tentative

+tentatively

+tentativeness

+tented

+tenter

+tenth

+tenthes

+tenting

+tents

+tenure

+tenured

+tenures

+tequila

+tequila's

+term

+termcap

+termed

+termer

+terminal

+terminal's

+terminally

+terminals

+terminate

+terminated

+terminates

+terminating

+termination

+terminations

+terminative

+terminatively

+terminator

+terminator's

+terminators

+terming

+terminologies

+terminology

+terminus

+termly

+terms

+ternary

+terrace

+terraced

+terraces

+terracing

+terrain

+terrain's

+terrains

+terrestrial

+terrestrial's

+terrestrially

+terrestrials

+terrible

+terribleness

+terribly

+terrier

+terrier's

+terriers

+terrific

+terrificly

+terrified

+terrifies

+terrify

+terrifying

+terrifyingly

+territorial

+territorially

+territories

+territory

+territory's

+terror

+terror's

+terrorism

+terrorist

+terrorist's

+terroristic

+terrorists

+terrors

+tertiaries

+tertiary

+test

+test's

+testability

+testable

+testament

+testament's

+testaments

+tested

+tester

+tester's

+testers

+testicle

+testicle's

+testicles

+testified

+testifier

+testifiers

+testifies

+testify

+testifying

+testimonies

+testimony

+testimony's

+testing

+testings

+tests

+text

+text's

+textbook

+textbook's

+textbooks

+textile

+textile's

+textiles

+texts

+textual

+textually

+texture

+textured

+textures

+texturing

+than

+thank

+thanked

+thanker

+thankful

+thankfully

+thankfulness

+thanking

+thankless

+thanklessly

+thanklessness

+thanks

+thanksgiving

+thanksgiving's

+thanksgivings

+that

+that's

+thatch

+thatched

+thatcher

+thatches

+thatching

+thats

+thaw

+thawed

+thawing

+thaws

+the

+theatrical

+theatrically

+theatricals

+theft

+theft's

+thefts

+their

+their's

+theirs

+them

+thematic

+theme

+theme's

+themes

+themselves

+then

+thence

+thenceforth

+theologian

+theologian's

+theologians

+theological

+theologically

+theologies

+theology

+theorem

+theorem's

+theorems

+theoretic

+theoretical

+theoretically

+theoreticians

+theoretics

+theories

+theorist

+theorist's

+theorists

+theory

+theory's

+therapeutic

+therapeutics

+therapies

+therapist

+therapist's

+therapists

+therapy

+therapy's

+there

+there's

+thereabouts

+thereafter

+thereby

+therefore

+therein

+thereof

+thereon

+thereto

+thereupon

+therewith

+thermodynamic

+thermodynamics

+thermometer

+thermometer's

+thermometers

+thermostat

+thermostat's

+thermostated

+thermostats

+these

+theses

+thesis

+they

+they'd

+they'll

+they're

+they've

+thick

+thicken

+thickened

+thickener

+thickeners

+thickening

+thickens

+thicker

+thickest

+thicket

+thicket's

+thicketed

+thickets

+thickly

+thickness

+thicknesses

+thicks

+thief

+thieve

+thieves

+thieving

+thigh

+thighed

+thighs

+thimble

+thimble's

+thimbles

+thin

+thiner

+thinest

+thing

+thingamajig

+thingamajig's

+thingamajigs

+thingness

+things

+think

+thinkable

+thinkableness

+thinkably

+thinker

+thinkers

+thinking

+thinkingly

+thinkingness

+thinks

+thinly

+thinner

+thinners

+thinness

+thinnest

+thins

+third

+thirdly

+thirds

+thirst

+thirsted

+thirster

+thirstier

+thirstiness

+thirsts

+thirsty

+thirteen

+thirteens

+thirteenth

+thirties

+thirtieth

+thirty

+this

+thistle

+thong

+thonged

+thorn

+thorn's

+thornier

+thorniness

+thorns

+thorny

+thorough

+thoroughfare

+thoroughfare's

+thoroughfares

+thoroughly

+thoroughness

+those

+though

+thought

+thought's

+thoughtful

+thoughtfully

+thoughtfulness

+thoughtless

+thoughtlessly

+thoughtlessness

+thoughts

+thousand

+thousands

+thousandth

+thrash

+thrashed

+thrasher

+thrashes

+thrashing

+thread

+threaded

+threader

+threaders

+threading

+threads

+threat

+threaten

+threatened

+threatener

+threatening

+threateningly

+threatens

+threats

+three

+three's

+threes

+threescore

+threshold

+threshold's

+thresholded

+thresholding

+thresholds

+threw

+thrice

+thrift

+thriftier

+thriftiness

+thrifty

+thrill

+thrilled

+thriller

+thrillers

+thrilling

+thrillingly

+thrills

+thrive

+thrived

+thriver

+thrives

+thriving

+thrivingly

+throat

+throated

+throating

+throats

+throb

+throbbed

+throbbing

+throbs

+throne

+throne's

+thrones

+throng

+throng's

+thronging

+throngs

+throning

+throttle

+throttled

+throttler

+throttles

+throttling

+through

+throughly

+throughout

+throughput

+throw

+thrower

+throwing

+thrown

+throws

+thrush

+thrushes

+thrust

+thruster

+thrusters

+thrusting

+thrusts

+thud

+thuds

+thug

+thug's

+thugs

+thumb

+thumbed

+thumbing

+thumbs

+thump

+thumped

+thumper

+thumping

+thumps

+thunder

+thunderbolt

+thunderbolt's

+thunderbolts

+thundered

+thunderer

+thunderers

+thundering

+thunderingly

+thunders

+thunderstorm

+thunderstorm's

+thunderstorms

+thunderstruck

+thus

+thusly

+thwart

+thwarted

+thwarter

+thwarting

+thwartly

+thwarts

+thyself

+tick

+ticked

+ticker

+tickers

+ticket

+ticket's

+ticketed

+ticketing

+tickets

+ticking

+tickle

+tickled

+tickler

+tickles

+tickling

+ticklish

+ticklishly

+ticklishness

+ticks

+tidal

+tidally

+tide

+tided

+tides

+tidied

+tidier

+tidies

+tidiness

+tiding

+tidings

+tidy

+tidying

+tie

+tied

+tier

+tiered

+tiers

+ties

+tiger

+tiger's

+tigers

+tight

+tighten

+tightened

+tightener

+tighteners

+tightening

+tightenings

+tightens

+tighter

+tightest

+tightly

+tightness

+tights

+tilde

+tildes

+tile

+tiled

+tiler

+tiles

+tiling

+till

+tillable

+tilled

+tiller

+tillered

+tillering

+tillers

+tilling

+tills

+tilt

+tilted

+tilter

+tilters

+tilting

+tilts

+timber

+timbered

+timbering

+timbers

+time

+timed

+timeless

+timelessly

+timelessness

+timelier

+timeliness

+timely

+timeout

+timeouts

+timer

+timers

+times

+timeshare

+timeshared

+timeshares

+timesharing

+timetable

+timetable's

+timetabled

+timetables

+timetabling

+timid

+timidity

+timidly

+timidness

+timing

+timings

+tin

+tin's

+tinge

+tinged

+tinging

+tingle

+tingled

+tingles

+tingling

+tinglingly

+tinier

+tiniest

+tinily

+tininess

+tinker

+tinkered

+tinkerer

+tinkering

+tinkers

+tinkle

+tinkled

+tinkles

+tinkling

+tinned

+tinnier

+tinniest

+tinnily

+tinniness

+tinning

+tinny

+tins

+tint

+tinted

+tinter

+tinting

+tints

+tiny

+tip

+tip's

+tipped

+tipper

+tipper's

+tippers

+tipping

+tips

+tiptoe

+tiptoed

+tire

+tired

+tiredly

+tiredness

+tireless

+tirelessly

+tirelessness

+tires

+tiresome

+tiresomely

+tiresomeness

+tiring

+tissue

+tissue's

+tissued

+tissues

+tissuing

+tit

+tit's

+tithe

+tithe's

+tither

+tithes

+tithing

+title

+titled

+titles

+titling

+tits

+titter

+tittered

+tittering

+titters

+tizzies

+tizzy

+to

+toad

+toad's

+toads

+toast

+toasted

+toaster

+toasters

+toastier

+toasting

+toasts

+toasty

+tobacco

+today

+today's

+todays

+toe

+toe's

+toed

+toes

+together

+togetherness

+toggle

+toggled

+toggles

+toggling

+toil

+toiled

+toiler

+toilet

+toilet's

+toilets

+toiling

+toils

+token

+token's

+tokens

+told

+tolerability

+tolerable

+tolerably

+tolerance

+tolerances

+tolerant

+tolerantly

+tolerate

+tolerated

+tolerates

+tolerating

+toleration

+tolerative

+toll

+tolled

+tolling

+tolls

+tom

+tom's

+tomahawk

+tomahawk's

+tomahawks

+tomato

+tomatoes

+tomb

+tomb's

+tombs

+tomography

+tomorrow

+tomorrow's

+tomorrows

+toms

+ton

+ton's

+tone

+toned

+toner

+tones

+tongs

+tongue

+tongued

+tongues

+tonguing

+tonic

+tonic's

+tonics

+tonight

+toning

+tonnage

+tons

+tonsil

+too

+took

+tool

+tooled

+tooler

+toolers

+tooling

+toolkit

+toolkit's

+toolkits

+tools

+tooth

+toothbrush

+toothbrush's

+toothbrushes

+toothbrushing

+toothed

+toothing

+toothpick

+toothpick's

+toothpicks

+top

+toped

+toper

+topic

+topic's

+topical

+topically

+topics

+toping

+topmost

+topological

+topologically

+topologies

+topology

+topple

+toppled

+topples

+toppling

+tops

+torch

+torch's

+torches

+tore

+torment

+tormented

+tormenter

+tormenters

+tormenting

+torments

+torn

+tornado

+tornadoes

+tornados

+torpedo

+torpedoed

+torpedoes

+torpedoing

+torpedos

+torque

+torquer

+torquers

+torques

+torquing

+torrent

+torrent's

+torrents

+torrid

+torridly

+torridness

+tortoise

+tortoise's

+tortoises

+torture

+tortured

+torturer

+torturers

+tortures

+torturing

+torus

+torus's

+toruses

+toss

+tossed

+tosser

+tosses

+tossing

+total

+total's

+totalities

+totality

+totality's

+totally

+totals

+totter

+tottered

+tottering

+totteringly

+totters

+touch

+touchable

+touched

+toucher

+touches

+touchier

+touchiest

+touchily

+touchiness

+touching

+touchingly

+touchy

+tough

+toughen

+toughened

+toughening

+toughens

+tougher

+toughest

+toughly

+toughness

+tour

+toured

+tourer

+touring

+tourist

+tourist's

+tourists

+tournament

+tournament's

+tournaments

+tours

+tow

+toward

+towardliness

+towardly

+towards

+towed

+towel

+towel's

+towels

+tower

+towered

+towering

+toweringly

+towers

+towing

+town

+town's

+towner

+towns

+township

+township's

+townships

+tows

+toxicity

+toxin

+toxin's

+toxins

+toy

+toyed

+toyer

+toying

+toys

+trace

+traceable

+traceableness

+traced

+traceless

+tracelessly

+tracer

+tracers

+traces

+tracing

+tracings

+track

+tracked

+tracker

+trackers

+tracking

+tracks

+tract

+tract's

+tractability

+tractable

+tractive

+tractor

+tractor's

+tractors

+tracts

+trade

+traded

+trademark

+trademark's

+trademarks

+tradeoff

+tradeoffs

+trader

+traders

+trades

+tradesman

+trading

+tradition

+tradition's

+traditional

+traditionally

+traditions

+traffic

+traffic's

+trafficked

+trafficker

+trafficker's

+traffickers

+trafficking

+traffics

+tragedies

+tragedy

+tragedy's

+tragic

+tragically

+trail

+trailed

+trailer

+trailers

+trailing

+trailings

+trails

+train

+trained

+trainee

+trainee's

+trainees

+trainer

+trainers

+training

+trains

+trait

+trait's

+traitor

+traitor's

+traitors

+traits

+trajectories

+trajectory

+trajectory's

+tramp

+tramped

+tramper

+tramping

+trample

+trampled

+trampler

+tramples

+trampling

+tramps

+trance

+trance's

+trances

+trancing

+tranquil

+tranquility

+tranquillity

+tranquilly

+tranquilness

+transact

+transacted

+transacting

+transaction

+transaction's

+transactions

+transacts

+transceiver

+transceiver's

+transceivers

+transcend

+transcended

+transcendent

+transcendently

+transcending

+transcends

+transcontinental

+transcribe

+transcribed

+transcriber

+transcribers

+transcribes

+transcribing

+transcript

+transcript's

+transcription

+transcription's

+transcriptions

+transcripts

+transfer

+transfer's

+transferability

+transferable

+transferal

+transferal's

+transferals

+transfered

+transference

+transferral

+transferral's

+transferrals

+transferred

+transferrer

+transferrer's

+transferrers

+transferring

+transfers

+transfinite

+transform

+transformable

+transformation

+transformation's

+transformational

+transformations

+transformed

+transformer

+transformers

+transforming

+transforms

+transgress

+transgressed

+transgresses

+transgressing

+transgression

+transgression's

+transgressions

+transgressive

+transience

+transiency

+transient

+transiently

+transients

+transistor

+transistor's

+transistors

+transit

+transition

+transitional

+transitionally

+transitioned

+transitions

+transitive

+transitively

+transitiveness

+transitivity

+transitoriness

+transitory

+translatability

+translatable

+translate

+translated

+translates

+translating

+translation

+translational

+translations

+translative

+translator

+translator's

+translators

+translucent

+translucently

+transmission

+transmission's

+transmissions

+transmit

+transmits

+transmittal

+transmitted

+transmitter

+transmitter's

+transmitters

+transmitting

+transmogrification

+transmogrify

+transparencies

+transparency

+transparency's

+transparent

+transparently

+transparentness

+transpire

+transpired

+transpires

+transpiring

+transplant

+transplanted

+transplanter

+transplanting

+transplants

+transport

+transportability

+transportation

+transportations

+transported

+transporter

+transporters

+transporting

+transports

+transpose

+transposed

+transposes

+transposing

+transposition

+trap

+trap's

+trapezoid

+trapezoid's

+trapezoidal

+trapezoids

+trapped

+trapper

+trapper's

+trappers

+trapping

+trappings

+traps

+trash

+trashed

+trasher

+trashes

+trashing

+traumatic

+travail

+travails

+travel

+travels

+traversal

+traversal's

+traversals

+traverse

+traversed

+traverser

+traverses

+traversing

+travesties

+travesty

+travesty's

+tray

+tray's

+trays

+treacheries

+treacherous

+treacherously

+treacherousness

+treachery

+treachery's

+tread

+treaded

+treader

+treading

+treads

+treason

+treasure

+treasured

+treasurer

+treasures

+treasuries

+treasuring

+treasury

+treasury's

+treat

+treated

+treater

+treaters

+treaties

+treating

+treatise

+treatise's

+treatises

+treatment

+treatment's

+treatments

+treats

+treaty

+treaty's

+treble

+trebled

+trebles

+trebling

+tree

+tree's

+treed

+trees

+treetop

+treetop's

+treetops

+trek

+trek's

+treks

+tremble

+trembled

+trembler

+trembles

+trembling

+tremendous

+tremendously

+tremendousness

+tremor

+tremor's

+tremors

+trench

+trenched

+trencher

+trenchers

+trenches

+trend

+trending

+trends

+trespass

+trespassed

+trespasser

+trespassers

+trespasses

+tress

+tress's

+tressed

+tresses

+trial

+trial's

+trials

+triangle

+triangle's

+triangles

+triangular

+triangularly

+tribal

+tribally

+tribe

+tribe's

+tribes

+tribunal

+tribunal's

+tribunals

+tribune

+tribune's

+tribunes

+tributary

+tribute

+tribute's

+tributes

+tributing

+trichotomy

+trick

+tricked

+tricker

+trickier

+trickiest

+trickiness

+tricking

+trickle

+trickled

+trickles

+trickling

+tricks

+tricky

+tried

+trier

+triers

+tries

+trifle

+trifled

+trifler

+trifles

+trifling

+trigger

+triggered

+triggering

+triggers

+trigonometric

+trigonometry

+trihedral

+trill

+trilled

+triller

+trillion

+trillions

+trillionth

+trim

+trimer

+trimly

+trimmed

+trimmer

+trimmest

+trimming

+trimmings

+trimness

+trims

+trinket

+trinket's

+trinketed

+trinketer

+trinkets

+trip

+trip's

+triple

+tripled

+triples

+triplet

+triplet's

+triplets

+triplication

+tripling

+triply

+trips

+triumph

+triumphal

+triumphantly

+triumphed

+triumphing

+triumphs

+trivia

+trivial

+trivialities

+triviality

+trivially

+trod

+troff

+troff's

+troffer

+troll

+troll's

+trolley

+trolley's

+trolleyed

+trolleys

+trolls

+troop

+trooped

+trooper

+troopers

+trooping

+troops

+trophied

+trophies

+trophy

+trophy's

+trophying

+tropic

+tropic's

+tropical

+tropically

+tropics

+trot

+trots

+trouble

+troubled

+troublemaker

+troublemaker's

+troublemakers

+troubler

+troubles

+troubleshoot

+troubleshooted

+troubleshooter

+troubleshooters

+troubleshooting

+troubleshoots

+troublesome

+troublesomely

+troublesomeness

+troubling

+trough

+trouser

+trousered

+trousers

+trout

+trouts

+trowel

+trowel's

+trowels

+truant

+truant's

+truants

+truce

+trucing

+truck

+trucked

+trucker

+truckers

+trucking

+trucks

+trudge

+trudged

+trudger

+trudges

+trudging

+true

+trued

+trueness

+truer

+trues

+truest

+truing

+truism

+truism's

+truisms

+truly

+trump

+trumped

+trumpet

+trumpeted

+trumpeter

+trumpeting

+trumpets

+trumps

+truncate

+truncated

+truncates

+truncating

+truncation

+truncation's

+truncations

+trunk

+trunk's

+trunked

+trunks

+trust

+trusted

+trustee

+trustee's

+trusteed

+trustees

+truster

+trustful

+trustfully

+trustfulness

+trustier

+trusties

+trustiness

+trusting

+trustingly

+trusts

+trustworthiness

+trustworthy

+trusty

+truth

+truthful

+truthfully

+truthfulness

+truths

+try

+trying

+tryingly

+tty

+tty's

+ttys

+tub

+tub's

+tube

+tubed

+tuber

+tuberculosis

+tubers

+tubes

+tubing

+tubs

+tuck

+tucked

+tucker

+tuckered

+tuckering

+tucking

+tucks

+tuft

+tuft's

+tufted

+tufter

+tufts

+tug

+tugs

+tuition

+tuitions

+tulip

+tulip's

+tulips

+tumble

+tumbled

+tumbler

+tumblers

+tumbles

+tumbling

+tumult

+tumult's

+tumults

+tumultuous

+tumultuously

+tumultuousness

+tunable

+tunableness

+tune

+tuned

+tuner

+tuners

+tunes

+tunic

+tunic's

+tunics

+tuning

+tuning's

+tunings

+tunnel

+tunnels

+tuple

+tuple's

+tuples

+turban

+turban's

+turbaned

+turbans

+turbulence

+turbulence's

+turbulent

+turbulently

+turf

+turkey

+turkey's

+turkeys

+turmoil

+turmoil's

+turmoils

+turn

+turnable

+turned

+turner

+turners

+turning

+turnings

+turnip

+turnip's

+turnips

+turnkey

+turnkeys

+turnover

+turnovers

+turns

+turpentine

+turquoise

+turret

+turret's

+turreted

+turrets

+turtle

+turtle's

+turtles

+turtling

+tutor

+tutored

+tutorial

+tutorial's

+tutorials

+tutoring

+tutors

+twain

+twang

+twanging

+twas

+tweak

+tweaked

+tweaker

+tweaking

+tweaks

+tweed

+tweezer

+tweezers

+twelfth

+twelve

+twelves

+twenties

+twentieth

+twenty

+twice

+twig

+twig's

+twigs

+twilight

+twilight's

+twilights

+twill

+twilled

+twilling

+twin

+twin's

+twine

+twined

+twiner

+twines

+twining

+twinkle

+twinkled

+twinkler

+twinkles

+twinkling

+twins

+twirl

+twirled

+twirler

+twirling

+twirlingly

+twirls

+twist

+twisted

+twister

+twisters

+twisting

+twists

+twitch

+twitched

+twitcher

+twitching

+twitter

+twittered

+twitterer

+twittering

+two

+two's

+twofold

+twos

+tying

+type

+type's

+typed

+typedef

+typedefs

+typer

+types

+typewriter

+typewriter's

+typewriters

+typhoid

+typical

+typically

+typicalness

+typification

+typified

+typifies

+typify

+typifying

+typing

+typist

+typist's

+typists

+typographic

+typographical

+typographically

+typography

+typos

+tyranny

+tyrant

+tyrant's

+tyrants

+ubiquitous

+ubiquitously

+ubiquitousness

+ubiquity

+ugh

+uglier

+ugliest

+ugliness

+ugly

+ulcer

+ulcer's

+ulcered

+ulcering

+ulcers

+ultimate

+ultimately

+ultimateness

+umbrella

+umbrella's

+umbrellas

+umpire

+umpire's

+umpired

+umpires

+umpiring

+unabashed

+unabashedly

+unabated

+unabatedly

+unabbreviated

+unable

+unabridged

+unaccelerated

+unacceptability

+unacceptable

+unacceptably

+unaccessible

+unaccommodated

+unaccompanied

+unaccomplished

+unaccountably

+unaccounted

+unaccustomed

+unaccustomedly

+unachievable

+unachieved

+unacknowledged

+unacquainted

+unadaptable

+unadjustable

+unadjusted

+unadopted

+unadorned

+unadulterated

+unadulteratedly

+unadvised

+unadvisedly

+unaffected

+unaffectedly

+unaffectedness

+unaffectionate

+unaffectionately

+unafraid

+unaggregated

+unaided

+unalienability

+unalienable

+unaligned

+unallocated

+unalloyed

+unalterable

+unalterableness

+unalterably

+unaltered

+unambiguous

+unambiguously

+unambitious

+unanchored

+unanimous

+unanimously

+unannounced

+unanswerable

+unanswered

+unanticipated

+unanticipatedly

+unapologetically

+unappealing

+unappealingly

+unappreciated

+unapproachability

+unapproachable

+unappropriated

+unapt

+unaptly

+unaptness

+unarguable

+unarguably

+unarmed

+unarticulated

+unary

+unashamed

+unashamedly

+unasked

+unassailable

+unassailableness

+unassembled

+unassigned

+unassigns

+unassisted

+unassuming

+unassumingness

+unattached

+unattainability

+unattainable

+unattended

+unattenuated

+unattractive

+unattractively

+unattractiveness

+unattributed

+unauthentic

+unauthenticated

+unavailability

+unavailable

+unavailing

+unavailingly

+unavailingness

+unavoidable

+unavoidably

+unaware

+unawarely

+unawareness

+unawares

+unbacked

+unbalanced

+unbalancedness

+unbanned

+unbanning

+unbans

+unbarbered

+unbarred

+unbated

+unbearable

+unbearably

+unbeatable

+unbeatably

+unbeaten

+unbeautifully

+unbecoming

+unbecomingly

+unbecomingness

+unbelievable

+unbelievably

+unbelieving

+unbelievingly

+unbelted

+unbendable

+unbetrothed

+unbiased

+unbiasedness

+unbidden

+unblemished

+unblinded

+unblinking

+unblinkingly

+unblock

+unblocked

+unblocking

+unblocks

+unblown

+unblushing

+unblushingly

+unbodied

+unbolted

+unboned

+unbonneted

+unborn

+unbound

+unbounded

+unboundedness

+unbowed

+unbranched

+unbreakable

+unbreathable

+unbred

+unbridled

+unbroken

+unbudging

+unbudgingly

+unbuffered

+unbuilt

+unbundled

+unburdened

+unbureaucratic

+unburied

+unburned

+unbuttered

+unbuttoned

+unbuttons

+uncaged

+uncalculating

+uncalled

+uncandidly

+uncanniness

+uncanny

+uncared

+uncaring

+uncatchable

+uncaught

+uncaused

+unceasing

+unceasingly

+uncensored

+uncertain

+uncertainly

+uncertainness

+uncertainties

+uncertainty

+uncertified

+unchallenged

+unchangeability

+unchangeable

+unchangeably

+unchanged

+unchanging

+unchangingly

+unchangingness

+uncharacteristically

+uncharged

+uncharitable

+uncharitableness

+uncharted

+unchartered

+uncheckable

+unchecked

+unchivalrously

+unchosen

+uncivil

+uncivilly

+unclaimed

+unclamorous

+unclamorously

+unclamorousness

+unclarity

+unclassified

+uncle

+uncle's

+unclean

+uncleanliness

+uncleanly

+uncleanness

+unclear

+uncleared

+unclenched

+uncles

+unclipped

+unclosed

+unclothed

+unclouded

+uncloudedly

+unclustered

+uncluttered

+uncoated

+uncoded

+uncoiled

+uncoined

+uncomfortable

+uncomfortably

+uncomforted

+uncommented

+uncommitted

+uncommon

+uncommonly

+uncommonness

+uncomplaining

+uncomplainingly

+uncompleted

+uncomplimentary

+uncomprehending

+uncomprehendingly

+uncompress

+uncompressed

+uncompresses

+uncompressing

+uncompromising

+uncompromisingly

+uncomputable

+unconceivable

+unconcerned

+unconcernedly

+unconcernedness

+unconditional

+unconditionally

+unconditioned

+unconfined

+unconfirmed

+unconformity

+unconnected

+unconquerable

+unconscious

+unconsciously

+unconsciousness

+unconsidered

+unconsolidated

+unconstitutional

+unconstitutionality

+unconstitutionally

+unconstrained

+uncontaminated

+uncontested

+uncontrollability

+uncontrollable

+uncontrollably

+uncontrolled

+unconventional

+unconventionally

+unconvertible

+unconvinced

+unconvincing

+unconvincingly

+unconvincingness

+uncool

+uncooled

+uncooperative

+uncoordinated

+uncorked

+uncorrectable

+uncorrected

+uncorrelated

+uncountable

+uncountably

+uncounted

+uncouth

+uncouthly

+uncouthness

+uncovenanted

+uncover

+uncovered

+uncovering

+uncovers

+uncreated

+uncritically

+uncrowned

+uncrushable

+uncured

+uncurled

+uncynical

+uncynically

+undamaged

+undamped

+undaunted

+undauntedly

+undebatable

+undecidable

+undecided

+undeclared

+undecomposable

+undecorated

+undefended

+undefinability

+undefinable

+undefined

+undefinedness

+undeformed

+undelete

+undeleted

+undemocratic

+undemocratically

+undemonstrative

+undemonstratively

+undemonstrativeness

+undeniable

+undeniableness

+undeniably

+undepicted

+under

+underbrush

+underdone

+underestimate

+underestimated

+underestimates

+underestimating

+underestimation

+underestimations

+underflow

+underflowed

+underflowing

+underflows

+underfoot

+undergo

+undergoes

+undergoing

+undergone

+undergrad

+undergrad's

+undergrads

+undergraduate

+undergraduate's

+undergraduates

+underground

+undergrounder

+underivable

+underived

+underlie

+underlies

+underline

+underlined

+underlines

+underling

+underling's

+underlings

+underlining

+underlinings

+underly

+underlying

+undermine

+undermined

+undermines

+undermining

+underneath

+underpayment

+underpayment's

+underpayments

+underpinning

+underpinnings

+underplay

+underplayed

+underplaying

+underplays

+underscore

+underscored

+underscores

+understand

+understandability

+understandable

+understandably

+understanding

+understandingly

+understandings

+understands

+understated

+understood

+undertake

+undertaken

+undertaker

+undertaker's

+undertakers

+undertakes

+undertaking

+undertakings

+undertook

+underway

+underwear

+underwent

+underworld

+underwrite

+underwriter

+underwriters

+underwrites

+underwriting

+undescended

+undesigned

+undesigning

+undesirability

+undesirable

+undesirableness

+undesirably

+undesired

+undetectable

+undetected

+undetermined

+undeveloped

+undeviated

+undeviating

+undeviatingly

+undid

+undies

+undifferentiated

+undigested

+undignified

+undiluted

+undiminished

+undimmed

+undiplomatic

+undirected

+undisciplined

+undisclosed

+undiscovered

+undiscussed

+undisguised

+undisguisedly

+undismayed

+undisputed

+undisrupted

+undissociated

+undistinguished

+undistorted

+undistributed

+undisturbed

+undivided

+undo

+undocumented

+undoer

+undoes

+undoing

+undoings

+undomesticated

+undone

+undoubled

+undoubted

+undoubtedly

+undrained

+undramatically

+undreamed

+undress

+undressed

+undresses

+undressing

+undried

+undrinkable

+undue

+unduly

+undumper

+undumper's

+undutiful

+undutifully

+undutifulness

+undying

+unearned

+unearthliness

+unearthly

+uneasily

+uneasiness

+uneasy

+uneconomical

+unedited

+unelected

+unembellished

+unemotional

+unemotionally

+unemphatic

+unemphatically

+unemployable

+unemployed

+unemployment

+unencumbered

+unending

+unendingly

+unendurable

+unendurableness

+unendurably

+unenlightening

+unenthusiastic

+unenthusiastically

+unenumerated

+unenvied

+unequal

+unequally

+unequivocal

+unequivocally

+unerring

+unerringly

+unessential

+unethically

+unevaluated

+uneven

+unevenly

+unevenness

+uneventful

+uneventfully

+unexamined

+unexampled

+unexceptionally

+unexcused

+unexpanded

+unexpected

+unexpectedly

+unexpectedness

+unexpended

+unexperienced

+unexplainable

+unexplained

+unexploited

+unexplored

+unexpressed

+unextended

+unfading

+unfadingly

+unfair

+unfairly

+unfairness

+unfaith

+unfaithful

+unfaithfully

+unfaithfulness

+unfaltering

+unfalteringly

+unfamiliar

+unfamiliarity

+unfamiliarly

+unfashionable

+unfashionably

+unfastened

+unfathered

+unfeathered

+unfeigned

+unfeignedly

+unfenced

+unfettered

+unfilial

+unfilially

+unfilled

+unfinished

+unfired

+unfit

+unfitly

+unfitness

+unfitted

+unfixed

+unflagging

+unflaggingly

+unflattering

+unflatteringly

+unfledged

+unflinching

+unflinchingly

+unfocused

+unfold

+unfolded

+unfolding

+unfolds

+unforeseen

+unforgeable

+unforgettable

+unforgettably

+unforgivable

+unforgiving

+unforgivingness

+unformatted

+unformed

+unforthcoming

+unfortunate

+unfortunately

+unfortunates

+unfounded

+unfrequented

+unfriendliness

+unfriendly

+unfrosted

+unfruitful

+unfruitfully

+unfruitfulness

+unfulfilled

+unfunded

+unfunnily

+unfurnished

+ungainliness

+ungainly

+ungallantly

+ungenerously

+ungirt

+unglazed

+unglued

+ungot

+ungotten

+ungoverned

+ungraceful

+ungracefully

+ungracefulness

+ungraciously

+ungraded

+ungrammatical

+ungrateful

+ungratefully

+ungratefulness

+ungratified

+ungrounded

+unguarded

+unguardedly

+unguardedness

+unguessable

+unguessed

+unguided

+unhallow

+unhallowed

+unhampered

+unhandily

+unhandsomely

+unhappier

+unhappiest

+unhappily

+unhappiness

+unhappy

+unharmed

+unhealthily

+unhealthiness

+unhealthy

+unheard

+unheeded

+unheeding

+unhelm

+unhelpfully

+unheralded

+unhesitating

+unhesitatingly

+unhinged

+unhitched

+unhooks

+unhoped

+unhurriedly

+unhysterical

+unhysterically

+unicorn

+unicorn's

+unicorns

+unidentifiable

+unidentified

+unidirectional

+unidirectionality

+unidirectionally

+unification

+unifications

+unified

+unifier

+unifiers

+unifies

+uniform

+uniformed

+uniforming

+uniformities

+uniformity

+uniformly

+uniformness

+uniforms

+unify

+unifying

+unilluminating

+unimaginable

+unimaginably

+unimaginatively

+unimpaired

+unimpassioned

+unimpeded

+unimplemented

+unimportance

+unimportant

+unimpressed

+unimproved

+unincorporated

+unindented

+uninfected

+uninfluenced

+uninformatively

+uninformed

+uninhabited

+uninhibited

+uninhibitedly

+uninhibitedness

+uninitiated

+uninjured

+uninspired

+uninspiring

+uninstantiated

+uninsulated

+unintelligent

+unintelligently

+unintelligibility

+unintelligible

+unintelligibleness

+unintelligibly

+unintended

+unintentional

+unintentionally

+uninteresting

+uninterestingly

+uninterpretable

+uninterpreted

+uninterrupted

+uninterruptedly

+uninterruptedness

+uninterviewed

+uninvited

+union

+union's

+unions

+unique

+uniquely

+uniqueness

+unison

+unit

+unit's

+unite

+united

+unitedly

+uniter

+unites

+unities

+uniting

+unitive

+units

+unity

+unity's

+univalve

+univalve's

+univalves

+universal

+universality

+universally

+universalness

+universals

+universe

+universe's

+universes

+universities

+university

+university's

+unjacketed

+unjam

+unjammed

+unjamming

+unjoined

+unjust

+unjustifiable

+unjustified

+unjustly

+unjustness

+unkind

+unkindliness

+unkindly

+unkindness

+unknit

+unknowable

+unknowing

+unknowingly

+unknown

+unknowns

+unlaced

+unlamented

+unlashed

+unlaundered

+unlawful

+unlawfully

+unlawfulness

+unleaded

+unleash

+unleashed

+unleashes

+unleashing

+unleavened

+unless

+unlettered

+unlicensed

+unlicked

+unlike

+unlikelihood

+unlikelihoods

+unlikeliness

+unlikely

+unlikeness

+unlimbers

+unlimited

+unlimitedly

+unlined

+unlink

+unlinked

+unlinking

+unlinks

+unlisted

+unload

+unloaded

+unloader

+unloaders

+unloading

+unloads

+unlock

+unlocked

+unlocking

+unlocks

+unlogged

+unloved

+unluckily

+unluckiness

+unlucky

+unmade

+unmagnified

+unmaintainable

+unmaintained

+unmaliciously

+unmanageable

+unmanageably

+unmanaged

+unmanned

+unmannered

+unmanneredly

+unmannerliness

+unmannerly

+unmapped

+unmaps

+unmarked

+unmarried

+unmarrieds

+unmasked

+unmatchable

+unmatched

+unmated

+unmates

+unmeant

+unmeasurable

+unmentionable

+unmentionables

+unmentioned

+unmerciful

+unmercifully

+unmeshed

+unmistakable

+unmistakably

+unmitigated

+unmitigatedly

+unmitigatedness

+unmixed

+unmoderated

+unmodifiable

+unmodified

+unmolested

+unmotivated

+unmount

+unmountable

+unmounted

+unmoved

+unmurmuring

+unnameable

+unnamed

+unnatural

+unnaturally

+unnaturalness

+unnecessarily

+unnecessary

+unneeded

+unnegated

+unnerve

+unnerved

+unnerves

+unnerving

+unnervingly

+unnoticed

+unnourished

+unnumbered

+unobservable

+unobservables

+unobserved

+unobtainable

+unoccupied

+unofficial

+unofficially

+unopened

+unordered

+unoriginals

+unorthodoxly

+unpack

+unpackaged

+unpackages

+unpacked

+unpacker

+unpacking

+unpacks

+unpadded

+unpaged

+unpaid

+unpainted

+unpaired

+unparliamentary

+unparsed

+unpartitioned

+unpatriotic

+unpaved

+unperceived

+unperformed

+unperturbed

+unperturbedly

+unplaced

+unplagued

+unplanned

+unpleasant

+unpleasantly

+unpleasantness

+unpleased

+unplowed

+unplugged

+unplugging

+unplugs

+unplumbed

+unpolled

+unpolluted

+unpopular

+unpopularity

+unprecedented

+unprecedentedly

+unpredictability

+unpredictable

+unpredictably

+unpredicted

+unprejudiced

+unprescribed

+unpreserved

+unpretending

+unpretentious

+unpretentiously

+unpretentiousness

+unpriced

+unprimed

+unprincipled

+unprincipledness

+unprintable

+unprinted

+unprivileged

+unproblematic

+unproblematical

+unproblematically

+unprocessed

+unprofitable

+unprofitableness

+unprofitably

+unprojected

+unpromising

+unpromisingly

+unprompted

+unpronounceable

+unpropagated

+unpropertied

+unprotected

+unprotectedly

+unprovability

+unprovable

+unproved

+unproven

+unprovided

+unpublished

+unpunched

+unpunished

+unqualified

+unqualifiedly

+unquantifiable

+unquenched

+unquestionably

+unquestioned

+unquestioningly

+unquoted

+unranked

+unrated

+unravel

+unravels

+unreachable

+unreacted

+unread

+unreadability

+unreadable

+unreal

+unrealism

+unrealistic

+unrealistically

+unrealized

+unrealizes

+unreasonable

+unreasonableness

+unreasonably

+unreassuringly

+unreconstructed

+unrecordable

+unrecorded

+unrecoverable

+unredeemed

+unreferenced

+unrefined

+unreflected

+unregister

+unregistered

+unregistering

+unregisters

+unregulated

+unrehearsed

+unreinforced

+unrelated

+unreleased

+unrelenting

+unrelentingly

+unreliabilities

+unreliability

+unreliable

+unreliably

+unremarked

+unreported

+unrepresentable

+unrepresented

+unrequested

+unrequited

+unreserved

+unreservedly

+unreservedness

+unresisted

+unresisting

+unresolved

+unresponsive

+unresponsively

+unresponsiveness

+unrest

+unrestrained

+unrestrainedly

+unrestrainedness

+unrestricted

+unrestrictedly

+unrestrictive

+unreturned

+unrevealing

+unrifled

+unrighteous

+unrighteously

+unrighteousness

+unroll

+unrolled

+unrolling

+unrolls

+unromantically

+unrotated

+unruffled

+unruled

+unruliness

+unruly

+unsafe

+unsafely

+unsaid

+unsalted

+unsanitary

+unsatisfactorily

+unsatisfactory

+unsatisfiability

+unsatisfiable

+unsatisfied

+unsatisfying

+unsaturated

+unsaved

+unscheduled

+unschooled

+unscientific

+unscientifically

+unscramble

+unscrambled

+unscrambler

+unscrambles

+unscrambling

+unscratched

+unscreened

+unscrews

+unscripted

+unscrupulous

+unscrupulously

+unscrupulousness

+unsealed

+unseals

+unseasonable

+unseasonableness

+unseasonably

+unseasoned

+unsecured

+unseeded

+unseeing

+unseemly

+unseen

+unsegmented

+unsegregated

+unselected

+unselfish

+unselfishly

+unselfishness

+unsent

+unserved

+unserviced

+unsettled

+unsettledness

+unsettling

+unsettlingly

+unshaded

+unshakable

+unshaken

+unshared

+unsharpened

+unshaved

+unshaven

+unsheathing

+unshelled

+unsheltered

+unshielded

+unshod

+unsigned

+unsimplified

+unsized

+unskilled

+unskillful

+unskillfully

+unskillfulness

+unslings

+unsloped

+unslung

+unsmiling

+unsmilingly

+unsnap

+unsnapped

+unsnapping

+unsnaps

+unsociability

+unsociable

+unsociableness

+unsociably

+unsocial

+unsocially

+unsolicited

+unsolvable

+unsolved

+unsophisticated

+unsophistication

+unsorted

+unsought

+unsound

+unsounded

+unsoundly

+unsoundness

+unsparing

+unsparingly

+unspeakable

+unspecified

+unspent

+unspoiled

+unspoken

+unspotted

+unsprayed

+unsprung

+unstable

+unstableness

+unstably

+unstacked

+unstacks

+unstained

+unstapled

+unstaring

+unstated

+unsteadily

+unsteadiness

+unsteady

+unstemmed

+unstinting

+unstintingly

+unstoppable

+unstopped

+unstrained

+unstratified

+unstreamed

+unstressed

+unstriped

+unstructured

+unstrung

+unstuck

+unsubscripted

+unsubstantially

+unsubstantiated

+unsubstituted

+unsuccessful

+unsuccessfully

+unsuffixed

+unsuitability

+unsuitable

+unsuitably

+unsuited

+unsung

+unsupportable

+unsupported

+unsure

+unsurpassed

+unsurprised

+unsurprising

+unsurprisingly

+unsuspected

+unsuspecting

+unsuspended

+unswerving

+unsymmetrically

+unsympathetic

+untamed

+untampered

+untaped

+untapped

+untaught

+untented

+unterminated

+untestable

+untested

+unthematic

+unthinkable

+unthinkably

+unthinkingly

+untidiness

+untidy

+untie

+untied

+unties

+until

+untimeliness

+untimely

+untitled

+unto

+untold

+untouchable

+untouchable's

+untouchables

+untouched

+untoward

+untowardly

+untowardness

+untraceable

+untraced

+untracked

+untrained

+untransformed

+untranslated

+untransposed

+untreated

+untried

+untrod

+untroubled

+untrue

+untruly

+untrusted

+untrustworthiness

+untruth

+untruthful

+untruthfully

+untruthfulness

+untutored

+untwisted

+untying

+untyped

+unusable

+unused

+unusual

+unusually

+unusualness

+unuttered

+unvalued

+unvarnished

+unvarying

+unveil

+unveiled

+unveiling

+unveils

+unventilated

+unverified

+unvisited

+unvoiced

+unwaged

+unwanted

+unwarily

+unwarranted

+unwashed

+unwashedness

+unwatched

+unwavering

+unwaveringly

+unwearied

+unweariedly

+unweighed

+unwelcome

+unwept

+unwholesome

+unwholesomely

+unwieldiness

+unwieldy

+unwilled

+unwilling

+unwillingly

+unwillingness

+unwind

+unwinder

+unwinders

+unwinding

+unwinds

+unwinking

+unwired

+unwise

+unwisely

+unwiser

+unwisest

+unwitnessed

+unwitting

+unwittingly

+unwonted

+unwontedly

+unwontedness

+unworldliness

+unworldly

+unworn

+unworthiness

+unworthy

+unwound

+unwounded

+unwoven

+unwrap

+unwrapped

+unwrapping

+unwraps

+unwrinkled

+unwritable

+unwritten

+unyielded

+unyielding

+unyieldingly

+up

+upbraid

+upbraider

+upbringing

+update

+updated

+updater

+updates

+updating

+upfield

+upgrade

+upgraded

+upgrades

+upgrading

+upheld

+uphill

+uphold

+upholder

+upholders

+upholding

+upholds

+upholster

+upholstered

+upholsterer

+upholsterers

+upholstering

+upholsters

+upkeep

+upland

+uplander

+uplands

+uplift

+uplifted

+uplifter

+uplifting

+uplifts

+upload

+uploaded

+uploading

+uploads

+upon

+upper

+uppermost

+uppers

+upright

+uprightly

+uprightness

+uprising

+uprising's

+uprisings

+uproar

+uproot

+uprooted

+uprooter

+uprooting

+uproots

+ups

+upset

+upsets

+upsetting

+upshot

+upshot's

+upshots

+upside

+upsides

+upstairs

+upstream

+upturn

+upturned

+upturning

+upturns

+upward

+upwardly

+upwardness

+upwards

+urban

+urchin

+urchin's

+urchins

+urge

+urged

+urgent

+urgently

+urger

+urges

+urging

+urgings

+urinate

+urinated

+urinates

+urinating

+urination

+urine

+urn

+urn's

+urning

+urns

+us

+usability

+usable

+usably

+usage

+usages

+use

+used

+useful

+usefully

+usefulness

+useless

+uselessly

+uselessness

+user

+user's

+users

+uses

+usher

+ushered

+ushering

+ushers

+using

+usual

+usually

+usualness

+usurp

+usurped

+usurper

+utensil

+utensil's

+utensils

+utilities

+utility

+utility's

+utmost

+utopian

+utopian's

+utopians

+utter

+utterance

+utterance's

+utterances

+uttered

+utterer

+uttering

+utterly

+uttermost

+utters

+uucp

+uucp's

+vacancies

+vacancy

+vacancy's

+vacant

+vacantly

+vacantness

+vacate

+vacated

+vacates

+vacating

+vacation

+vacationed

+vacationer

+vacationers

+vacationing

+vacations

+vacillate

+vacillated

+vacillates

+vacillating

+vacillatingly

+vacillation

+vacillations

+vacillator

+vacillator's

+vacillators

+vacuo

+vacuous

+vacuously

+vacuousness

+vacuum

+vacuumed

+vacuuming

+vacuums

+vagabond

+vagabond's

+vagabonds

+vagaries

+vagary

+vagary's

+vagina

+vagina's

+vaginas

+vagrant

+vagrantly

+vagrants

+vague

+vaguely

+vagueness

+vaguer

+vaguest

+vainly

+vale

+vale's

+valedictorian

+valedictorian's

+valence

+valence's

+valences

+valentine

+valentine's

+valentines

+vales

+valet

+valet's

+valets

+valiant

+valiantly

+valiantness

+valid

+validate

+validated

+validates

+validating

+validation

+validations

+validity

+validly

+validness

+valley

+valley's

+valleys

+valuable

+valuableness

+valuables

+valuably

+valuation

+valuation's

+valuations

+valuator

+valuators

+value

+valued

+valuer

+valuers

+values

+valuing

+valve

+valve's

+valved

+valves

+valving

+van

+van's

+vane

+vane's

+vaned

+vanes

+vanilla

+vanish

+vanished

+vanisher

+vanishes

+vanishing

+vanishingly

+vanities

+vanity

+vanquish

+vanquished

+vanquisher

+vanquishes

+vanquishing

+vans

+vantage

+vantages

+variability

+variable

+variable's

+variableness

+variables

+variably

+variance

+variance's

+variances

+variant

+variantly

+variants

+variation

+variation's

+variations

+varied

+variedly

+varier

+varies

+varieties

+variety

+variety's

+various

+variously

+variousness

+varnish

+varnish's

+varnished

+varnisher

+varnishers

+varnishes

+varnishing

+vary

+varying

+varyingly

+varyings

+vase

+vase's

+vases

+vassal

+vassals

+vast

+vaster

+vastest

+vastly

+vastness

+vat

+vat's

+vats

+vaudeville

+vault

+vaulted

+vaulter

+vaulting

+vaults

+vaunt

+vaunted

+vaunter

+veal

+vealer

+vealing

+vector

+vector's

+vectored

+vectoring

+vectors

+veer

+veered

+veering

+veeringly

+veers

+vegetable

+vegetable's

+vegetables

+vegetarian

+vegetarian's

+vegetarians

+vegetate

+vegetated

+vegetates

+vegetating

+vegetation

+vegetative

+vegetatively

+vegetativeness

+vehemence

+vehement

+vehemently

+vehicle

+vehicle's

+vehicles

+vehicular

+veil

+veiled

+veiling

+veils

+vein

+veined

+veiner

+veining

+veins

+velocities

+velocity

+velocity's

+velvet

+vend

+vender

+vending

+vendor

+vendor's

+vendors

+venerable

+venerableness

+vengeance

+venison

+venom

+venomous

+venomously

+venomousness

+vent

+vented

+venter

+ventilate

+ventilated

+ventilates

+ventilating

+ventilation

+ventilations

+ventilative

+venting

+ventral

+ventrally

+ventricle

+ventricle's

+ventricles

+vents

+venture

+ventured

+venturer

+venturers

+ventures

+venturing

+venturings

+veracity

+veranda

+veranda's

+verandaed

+verandas

+verb

+verb's

+verbal

+verbally

+verbose

+verbosely

+verboseness

+verbs

+verdict

+verdicts

+verdure

+verdured

+verge

+verger

+verges

+verier

+veriest

+verifiability

+verifiable

+verifiableness

+verification

+verifications

+verified

+verifier

+verifier's

+verifiers

+verifies

+verify

+verifying

+verily

+veritable

+veritableness

+vermin

+versa

+versatile

+versatilely

+versatileness

+versatility

+verse

+versed

+verser

+verses

+versing

+version

+versions

+versus

+vertebrate

+vertebrate's

+vertebrates

+vertebration

+vertex

+vertexes

+vertical

+vertically

+verticalness

+verticals

+vertices

+very

+vessel

+vessel's

+vessels

+vest

+vested

+vestige

+vestige's

+vestiges

+vestigial

+vestigially

+vesting

+vests

+veteran

+veteran's

+veterans

+veterinarian

+veterinarian's

+veterinarians

+veterinary

+veto

+vetoed

+vetoer

+vetoes

+vetoing

+vetting

+vex

+vexation

+vexed

+vexedly

+vexes

+vexing

+vi

+vi's

+via

+viability

+viable

+viably

+vial

+vial's

+vials

+vibrate

+vibrated

+vibrates

+vibrating

+vibration

+vibrations

+vice

+vice's

+viceroy

+vices

+vicing

+vicinities

+vicinity

+vicious

+viciously

+viciousness

+vicissitude

+vicissitude's

+vicissitudes

+victim

+victim's

+victims

+victor

+victor's

+victories

+victorious

+victoriously

+victoriousness

+victors

+victory

+victory's

+victual

+victuals

+video

+videos

+videotape

+videotape's

+videotaped

+videotapes

+videotaping

+vie

+vied

+vier

+vies

+view

+viewable

+viewed

+viewer

+viewers

+viewing

+viewings

+viewpoint

+viewpoint's

+viewpoints

+views

+vigilance

+vigilant

+vigilante

+vigilante's

+vigilantes

+vigilantly

+vignette

+vignette's

+vignetted

+vignetter

+vignettes

+vignetting

+vigorous

+vigorously

+vigorousness

+vii

+viii

+vile

+vilely

+vileness

+viler

+vilest

+vilification

+vilifications

+vilified

+vilifier

+vilifies

+vilify

+vilifying

+villa

+villa's

+village

+village's

+villager

+villagers

+villages

+villain

+villain's

+villainous

+villainously

+villainousness

+villains

+villainy

+villas

+vindictive

+vindictively

+vindictiveness

+vine

+vine's

+vinegar

+vinegars

+vines

+vineyard

+vineyard's

+vineyards

+vining

+vintage

+vintager

+vintages

+violate

+violated

+violates

+violating

+violation

+violations

+violative

+violator

+violator's

+violators

+violence

+violent

+violently

+violet

+violet's

+violets

+violin

+violin's

+violinist

+violinist's

+violinists

+violins

+viper

+viper's

+vipers

+viral

+virally

+virgin

+virgin's

+virginity

+virgins

+virtual

+virtually

+virtue

+virtue's

+virtues

+virtuoso

+virtuoso's

+virtuosos

+virtuous

+virtuously

+virtuousness

+virus

+virus's

+viruses

+vis

+visa

+visaed

+visage

+visaged

+visaing

+visas

+viscosities

+viscosity

+viscount

+viscount's

+viscounts

+viscous

+viscously

+viscousness

+visibilities

+visibility

+visible

+visibleness

+visibly

+vision

+vision's

+visionariness

+visionary

+visioned

+visioning

+visions

+visit

+visitation

+visitation's

+visitations

+visited

+visiting

+visitor

+visitor's

+visitors

+visits

+visor

+visor's

+visored

+visors

+vista

+vista's

+vistaed

+vistas

+visual

+visually

+visuals

+vita

+vitae

+vital

+vitality

+vitally

+vitals

+vitamin

+vitamin's

+vitamins

+vivid

+vividly

+vividness

+vizier

+vocabularies

+vocabulary

+vocal

+vocally

+vocals

+vocation

+vocation's

+vocational

+vocationally

+vocations

+vogue

+voice

+voiced

+voicer

+voicers

+voices

+voicing

+void

+voided

+voider

+voiding

+voidness

+voids

+volatile

+volatileness

+volatiles

+volatilities

+volatility

+volcanic

+volcano

+volcano's

+volcanos

+volley

+volleyball

+volleyball's

+volleyballs

+volleyed

+volleyer

+volleying

+volleys

+volt

+voltage

+voltages

+volts

+volume

+volume's

+volumed

+volumes

+voluming

+voluntarily

+voluntariness

+voluntary

+volunteer

+volunteered

+volunteering

+volunteers

+vomit

+vomited

+vomiter

+vomiting

+vomits

+vortex

+vortexes

+vote

+voted

+voter

+voters

+votes

+voting

+votive

+votively

+votiveness

+vouch

+voucher

+vouchers

+vouches

+vouching

+vow

+vowed

+vowel

+vowel's

+vowels

+vower

+vowing

+vows

+voyage

+voyaged

+voyager

+voyagers

+voyages

+voyaging

+voyagings

+vulgar

+vulgarly

+vulnerabilities

+vulnerability

+vulnerable

+vulnerableness

+vulture

+vulture's

+vultures

+wade

+waded

+wader

+waders

+wades

+wading

+wafer

+wafer's

+wafered

+wafering

+wafers

+waffle

+waffle's

+waffled

+waffles

+waffling

+waft

+wafter

+wag

+wage

+waged

+wager

+wagered

+wagerer

+wagering

+wagers

+wages

+waging

+wagon

+wagon's

+wagons

+wags

+wail

+wailed

+wailer

+wailing

+wails

+waist

+waist's

+waistcoat

+waistcoat's

+waistcoated

+waistcoats

+waisted

+waister

+waists

+wait

+waited

+waiter

+waiter's

+waiters

+waiting

+waitress

+waitress's

+waitresses

+waits

+waive

+waived

+waiver

+waiverable

+waivers

+waives

+waiving

+wake

+waked

+waken

+wakened

+wakener

+wakening

+waker

+wakes

+waking

+walk

+walked

+walker

+walkers

+walking

+walks

+walkway

+walkway's

+walkways

+wall

+wall's

+walled

+waller

+wallet

+wallet's

+wallets

+walling

+wallow

+wallowed

+wallower

+wallowing

+wallows

+walls

+walnut

+walnut's

+walnuts

+walrus

+walrus's

+walruses

+waltz

+waltzed

+waltzer

+waltzes

+waltzing

+wan

+wand

+wander

+wandered

+wanderer

+wanderers

+wandering

+wanderings

+wanders

+wane

+waned

+wanes

+waning

+wanly

+wanness

+want

+wanted

+wanter

+wanting

+wanton

+wantoner

+wantonly

+wantonness

+wants

+war

+war's

+warble

+warbled

+warbler

+warbles

+warbling

+ward

+warded

+warden

+wardens

+warder

+warding

+wardrobe

+wardrobe's

+wardrobes

+wards

+ware

+warehouse

+warehoused

+warehouser

+warehouses

+warehousing

+wares

+warfare

+warier

+wariest

+warily

+wariness

+waring

+warlike

+warm

+warmed

+warmer

+warmers

+warmest

+warming

+warmly

+warmness

+warms

+warmth

+warn

+warned

+warner

+warning

+warningly

+warnings

+warns

+warp

+warp's

+warped

+warper

+warping

+warps

+warrant

+warranted

+warranter

+warranties

+warranting

+warrants

+warranty

+warranty's

+warred

+warring

+warrior

+warrior's

+warriors

+wars

+warship

+warship's

+warships

+wart

+wart's

+warted

+warts

+wary

+was

+wash

+washed

+washer

+washers

+washes

+washing

+washings

+wasn't

+wasp

+wasp's

+wasps

+waste

+wasted

+wasteful

+wastefully

+wastefulness

+waster

+wastes

+wasting

+wastingly

+watch

+watched

+watcher

+watchers

+watches

+watchful

+watchfully

+watchfulness

+watching

+watchings

+watchman

+watchword

+watchword's

+watchwords

+water

+watered

+waterer

+waterfall

+waterfall's

+waterfalls

+wateriness

+watering

+waterings

+waterproof

+waterproofed

+waterproofer

+waterproofing

+waterproofness

+waterproofs

+waters

+waterway

+waterway's

+waterways

+watery

+wave

+waved

+waveform

+waveform's

+waveforms

+wavefront

+wavefront's

+wavefronts

+wavelength

+wavelengths

+waver

+wavered

+waverer

+wavering

+waveringly

+wavers

+waves

+waving

+wax

+waxed

+waxen

+waxer

+waxers

+waxes

+waxier

+waxiness

+waxing

+waxy

+way

+way's

+ways

+wayside

+waysides

+wayward

+waywardly

+waywardness

+we

+we'd

+we'll

+we're

+we've

+weak

+weaken

+weakened

+weakener

+weakening

+weakens

+weaker

+weakest

+weakliness

+weakly

+weakness

+weakness's

+weaknesses

+wealth

+wealthier

+wealthiest

+wealthiness

+wealths

+wealthy

+wean

+weaned

+weaner

+weaning

+weapon

+weapon's

+weaponed

+weapons

+wear

+wearable

+wearer

+wearied

+wearier

+wearies

+weariest

+wearily

+weariness

+wearing

+wearingly

+wearisome

+wearisomely

+wearisomeness

+wears

+weary

+wearying

+weasel

+weasel's

+weasels

+weather

+weathercock

+weathercock's

+weathercocks

+weathered

+weatherer

+weathering

+weatherly

+weathers

+weave

+weaver

+weavers

+weaves

+weaving

+web

+web's

+weber

+webs

+wed

+wedded

+wedding

+wedding's

+weddings

+wedge

+wedged

+wedges

+wedging

+weds

+wee

+weed

+weeded

+weeder

+weeding

+weeds

+week

+week's

+weekday

+weekday's

+weekdays

+weekend

+weekend's

+weekender

+weekends

+weeklies

+weekly

+weeks

+weep

+weeped

+weeper

+weepers

+weeping

+weeps

+weigh

+weighed

+weigher

+weighing

+weighings

+weighs

+weight

+weighted

+weighter

+weighting

+weightings

+weights

+weird

+weirdly

+weirdness

+welcome

+welcomed

+welcomely

+welcomeness

+welcomer

+welcomes

+welcoming

+weld

+welded

+welder

+welders

+welding

+weldings

+welds

+welfare

+well

+welled

+welling

+wellness

+wells

+wench

+wench's

+wencher

+wenches

+went

+wept

+were

+weren't

+west

+wester

+westered

+westering

+westerlies

+westerly

+western

+westerner

+westerners

+westing

+westward

+westwards

+wet

+wetly

+wetness

+wets

+wetted

+wetter

+wettest

+wetting

+whack

+whacked

+whacker

+whacking

+whacks

+whale

+whaler

+whales

+whaling

+whammies

+whammy

+wharf

+wharfs

+wharves

+what

+what's

+whatchamacallit

+whatchamacallit's

+whatchamacallits

+whatever

+whatsoever

+wheat

+wheaten

+wheel

+wheeled

+wheeler

+wheelers

+wheeling

+wheelings

+wheels

+whelp

+when

+whence

+whenever

+whens

+where

+where's

+whereabouts

+whereas

+whereby

+wherein

+whereupon

+wherever

+whether

+whew

+whey

+which

+whichever

+while

+whiled

+whiles

+whiling

+whim

+whim's

+whimper

+whimpered

+whimpering

+whimpers

+whims

+whimsical

+whimsically

+whimsicalness

+whimsied

+whimsies

+whimsy

+whimsy's

+whine

+whined

+whiner

+whines

+whining

+whiningly

+whip

+whip's

+whipped

+whipper

+whipper's

+whippers

+whipping

+whipping's

+whippings

+whips

+whirl

+whirled

+whirler

+whirling

+whirlpool

+whirlpool's

+whirlpools

+whirls

+whirlwind

+whirr

+whirring

+whisk

+whisked

+whisker

+whiskered

+whiskers

+whiskey

+whiskey's

+whiskeys

+whisking

+whisks

+whisper

+whispered

+whisperer

+whispering

+whisperingly

+whisperings

+whispers

+whistle

+whistled

+whistler

+whistlers

+whistles

+whistling

+whit

+white

+whited

+whitely

+whiten

+whitened

+whitener

+whiteners

+whiteness

+whitening

+whitens

+whiter

+whites

+whitespace

+whitest

+whitewash

+whitewashed

+whitewasher

+whitewashing

+whiting

+whittle

+whittled

+whittler

+whittles

+whittling

+whittlings

+whiz

+whizzed

+whizzes

+whizzing

+who

+who's

+whoever

+whole

+wholehearted

+wholeheartedly

+wholeness

+wholes

+wholesale

+wholesaled

+wholesaler

+wholesalers

+wholesales

+wholesaling

+wholesome

+wholesomely

+wholesomeness

+wholly

+whom

+whomever

+whoop

+whooped

+whooper

+whooping

+whoops

+whore

+whore's

+whores

+whoring

+whorl

+whorl's

+whorled

+whorls

+whose

+why

+wick

+wicked

+wickedly

+wickedness

+wicker

+wicking

+wicks

+wide

+widely

+widen

+widened

+widener

+wideness

+widening

+widens

+wider

+widespread

+widest

+widget

+widget's

+widgets

+widow

+widowed

+widower

+widowers

+widows

+width

+widths

+wield

+wielded

+wielder

+wielding

+wields

+wife

+wife's

+wifeliness

+wifely

+wig

+wig's

+wigs

+wigwam

+wild

+wildcat

+wildcat's

+wildcats

+wilder

+wilderness

+wildest

+wilding

+wildly

+wildness

+wile

+wiled

+wiles

+wilier

+wiliness

+wiling

+will

+willed

+willer

+willful

+willfully

+willfulness

+willing

+willingly

+willingness

+willings

+willow

+willow's

+willower

+willows

+wills

+wilt

+wilted

+wilting

+wilts

+wily

+win

+wince

+winced

+winces

+wincing

+wind

+winded

+winder

+winders

+windier

+windiness

+winding

+windmill

+windmill's

+windmilling

+windmills

+window

+window's

+windowed

+windowing

+windows

+winds

+windy

+wine

+wined

+winer

+winers

+wines

+wing

+winged

+winger

+wingers

+winging

+wings

+wining

+wink

+winked

+winker

+winking

+winks

+winner

+winner's

+winners

+winning

+winningly

+winnings

+wins

+winter

+wintered

+winterer

+wintering

+winterly

+winters

+wintrier

+wintriness

+wintry

+wipe

+wiped

+wiper

+wipers

+wipes

+wiping

+wire

+wired

+wireless

+wirer

+wires

+wiretap

+wiretap's

+wiretaps

+wirier

+wiriness

+wiring

+wirings

+wiry

+wisdom

+wisdoms

+wise

+wised

+wisely

+wiseness

+wiser

+wises

+wisest

+wish

+wished

+wisher

+wishers

+wishes

+wishful

+wishfully

+wishfulness

+wishing

+wising

+wisp

+wisp's

+wisps

+wistful

+wistfully

+wistfulness

+wit

+wit's

+witch

+witchcraft

+witches

+witching

+with

+withal

+withdraw

+withdrawal

+withdrawal's

+withdrawals

+withdrawer

+withdrawing

+withdrawn

+withdrawnness

+withdraws

+withdrew

+wither

+withered

+withering

+witheringly

+withers

+withheld

+withhold

+withholder

+withholders

+withholding

+withholdings

+withholds

+within

+without

+withstand

+withstanding

+withstands

+withstood

+witness

+witnessed

+witnesses

+witnessing

+wits

+wittier

+wittiest

+wittiness

+witty

+wives

+wizard

+wizard's

+wizardly

+wizards

+woe

+woeful

+woefully

+woeness

+woke

+wolf

+wolfer

+wolves

+woman

+woman's

+womanhood

+womanliness

+womanly

+womb

+womb's

+wombed

+wombs

+women

+women's

+womens

+won't

+wonder

+wondered

+wonderer

+wonderful

+wonderfully

+wonderfulness

+wondering

+wonderingly

+wonderland

+wonderland's

+wonderment

+wonders

+wondrous

+wondrously

+wondrousness

+wont

+wonted

+wontedly

+wontedness

+wonting

+woo

+wood

+wood's

+woodchuck

+woodchuck's

+woodchucks

+woodcock

+woodcock's

+woodcocks

+wooded

+wooden

+woodenly

+woodenness

+woodier

+woodiness

+wooding

+woodland

+woodlander

+woodman

+woodpecker

+woodpecker's

+woodpeckers

+woods

+woodser

+woodwork

+woodworker

+woodworking

+woody

+wooed

+wooer

+woof

+woofed

+woofer

+woofers

+woofing

+woofs

+wooing

+wool

+wooled

+woolen

+woolens

+woollier

+woollies

+woolliness

+woolly

+wools

+wooly

+woos

+word

+word's

+worded

+wordier

+wordily

+wordiness

+wording

+wordings

+words

+wordy

+wore

+work

+workable

+workableness

+workably

+workaround

+workaround's

+workarounds

+workbench

+workbench's

+workbenches

+workbook

+workbook's

+workbooks

+worked

+worker

+worker's

+workers

+workhorse

+workhorse's

+workhorses

+working

+workingman

+workings

+workload

+workloads

+workman

+workmanly

+workmanship

+workmen

+workmen's

+works

+workshop

+workshop's

+workshops

+workstation

+workstation's

+workstations

+world

+world's

+worlders

+worldliness

+worldly

+worlds

+worldwide

+worm

+wormed

+wormer

+worming

+worms

+worn

+worried

+worriedly

+worrier

+worriers

+worries

+worrisome

+worrisomely

+worrisomeness

+worry

+worrying

+worryingly

+worse

+worser

+worship

+worshipful

+worshipfully

+worshipfulness

+worships

+worst

+worsted

+worth

+worthier

+worthies

+worthiest

+worthiness

+worthing

+worthless

+worthlessly

+worthlessness

+worths

+worthwhile

+worthwhileness

+worthy

+would

+wouldest

+wouldn't

+wound

+wounded

+wounding

+wounds

+wove

+woven

+wrangle

+wrangled

+wrangler

+wranglers

+wrangles

+wrangling

+wrap

+wrap's

+wrapped

+wrapper

+wrapper's

+wrappers

+wrapping

+wrappings

+wraps

+wrath

+wreak

+wreaks

+wreath

+wreathed

+wreathes

+wreathing

+wreck

+wreckage

+wrecked

+wrecker

+wreckers

+wrecking

+wrecks

+wren

+wren's

+wrench

+wrenched

+wrenches

+wrenching

+wrenchingly

+wrens

+wrest

+wrested

+wrester

+wresting

+wrestle

+wrestled

+wrestler

+wrestles

+wrestling

+wrestlings

+wrests

+wretch

+wretched

+wretchedly

+wretchedness

+wretches

+wriggle

+wriggled

+wriggler

+wriggles

+wriggling

+wring

+wringer

+wringing

+wrings

+wrinkle

+wrinkled

+wrinkles

+wrinkling

+wrist

+wrist's

+wrists

+wristwatch

+wristwatch's

+wristwatches

+writ

+writ's

+writable

+write

+writer

+writer's

+writers

+writes

+writhe

+writhed

+writhes

+writhing

+writing

+writings

+writs

+written

+wrong

+wronged

+wronger

+wrongest

+wronging

+wrongly

+wrongness

+wrongs

+wrote

+wrought

+wrung

+xi

+xii

+xiii

+xiv

+xix

+xv

+xvi

+xvii

+xviii

+xx

+yacc

+yacc's

+yank

+yanked

+yanking

+yanks

+yard

+yard's

+yarded

+yarding

+yards

+yardstick

+yardstick's

+yardsticks

+yarn

+yarn's

+yarned

+yarning

+yarns

+yawn

+yawner

+yawning

+yawningly

+yawns

+yea

+yeah

+year

+year's

+yearly

+yearn

+yearned

+yearner

+yearning

+yearningly

+yearnings

+yearns

+years

+yeas

+yeast

+yeast's

+yeasts

+yecch

+yell

+yelled

+yeller

+yelling

+yellow

+yellowed

+yellower

+yellowest

+yellowing

+yellowish

+yellowness

+yellows

+yells

+yelp

+yelped

+yelper

+yelping

+yelps

+yeoman

+yeomanly

+yeomen

+yes

+yeses

+yesterday

+yesterday's

+yesterdays

+yet

+yield

+yielded

+yielder

+yielding

+yields

+yoke

+yoke's

+yokes

+yoking

+yon

+yonder

+you

+you'd

+you'll

+you're

+you've

+young

+younger

+youngest

+youngly

+youngness

+youngster

+youngster's

+youngsters

+your

+your's

+yours

+yourself

+yourselves

+youth

+youth's

+youthes

+youthful

+youthfully

+youthfulness

+yuck

+yummier

+yummy

+yuppie

+yuppie's

+yuppies

+zap

+zapped

+zapping

+zaps

+zeal

+zealous

+zealously

+zealousness

+zebra

+zebra's

+zebras

+zenith

+zero

+zeroed

+zeroes

+zeroing

+zeros

+zeroth

+zest

+zigzag

+zinc

+zinc's

+zodiac

+zodiacs

+zonal

+zonally

+zone

+zoned

+zonely

+zoner

+zones

+zoning

+zoo

+zoo's

+zoological

+zoologically

+zoom

+zoomed

+zooming

+zooms

+zoos

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.1 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.1
new file mode 100644
index 0000000..658faad
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.1
@@ -0,0 +1,20864 @@
+AI

+ALU

+AMA

+ANSI's

+ARCO

+ARPA

+Aaron

+Abe

+Abe's

+Abigail

+Abigail's

+Abilene

+Abilene's

+Abner

+Abner's

+Abraham

+Abrams

+Abramson

+Acapulco

+Ackerman

+Acta

+Adam

+Adams

+Adamson

+Addison

+Addressograph

+Adirondack

+Adirondacks

+Adonis

+Adriatic

+Aegean

+Aeneid

+Afghani

+Afghani's

+Afghanis

+Afrikaans

+Agatha

+Aggie

+Aggies

+Agnes

+Aires

+Ajax

+Akron

+Al

+Al's

+Alabamans

+Alameda

+Alamo

+Alamos

+Alan

+Alan's

+Albany

+Albert

+Alberta

+Alberto

+Albuquerque

+Alcoa

+Alec

+Aleck

+Aler

+Aleut

+Alex

+Alexander

+Alexanders

+Alexandra

+Alexandre

+Alexandria

+Alfa

+Algiers

+Alhambra

+Alice

+Alicia

+Alistair

+Allan

+Alleghenies

+Allegheny

+Allen

+Allendale

+Allentown

+Allison

+Allstate

+Alsatian

+Alsatians

+Alvarez

+Alvin

+Amadeus

+Amarillo

+Amarillo's

+Americanism

+Amherst

+Amherst's

+Amoco

+Amoco's

+Amos

+Ampex

+Ampex's

+Amy

+Amy's

+Anaheim

+Anaheim's

+Andean

+Andean's

+Andersen

+Andersen's

+Anderson

+Anderson's

+Andes

+Andover

+Andover's

+Andre

+Andre's

+Andrew

+Andrew's

+Andromeda

+Andy

+Andy's

+Angela

+Angeles

+Angelina

+Angeline

+Angelo

+Angie

+Anglia

+Anglo

+Angus

+Anheuser

+Anita

+Ankara

+Ann

+Anna

+Annapolis

+Anne

+Anne's

+Annie

+Anson

+Antares

+Anthony

+Antietam

+Antioch

+Antoine

+Antoinette

+Antony

+Apollinaire

+Appaloosas

+Appian

+Appleton

+Appomattox

+Aquinas

+Araby

+Arcadia

+Archibald

+Archimedes

+Arcturus

+Argonne

+Argus

+Ariadne

+Aristotelean

+Arkansan

+Arlene

+Arlington

+Armonk

+Arnold

+Arnold's

+Arpanet

+Arthur

+Aruba

+Asheville

+Ashland

+Ashley

+Assad

+Assyria

+Astaire

+Astaires

+Astor

+Astoria

+Atari

+Atkins

+Atkinson

+Atlanta

+Atlantis

+Atreus

+Attica

+Augean

+Augustan

+Augustine

+Augustus

+Aurelius

+Auschwitz

+Australis

+Aventine

+Aventino

+Avis

+Aviv

+Avogadro

+Avon

+Aztec

+Aztecan

+BCD

+BS

+BTW

+Babcock

+Babylon

+Babylonian

+Babylonians

+Bacchus

+Baghdad

+Bahama

+Bahamas

+Bailey

+Baileys

+Bakelite

+Bakersfield

+Baldwin

+Bali

+Balinese

+Ballard

+Ballards

+Baltimore

+Balzac

+Bamberger

+Bambi

+Bancroft

+Bangor

+Baptiste

+Barbara

+Barcelona

+Barclay

+Barnabas

+Barnard

+Barney

+Barron

+Barry

+Barry's

+Barrymore

+Barrymores

+Barstow

+Barth

+Bartholomew

+Bartlett

+Bartok

+Bascom

+Basie

+Bassett

+Batavia

+Batista

+Baudelaire

+Bauer

+Bauhaus

+Bavaria

+Bavarian

+Bayesian

+Baylor

+Bayonne

+Beatrice

+Beauchamps

+Beaujolais

+Beaumont

+Beauregard

+Beaverton

+Bechtel

+Becky

+Bedford

+Beelzebub

+Beelzebub's

+Beirut

+Belfast

+Belgrade

+Bella

+Bellatrix

+Belleville

+Bellwood

+Belmont

+Beloit

+Belton

+Beltsville

+Ben

+Ben's

+Bendix

+Benjamin

+Bennett

+Bennington

+Benny

+Benson

+Bentham

+Bentley

+Bentleys

+Benz

+Beowulf

+Bergson

+Beringer

+Berkowitz

+Berkshire

+Berkshires

+Berlioz

+Berlitz

+Bern

+Bernadine

+Bernard

+Bernardine

+Bernice

+Bernie

+Bernoulli

+Bernstein

+Berra

+Bert

+Bertha

+Bertrand

+Bess

+Bessemer

+Bessie

+Betelgeuse

+Bethesda

+Bethlehem

+Betsy

+Betties

+Betty

+Bhutan

+Biddle

+Bienville

+Bierce

+Bigelow

+Billie

+Bimini

+Bingham

+Binghamton

+Biscayne

+Bismarck

+Blackburn

+Blackfeet

+Blackman

+Blackmer

+Blackstone

+Blackwell

+Blackwells

+Blair

+Blake

+Blakey

+Blanche

+Blanton

+Blatz

+Bloomfield

+Bloomington

+Blvd

+Bobbie

+Bobbsey

+Bobrow

+Bodenheim

+Boeing

+Boer

+Bogart

+Bogartian

+Bogota

+Boheme

+Bohemia

+Bohemian

+Bohr

+Boise

+Bolshevist

+Bolshevistic

+Bolshoi

+Bolton

+Boltzmann

+Bombay

+Bombay's

+Bonaparte

+Bonaventure

+Bonham

+Boniface

+Bonn

+Bonneville

+Bonnie

+Bontempo

+Boone

+Bootle

+Bordeaux

+Borden

+Borealis

+Boreas

+Borg

+Borroughs

+Bose

+Bostitch

+Boswell

+Bouvier

+Bowes

+Boyce

+Bradbury

+Bradford

+Bradley

+Bradshaw

+Brady

+Brahms

+Brainard

+Brainards

+Branchville

+Brandeis

+Brandel

+Brandenburg

+Brandon

+Braniff

+Brannon

+Brasilia

+Braun

+Brenda

+Brian

+Bridewell

+Bridgeport

+Bridgetown

+Bridgewater

+Brien

+Brigadoon

+Brigham

+Brinkley

+Britannic

+Britannica

+Brittany

+Britten

+Britten's

+Broadway

+Brock

+Bronx

+Brookdale

+Brooke

+Brookfield

+Brookhaven

+Brooklyn

+Brookmont

+Browne

+Brownell

+Brownian

+Bruce

+Brunhilde

+Bruno

+Brussels

+Bruxelles

+Bryan

+Bryant

+Bryce

+Bryn

+Buchanan

+Bucharest

+Buchwald

+Bucky

+Budapest

+Budd

+Buddha

+Buddhism

+Buddhist

+Buddhists

+Budweiser

+Budweisers

+Bugatti

+Buick

+Bulba

+Bulgaria

+Bulgarian

+Bumbry

+Bundestag

+Bundy

+Bunsen

+Bunsen's

+Bunsens

+Bunyan

+Bunyan's

+Burbank

+Burbank's

+Burch

+Burgundian

+Burgundies

+Burgundy

+Burlingame

+Burma

+Burmese

+Burne

+Burnes

+Burnett

+Burnside

+Burnsides

+Burroughs

+Burt

+Burton

+Burundi

+Busch

+Bushnell

+Butterfield

+Byrne

+Byron

+Byron's

+Byronic

+Byronism

+Byzantine

+Byzantium

+CACM

+CDT

+CIA

+CPA

+CPR

+CRT

+CST

+Cadillac

+Cadillacs

+Caesar

+Cain

+Caine

+Cairo

+Cal

+CalComp

+Calcutta

+Calcutta's

+Calder

+Calgary

+Calif

+Caligula

+Callisto

+Caltech

+Calumet

+Calvinist

+Cambodia

+Camelot

+Camille

+Camino

+Campbellsport

+Canadian

+Canadians

+Canaveral

+Canberra

+Candide

+Candlewick

+Canis

+Canoga

+Canterbury

+Cantonese

+Canute

+Capet

+Capetown

+Capistrano

+Capitan

+Cappy

+Capricorn

+Capt

+Caracas

+Carbondale

+Carbones

+Caribbean

+Carl

+Carl's

+Carla

+Carleton

+Carletonian

+Carlos

+Carlsbad

+Carlson

+Carlton

+Carlyle

+Carmichael

+Carnegie

+Caroline

+Caroline's

+Carolinian

+Carolinians

+Carolyn

+Carrie

+Carson

+Carthage

+Carty

+Caruso

+Casey

+Cassandra

+Cassiopeia

+Cassite

+Cassius

+Castro

+Catalina

+Catawba

+Catherine

+Cathy

+Catskill

+Catskills

+Caucasian

+Caucasians

+Caucasus

+Cauchy

+Cavendish

+Cecil

+Cecilia

+Celanese

+Celsius

+Celtic

+Cenozoic

+Centralia

+Cerberus

+Cervantes

+Cessna

+Cetus

+Ceylon

+Cezanne

+Cezannes

+Chablis

+Chad

+Chaffey

+Chalmers

+Champlain

+Chancellorsville

+Chandy

+Chandy's

+Chang

+Channing

+Chantilly

+Chaplin

+Chapman

+Charles

+Charleston

+Charley

+Charlie

+Charlotte

+Charlottesville

+Charybdis

+Chattahoochee

+Chattanooga

+Chaucer

+Chautauqua

+Chekhov

+Chen

+Cheng

+Cheriton

+Cheriton's

+Cherokee

+Cherokees

+Cheryl's

+Chesapeake

+Cheshire

+Chesterfield

+Chesterton

+Chevrolet

+Chevy

+Cheyenne

+Cheyennes

+Chicago

+Chicago's

+Chicagoan

+Chicagoans

+Chicana

+Chicana's

+Chicanas

+Chicano

+Chicano's

+Chicanos

+Chickasaws

+Chile

+Chiles

+Chimiques

+Chinaman

+Chinamen

+Ching

+Chinook

+Chippendale

+Chippewa

+Chisholm

+Choctaw

+Choctaws

+Chomsky

+Chomsky's

+Chopin

+Chris

+Christ

+Christendom

+Christenson

+Christianity

+Christie

+Christine

+Christlike

+Christopher

+Christopher's

+Christy

+Chrysler

+Churchill

+Churchillian

+Cicero

+Ciceronian

+Cincinnati

+Cinderella

+Cinerama

+Circe

+Citroen

+Claire

+Clara

+Clare

+Claremont

+Clarence

+Clark

+Clarke

+Clarridge

+Claude

+Claudia

+Claudio

+Claus

+Clausen

+Clearwater

+Clemens

+Clemente

+Clemson

+Cleveland

+Clifford

+Clint

+Clinton

+Clinton's

+Clio

+Clive

+Clyde

+Clytemnestra

+Coates

+Cochise

+Coffman

+Cohen

+Cohn

+Colby

+Coleridge

+Colgate

+Colombia

+Colombian

+Colombians

+Colosseum

+Columbia

+Columbian

+Columbus

+Comanche

+Commie

+Compuserve

+Compuserve's

+Concorde

+Concordia

+Conestoga

+Confucian

+Confucianism

+Confucius

+Congo

+Connecticut

+Connelly

+Connie

+Conrad

+Conrad's

+Conrail

+Conrail's

+Constantinople

+Coolidge

+Coors

+Copeland

+Copenhagen

+Copernicus

+Copperfield

+Corinthian

+Corinthians

+Cornell

+Cornell's

+Cornish

+Cornwall

+Cornwallis

+Corp

+Corsica

+Corsican

+Cortland

+Costello

+Covent

+Coventry

+Craig

+Cramer

+Crandall

+Cranford

+Cranston

+Crawford

+Cree

+Creighton

+Creole

+Creon

+Crestview

+Cretaceous

+Cretaceously

+Cretan

+Crete

+Crimea

+Crimean

+Croatian

+Crockett

+Croix

+Cromwell

+Cromwellian

+Crosby

+Crowley

+Crusoe

+Cuba

+Cuban

+Cubans

+Culver

+Culvers

+Cumberland

+Cunard

+Cunningham

+Cupid

+Cushman

+Cyanamid

+Cygnus

+Cynthia

+Cyprian

+Cypriot

+Cyprus

+Cyril

+Cyrus

+Czech

+Czechoslovakia

+DAG

+DB

+DECsystem

+DECtape

+DNA

+Dacron

+Dadaism

+Dadaist

+Dade

+Daedalus

+Daimler

+Dakar

+Dakota

+Dali

+Dallas

+Dalton

+Daly

+Damascus

+Danbury

+Dane

+Danes

+Daniel

+Daniels

+Danielson

+Danish

+Danny

+Danny's

+Dante

+Danube

+Danville

+Danzig

+Daphne

+Darlene

+Darlington

+Darrell

+Darrow

+Dartmouth

+Darwin

+Darwinian

+Darwinism

+Datamedia

+Datsun

+Dave

+Dave's

+David

+David's

+Davidson

+Davie

+Davies

+Davinich

+Davis

+Davy

+Dawson

+Dayton

+DeKalb

+Dearborn

+Debby

+Deborah

+Debra

+Debussy

+Dec

+Decca

+Deere

+Defoe

+Delhi

+Delhi's

+Delilah

+Dellwood

+Delphi

+Delphic

+Dempsey

+Deneen

+Dennis

+Denny

+Denver

+Dependant

+Dependants

+Dept

+Derbyshire

+Descartes

+Desmond

+Deutsch

+Devon

+Devonshire

+Dewey

+Dewitt

+Dexedrine

+DiMaggio

+Diana

+Diane

+Dianne

+Dick's

+Dickinson

+Dickson

+Diego

+Dietrich

+Dijon

+Dillon

+Dinah

+Diogenes

+Dion

+Dionysian

+Dionysus

+Dirac

+Disney

+Disneyland

+Disraeli

+Dixie

+Dixiecrats

+Dixieland

+Djakarta

+Dmitri

+Doberman

+Doc

+Dodington

+Dogtown

+Dolores

+Domesday

+Domingo

+Dominic

+Dominican

+Dominicans

+Donahue

+Donald

+Donald's

+Donaldson

+Donna

+Donnelly

+Donovan

+Doolittle

+Doppler

+Dora

+Dora's

+Dorado

+Dorchester

+Doris

+Dorothy

+Dostoevsky

+Doubleday

+Doug

+Dougherty

+Douglas

+Douglass

+Dow

+Downey

+Doyle

+Dr

+Dramamine

+Drexel

+Dreyfuss

+Drury

+Dryden

+DuPont

+DuPonts

+Duane

+Dublin

+Dubuque

+Duffy

+Dulles

+Duluth

+Dumas

+Dumont

+Dumpty

+Duncan

+Dunham

+Dunkirk

+Dunlap

+Dunne

+Dupont

+Duponts

+Durham

+Durkee

+Dusenberg

+Dusseldorf

+Dustin

+Dutch

+Dutchman

+Dutchmen

+Dvorak

+Dwight

+Dyke

+EBCDIC

+EEG

+EPA

+Earp

+Easthampton

+Eastland

+Eastman

+Eastwick

+Eastwood

+Econometrica

+Ecuador

+Eddie

+Edgar

+Edgerton

+Edgewater

+Edgewood

+Edinburgh

+Edison

+Edith

+Edmund

+Edna

+Eduard

+Edward

+Edwardian

+Edwards

+Edwin

+Edwina

+Egerton

+Egypt

+Egyptian

+Egyptians

+Eichmann

+Eileen

+Einstein

+Einsteinian

+Eisenhower

+Ekberg

+Ektachrome

+Elaine

+Elba

+Eleanor

+Electra

+Eli

+Elijah

+Eliot

+Elisabeth

+Elise

+Elise's

+Elizabeth

+Elizabethan

+Elizabethans

+Elkhart

+Ella

+Ellie

+Elliot

+Elliott

+Ellis

+Ellison

+Ellsworth

+Elmhurst

+Elmira

+Elmsford

+Eloise

+Elroy

+Elsie

+Elsinore

+Elysees

+Elysium

+Emanuel

+Emerson

+Emily

+Emma

+Emmanuel

+Emory

+Endicott

+Englewood

+Englishman

+Englishmen

+Enoch

+Enos

+Enrico

+Ensolite

+Eocene

+Ephesian

+Ephesians

+Ephraim

+Epicurus

+Episcopalian

+Epsom

+Epstein

+Erasmus

+Eratosthenes

+Eric

+Erich

+Erickson

+Ericsson

+Erie

+Erik

+Erik's

+Erikson

+Ernest

+Ernestine

+Ernie

+Ernst

+Eros

+Errol

+Ervin

+Erwin

+Eskimo

+Eskimos

+Esp

+Espagnol

+Essex

+Esther

+Ethan

+Ethel

+Ethiopia

+Ethiopians

+Etruscan

+Eucharist

+Euclid

+Euclidean

+Eugene

+Eugenia

+Euler

+Eulerian

+Eunice

+Euphrates

+Eurasia

+Eurasian

+Euripides

+Europa

+Eurydice

+Eva

+Evangeline

+Evans

+Evanston

+Evansville

+Evelyn

+Eveready

+Everett

+Everglades

+Ewen

+Exeter

+Exxon

+Ezekiel

+Ezra

+FAQ's

+FAQs

+FBI

+FCC

+FDA

+FTP

+Fagin

+Fahrenheit

+Fahrenheits

+Fairchild

+Fairfax

+Fairfield

+Fairmont

+Fairport

+Fairview

+Falk

+Falstaff

+Fannies

+Fanny

+Faraday

+Farber

+Fargo

+Farley

+Farmington

+Farrell

+Fatima

+Faulkner

+Faulknerian

+Fauntleroy

+Faust

+Faustian

+Faustus

+Fawkes

+Fayetteville

+Featherman

+Feb

+Feldman

+Felice

+Felicia

+Felix

+Fellini

+Fenwick

+Ferdinand

+Ferdinando

+Fermi

+Fernando

+Fess

+Fiberglas

+Fibonacci

+Fidel

+Figaro

+Filipino

+Filipinos

+Filippo

+Fillmore

+Finland

+Finn

+Finnegan

+Finnish

+Finns

+Fiorello

+Fiori

+Firestone

+Fischer

+Fishkill

+Fisk

+Fitch

+Fitchburg

+Fitzgerald

+Fitzpatrick

+Fitzroy

+Flanagan

+Flanders

+Fledermaus

+Fleischman

+Fleisher

+Fleming

+Flemings

+Flemish

+Flemished

+Flemishes

+Flemishing

+Florence

+Florentine

+Floridian

+Floridians

+Floyd

+Flynn

+Folsom

+Fontainebleau

+Fontana

+Foote

+Forbes

+Fordham

+Formica

+Formosa

+Formosan

+Foxhall

+Fran

+Fran's

+Francaise

+Francesca

+Francesco

+Francie

+Francis

+Franciscan

+Franciscans

+Francisco

+Franco

+Francois

+Frankford

+Frankfort

+Frankfurt

+Frankie

+Franny

+Franz

+Frau

+Frayne

+Frazier

+Fred

+Freddie

+Freddy

+Freddy's

+Frederic

+Frederick

+Fredericks

+Frederico

+Fredrick

+Fredrickson

+Freeport

+Freida

+Frenchman

+Frenchmen

+Fresnel

+Fresno

+Freud

+Freudian

+Frey

+Fri

+Frick

+Friedman

+Frigga

+Frigidaire

+Frisbee

+Frito

+Fritz

+Frostbelt

+Frostbelt's

+Fuchs

+Fuji

+Fulbright

+Fullerton

+GM

+GNP

+GSA

+Gabriel

+Gabrielle

+Gaelic

+Gail

+Gainesville

+Gaithersburg

+Galahad

+Galapagos

+Galatea

+Galbreath

+Galilee

+Galloway

+Gallup

+Galois

+Galveston

+Ganges

+Ganymede

+Garcia

+Gardner

+Garfield

+Garibaldi

+Garnett

+Garrett

+Garry

+Garvey

+Gary

+Gary's

+Gascony

+Gasset

+Gaston

+Gatlinburg

+Gatsby

+Gauguin

+Gaul

+Gauntley

+Gaussian

+Gavin

+Gaylor

+Gaylord

+Gaynor

+Geary

+Gehrig

+Geiger

+Gemini

+Geneva

+Geneva's

+Genevieve

+Genevieve's

+George

+George's

+Georges

+Georgetown

+Georgia

+Georgian

+Georgians

+Gerald

+Geraldine

+Gerard

+Gerber

+Gerhard

+Gerhardt

+Germania

+Germanic

+Germantown

+Gerome

+Gerry

+Gerry's

+Gershwin

+Gershwins

+Gertrude

+Getty

+Gettysburg

+Ghana

+Ghent

+Giacomo

+Gibbs

+Gibby

+Gibraltar

+Giddings

+Gideon

+Gifford

+Gilbertson

+Gilda

+Gilda's

+Giles

+Gilkson

+Gillespie

+Gillette

+Gilligan

+Gimbel

+Gioconda

+Giorgio

+Giovanni

+Gladstone

+Gladys

+Glasgow

+Gleason

+Glenda

+Glendale

+Glenn

+Gloria

+Gloucester

+Glynn

+Godot

+Goethe

+Gogh

+Golda

+Goldberg

+Goldman

+Goldstein

+Goldstein's

+Goldwater

+Goliath

+Gomez

+Gonzales

+Goodman

+Goodrich

+Goodwin

+Goodyear

+Gordian

+Gordon

+Gorham

+Gorky

+Gotham

+Gothicism

+Gracie

+Grady

+Grafton

+Granville

+Grayson

+Grecian

+Greece

+Greenberg

+Greenblatt

+Greenbriar

+Greenfeld

+Greenfield

+Greenland

+Greensboro

+Greensville

+Greentree

+Greenville

+Greenwich

+Gregg

+Gregory

+Grendel

+Grenier

+Grenoble

+Grenville

+Greta

+Gretchen

+Gretel

+Gretel's

+Griffith

+Grimm

+Gris

+Groot

+Grosset

+Grossman

+Grosvenor

+Groton

+Grumman

+Grusky

+Guadalupe

+Guam

+Guatemala

+Guatemalan

+Guggenheim

+Guhleman

+Guiana

+Gunderson

+Gunnar

+Gus

+Gutenberg

+Guthrie

+Guyana

+Gwen

+HP

+Hackett

+Hades

+Hafiz

+Hague

+Haifa

+Haiti

+Haitian

+Hal

+Halifax

+Hallinan

+Halloween

+Hamey

+Hamilton

+Hamiltonian

+Hamiltonians

+Hammett

+Hammond

+Hampshire

+Hampton

+Hancock

+Hannah

+Hannibal

+Hanoi

+Hanover

+Hanoverian

+Hans

+Hansel

+Hansen

+Hanson

+Hanukkah

+Hapgood

+Harcourt

+Hardin

+Harlem

+Harold

+Harriet

+Harris

+Harrisburg

+Harrison

+Harrisonburg

+Harry's

+Hartford

+Hartley

+Hartman

+Harvard

+Harvey

+Harveys

+Haskell

+Haskins

+Hatchure

+Hatfield

+Hattie

+Hauser

+Havana

+Hawaii

+Hawaiian

+Hawkins

+Hawley

+Hawthorne

+Haydn

+Hayes

+Haynes

+Hayward

+Haywood

+Hearst

+Heartwood

+Heathkit

+Heathman

+Hebraic

+Hebrew

+Hebrews

+Hecuba

+Hedda

+Hegel

+Hegelian

+Heidegger

+Heidelberg

+Heidi

+Heidi's

+Heinz

+Heinze

+Heisenberg

+Heiser

+Helen

+Helena

+Helene

+Heliopolis

+Hellenic

+Helmholtz

+Helmut

+Helsinki

+Hemingway

+Henderson

+Hendrick

+Hendricks

+Hendrickson

+Hendrix

+Hennessey

+Hennessey's

+Henrietta

+Hepburn

+Hera

+Heraclitus

+Herbert

+Herculean

+Hercules

+Hereford

+Herman

+Hermes

+Hermite

+Hermosa

+Hernandez

+Herodotus

+Herr

+Herrington

+Herschel

+Hersey

+Hershel

+Hershey

+Hesperus

+Hess

+Hessian

+Hessians

+Heublein

+Heywood

+Hiawatha

+Hibernia

+Hickey

+Hickeys

+Hickok

+Hieronymus

+Highfield

+Hilbert

+Hillary

+Hillcrest

+Hillel

+Hillsboro

+Hillsdale

+Hilton

+Himalayas

+Himmler

+Hindi

+Hindu

+Hindu's

+Hinduism

+Hindus

+Hinkle

+Hinsdale

+Hiram

+Hirey

+Hiroshima

+Hispanic

+Hispanic's

+Hispanics

+Hitachi

+Hitchcock

+Hitler

+Hobbes

+Hobbs

+Hobday

+Hoboken

+Hoffman

+Holbrook

+Hollerith

+Hollister

+Hollywood

+Hollywood's

+Holmes

+Holocene

+Holst

+Holstein

+Holyoke

+Holzman

+Homeric

+Hondo

+Honduras

+Honeywell

+Honolulu

+Hoosier

+Hoover

+Hoover's

+Hopi

+Hopkins

+Hopkinsian

+Horace

+Horatio

+Hornblower

+Horowitz

+Horton

+Houdini

+Houston

+Howard

+Howe

+Howell

+Hubble

+Hubble's

+Hubert

+Huck

+Hudson

+Huey

+Hugh

+Hughes

+Hugo

+Humboldt

+Hume

+Humphrey

+Humphreys

+Humpty

+Hungarian

+Hungary

+Huntsville

+Huron

+Hurst

+Hutchins

+Hutchinson

+Hutchison

+Huxley

+Hyannis

+ICC

+ISO

+ITT

+IUD

+IUDs

+Iberia

+Iberian

+Ibero

+Ibsen

+Icarus

+Iceland

+Iceland's

+Icelander

+Icelandic

+Idaho

+Igor

+Iliad

+Imbrium

+Inca

+Incas

+Indianapolis

+Indies

+Indira

+Indochina

+Indonesia

+Indonesian

+Indy

+Ingersoll

+Ingram

+Inverness

+Io

+Iowa

+Iraq

+Iraqi

+Irene

+Irish

+Irishman

+Irishmen

+Irma

+Iroquois

+Irvine

+Irving

+Irwin's

+Isaac

+Isaacs

+Isabel

+Islam

+Islamic

+Islandia

+Israelite

+Israelites

+Istanbul

+Italy

+Ithaca

+Ithacan

+Ivan

+Ivanhoe

+Izaak

+Izvestia

+Jackie

+Jackman

+Jackson

+Jacksonian

+Jacksons

+Jacksonville

+Jacky

+Jacob

+Jacobean

+Jacobian

+Jacobite

+Jacobs

+Jacobsen

+Jacoby

+Jacqueline

+Jacques

+Jakarta

+Jake

+Jakes

+Jamaica

+Jamaican

+Jameson

+Jamestown

+Jan

+Jane

+Jane's

+Janeiro

+Janesville

+Janet

+Janet's

+Janice

+Janis

+Jansen

+Janus

+Jason

+Jastrow

+Java

+Javanese

+Jaycee

+Jaycees

+Jeanette

+Jeanie

+Jeanne

+Jeannie

+Jeff

+Jeffersonian

+Jeffersonians

+Jeffrey

+Jeffreys

+Jehovah

+Jello

+Jenkins

+Jennie

+Jennifer

+Jennings

+Jeremiah

+Jeremy

+Jericho

+Jerome

+Jerry's

+Jerusalem

+Jesse

+Jesse's

+Jessica

+Jessie

+Jessy

+Jesuit

+Jesuits

+Jesus

+Jew

+Jewelled

+Jewish

+Jewishness

+Jews

+Jim

+Jim's

+Jimmie

+Jimmy's

+Jinny

+Joan

+Joanna

+Joanne

+Joanne's

+Joannes

+Joaquin

+Jobrel

+Jodi

+Jodi's

+Jody

+Joe

+Joel

+Joes

+Johann

+Johannes

+Johannesburg

+Johansen

+Johanson

+Johnny

+Johnny's

+Johnsen

+Johnson

+Johnstown

+Joliet

+Jon

+Jon's

+Jonas

+Jonathan

+Jones

+Joneses

+Joplin

+Jordan

+Jorge

+Jorgensen

+Jorgenson

+Jose

+Josef

+Joseph

+Josephine

+Josephson

+Josephus

+Joshua

+Josiah

+Jovanovich

+Jove

+Jovian

+Joyce

+Juan

+Juanita

+Jubal

+Judaism

+Judas

+Jude

+Judea

+Judith

+Judy

+Jules

+Julia

+Julian

+Juliet

+Julio

+Julius

+Juneau

+Jungian

+Juno

+Jupiter

+Justine

+Justinian

+Jutish

+KGB

+Kabuki

+Kabul

+Kaddish

+Kafka

+Kafkaesque

+Kalamazoo

+Kamikazes

+Kankakee

+Kansas

+Kant

+Karen

+Karl

+Karol

+Kate

+Katherine

+Kathleen

+Kathy

+Katie

+Katie's

+Katmandu

+Kay

+Keaton

+Keats

+Keegan

+Keenan

+Keith

+Keller

+Kelley

+Kellogg

+Kelly

+Kelly's

+Kelvin

+Kenilworth

+Kennecott

+Kennedy

+Kenneth

+Kenny

+Kenosha

+Kensington

+Kent

+Kentucky

+Kenya

+Kepler

+Kepler's

+Kermit

+Kettering

+Kevin

+Kewaskum

+Kewaunee

+Keynes

+Keynesian

+Khmer

+Khrushchev

+Khrushchevs

+Kickapoo

+Kiel

+Kiev

+Killebrew

+Kim

+Kingsbury

+Kingsley

+Kingston

+Kingstown

+Kingwood

+Kinnickinnic

+Kinsey

+Kipling

+Kirby

+Kirchoff

+Kirk

+Kirk's

+Kirkland

+Kirkpatrick

+Kirkwood

+Kiwanis

+Klan

+Klaus

+Knobeloch

+Knowles

+Knox

+Knoxville

+Knudsen

+Knudson

+Knutsen

+Knutson

+Koch

+Kodachrome

+Kodak

+Kodaks

+Kodiak

+Koenig

+Koenigsberg

+Kohler

+Kong

+Konrad

+Korea

+Korean

+Koreans

+Kraemer

+Krakatoa

+Krakow

+Kramer

+Krause

+Kremlin

+Kresge

+Kris

+Krishna

+Kristina

+Krueger

+Kruger

+Kurd

+Kurdish

+Kurt

+Kuwait

+Kyle

+Kyoto

+LIFO

+Labrador

+Lacey

+Lackawanna

+Lafayette

+Lagrange

+Laguna

+Lakehurst

+Lakewood

+Lancashire

+Lancaster

+Landis

+Landwehr

+Lange

+Langeland

+Langford

+Langley

+Lansing

+Laocoon

+Laos

+Laotian

+Laotians

+Laplace

+Laramie

+Laredo

+Larry

+Larry's

+Lars

+Larsen

+Larson

+Lathrop

+Latinate

+Lattimer

+Lauderdale

+Laundromat

+Laundromats

+Laura's

+Lauren

+Laurence

+Laurentian

+Lawford

+Lawrence

+Lawrenceville

+Lawson

+Lazarus

+Leary

+Leavenworth

+Lebanese

+Lebanon

+Lebesgue

+Lee's

+Lehigh

+Leigh

+Leighton

+Leila

+Lemke

+Lenin

+Leningrad

+Leninism

+Leninist

+Lenny

+Leo

+Leon

+Leona

+Leonard

+Leonardo

+Leone

+Leopold

+Leopoldville

+Leroy

+Leslie

+Levi

+Levine

+Levis

+Leviticus

+Lewellyn

+Lexington

+Leyden

+Liberace

+Liberia

+Libya

+Libyan

+Lichtenstein

+Lichter

+Lieberman

+Liechtenstein

+Lilliputian

+Lima

+Lincoln

+Linda

+Lindberg

+Lindy

+Linotype

+Linus

+Lionel

+Lipton

+Lisa

+Lisbon

+Liss

+Liston

+Lithuanian

+Littleton

+Litton

+Livermore

+Liverpool

+Livingston

+Lizzie

+Lizzy

+Lloyd

+Locke

+Lockhart

+Lockheed

+Lockian

+Lockwood

+Logan

+Lois

+Lola

+Lombard

+London

+Londonderry

+Londoner

+Longfellow

+Longstreet

+Lopez

+Lorelei

+Lorentzian

+Lorenz

+Lorenz's

+Lorraine

+Lothario

+Lottie

+Louis

+Louisa

+Louise

+Louisiana

+Louisianan

+Louisville

+Lovejoy

+Lovelace

+Loveland

+Lowell

+Loy

+Loyola

+Ltd

+Lubbock

+Lucas

+Lucerne

+Lucia

+Lucian

+Lucien

+Lucifer

+Lucille

+Lucius

+Lucretia

+Lucretius

+Lucy

+Ludmilla

+Ludwig

+Lufthansa

+Luftwaffe

+Luke

+Luke's

+Luna

+Luna's

+Luther

+Lutheran

+Luxembourg

+Lydia

+Lynchburg

+Lyndon

+Lynn

+Lyon

+MAG

+MBA

+MD

+MDT

+MIG

+MIGs

+MIMD

+MPH

+MST

+MTS

+MTV

+Mac

+MacArthur

+MacDonald

+MacGregor

+MacKenzie

+MacMillan

+Macarthur

+Macaulay

+Macbeth

+Macdonald

+Macedon

+Macedonia

+Macedonian

+Macgregor

+Mach

+Machiavelli

+Mackenzie

+Mackinac

+Macmillan

+Macon

+Madagascar

+Madame

+Madames

+Madeleine

+Madeleine's

+Madeline

+Madeline's

+Madison

+Madonna

+Madonnas

+Madrid

+Maelstrom

+Magdalene

+Maggie

+Magill

+Magruder

+Maguire

+Maguires

+Mahler

+Mahler's

+Maine

+Malamud

+Malay

+Malaysia

+Malaysian

+Malcolm

+Mallory

+Malone

+Malta

+Maltese

+Malthusian

+Managua

+Manchester

+Manfred

+Manitoba

+Manitowoc

+Mankowski

+Mansfield

+Manville

+Mao

+Maori

+Maplecrest

+Marcotte

+Marcus

+Marcy

+Mardi

+Mardis

+Marguerite

+Maria's

+Marian

+Marian's

+Marie

+Marie's

+Marietta

+Marilyn

+Marin

+Marino

+Mario

+Marion

+Marjorie

+Mark's

+Markov

+Markovian

+Markovitz

+Marlborough

+Marlene

+Marlowe

+Marquette

+Marriott

+Marseilles

+Marsha

+Marshall

+Marshalled

+Marshalling

+Martha

+Martian

+Martians

+Martinez

+Martinique

+Martinson

+Marty

+Marvin

+Marx

+Marxism

+Marxisms

+Marxist

+Masonic

+Masonite

+Mathews

+Mathewson

+Mathias

+Mathieu

+Matilda

+Matisse

+Matisses

+Matthew

+Matthews

+Mattie

+Maude

+Maureen

+Maurice

+Mauritania

+Mauritius

+Mawr

+Maximilian

+Maxine

+Maxwellian

+Maya

+Mayans

+Mayfair

+Mayflower

+Maynard

+Mazda

+McAdams

+McAllister

+McAllister's

+McBride

+McBride's

+McCabe

+McCabe's

+McCall

+McCall's

+McCarthy

+McCarthy's

+McCauley

+McCauley's

+McClain

+McClain's

+McClellan

+McClellan's

+McClure

+McClure's

+McCluskey

+McCluskey's

+McConnell

+McConnell's

+McCoy

+McCoy's

+McCracken

+McCracken's

+McDaniel

+McDaniel's

+McDermott

+McDermott's

+McDonald

+McDonald's

+McDonnell

+McDonnell's

+McDougall

+McDougall's

+McFadden

+McFadden's

+McFarland

+McFarland's

+McGill

+McGill's

+McGovern

+McGovern's

+McGrath

+McGrath's

+McGraw

+McGraw's

+McGregor

+McGregor's

+McGuire

+McGuire's

+McIntosh

+McIntosh's

+McIntyre

+McIntyre's

+McKay

+McKay's

+McKee

+McKee's

+McKesson

+McKesson's

+McKinley

+McKinley's

+McKinney

+McKinney's

+McKnight

+McKnight's

+McLanahan

+McLaughlin

+McLaughlin's

+McLean

+McLean's

+McLeod

+McLeod's

+McMillan

+McMillan's

+McNaughton

+McNaughton's

+McNeil

+McNeil's

+McPherson

+McPherson's

+Medea

+Medfield

+Medicaid

+Medicare

+Medici

+Medicis

+Mediterranean

+Meister

+Meistersinger

+Mekong

+Mel

+Melanesia

+Melanesian

+Melanie

+Melbourne

+Melinda

+Melisande

+Melissa

+Mellon

+Melville

+Melvin

+Memphis

+Mencken

+Mendelssohn

+Mendoza

+Menelaus

+Menlo

+Mennonite

+Mennonites

+Menominee

+Mensch

+Mephistopheles

+Mercator

+Mercedes

+Meredith

+Meriwether

+Merle

+Merriam

+Merrick

+Merrill

+Merrimac

+Merrimack

+Mesozoic

+Messrs

+Methuselah

+Methuselahs

+Mexican

+Mexicans

+Mexico

+Meyer

+Meyers

+Miami

+Michael

+Michael's

+Michaelangelo

+Michaels

+Michaelson

+Michelangelo

+Michelin

+Michelson

+Mick

+Mickelson

+Mickey

+Mickey's

+Mickie

+Micky

+Micronesia

+Micronesian

+Middlebury

+Middlesex

+Middleton

+Middletown

+Midwestern

+Midwesterner

+Midwesterners

+Miguel

+Mikhail

+Mikoyan

+Milan

+Mildred

+Millard

+Millie

+Milquetoast

+Milquetoasts

+Milton

+Miltonic

+Milwaukee

+Mimi

+Minerva

+Minneapolis

+Minnie

+Minoan

+Miocene

+Mira

+Miranda

+Miriam

+Mississippi

+Mississippian

+Mississippians

+Missoula

+Missouri

+Missy

+Mitch

+Mitch's

+Mitchell

+Mitchell's

+Mobil

+Modesto

+Mohammed

+Mohammedan

+Mohawk

+Moines

+Moliere

+Moline

+Molly

+Molotov

+Mon

+Monaco

+Monet

+Monfort

+Mongolia

+Mongolian

+Monica

+Monroe

+Monrovia

+Monsanto

+Montague

+Montaigne

+Montclair

+Monterey

+Montevideo

+Montgomery

+Monticello

+Montpelier

+Montreal

+Monty

+Mooney

+Moore

+Moorish

+Moravia

+Moravian

+Morehouse

+Moreland

+Morgan

+Moriarty

+Mormon

+Moroccan

+Morrison

+Morristown

+Morse

+Mortimer

+Morton

+Morton's

+Moscone

+Moscow

+Moses

+Mossberg

+Mozart

+Mozart's

+Muhammad

+Muir

+Mulligan's

+Mumford

+Muncie

+Mundt

+Munich

+Munroe

+Munson

+Muriel

+Murphy

+Murray

+Murrow

+Muscat

+Muscovy

+Muskegon

+Mussolini

+Mussolini's

+Mussolinis

+Mussorgsky

+Mussorgsky's

+Muzak

+Mycenae

+Mycenaean

+Myron

+NAACP

+NASA

+NATO

+NBC

+NBS

+NCAA

+NCC

+NCR

+NOAA

+NSF

+NYSE

+NaCl

+Nabisco

+Nagasaki

+Nairobi

+Nakamura

+Nakoma

+Nan

+Nancy

+Nancy's

+Nanette

+Nanking

+Nanook

+Nantucket

+Naomi

+Naples

+Napoleon

+Napoleonic

+Nash

+Nashua

+Nashville

+Nassau

+Nat

+Natalie

+Natalie's

+Natchez

+Nate

+Nathan

+Nathaniel

+Navaho

+Navajo

+Navona

+Nazarene

+Nazareth

+Nazism

+Neal's

+Neanderthal

+Neapolitan

+Needham

+Nepali

+Neptune

+Nero

+Nestor

+Neumann

+Nevada

+Newark

+Newbury

+Newburyport

+Newcastle

+Newell

+Newman

+Newport

+Newsweek

+Newsweekly

+Niagara

+Nicaean

+Nicaragua

+Niccolo

+Nicholas

+Nichols

+Nicholson

+Nicklaus

+Nicodemus

+Nielsen

+Nielson

+Nietzsche

+Nigeria

+Nigerian

+Nijinsky

+Nile

+Nilsen

+Nilsson

+Nina

+Niobe

+Nippon

+Nixon

+Noah

+Nobel

+Noel

+Norfolk

+Norma

+Norman

+Normandy

+Norris

+Norristown

+Norse

+Northampton

+Northfield

+Northumberland

+Norton

+Norwalk

+Norway

+Norwegian

+Norwich

+Nostradamus

+Notre

+Nottingham

+Noyes

+Nubian

+Nugent

+O'Brien

+O'Brien's

+O'Clock

+O'Connell

+O'Connell's

+O'Connor

+O'Connor's

+O'Dell

+O'Dell's

+O'Donnell

+O'Donnell's

+O'Dwyer

+O'Dwyer's

+O'Er

+O'Hare

+O'Hare's

+O'Leary

+O'Leary's

+O'Shea

+O'Shea's

+O'Sullivan

+O'Sullivan's

+OK's

+OPEC

+Oakland

+Oakley

+Oakmont

+Oberlin

+Occam

+Occam's

+Oconomowoc

+Octavia

+Odessa

+Odysseus

+Oedipal

+Oedipally

+Offenbach

+Ogden

+Okamoto

+Okinawa

+Olaf

+Oldenburg

+Oldsmobile

+Oleg

+Olga

+Olivers

+Olivetti

+Olivia

+Olsen

+Olson

+Olympia

+Olympian

+Olympic

+Olympics

+Olympus

+Omaha

+Oman

+Oneida

+Ontario

+Opel

+Oppenheimer

+Oregon

+Oregonians

+Orlando

+Orleans

+Orlick

+Orpheus

+Orphic

+Ortega

+Orwell

+Orwellian

+Osaka

+Osbert

+Osborn

+Osborne

+Oscar

+Oshkosh

+Oslo

+Ostrander

+Oswald

+Othello

+Ottawa

+Otto

+Otto's

+Ottoman

+Ovid

+Owen

+Owens

+Oxford

+Oxnard

+Oz

+Ozark

+Ozarks

+Ozzie

+PBS

+PDT

+PM

+PST

+PTA

+Pablo

+Pabst

+Packwood

+Paganini

+Paine

+Pakistan

+Pakistani

+Pakistanis

+Palatine

+Paleolithic

+Paleozoic

+Palermo

+Palestine

+Palmolive

+Palmyra

+Palomar

+Pam

+Pam's

+Pamela

+Pancho

+Pandora

+Pappas

+Paraguay

+Paris

+Parisian

+Parkersburg

+Parkhouse

+Parkinson

+Parrish

+Parthenon

+Pasadena

+Passaic

+Passover

+Pasternak

+Pasteur

+Patagonia

+Patagonians

+Patrice

+Patricia

+Patrick

+Patsies

+Patsy

+Patterson

+Patton

+Paul

+Paul's

+Paula

+Paulette

+Paulette's

+Pauli

+Pauline

+Pauling

+Paulsen

+Paulson

+Pavlov

+Pawtucket

+Payne

+Paynes

+Payson

+Peabody

+Peachtree

+Pearce

+Pearson

+Pecos

+Pedro

+Pegasus

+Peggy

+Peking

+Pelham

+Pendleton

+Penn

+Pensacola

+Pentecost

+Peoria

+Pepsi

+Pepsico

+Percy

+Perez

+Pergamon

+Pericles

+Perkins

+Pernod

+Perry

+Perry's

+Perseus

+Pershing

+Persia

+Persian

+Persians

+Perth

+Peru

+Peruvian

+Peruvians

+Pete

+Pete's

+Petersburg

+Petersen

+Peterson

+Pettibone

+Peugeot

+Pewaukee

+Peyton

+Peyton's

+Pfizer

+Ph

+Phaedra

+Phil

+Philadelphia

+Philco

+Philip

+Philippe

+Philippians

+Philippine

+Philippines

+Philistine

+Philistines

+Phillies

+Phillips

+Philly

+Phyllis

+Picasso

+Piccadilly

+Pickford

+Pickman

+Pierre

+Pierson

+Pillsbury

+Pinehurst

+Pipestone

+Pisa

+Pisces

+Pitney

+Pitt

+Pittsburgh

+Pittsburghers

+Pittsfield

+Pittston

+Pius

+Plainfield

+Plainview

+Plato

+Platonism

+Platonist

+Platteville

+Pleiades

+Pleistocene

+Plexiglas

+Pliny

+Pliocene

+Plutarch

+Pluto

+Plymouth

+Pocahontas

+Pocono

+Poconos

+Poe

+Poincare

+Poindexter

+Poisson

+Polaris

+Polaroid

+Polk

+Pollux

+Polynesian

+Polyphemus

+Pomerania

+Pomeranian

+Pomona

+Pompeii

+Pompey

+Pontiac

+Popsicle

+Popsicles

+Portland

+Portsmouth

+Portugal

+Portuguese

+Poseidon

+Potemkin

+Potomac

+Potsdam

+Pottawatomie

+Potts

+Poughkeepsie

+Poussin

+Poussins

+Powell

+Prague

+Pratt

+Prattville

+Pravda

+Precambrian

+Prentice

+Prenticed

+Prenticing

+Presbyterian

+Presbyterianism

+Prescott

+Presley

+Preston

+Preston's

+Pretoria

+Priestley

+Princeton

+Principia

+Priscilla

+Procrustes

+Procyon

+Prokofieff

+Promethean

+Prometheus

+Protestantism

+Proust

+Proxmire

+Prussia

+Prussian

+Ptolemaic

+Ptolemaists

+Ptolemy

+Puccini

+Puerto

+Pulaski

+Pulitzer

+Pullman

+Pullmans

+Purcell

+Purdue

+Purina

+Pygmalion

+Pyhrric

+Pyrex

+Pythagoras

+Pythagorean

+Pythagoreans

+Quakeress

+Quantico

+Quasimodo

+Quebec

+Quinn

+Quinn's

+Quixote

+RCA

+RISC

+RMS

+ROTC

+RPM

+RSVP

+Rachel

+Rachmaninoff

+Racine

+Radcliffe

+Rafael

+Rajive

+Rajive's

+Raleigh

+Ralph

+Ralph's

+Ralston

+Ramada

+Ramirez

+Ramona

+Ramsey

+Rand

+Randall

+Randolph

+Randy's

+Rangoon

+Raoul

+Raphael

+Rapunzel

+Rasmussen

+Rawlings

+Rawlins

+Rawlinson

+Rawson

+Rayburn

+Rayleigh

+Raymond

+Raymondville

+Raytheon

+Reagan

+Rebecca

+Redhook

+Redstone

+Reedville

+Reese

+Regina

+Reginald

+Regulus

+Reich

+Reichenberg

+Reichstag

+Reilly

+Reinhard

+Reinhardt

+Reinhold

+Rembrandt

+Remington

+Remus

+Renaults

+Renee

+Renee's

+Renoir

+Renville

+Reuben

+Reuters

+Reuther

+Rev

+Rex

+Reynolds

+Rhea

+Rheims

+Rheinholdt

+Rhenish

+Rhine

+Rhinelander

+Rhodes

+Rhodesia

+Rhonda

+Rican

+Ricans

+Richard

+Richard's

+Richards

+Richardson

+Richey

+Richfield

+Richland

+Richmond

+Richter

+Rickenbaugh

+Ridgefield

+Ridgway

+Riemann

+Riggs

+Riley

+Rilke

+Rinehart

+Rio

+Ripley

+Ritter

+Ritz

+Riverview

+Riviera

+Riyadh

+Robbie

+Robbins

+Roberta

+Roberto

+Robertson

+Robertsons

+Robinsonville

+Rochester

+Rochester's

+Rockaway

+Rockaways

+Rockefeller

+Rockford

+Rockland

+Rockville

+Rockwell

+Rodgers

+Rodney

+Rodney's

+Rodriguez

+Roger

+Roger's

+Rogers

+Roland

+Rollie

+Rollins

+Romano

+Rome

+Romeo

+Romeos

+Romulus

+Ron

+Ronald

+Ronnie

+Rooney

+Roosevelt

+Roosevelt's

+Rooseveltian

+Rorschach

+Rosa

+Rosabelle

+Rosalie

+Roseland

+Rosella

+Rosen

+Rosenberg

+Rosetta

+Rosie

+Ross

+Rossi

+Roswell

+Rotarian

+Rotarians

+Roth

+Rousseau

+Rousseau's

+Rowena

+Rowena's

+Rowland

+Rowland's

+Rowley

+Rowley's

+Roxy

+Roxy's

+Rozelle

+Rozelle's

+Rudolph

+Rudolph's

+Rudy

+Rufus

+Rumania

+Rumanian

+Rumanians

+Rumford

+Rummel

+Runnymede

+Runyon

+Ruppert

+Rushmore

+Russ

+Russell

+Russia

+Rutgers

+Ruth

+Rutherford

+Rutland

+Rutledge

+Ryan

+Ryder

+SCSI

+SIMD

+SMSA

+SMSA's

+SMSAs

+SPSS

+Sabine

+Sacramento

+Sadie

+Saginaw

+Sahara

+Saigon

+Salem

+Salerno

+Salisbury

+Salk

+Salvador

+Salvadoran

+Salvatore

+Sammy

+Sammy's

+Samoa

+Samoan

+Sampson

+Samson

+Samuel

+Samuels

+Samuelson

+Sanchez

+Sancho

+Sandburg

+Sanderson

+Sandia

+Sandra

+Sandusky

+Sanford

+Sanhedrin

+Sanskrit

+Sanskritic

+Santa

+Santayana

+Santiago

+Sara

+Sarah

+Sarasota

+Saratoga

+Sargent

+Sartre

+Saskatchewan

+Satan

+Saturn

+Satyanarayanan

+Satyanarayanan's

+Saud

+Saudi

+Saukville

+Saunders

+Savannah

+Saviour

+Savonarola

+Saxon

+Saxons

+Saxony

+Saxton

+Scandinavia

+Scandinavian

+Scandinavians

+Schaefer

+Schaeffer

+Schafer

+Schaffner

+Schapiro

+Scheherezade

+Schelling

+Schenectady

+Schlitz

+Schmidt

+Schmitt

+Schneider

+Schopenhauer

+Schroeder

+Schroedinger

+Schubert

+Schultz

+Schulz

+Schumacher

+Schuman

+Schumann

+Schuster

+Schwartz

+Scorpio

+Scot

+Scotchgard

+Scotchman

+Scotia

+Scotian

+Scots

+Scotsman

+Scotsmen

+Scott

+Scottish

+Scottsdale

+Scotty

+Scranton

+Scribners

+Scripps

+Scylla

+Scythia

+Seaborg

+Seabrook

+Seaquarium

+Seattle

+Seattle's

+Sebastian

+Sedgwick

+Seeley

+Segundo

+Selectric

+Selfridge

+Selma

+Seminole

+Semite

+Seneca

+Senegal

+Senora

+Seoul

+Serafin

+Serbian

+Serbo

+Serra

+Seville

+Seward

+Seymour

+Shakespeare

+Shakespearean

+Shakespearian

+Shanghai

+Shanghaiing

+Shapiro

+Sharon

+Shasta

+Shawano

+Shawnee

+Sheboygan

+Sheffield

+Sheffielder

+Sheffielders

+Sheila

+Shelby

+Sheldon

+Shelley

+Shelton

+Shenandoah

+Sheraton

+Sheridan

+Sherman

+Sherwin

+Sherwood

+Shiite

+Shiite's

+Shiites

+Shillong

+Shiloh

+Shinto

+Shintoism

+Shirley

+Shorewood

+Shreveport

+Shylock

+Shylockian

+Siamese

+Siberia

+Siberian

+Sicilian

+Siciliana

+Sicilians

+Sicily

+Sidney

+Siegfried

+Sigmund

+Signora

+Sikh

+Sikh's

+Sikhes

+Sikhs

+Sikorsky

+Silas

+Silverman

+Simmons

+Simmonsville

+Simms

+Simon

+Simpson

+Sinai

+Sinatra

+Sinclair

+Sioux

+Sirius

+Sistine

+Sisyphean

+Sisyphus

+Siva

+Skippy

+Skye

+Slav

+Slavic

+Slavs

+Slesinger

+Sloan

+Sloane

+Smallwood

+Smithfield

+Smithsonian

+Smithtown

+Smucker

+Snead

+Sneed

+Snodgrass

+Snowbelt

+Snowbelt's

+Snyder

+Socrates

+Socratic

+Sofia

+Sol

+Solly

+Solomon

+Somali

+Somalis

+Somerset

+Somerville

+Sonoma

+Sonora

+Sophia

+Sophias

+Sophie

+Sophoclean

+Sophocles

+Sorensen

+Sorenson

+Sorrentine

+Sousa

+Southampton

+Southfield

+Spahn

+Spalding

+Spaniard

+Spaniards

+Sparkman

+Sparta

+Spartan

+Spencerian

+Spenglerian

+Sperry

+Spiegel

+Spokane

+Springfield

+Squaresville

+Squibb

+Squibbing

+Stacy

+Stacy's

+Stafford

+Staffordshire

+Staley

+Staley's

+Stalin

+Stalin's

+Stalinist

+Stalins

+Stamford

+Stan

+Stan's

+Standish

+Standish's

+Stanford

+Stanford's

+Stanley

+Stans

+Stanton

+Stapleton

+Starkey

+Starr

+Staten

+Statler

+Stauffer

+Stearns

+Steinbecks

+Steinberg

+Stella

+Stephan

+Stephanie

+Stephanie's

+Stephen

+Stephens

+Stephenson

+Sterno

+Stetson

+Stetsons

+Steuben

+Steve

+Steve's

+Steven

+Steven's

+Stevens

+Stevenson

+Stevie

+Stewart

+Stewart's

+Stillwell

+Stimson

+Stirling

+Stockholm

+Stockton

+Stonehenge

+Stouffer

+Stowe

+Strasbourg

+Stratford

+Strauss

+Stravinsky

+Stromberg

+Strongheart

+Stuart

+Stubblefield

+Stubblefields

+Studebaker

+Stuttgart

+Stuyvesant

+Stygian

+Styrofoam

+Styx

+Sudan

+Sudanese

+Sudanic

+Suez

+Suffolk

+Sukarno

+Sullivan

+Sulzberger

+Sumatra

+Sumerian

+Summerdale

+Sumter

+Sunbelt

+Sunbelt's

+Sunnyvale

+Superman's

+Susan

+Susan's

+Susanne

+Susanne's

+Susie

+Susie's

+Susquehanna

+Susquehanna's

+Sussex

+Sussex's

+Sutherland

+Sutherland's

+Sutton

+Sutton's

+Suwanee

+Suwanee's

+Suzanne

+Suzanne's

+Suzuki

+Suzuki's

+Swabian

+Swabian's

+Swabians

+Swahili

+Swahili's

+Swanson

+Swarthmore

+Swartz

+Swaziland

+Swede

+Sweden

+Swedes

+Swedish

+Sweeney

+Sweeneys

+Swenson

+Swinburne

+Switzer

+Switzerland

+Sybil

+Sydney

+Sylvania

+Sylvester

+Sylvia

+Sylvie

+Symington

+Syracuse

+Syria

+Syrian

+Syrian's

+Syrians

+TNT

+TRW

+TTL

+TV

+TVA

+TWA

+Tacitus

+Tacoma

+Taft

+Tahiti

+Tahoe

+Taipei

+Taiwan

+Taiwanese

+Talladega

+Tallahassee

+Tallahatchie

+Tallahoosa

+Tallchief

+Talleyrand

+Talmud

+Tammany

+Tampa

+Tanganyika

+Tanganyika's

+Tannenbaum

+Tantalus

+Tanya

+Tanzania

+Tapdance

+Tara

+Tarrytown

+Tartuffe

+Tarzan

+Tasmania

+Tate

+Tawney

+Taylor

+Taylors

+Tchaikovsky

+Teddy

+Teheran

+Tehran

+Teledyne

+Telefunken

+Telemann

+Telex

+Templeman

+Templeton

+Tenex

+Tenneco

+Tenney

+Tennyson

+Teresa

+Terra

+Terran

+Tess

+Tessie

+Teutonic

+Tex

+Texaco

+Texan

+Texans

+Textron

+Thai

+Thailand

+Thames

+Thebes

+Thelma

+Theodore

+Theodosian

+Theodosius

+Theresa

+Theseus

+Thiensville

+Thomas

+Thompson

+Thompson's

+Thomson

+Thor

+Thoreau

+Thornburg

+Thornton

+Thorpe

+Throneberry

+Thruway

+Thruways

+Thu

+Thule

+Thurber

+Thurman

+Tiber

+Tibet

+Tibetan

+Tiburon

+Ticonderoga

+Tieck

+Tigris

+Tijuana

+Tillich

+Tillie

+Tim

+Tim's

+Timex

+Timmy

+Timon

+Tims

+Tioga

+Tippecanoe

+Tipperary

+Tito

+Titus

+Tobago

+Todd

+Todd's

+Togo

+Tokyo

+Toland

+Toledo

+Tolley

+Tolstoy

+Tombigbee

+Tommie

+Toni

+Tonio

+Toomey

+Topeka

+Topsy

+Torah

+Toronto

+Torquemada

+Tosca

+Tosca's

+Toscanini

+Toscanini's

+Toshiba

+Toshiba's

+Toto

+Toulouse

+Townley

+Townsend

+Towsley

+Toynbee

+Toyota

+Tractarians

+Tracy

+Transylvania

+Travis

+Treadwell

+Trenton

+Trianon

+Trimble

+Trinidad

+Tristan

+Trojan

+Tropez

+Trotsky

+Troutman

+Truckee

+Trudy

+Trujillo

+Truman

+Trumbull

+Tsunematsu

+Tucson

+Tudor

+Tue

+Tulane

+Tulsa

+Tunis

+Tunisia

+Tunisian

+Turin

+Turkish

+Tuscaloosa

+Tuscan

+Tuscany

+Tuskegee

+Tuttle

+Tyler

+Typhon

+Tyson

+UN

+UNESCO

+USA

+USAF

+USART

+USDA

+USPS

+USSR

+Udall

+Uganda

+Ukrainian

+Ukrainians

+Ullman

+Ulysses

+Unibus

+Uniroyal

+Unisys

+Univac

+Upton

+Uranus

+Urbana

+Ursa

+Ursula

+Ursuline

+Uruguay

+Utica

+Uzi

+Uzi's

+VGA

+VHF

+VLSI

+Vail

+Valerie

+Valhalla

+Valkyrie

+Vance

+Vancouver

+Vandenberg

+Vanderbilt

+Vanderburgh

+Varian

+Varityping

+Vatican

+Vaudois

+Vaughn

+Vega

+Vegas

+Velasquez

+Venetian

+Venetian's

+Venetians

+Venezuela

+Venezuelan

+Venice

+Venn

+Venus

+Venusian

+Venusians

+Vera

+Vergil

+Verlag

+Vermont

+Vern

+Verne

+Vernon

+Verona

+Veronica

+Versailles

+Vic

+Vic's

+Vichy

+Vichy's

+Vickers

+Vickie

+Vickie's

+Vicksburg

+Vicksburg's

+Vicky

+Vicky's

+Victoria

+Victoria's

+Victorian

+Victorians

+Victrola

+Victrola's

+Victrolas

+Vidal

+Vidal's

+Vienna

+Vienna's

+Viennese

+Viennese's

+Viet

+Vietnam

+Vietnam's

+Vietnamese

+Vietnamese's

+Viking

+Vikings

+Vince

+Vincent

+Vincent's

+Vinson

+Virginian

+Virginians

+Virgo

+Virgo's

+Virgos

+Vishnu

+Visigoth

+Visigoths

+Vitus

+Vivaldi

+Vivian

+Vladimir

+Vladivostok

+Vogel

+Vol

+Volkswagen

+Volkswagens

+Volstead

+Volta

+Voltaire

+Volvo

+Vulcan

+WFF

+WWW

+Wabash

+Waco

+Wade's

+Wagner

+Wainwright

+Wakefield

+Walbridge

+Walcott

+Walden

+Waldensian

+Waldo

+Waldorf

+Walford

+Walgreen

+Wallace

+Wallenstein

+Wally's

+Walpole

+Walsh

+Walt

+Walter

+Walters

+Walton

+Walworth

+Wang

+Wansee

+Wansley

+Warfield

+Warfield's

+Warsaw

+Warsaw's

+Warwick

+Warwick's

+Washburn

+Washoe

+Wasserman

+Waterbury

+Watergate

+Waterhouse

+Watertown

+Watkins

+Watson

+Watson's

+Wattenberg

+Watterson

+Waukesha

+Waunona

+Waupaca

+Waupun

+Wausau

+Wauwatosa

+Waveland

+Wayne

+Waynesboro

+Weatherford

+Webber

+Webster

+Webster's

+Websterville

+Weider

+Weidman

+Weinberg

+Weiner

+Weinstein

+Weiss

+Weissman

+Weissmuller

+Welch

+Welcher

+Welches

+Weldon

+Weldwood

+Wellesley

+Wellington

+Wellman

+Wellsville

+Welmers

+Wendell

+Wendy

+Wentworth

+Werner

+Wesley

+Wesleyan

+Wesson

+Westbrook

+Westchester

+Westfield

+Westhampton

+Westinghouse

+Westminster

+Westmore

+Weston

+Westphalia

+Westport

+Westwood

+Weyerhauser

+Wharton

+Wheatland

+Wheaton

+Wheatstone

+Wheelock

+Whelan

+Wheller

+Whippany

+Whipple

+Whitcomb

+Whitehall

+Whiteleaf

+Whiteley

+Whitewater

+Whitfield

+Whitlock

+Whitman

+Whitney

+Whittaker

+Whittier

+Wichita

+Wieland

+Wiggins

+Wilcox

+Wiley

+Wilfred

+Wilhelm

+Wilhelmina

+Wilkes

+Wilkinson

+Willamette

+Willard

+Willcox

+Willem

+William

+Williams

+Williamsburg

+Williamson

+Willie

+Willied

+Willies

+Willoughby

+Willy

+Wilma

+Wilmette

+Wilmington

+Wilshire

+Wilsonian

+Winchell

+Windsor

+Winehead

+Winfield

+Winifred

+Winnebago

+Winnetka

+Winnie

+Winnipeg

+Winograd

+Winooski

+Winsborough

+Winsett

+Winslow

+Winston

+Winthrop

+Wisconsin

+Wisconsin's

+Witherspoon

+Wolcott

+Wolfgang

+Wolverton

+Woodard

+Woodberry

+Woodbury

+Woodlawn

+Woodrow

+Woodward

+Woodwards

+Woolworth

+Woonsocket

+Wooster

+Worcester

+Worcestershire

+Worcestershire's

+Wordsworth

+Worthington

+Wrigley

+Wronskian

+Wyman

+Wyoming

+XOR

+Xanthus

+Xavier

+Xenia

+Xerox

+Xerox's

+Xerxes

+YMCA

+YWCA

+Yakima

+Yale

+Yalies

+Yalta

+Yankee

+Yankees

+Yaqui

+Yates

+Yeager

+Yeats

+Yemen

+Yiddish

+Yoknapatawpha

+Yokohama

+Yonkers

+Yorick

+Yorktown

+Yosemite

+Youngstown

+Ypsilanti

+Yuba

+Yucatan

+Yugoslav

+Yugoslavia

+Yukon

+Yuri

+Yves

+Yvette

+Zachary

+Zaire

+Zanzibar

+Zeffirelli

+Zeiss

+Zellerbach

+Zen

+Zennist

+Zeus

+Zeus's

+Ziegfeld

+Ziegfeld's

+Ziegfelds

+Ziegler

+Ziegler's

+Ziggy

+Zimmerman

+Zimmerman's

+Zion

+Zion's

+Zionism

+Zionist

+Zionist's

+Zionists

+Zions

+Zoroaster

+Zoroastrian

+Zoroastrians

+Zurich

+Zurich's

+aardvark

+aardvark's

+aardvarks

+abalone

+abalone's

+abalones

+abdicate

+abdicated

+abdicates

+abdicating

+abdication

+abeyant

+abominate

+abominated

+abominates

+abominating

+abomination

+abominations

+aborning

+aboveboard

+abrasive

+abrasively

+abrasiveness

+abrasives

+abscissae

+abstemiously

+abstinent

+abstinently

+abusable

+academician

+academicianship

+acceptant

+accessors

+accordant

+accordantly

+accrual

+accruals

+acetic

+achromatic

+acknowledgeable

+acquiescent

+acquiescently

+acquisitive

+acquisitively

+acrylate

+actinic

+actinide

+actuaries

+addend

+addle

+addled

+addles

+addling

+adios

+adjectival

+adjectivally

+adjoint

+administrable

+administrate

+administrated

+administrates

+administrating

+administratrix

+adsorbate

+adsorptive

+adsorptively

+advert

+adverted

+adverting

+adverts

+aeolian

+afforest

+afforestation

+afro

+afterbirth

+afterglow

+afterlife

+aftershave

+agribusiness

+agriculturalists

+aha

+ahem

+ahoy

+ain't

+airfare

+airmass

+airpark

+airplay

+airtight

+airtightness

+ala

+albatross

+aldehyde

+aleph

+alewife

+allegiant

+alliterate

+alliterated

+alliterates

+alliterating

+allocable

+allotropic

+allspice

+alluvial

+alluvium

+almagest

+almshouses

+alp

+altercate

+altho

+altimeter

+altimeter's

+altimeters

+alway

+ambrose

+ambrosia

+ambulant

+amethyst

+amethystine

+aminobenzoic

+ammeter

+ammeter's

+ammeters

+amoebae

+amperage

+amperages

+anachronistic

+anaglyph

+analgesic

+anamorphic

+anastigmatic

+androgynous

+angelfish

+angiosperm

+angora

+anhydride

+anhydrite

+animadversion

+animadvert

+anneal

+annealed

+annealer

+annealers

+annealing

+anneals

+annuities

+annuity

+annular

+annularly

+annulus

+anodic

+antacid

+antebellum

+anthropogenic

+anthropometric

+anthropometrics

+anthropometry

+anticlimactic

+antifreeze

+antigone

+antilogs

+antimatter

+antimatter's

+antipasto

+antiperspirant

+antiquary

+antisemitic

+antisemitism

+antisemitism's

+antithetic

+anytime

+apache

+apaches

+apolar

+apparency

+applesauce

+applicate

+apposite

+appositely

+appositeness

+apposition

+appositive

+appositively

+appropriable

+arbitrage

+arbitrager

+arboretum

+arcana

+archetypical

+archetypically

+arcsine

+arctangent

+ardency

+areawide

+arenaceous

+armada

+armature

+armatures

+arrangeable

+arrear

+arrestee

+arrestee's

+arrestees

+arrowroot

+arsenate

+arsenide

+artesian

+articulable

+artier

+artiness

+arty

+ascriptive

+ashame

+ashier

+ashy

+asperity

+asphyxiate

+asphyxiation

+asplenium

+assertional

+assignation

+assignations

+assimilationist

+assn

+associable

+assumability

+asteria

+astigmatic

+astigmatism

+astraddle

+astronautic

+astronomic

+astrophysicist

+astrophysicist's

+astrophysicists

+athwart

+attestation

+attributional

+audibility

+audiotape

+audiovisual

+audiovisuals

+auntie

+auric

+australites

+autoloader

+autostart

+aviate

+aviations

+aviatrix

+axiology

+azimuthal

+azimuthally

+babbitt

+babbitted

+babbitting

+babbitts

+baboon

+babysitting

+baccarat

+bachelorhood

+backarrow

+backboard

+backchaining

+backfill

+backfilled

+backfilling

+backfills

+backhand

+backhanded

+backhandedly

+backhander

+backorder

+backplate

+backplates

+backside

+backstop

+backwood

+badland

+badmen

+baggageman

+baggagemen

+baldy

+baleen

+ballfields

+bandaid

+bandoleers

+bandstop

+bangkok

+barefaced

+barefacedly

+barefacedness

+barkeep

+barkeeper

+barnacle

+barnacled

+barnful

+barnsful

+baronet

+barrette

+barrette's

+barrettes

+barstool

+barstool's

+barstools

+bartend

+baseband

+basemen

+baseplate

+basilar

+basilisk

+basophilic

+basswood

+bates

+batik

+batwings

+bayberries

+bayberry

+beadsman

+beadworker

+beasties

+beautician

+beauticians

+beaux

+bebop

+bedmate

+bedmate's

+bedmates

+bedpan

+bedpan's

+bedpans

+bedstraw

+beechwood

+befuddlement

+begonia

+behemoths

+belate

+belladonna

+bellflower

+bellyache

+bellyacher

+bellyaching

+bellyfull

+belove

+belvedere

+beman

+bemuse

+bemused

+bemusedly

+benefice

+beneficent

+beneficently

+berg

+bergen

+berger

+bergs

+beribbon

+berserk

+berserker

+bespoke

+bestir

+bestirring

+bestubble

+bestubbled

+betatron

+bethel

+bethought

+betoken

+betokened

+betokening

+bettor

+bewhisker

+bezel

+biaxial

+biaxially

+bicep

+bichromate

+bichromated

+biconnected

+bidiagonal

+biharmonic

+bilayer

+bilayers

+bilingualism

+billies

+billy

+bimetallic

+bimetallism

+bindery

+bindle

+biochemist

+biochemists

+biograph

+biologic

+biomass

+biometric

+biometrics

+biometry

+biomolecule

+biomolecules

+biophysic

+biophysical

+biophysically

+biophysicist

+biophysicists

+biophysics

+bioscience

+biosciences

+biosphere

+biostatistic

+biostatistics

+biotic

+birdseed

+birdwatch

+birth's

+birthrate

+birthrate's

+birthrates

+biserial

+bisexual

+bisexual's

+bisexually

+bisexuals

+bishopric

+bistable

+bistate

+bisyllabic

+bittern

+bitternut

+bitterroot

+bitumen

+blackball

+blackballed

+blackballing

+blackballs

+blackbodies

+blackbody

+bladdernut

+bladderwort

+blameworthiness

+blameworthy

+blanc

+blatancy

+blather

+blathered

+blatherer

+blathering

+blatting

+blazon

+blazoned

+blazoner

+blazoning

+bldg

+bleeps

+blest

+blindside

+blindsided

+blindsides

+blindsiding

+blockier

+blocky

+bloodbath

+bloodroot

+blotch

+blowtorch

+blueback

+bluebill

+bluebook

+bluebush

+bluegill

+bluegrass

+bluejacket

+boa

+boas

+bobble

+bobbled

+bobbles

+bobbling

+bobcat

+bobsled

+bobsledding

+bock

+bockwurst

+bodhisattva

+bodyweight

+bogey

+bogeyed

+bogeying

+bogeymen

+bogeys

+bogging

+boggy

+bogies

+bogy

+boilermaker

+boilermaker's

+boilermakers

+bolivar

+bolo

+bolometer

+bolometer's

+bolometers

+bolos

+bona

+bongo

+bonito

+bonjour

+bonzes

+boogie

+bookbind

+bookbinder

+bookbinders

+bookbinding

+bookend

+bookends

+bookkeep

+bookplate

+bookplates

+boomtown

+boomtowns

+boosterism

+bootblack

+bootblacks

+bop

+bopping

+borosilicate

+boson

+bossier

+bossies

+bossiness

+bossy

+botanic

+botfly

+bottommost

+botulin

+bouillon

+boutique

+boutiques

+bowie

+boxier

+boxiness

+boxy

+bpi

+brachia

+brachium

+bracken

+brad

+braggadocio

+brakeman

+brakemen

+brakemen's

+brandywine

+bratwurst

+breadfruit

+breadfruits

+breastfed

+breastfeed

+breastfeeding

+breastplate

+bribery

+brickmason

+brickmasons

+brickyard

+brimming

+brimstone

+brinier

+brininess

+briny

+bristlier

+bristly

+bristol

+bristols

+broadloom

+bronc

+bronchiolar

+bronchiolitis

+bronco

+broncos

+broncs

+broodiness

+broody

+brookside

+brouhaha

+brucellosis

+brushwork

+bubonic

+buckaroo

+buckaroos

+bucketful

+bucketful's

+buckeye

+buckhorn

+bufflehead

+bugaboo

+bugbears

+bugeyed

+bulblet

+bullfinch

+bullfrog

+bullhead

+bullheaded

+bullheadedly

+bullheadedness

+bullhide

+bullseye

+bullshit

+bullwhackers

+bullyboy

+bullyboys

+bulrush

+burble

+burbled

+burbler

+burbles

+burbling

+burg

+burgers

+burlap

+burley

+bushmaster

+busyness

+butch

+butene

+butterball

+buttercup

+buttermilk

+buttery

+buttonweed

+bypath

+byroad

+cabal

+cabals

+cabana

+cabanas

+cabaret

+cabarets

+cabdriver

+cabdrivers

+cabinetmaker

+cabinetmaker's

+cabinetmakers

+cabinetry

+cacao

+cacciatore

+cackly

+cacophonist

+cacophony

+cadaver

+cadaverous

+cadaverously

+caddies

+caddy

+cadent

+cadenza

+cadet

+cadge

+cadged

+cadger

+cadges

+cadging

+cadmium

+cadre

+caffeine

+caffeine's

+cagey

+cageyness

+cahoot

+cahoots

+cairn

+cairned

+cairns

+calamitous

+calamitously

+calamitousness

+calcareous

+calcareously

+calcareousness

+calcification

+calcified

+calcify

+calcite

+calculability

+calculable

+calculableness

+calculi

+calfskin

+californium

+caliphate

+calisthenic

+calisthenics

+callable

+callee

+callee's

+calligraph

+calligrapher

+calligraphers

+calligraphy

+calliope

+callow

+callowness

+caloric

+calorimeter

+calorimeter's

+calorimeters

+calorimetric

+calorimetry

+calumniate

+calumniated

+calumniation

+calumny

+calvary

+calve

+calving

+calypso

+cam

+camaraderie

+camber

+cambered

+cambering

+camellias

+cameo

+cameos

+cameraman

+cameramen

+campesinos

+campfire

+campground

+campgrounds

+campsite

+campsites

+cams

+cancerous

+cancerously

+candidacy

+candlelight

+candlelighter

+canine

+canines

+canister

+canisters

+cannabis

+canneries

+cannery

+cannibalism

+cannibalism's

+cannibalistic

+cannier

+canniness

+cannonball

+canny

+canonic

+canonist

+cant

+cantaloupe

+cantaloupe's

+cantaloupes

+canted

+canteen

+canteens

+canter

+cantered

+canticle

+cantilever

+cantilevers

+canting

+canvasback

+capacitate

+capacitative

+capitalistic

+capitulate

+capitulated

+capitulates

+capitulation

+caprice

+capsize

+capsized

+capsizes

+capsizing

+capstan

+capstans

+capstone

+capsule

+capsuled

+capsules

+capsuling

+captaincy

+captious

+captiously

+captiousness

+caramel

+caraway

+carbide

+carbine

+carbines

+carbonaceous

+carbonyl

+carborundum

+carboy

+carbuncle

+carbuncled

+carcinogen

+carcinogenic

+carcinogens

+carcinoma

+cardiology

+cardiomegaly

+cardiovascular

+careen

+careened

+careening

+careerism

+caretaker

+caretakers

+careworn

+caricature

+caricatured

+caricatures

+caricaturist

+carload

+carloading

+carloads

+carmine

+carnage

+carnal

+carnality

+carnally

+carob

+carouse

+caroused

+carouser

+carousing

+carp

+carped

+carpentry

+carper

+carping

+carpingly

+carport

+carps

+carrageen

+carrel

+carrels

+carrion

+carte

+cartels

+cartilage

+cartographer

+cartographers

+cartographic

+cartoonist

+cartoonists

+cartwheel

+cartwheeler

+cartwheels

+carven

+casbah

+casebook

+casebooks

+casein

+casework

+caseworker

+caseworkers

+cashew

+cashews

+cashmere

+casino

+casinos

+cassette

+cassettes

+cassock

+cassocked

+castanet

+castanets

+castigate

+castigated

+castigates

+castigation

+castor

+cataclysmic

+catalysis

+catalytic

+catalytically

+catapult

+catapulted

+catapulting

+catapults

+catastrophically

+catatonia

+catbird

+catchier

+catchword

+catchwords

+catchy

+catechism

+catecholamine

+catecholamines

+categoric

+catenate

+catenation

+catfish

+catharsis

+cathodic

+catholicism

+catlike

+catnip

+cattail

+cattier

+catties

+cattiness

+cattleman

+cattlemen

+catty

+catwalk

+catwalk's

+catwalks

+caucus

+caucuses

+caucusing

+cauliflower

+cauliflowers

+caulk

+caulker

+caulks

+causate

+causative

+causatively

+cautionary

+cavalcade

+cavalcades

+cavalrymen

+caveman

+cavemen

+cavernous

+cavernously

+caviar

+cavil

+cavort

+cavorted

+cavorting

+cayenne

+cede

+ceded

+ceder

+cedilla

+ceding

+celebrant

+celebrants

+celerity

+celesta

+cello

+cellophane

+cellos

+cellulose

+celluloses

+censorial

+centaur

+centaurs

+centenary

+centennial

+centennially

+centigrade

+centigrades

+centrality

+centrifugal

+centrifugally

+centrifugals

+centrifugate

+centrifugation

+centrist

+centroid

+centroids

+ceramic

+ceramics

+cerate

+cerated

+cerebellum

+cerebrate

+cerebrated

+cerebrates

+cerebrating

+cerebration

+cerebrations

+ceremonious

+ceremoniously

+ceremoniousness

+cerise

+cerium

+certiorari

+certitude

+certitudes

+cerulean

+cervical

+cesium

+cession

+cetera

+ceteras

+chainlike

+chairlady

+chairwoman

+chairwomen

+chaise

+chalkline

+chalky

+chambermaid

+chambermaids

+chamfer

+chamfered

+chamfering

+chamfers

+chamois

+champ

+champers

+champs

+chanceries

+chancery

+chancier

+chanciness

+chancy

+chantey

+chantries

+chantry

+chaparral

+chaperone

+chaperones

+chapping

+charisma

+charismatic

+charitably

+charlatans

+charred

+chartist

+chartists

+chartreuse

+chartroom

+chartrooms

+charwomen

+chassis

+chastisement

+chastisements

+chastity

+chateaux

+chatted

+chattel

+chattels

+chattier

+chattiness

+chatting

+chatty

+chaw

+checkerboard

+checkerboards

+checklist

+checklists

+checksummed

+checksumming

+checkup

+checkups

+cheekbone

+cheekbones

+cheekier

+cheekiness

+cheeky

+cheerleader

+cheerleaders

+cheesecloth

+cheesier

+cheesiness

+cheesy

+cheetah

+chelate

+chelated

+chelating

+chelation

+chelations

+chemic

+chemotherapy

+chemotherapy's

+chevalier

+chevron

+chevroned

+chianti

+chic

+chicanery

+chicly

+chicness

+chicory

+chiefdom

+chiefdoms

+chigger

+chiggers

+chilblain

+chilblains

+childbearing

+childbirth

+childless

+childlessness

+childlike

+childlikeness

+childrearing

+chili

+chimera

+chimeric

+chimpanzee

+chimpanzees

+china

+chinchilla

+chinless

+chipboard

+chipped

+chipper

+chipping

+chiropractor

+chiropractors

+chive

+chives

+chivying

+chlorate

+chloride

+chlorides

+chlorinate

+chlorinated

+chlorinates

+chlorination

+chloroform

+chlorophyll

+choirmaster

+chokeberry

+cholesterol

+cholinesterase

+chomp

+choosier

+choosy

+choppier

+choppiness

+choppy

+chorale

+chorales

+chordal

+chordata

+chordate

+choreograph

+choreographed

+choreographer

+choreographers

+choreographic

+choreography

+chorines

+chortle

+chortled

+chortles

+chortling

+chow

+chowder

+chowders

+chrissake

+chromate

+chromatic

+chromaticness

+chromatics

+chromatogram

+chromatogram's

+chromatograms

+chromatograph

+chromatographic

+chromatography

+chrome

+chromed

+chromes

+chromic

+chroming

+chromite

+chromium

+chromosphere

+chronically

+chronograph

+chronography

+chrysalis

+chrysanthemum

+chrysanthemum's

+chrysanthemums

+chub

+chubs

+chug

+chugging

+chugs

+chummier

+chumminess

+chumming

+chummy

+chunkier

+chunky

+churchgoers

+churchgoing

+churchmen

+churchwoman

+churchwomen

+churl

+churls

+chutney

+chutneys

+ciao

+cicada

+cicadas

+cilia

+ciliate

+ciliated

+ciliately

+ciliates

+cinch

+cinches

+cinema

+cinemas

+cinematic

+cinnabar

+circa

+circlet

+circulant

+circulatory

+circumcise

+circumcised

+circumciser

+circumcises

+circumcising

+circumcision

+circumcisions

+circumferential

+circumferentially

+circumpolar

+circumscribe

+circumscribed

+circumscribes

+circumscribing

+circumscriptions

+circumspection

+circumspections

+circumsphere

+circumvention

+circumventions

+citizenry

+citrate

+citrated

+citric

+citron

+citrus

+citruses

+cityscape

+cityscapes

+citywide

+civet

+cladding

+clairvoyance

+clammier

+clamminess

+clamming

+clammy

+clamshell

+clamshells

+clandestine

+clandestinely

+clandestineness

+clank

+clanked

+clanking

+clankingly

+clannish

+clannishly

+clannishness

+clapboard

+clapboards

+clapped

+clapping

+claret

+clarets

+clarinet

+clarinets

+clarion

+classicist

+classier

+classiest

+classificatory

+classiness

+classless

+classlessness

+classy

+clattery

+claustrophobia

+claustrophobic

+clave

+claver

+clavicle

+clavicle's

+clavicles

+clearcut

+clearheaded

+clearheadedly

+clearheadedness

+clearinghouse

+cleat

+cleated

+cleating

+cleats

+clemence

+clemency

+clement

+clemently

+clements

+clergymen

+cleric

+clerics

+clientele

+cliffhanging

+climactic

+climatological

+climatologically

+climatology

+clinician

+clinicians

+clinometer

+clinometer's

+clinometers

+clipboard

+clipboards

+cloakroom

+cloakrooms

+clockwatcher

+cloddish

+cloddishness

+clodhopper

+clodhopper's

+clodhoppers

+clomp

+clomped

+clomping

+clomps

+closeup

+closeups

+clot

+clothbound

+clothesbrush

+clothesline

+clotheslines

+clothesman

+clothesmen

+clothier

+clotted

+clotting

+cloture

+clotured

+clotures

+cloturing

+cloudburst

+cloudbursts

+cloy

+cloying

+cloyingly

+clubhouse

+clubroom

+clubrooms

+clunkiness

+clunky

+clunkyly

+cm

+coachmen

+coachwork

+coadjutor

+coagulable

+coalescence

+coalescent

+coastline

+coattail

+coattails

+coauthor

+cobalt

+cobble

+cobbled

+cobbles

+cobblestone

+cobblestoned

+cobblestones

+cobbling

+coble

+cobra

+cocaine

+cochineal

+cochlea

+cockatoo

+cockcrow

+cockeye

+cockeyed

+cockeyedly

+cockeyedness

+cockier

+cockiness

+cockle

+cocklebur

+cockleshell

+cockpit

+cockpits

+cockscomb

+cocksure

+cocky

+coda

+coddle

+coddled

+coddler

+coddles

+coddling

+codebook

+codebooks

+codebreak

+codetermine

+codetermines

+codfish

+codicil

+coed

+coedited

+coediting

+coeditor

+coeditor's

+coeditors

+coedits

+coeds

+coeducation

+coequal

+coequally

+coercible

+coexistent

+coextensive

+coextensively

+cofactor

+cofactors

+coffeecup

+coffeepot

+cog

+cognac

+cognate

+cognately

+cognates

+cognation

+cognations

+cogs

+cohabitational

+coherency

+cohort

+cohort's

+cohorts

+coiffure

+coiffured

+coincident

+coincidently

+coital

+coitally

+coitus

+cola

+colander

+colanders

+colatitude

+colatitudes

+coleus

+colicky

+coliform

+coliseum

+collagen

+collapsibility

+collapsible

+collarbone

+collard

+collectivities

+collegian

+collegians

+collimate

+collimated

+collimates

+collimating

+collimation

+collinear

+collinearity

+collocation

+colloidal

+colloidally

+colloquia

+colloquial

+colloquialism

+colloquialism's

+colloquialisms

+colloquially

+colloquium

+collude

+colluded

+colludes

+colluding

+collusion

+collusions

+colonialism

+colonialist

+colonnade

+colonnaded

+colonnades

+coloration

+coloratura

+coltish

+coltishly

+coltishness

+columbines

+columnist

+columnists

+coma

+comas

+comatose

+combatted

+combinable

+combo

+combos

+combustible

+combustibles

+comeback

+cometary

+comeuppance

+commando

+commandos

+commendable

+commendatory

+commensurable

+commercialism

+commies

+commingle

+commingled

+commiserate

+commiserated

+commiserates

+commiserating

+commiseration

+commiserative

+commissary

+committable

+committal

+committeeman

+committeemen

+committeewoman

+committeewomen

+commodious

+commodiously

+commodiousness

+communicable

+communicational

+communique

+communiques

+communism

+communistic

+commutable

+commutate

+commutated

+commutates

+commutating

+commutation

+commutations

+compaction

+compatriot

+compatriots

+compellable

+compendia

+compensable

+competencies

+competency

+complacency

+complacent

+complainant

+complainants

+complaisance

+complaisant

+complaisantly

+complementarity

+complementation

+compliant

+compliantly

+comport

+comported

+comportment

+compositor

+compositors

+compost

+compote

+compressibility

+compressor

+compressors

+compulsive

+compulsively

+compulsiveness

+compulsives

+compulsivity

+con

+concave

+conceptuality

+concertina

+concertmaster

+concerto

+concertos

+concessionaire

+concessionaires

+conch

+conches

+concierge

+concierges

+conciliate

+conciliated

+conciliates

+conciliation

+conciliations

+conciliative

+conciliator

+conciliatory

+conclave

+conclaves

+concoct

+concocted

+concocter

+concoctive

+concocts

+concordance

+concordant

+concordantly

+concourse

+concourses

+concubine

+concubines

+concussion

+concussions

+condemnate

+condemnatory

+condensate

+condensates

+condensations

+condensible

+condescension

+condiment

+condiments

+condo

+condo's

+condolence

+condolences

+condominium

+condominium's

+condominiums

+condoms

+condos

+conduce

+conduced

+conduces

+conducing

+conductance

+conductances

+coneflower

+coney

+confabulate

+confabulated

+confabulates

+confabulation

+confabulations

+confect

+confectionery

+confects

+conferee

+conferees

+conferrable

+confessional

+confessionally

+confessionals

+confirmatory

+confiscatory

+conflagration

+conflagrations

+confluent

+confluents

+conformal

+conformance

+conformation

+conformation's

+conformational

+conformationally

+conformations

+conformist

+conformists

+confrontational

+confute

+confuted

+confuter

+confutes

+confuting

+congeal

+congealed

+congealing

+congeals

+congeniality

+congenital

+congenitally

+congest

+congesting

+congestive

+congests

+conglomerate

+conglomerated

+conglomerates

+conglomeration

+conglomerations

+conglomerative

+congratulatory

+congregationalism

+congregationalist

+congregationalists

+congressmen

+congresswoman

+congresswomen

+congruity

+congruous

+congruously

+congruousness

+conic

+conical

+conically

+conicalness

+conics

+conifer

+coniferous

+conifers

+conjectural

+conjecturally

+conjoin

+conjoining

+conjoins

+conjoint

+conjointly

+conjugal

+conjugally

+conjugate

+conjugated

+conjugately

+conjugateness

+conjugates

+conjugating

+conjugation

+conjugations

+conjugative

+conjuncture

+conjunctures

+conk

+conked

+conker

+conkers

+conking

+conks

+conn

+conned

+conner

+conning

+connivance

+connive

+connived

+conniver

+connives

+conniving

+connotation

+connotations

+connotative

+connotatively

+connubial

+connubially

+conquistador

+conquistadores

+conquistadors

+consanguine

+consanguineous

+consanguineously

+consanguinity

+conscionable

+conscript

+conscripted

+conscripting

+conscription

+conscriptions

+conscripts

+consensual

+consensually

+conservator

+conservatory

+consistence

+consonance

+consonantal

+conspiratorial

+conspiratorially

+constance

+consternate

+consternated

+consternates

+consternating

+constrict

+constricted

+constricting

+constriction

+constrictions

+constrictive

+constrictor

+constrictors

+constricts

+constructional

+constructionally

+consular

+cont'd

+contaminant

+contaminants

+contentious

+contentiously

+contentiousness

+contestant

+contestants

+continence

+continuant

+contort

+contorted

+contorting

+contortion

+contortions

+contortive

+contorts

+contraband

+contrabass

+contraception

+contraceptive

+contraceptives

+contradictorily

+contraindicate

+contraindicated

+contraindicates

+contraindicating

+contraindication

+contraindication's

+contraindications

+contraindicative

+contrarily

+contravene

+contravened

+contravener

+contravenes

+contravening

+contravention

+contrite

+contritely

+contriteness

+contrition

+controversialists

+controvertible

+contumacy

+contumely

+contusion

+contusions

+convalesce

+convalescent

+convalescing

+convection

+convections

+conventionality

+conversationalist

+convexity

+conveyor

+conveyors

+convivial

+convivially

+convocation

+convocations

+convoke

+convoked

+convokes

+convoking

+convolute

+convolutely

+convolution

+convolutions

+convolve

+convolved

+convolves

+convolving

+convulse

+convulsed

+convulses

+convulsing

+convulsive

+convulsively

+convulsiveness

+cookbook

+cookbooks

+coolant

+coolants

+coolheaded

+coplanar

+copolymer

+copolymers

+copperhead

+coppersmith

+coppersmiths

+coppery

+copter

+copters

+copybook

+copybooks

+copyist

+copywriter

+coquette

+coquetted

+coquetting

+cordage

+cordite

+cordon

+corduroy

+corduroys

+coriander

+corkscrew

+corkscrews

+cornbread

+cornea

+cornet

+cornflower

+cornier

+corniest

+corniness

+cornmeal

+cornstarch

+cornucopia

+corny

+corona

+coronal

+coronate

+coroner

+coroners

+corporeal

+corporeality

+corporeally

+corporealness

+corpsman

+corpsmen

+corpulence

+corpulences

+corpulent

+corpulently

+corpulentness

+corpulentnesses

+corpuscular

+corral

+corralled

+corralling

+corrals

+corrigendum

+corrigible

+corrode

+corroded

+corrodes

+corrodible

+corroding

+corrosive

+corrosively

+corrosiveness

+corrosives

+corrugate

+corrugated

+corrugates

+corrugating

+corrugation

+corrugations

+corruptible

+corsage

+corsages

+cortex

+cortexes

+cortical

+cortically

+corticosteroid

+corticosteroids

+cortisone

+corundum

+coruscate

+coruscated

+coruscates

+coruscating

+coruscation

+coruscations

+corvette

+cosily

+cosmic

+cosmical

+cosmically

+cosmological

+cosmologically

+cosmologist

+cosmologist's

+cosmologists

+cosmopolitanism

+cosmos

+cosmoses

+cosponsor

+cosponsored

+cosponsors

+cossack

+cossacks

+cosy

+cotangent

+coterminous

+coterminously

+cotillion

+cotter

+cotters

+cottonmouth

+cottonseed

+cottonwood

+cottony

+cougar

+cougars

+could've

+coulomb

+councilman

+councilmen

+councilwoman

+councilwomen

+counterargument

+counterarguments

+counterattack

+counterattacker

+counterbalance

+counterbalanced

+counterbalances

+counterbalancing

+counterclaim

+countercyclical

+counterflow

+counterforce

+counterintuitive

+counterman

+countermand

+countermanded

+countermanding

+countermands

+countermen

+counterpoise

+counterproposal

+countersink

+countersinking

+countersinks

+countersunk

+countervail

+countervailed

+countervailing

+countervails

+counterweight

+counterweight's

+counterweighted

+counterweighting

+counterweights

+countrified

+countrify

+countrymen

+countrywide

+coup

+coupe

+couplet

+couplet's

+couplets

+coups

+courtesan

+covalent

+covalently

+covariance

+covariances

+covariant

+covariants

+covariate

+covariates

+covariation

+covary

+coven

+coverall

+coveralled

+coveralls

+covington

+cowbell

+cowbird

+cowbirds

+cowhand

+cowhands

+cowherd

+cowhide

+cowhided

+cowhiding

+cowlick

+coworker

+coworker's

+coworkers

+cowpoke

+cowpony

+cowpox

+cowpunch

+cowpuncher

+coxcomb

+coxcombs

+coy

+coyly

+coyness

+cozen

+crabapple

+crabbed

+crabbedly

+crabbedness

+crabbing

+crackpot

+crackpots

+craftsmanship

+craftsmen

+craftspeople

+craggier

+cragginess

+craggy

+crammed

+cramming

+cranelike

+crania

+cranium

+crankcase

+crankshaft

+crannied

+crannies

+cranny

+crappie

+crappier

+crass

+crassest

+crassly

+crassness

+craw

+crawlspace

+crawlway

+crawly

+crayfish

+crayon

+crayons

+creakier

+creaky

+creamery

+creationism

+creationism's

+credent

+credential

+credentials

+credenza

+credo

+credos

+creedal

+creekside

+creepier

+creepiness

+creepy

+crematory

+crescendo

+cress

+crestfallen

+crestfallenly

+crestfallenness

+cretinous

+crewcut

+crewel

+crewman

+crewmen

+cribbing

+criminality

+crimp

+crimped

+crimper

+crimping

+crimps

+crinkle

+crinkled

+crinkles

+crinkling

+crinkly

+criss

+crisscross

+crisscrossed

+crisscrosses

+criticality

+crock

+crocked

+crocker

+crockery

+crocks

+crocodile

+crocodiles

+crocus

+crocuses

+croft

+crofter

+crofters

+crone

+crones

+cronies

+crony

+croon

+crooned

+crooner

+crooners

+crooning

+croons

+crossarm

+crosshatch

+crosshatched

+crosshatches

+crosshatching

+crosspoint

+crossproduct

+crossproducts

+crossroad

+crossroading

+crossroads

+crosstalk

+crosswalk

+crossway

+crossways

+crosswise

+crotch

+crotched

+crotches

+crotchetiness

+crotchety

+croupier

+croutons

+crowbait

+crowbar

+crowbar's

+crowbars

+crowfoot

+crowfoots

+crucible

+crucifix

+crucifixion

+crud

+cruddy

+crudities

+crudity

+cruft

+crufty

+crummier

+crummies

+crummy

+crump

+crushproof

+cryogenic

+cryogenics

+cryostat

+crypt

+cryptanalyst

+cryptanalytic

+cryptogram

+cryptogram's

+cryptograms

+cryptographer

+cryptologic

+cryptological

+cryptologist

+crypts

+crystallite

+crystallites

+crystallographer

+crystallographers

+crystallographic

+crystallography

+cubbyhole

+cubicles

+cubism

+cubist

+cubists

+cud

+cuddlier

+cuddly

+cufflink

+cufflinks

+cuisine

+culinary

+culpa

+culpable

+culpableness

+culpas

+cultist

+cultists

+cultivable

+culvert

+cumin

+cumulate

+cumulated

+cumulates

+cumulating

+cumulation

+cumulations

+cumulus

+cupcakes

+cupidity

+cupric

+cuprous

+curate

+curative

+curatively

+curator

+curators

+curbside

+curd

+curdle

+curdled

+curdles

+curdling

+curia

+curiae

+curie

+curio

+curios

+curlicue

+curricula

+curtsey

+curtseyed

+curtseying

+curtseys

+curvaceous

+curvaceously

+curvilinear

+curvilinearity

+curvilinearly

+cushiest

+cushy

+custodial

+customhouse

+customhouses

+cutaneous

+cutaneously

+cutback

+cutbacks

+cutlass

+cutlet

+cutlets

+cutout

+cutouts

+cutthroat

+cuttlebone

+cuttlebones

+cuttlefish

+cuttlefishes

+cutworm

+cyanate

+cyanic

+cyanide

+cyclical

+cyclist

+cyclists

+cyclohexanol

+cyclopean

+cyclops

+cylindric

+cynic

+cynicism

+cynics

+cytochemistry

+cytolysis

+cytoplasm

+czarevitch

+czarina

+czarism

+czarist

+czarship

+d'art

+d'etat

+d'etre

+d'oeuvre

+d's

+dab

+dabbed

+dabbing

+dabs

+dachshund

+dactyl

+dactylic

+dactyls

+daffier

+daffy

+dairyland

+dairyman

+dairymen

+dais

+daises

+dallied

+dallier

+dally

+dallying

+dammed

+damming

+dammit

+dancelike

+dandily

+dang

+danged

+dank

+dankly

+dankness

+dapper

+dapperly

+dapperness

+dapple

+dappled

+dapples

+dappling

+dashboard

+dashboards

+dastard

+dastardliness

+dastardly

+databanks

+datafile

+datagram

+datagram's

+datagrams

+dataset

+datasets

+dateline

+datelined

+datelines

+daub

+daubed

+dauber

+daubs

+davenport

+davits

+dawdle

+dawdled

+dawdler

+dawdlers

+dawdles

+dawdling

+daybed

+deaconess

+deactivate

+deactivated

+deactivates

+deactivating

+deactivation

+deadhead

+deadheads

+deadweight

+deadwood

+dealerships

+dearie

+deassign

+deassigns

+deathbed

+deathward

+debacle

+debacles

+debar

+debarring

+debars

+debase

+debased

+debaser

+debases

+debasing

+debauch

+debauched

+debauchedly

+debauchedness

+debaucher

+debauchery

+debauches

+debenture

+debentures

+debility

+debit

+debited

+debiting

+debits

+debonair

+debonairly

+debonairness

+debrief

+debriefed

+debriefing

+debriefs

+debunk

+debunker

+debunking

+debunks

+debut

+debutante

+debutante's

+debutantes

+debuting

+debuts

+decaffeinate

+decaffeinated

+decaffeinates

+decaffeinating

+decal

+decant

+decanted

+decanter

+decanters

+decanting

+decants

+decapitated

+decathlon

+decathlons

+decedent

+decennial

+decennially

+decertification

+decertify

+dechlorinate

+dechlorinated

+dechlorinates

+dechlorination

+decibel

+decibels

+deciduous

+deciduously

+deciduousness

+decile

+decisional

+declaim

+declaimed

+declaimer

+declaiming

+declaims

+declamation

+declamations

+declamatory

+declarator

+declarators

+declaratory

+declassification

+declassifications

+declassify

+declension

+declensions

+declivity

+decolletage

+decolletages

+decollimate

+decompress

+decompressed

+decompresser

+decompresses

+decompressing

+decontaminated

+decontrol

+decontrolled

+decontrolling

+decor

+decorator

+decorators

+decorous

+decorously

+decorousness

+decorticate

+decorticated

+decorticates

+decorticating

+decortication

+decried

+decrier

+decries

+decry

+decrying

+decrypt

+decrypted

+decrypting

+decryption

+decrypts

+deductibility

+deductible

+deductibles

+deemphasis

+deerskin

+deerskins

+deerstalker

+deface

+defacement

+defacer

+defaces

+defacing

+defame

+defamed

+defamer

+defames

+defaming

+defecate

+defecated

+defecates

+defecating

+defecation

+defecations

+defensible

+deferent

+deferents

+deflate

+deflated

+deflater

+deflates

+deflating

+deflation

+deflect

+deflected

+deflecting

+deflection

+deflections

+deflective

+deflector

+deflects

+defocus

+defocusing

+deforestation

+deform

+deformational

+deforming

+deforms

+defraud

+defrauded

+defrauder

+defrauding

+defrauds

+defray

+defrayed

+defraying

+defrays

+defrost

+defrosted

+defroster

+defrosting

+defrosts

+deft

+defter

+deftest

+deftness

+defunct

+degrease

+degum

+degumming

+dehumidification

+dehumidifications

+dehumidified

+dehumidifier

+dehumidify

+dehydrate

+dehydrated

+dehydrates

+dehydrating

+dehydration

+deification

+deify

+deja

+deject

+dejection

+delectable

+delectableness

+delectation

+delegable

+deleterious

+deleteriously

+deleteriousness

+deli

+deli's

+delicatessen

+delicti

+delimitation

+delirium

+deliriums

+delis

+deliveryman

+deliveryman's

+deliverymen

+deliverymen's

+delouse

+deloused

+delouses

+delousing

+deltoid

+deltoids

+delusive

+delusively

+delusiveness

+deluxe

+demagnification

+demagnify

+demagogue

+demagogues

+demarcate

+demarcated

+demarcates

+demarcating

+demarcation

+demean

+demeaned

+demeaning

+demeans

+demented

+dementedly

+dementedness

+demerit

+demerits

+demigod

+demiscible

+demit

+demitted

+demitting

+demographer

+demographer's

+demographers

+demographical

+demographically

+demography

+demoniac

+demonic

+demonstrably

+demote

+demoted

+demotes

+demoting

+demotion

+demountable

+demultiplex

+demurred

+demurrer

+demurring

+denature

+denatured

+denatures

+denaturing

+denim

+denims

+denominate

+denominated

+denominationally

+denominative

+denouement

+densitometer

+densitometer's

+densitometers

+densitometric

+densitometry

+dentistry

+denture

+dentures

+denude

+denuded

+denuder

+denudes

+denuding

+denumerable

+denunciate

+denunciated

+denunciates

+denunciating

+denunciation

+denunciations

+denunciative

+deodorant

+deodorant's

+deodorants

+deoxyribonucleic

+depiction

+depictions

+deplorably

+deployable

+depositary

+depository

+depravities

+depravity

+deprecate

+deprecated

+deprecates

+deprecating

+deprecatingly

+deprecation

+deprecations

+deprecatory

+depreciable

+depredations

+depressant

+depressants

+depressible

+depressors

+deputation

+deputations

+depute

+deputed

+deputes

+deputing

+derange

+deranged

+derangement

+deranges

+deranging

+deregulate

+derelict

+dereliction

+derelicts

+derisive

+derisively

+derisiveness

+derivate

+derogate

+derogated

+derogates

+derogating

+derogation

+derogative

+derogatory

+derrick

+derricked

+derricking

+derricks

+derriere

+dervish

+dervishes

+descant

+descendent

+descendent's

+descendents

+desecrate

+desecrated

+desecrater

+desecrates

+desecration

+desegregate

+desegregated

+desegregates

+desegregating

+desegregation

+desist

+desorption

+desperado

+desperadoes

+despicably

+despoil

+despoiled

+despoiler

+despoilers

+despoiling

+despoils

+despond

+despondency

+despondent

+despondently

+despotism

+dessicate

+destinate

+destruct

+destructor

+destructs

+desuetude

+desultoriness

+desultory

+detachable

+detente

+detentions

+deter

+detergency

+detergent

+detergents

+determinability

+deterred

+deterrence

+deterrent

+deterrently

+deterrents

+deterring

+deters

+detersive

+detersives

+detestation

+detestations

+detonable

+detonator

+detonator's

+detonators

+detour

+detoured

+detouring

+detours

+detrimental

+detrimentally

+detune

+detuned

+detunes

+detuning

+deuce

+deuced

+deucedly

+deuces

+deucing

+deus

+deuterium

+deuteriums

+devaluation

+devalue

+devalued

+devalues

+devaluing

+deviance

+deviances

+devious

+deviously

+deviousness

+devoice

+devoiced

+devoices

+devoicing

+devolve

+devolved

+devolves

+devolving

+devotional

+devotionally

+dewar

+dewars

+dexter

+dextrous

+diabase

+diabetic

+diabetics

+diabolic

+diabolical

+diabolically

+diabolicalness

+diachronic

+diachronicness

+diacritical

+diacritically

+diacriticals

+diagnometer

+diagnometer's

+diagnometers

+diagnostician

+diagnosticians

+diagrammaticality

+dialectal

+dialectally

+dialectic

+dialectical

+dialectically

+dialectics

+dialysis

+diamagnetic

+diametric

+diaphanous

+diaphanously

+diaphanousness

+diathermy

+diathesis

+diatom

+diatomic

+diatoms

+diatonic

+dichloride

+dichotomous

+dichotomously

+dichotomousness

+dick

+dicker

+dickered

+dickering

+dickers

+dickey

+dicks

+dicotyledon

+dictatorial

+dictatorially

+dictatorialness

+didactic

+didactics

+diddle

+diddled

+diddler

+diddling

+diehard

+diehards

+diem

+diesel

+diesels

+dietaries

+dietary

+dietetic

+dietetics

+diethylaminoethyl

+diethylstilbestrol

+dietician

+dieticians

+differentiability

+differentiable

+differentiator

+difficile

+diffidence

+diffident

+diffidently

+diffract

+diffracted

+diffracting

+diffraction

+diffractions

+diffractometer

+diffractometer's

+diffractometers

+diffracts

+diffusible

+digitalis

+dignitaries

+dignitary

+digram

+dihedral

+dilapidate

+dilapidated

+dilapidates

+dilapidating

+dilapidation

+dilatation

+dilator

+dilatoriness

+dilatory

+dilettante

+dilettantes

+dilithium

+dill

+dillinger

+dilogarithm

+dimensionless

+dimethyl

+dimethylglyoxime

+ding

+dinghies

+dinghy

+dingo

+dinnertime

+dinnerware

+dinosaur

+dinosaurs

+diocesan

+diocese

+diorama

+dioramas

+dioxalate

+diphthong

+diphthongs

+dipodic

+dipody

+dipole

+dipole's

+dipoles

+directivity

+directorate

+directorship

+directrices

+directrix

+direful

+direfully

+disablement

+disaffected

+disaffectedly

+disaffectedness

+disaffection

+disaffiliate

+disaffiliated

+disaffiliates

+disaffiliating

+disaffiliation

+disaggregate

+disaggregated

+disaggregating

+disaggregation

+disaggregative

+disapprobation

+disarranged

+disarray

+disarrays

+disarticulated

+disassembly

+disavow

+disavowal

+disavowals

+disavowed

+disavowing

+disavows

+disbar

+disbars

+disbelief

+discipleship

+discomfit

+discomfited

+discomfiting

+discomfits

+discontinuation

+discordant

+discordantly

+discorporate

+discorporated

+discourteous

+discourteously

+discourteousness

+discrepant

+discrepantly

+discretionary

+discriminable

+discriminant

+discursive

+discursively

+discursiveness

+discus

+discuses

+discussant

+discussants

+disdainful

+disdainfully

+disdainfulness

+disembodied

+disembowel

+disembowels

+disenchantment

+disengagement

+disequilibrium

+disgruntle

+disgruntles

+disgruntling

+disgustful

+disgustfully

+disharmony

+dishevel

+dishevels

+dishonesty

+dishwater

+disincentives

+disinclination

+disincorporated

+disinherit

+disinheritance

+disinherited

+disinheriting

+disinherits

+disintegrate

+disintegrated

+disintegrates

+disintegrating

+disintegration

+disintegrations

+disintegrative

+disinterest

+disinterred

+disjoin

+diskette

+diskettes

+dislodgement

+disloyal

+disloyally

+disloyalty

+dismantle

+dismantled

+dismantles

+dismantling

+dismembered

+dismemberment

+disobedient

+disobediently

+disoriented

+disparage

+disparaged

+disparagement

+disparager

+disparages

+disparaging

+disparagingly

+dispassionate

+dispassionately

+dispassionateness

+dispensary

+dispensate

+dispersal

+dispersement

+dispersible

+dispositional

+dispossessed

+dispossession

+disproportion

+disproportional

+disproportionate

+disproportionately

+disproportionation

+disputable

+disputant

+disquietude

+disquisition

+disrepair

+disreputable

+disreputableness

+disrepute

+disrespect

+disrobe

+dissect

+dissected

+dissecting

+dissection

+dissects

+dissemble

+dissembled

+dissembler

+dissembling

+dissimulation

+dissociable

+dissonant

+dissonantly

+dissuade

+dissuaded

+dissuader

+dissuades

+dissuading

+distaff

+distaffs

+distend

+distended

+distension

+distillate

+distillates

+distillations

+distilleries

+distillery

+distortable

+distributorship

+disulfide

+disunion

+disunited

+disunity

+disuse

+disused

+disvalues

+disyllable

+dither

+dithered

+ditherer

+dithering

+ditties

+ditto

+dittos

+ditty

+diurnal

+diva

+divalent

+diversionary

+divertimento

+divestiture

+divination

+divisible

+divisional

+divisive

+divisively

+divisiveness

+divorcee

+divorcees

+divvied

+divvies

+divvying

+dizzily

+doable

+docile

+docilely

+docket

+docketed

+docketing

+dockets

+dockside

+dockyard

+doctrinaire

+doctrinal

+doctrinally

+dodecahedra

+dodecahedral

+dodecahedron

+doe

+doff

+doffing

+doffs

+doggone

+doggoned

+doggoning

+doghouse

+dogleg

+dogmatic

+dogmatically

+dogmatics

+dogtooth

+dogtrot

+dogwood

+doldrum

+doldrums

+dolomite

+dolomites

+dolomitic

+dolt

+doltish

+doltishly

+doltishness

+domesticity

+domicile

+domiciled

+dominator

+domineer

+domineering

+domineeringly

+domineeringness

+domino

+donned

+donning

+donnish

+donnishly

+donnishness

+donnybrook

+donor

+donors

+donuts

+doodle

+doodled

+doodler

+doodles

+doodling

+doomsday

+doorbell

+doorkeep

+doorkeeper

+doorkeepers

+doorknob

+doorknobs

+doorman

+doormen

+dopant

+dorm

+dormer

+dosage

+dosages

+dosimeter

+dosimeter's

+dosimeters

+dosimetry

+dossier

+dossiers

+dotage

+dotard

+doubleheader

+doubleton

+doubloon

+dour

+dourly

+dourness

+dovetail

+dowager

+dowagers

+dowdier

+dowdies

+dowdiness

+dowdy

+dowel

+dower

+downbeat

+downgrade

+downgraded

+downgrades

+downgrading

+downhill

+downpour

+downside

+downslope

+downspout

+downswings

+downtrend

+downtrodden

+downturn

+downturns

+downwind

+dowries

+dowry

+dowse

+dowser

+dowses

+dowsing

+draftee

+draftees

+dragger

+dragnet

+dragonfly

+dragonhead

+dram

+dramatical

+dramaturgy

+dreadnought

+dreamboat

+dreamless

+dreamlessly

+dreamlessness

+dreamlike

+dreamt

+dreg

+dressier

+dressiness

+dressmaking

+dressy

+drib

+dribble

+dribbled

+dribbler

+dribbles

+dribbling

+dribs

+dripped

+drippier

+dripping

+drippy

+drizzle

+drizzled

+drizzles

+drizzling

+drizzlingly

+drizzly

+droll

+drollness

+dromedary

+droopier

+droopy

+drophead

+droplet

+droplets

+dropout

+dropouts

+drosophila

+dross

+drowse

+drowsed

+drowses

+drowsily

+drowsing

+drub

+drubbing

+drudge

+drudger

+drudges

+drudging

+drudgingly

+drugged

+drugging

+drugless

+drugstore

+drugstores

+druid

+drumhead

+dryer

+dryers

+dryness

+drywall

+dualism

+dubbed

+ducat

+duce

+duces

+duckling

+duct

+ducted

+ductile

+ducting

+ducts

+ductwork

+dud

+duds

+duet

+duets

+duff

+duffel

+duffer

+duffers

+dugout

+dukedom

+dulcet

+dulcetly

+dulcify

+dullard

+dumbfound

+dumbfounded

+dumbfounder

+dumbfounds

+dumpier

+dumpiness

+dumpy

+dun

+dung

+dunk

+dunker

+duopolist

+duopoly

+dupe

+duped

+duper

+dupes

+duping

+dupion

+duplex

+duplexer

+duplicable

+duplicity

+durational

+duress

+dustbin

+dustbins

+dutiable

+dwarves

+dwelt

+dyad

+dyadic

+dyads

+dynamical

+dynamism

+dynamo

+dynamos

+dynastic

+dysentery

+dyspeptic

+dysprosium

+dystopia

+dystrophy

+e'er

+e's

+eardrum

+eardrums

+earphone

+earphones

+earsplitting

+earthier

+earthiness

+earthmen

+earthmover

+earthmoving

+earthy

+easel

+eastbound

+easternmost

+easygoing

+easygoingness

+eatable

+eatables

+eave

+ebullient

+ebulliently

+ecclesiastic

+echelon

+echelons

+echinoderm

+eclectic

+eclectically

+ecliptic

+ecological

+ecologically

+ecologists

+econometric

+econometricians

+econometrics

+ecosystem

+ecosystems

+ecstatic

+ecstatics

+ecumenic

+ecumenic's

+ecumenical

+ecumenically

+ecumenicist

+ecumenicist's

+ecumenicists

+ecumenics

+ecumenist

+ecumenist's

+ecumenists

+ed

+edelweiss

+eden

+edgewise

+edgier

+edginess

+edgy

+edification

+edified

+edifies

+edify

+edifying

+editorialist

+editorship

+educe

+educing

+eelgrass

+eerily

+efface

+effaceable

+effaced

+effacer

+effaces

+effacing

+effectual

+effectualness

+effectuate

+effectuated

+effectuates

+effectuating

+effectuation

+efferent

+efferently

+effete

+effetely

+effeteness

+efficacious

+efficaciously

+efficaciousness

+effloresce

+efflorescent

+effluent

+effluents

+effluvia

+effluvium

+efflux

+effluxion

+effuse

+effused

+effuses

+effusing

+effusion

+effusive

+effusively

+effusiveness

+egalitarian

+egalitarianism

+egghead

+eggheaded

+eggheadedness

+eggplant

+eggshell

+egocentric

+egotism

+egotist

+egotistic

+egotistical

+egotistically

+egotists

+egregious

+egregiously

+egregiousness

+egress

+egret

+egrets

+eh

+eider

+eidetic

+eigenstate

+eigenstates

+eigenvector

+eigenvectors

+eightfold

+einsteinium

+ejection

+ejector

+ejectors

+elan

+elastomer

+electorate

+electress

+electrician

+electricians

+electro

+electrocardiogram

+electrocardiogram's

+electrocardiograms

+electrocardiograph

+electrodynamic

+electrodynamicly

+electrodynamics

+electroencephalogram

+electroencephalogram's

+electroencephalograms

+electrolysis

+electromagnet

+electromagnetism

+electromagnetisms

+electromagnets

+electromyograph

+electromyographic

+electromyographically

+electromyography

+electrophoresis

+electrophorus

+electroshock

+electroshocks

+electrostatic

+electrostatics

+electrotherapist

+electrotypers

+electroweak

+elegiac

+elegies

+elegy

+elephantine

+elfin

+elision

+elisions

+elite

+eliteness

+elites

+ellipsometer

+ellipsometer's

+ellipsometers

+ellipsometry

+ellipticity

+elocution

+elope

+eloped

+eloper

+elopes

+eloping

+eluate

+eluates

+elute

+eluted

+eluting

+elution

+elysian

+emaciate

+emaciates

+emaciating

+emaciation

+emanate

+emanated

+emanates

+emanation

+emanations

+emanative

+emancipate

+emancipated

+emancipates

+emancipating

+emasculate

+emasculated

+emasculates

+emasculating

+emasculation

+embalm

+embalmer

+embalmers

+embalming

+embalms

+embank

+embanked

+embanking

+embankment

+embankments

+embanks

+embarcadero

+embargo

+embargoed

+embargoes

+embargoing

+embattle

+embattled

+embattles

+embattling

+embedder

+embezzlement

+embittered

+emblematic

+embolden

+emboldened

+emboldens

+emboss

+embossed

+embosser

+embossers

+embosses

+embossing

+embower

+embraceable

+embrittle

+embroil

+embroiled

+embroiling

+embroils

+embryonic

+emcee

+emceed

+emend

+emendable

+emender

+emeritus

+emirate

+emissaries

+emissary

+emission

+emission's

+emissions

+emissivities

+emissivity

+emittance

+emitter

+emitters

+emitting

+emolument

+emoluments

+emotionalism

+emotionality

+empath

+empathetically

+empathic

+emphysema

+emphysematous

+empiric

+empiricism

+emplace

+employability

+emporium

+emporiums

+emulsification

+emulsified

+emulsifier

+emulsifies

+emulsify

+emulsion

+emulsions

+encampment

+encase

+encased

+encephalitis

+encephalographic

+enchain

+enchained

+enchantress

+enchiladas

+enclave

+enclaves

+encomium

+encomiums

+encore

+encored

+encores

+encoring

+encroach

+encroached

+encroacher

+encroaches

+encroaching

+encroachment

+encrust

+encrusted

+encrusting

+encrusts

+encumbrance

+encumbrancer

+encumbrances

+encyclical

+endearment

+endearments

+endemicity

+endgame

+endnote

+endnote's

+endnotes

+endogamous

+endogamy

+endogenous

+endogenously

+endosperm

+endothelial

+endothermic

+endpoint

+endpoints

+energetically

+enervate

+enervated

+enervates

+enervating

+enervation

+enervative

+enfeeble

+enfeebled

+enfeebles

+enfeebling

+enforceability

+enforceable

+enforcible

+engorge

+engorged

+engorges

+engorging

+engulfed

+engulfing

+engulfs

+enigma

+enjoinder

+enlargeable

+enmesh

+enmeshed

+enquiries

+enquiry

+enrapture

+enraptured

+enraptures

+enrapturing

+enrichment

+enrollee

+enrollees

+ensconced

+enshroud

+enslavement

+entailment

+entanglement

+enthalpy

+enthralled

+enthralling

+enthrone

+enthroned

+enthrones

+enthroning

+enthuse

+enthused

+enthuses

+enthusing

+enticements

+entitlement

+entitlements

+entomb

+entombed

+entomologist

+entomology

+entourage

+entourages

+entrain

+entrained

+entrainer

+entraining

+entrains

+entranceway

+entrant

+entrants

+entrap

+entrapment

+entrapments

+entrapped

+entraps

+entree

+entrees

+entrenchment

+entrenchments

+entrepreneurial

+entrepreneurship

+entwine

+entwined

+entwines

+entwining

+enunciable

+enunciate

+enunciated

+enunciates

+enunciating

+envenom

+envenomed

+envenoming

+envenoms

+enviable

+enviableness

+enzymatic

+enzymatically

+enzyme

+enzymes

+enzymology

+eohippus

+ephemerides

+ephemeris

+epicure

+epicurean

+epicycle

+epicycles

+epicyclic

+epicyclical

+epicyclically

+epidemiological

+epidemiologically

+epidemiology

+epidermic

+epidermis

+epigenetic

+epigram

+epigrammatic

+epigrams

+epigraph

+epigrapher

+epilepsy

+epileptic

+epileptics

+epilogue

+epilogues

+epiphany

+epiphenomena

+episcopate

+epistolatory

+epitaxy

+epithelial

+epithelium

+epitome

+epitomes

+epochal

+epochally

+epoxy

+equable

+equableness

+equanimities

+equanimity

+equestrian

+equestrians

+equidistant

+equidistantly

+equilateral

+equilaterals

+equilibrate

+equilibrated

+equilibrates

+equilibrating

+equilibration

+equilibria

+equine

+equines

+equinox

+equipotent

+equiproportional

+equiproportionality

+equiproportionate

+equivocal

+equivocally

+equivocalness

+equivocation

+eradicable

+erbium

+ergodic

+ergodicity

+erode

+eroded

+erodes

+erodible

+eroding

+erosible

+erosion

+erosive

+erosiveness

+erotic

+erotica

+erotically

+errancies

+errancy

+errant

+errantly

+errantry

+errants

+errata

+erratas

+erratically

+erratum

+ersatz

+erstwhile

+erudite

+eruditely

+erudition

+erupt

+erupted

+erupting

+eruptive

+eruptively

+erupts

+escadrille

+escapist

+escarpment

+escarpment's

+escarpments

+escritoire

+escrow

+escutcheon

+escutcheons

+esophagi

+esplanade

+espousal

+espousals

+essayists

+esters

+estimable

+estimableness

+estimator

+estimators

+estoppal

+estrange

+estranged

+estrangement

+estranger

+estranges

+estranging

+estuaries

+estuarine

+estuary

+et

+eta

+etas

+etcetera

+etceteras

+etched

+ethane

+ethanol

+ethicist

+ethicists

+ethnically

+ethnicities

+ethnicity

+ethnographers

+ethnographic

+ethnography

+ethnology

+ethnomethodology

+ethology

+ethos

+ethyl

+ethylene

+etymological

+etymologically

+etymologies

+etymology

+eucalyptus

+eugenic

+eugenics

+eulogies

+eulogy

+euphemist

+euphony

+euphoric

+eureka

+europium

+euthanasia

+evanescent

+evangelic

+evangelical

+evangelicalism

+evangelically

+evangelism

+evangelist

+evangelistic

+evangelists

+evasion

+evasions

+evasive

+evasively

+evasiveness

+evensong

+eventide

+eventides

+eventuate

+eventuated

+eventuates

+eventuating

+everyman

+evidential

+evidentially

+evildoer

+evildoers

+evocable

+evocate

+evocation

+evocations

+evocative

+evocatively

+evocativeness

+evolutionists

+ex

+exaltation

+exaltations

+examinable

+excelsior

+excisable

+excitability

+excitatory

+exclamatory

+exclusionary

+excoriate

+excoriated

+excoriates

+excoriating

+excoriation

+excoriations

+excrescence

+excrescences

+excretory

+excruciate

+excruciated

+excruciates

+excruciating

+excruciation

+exculpatory

+excursus

+excursuses

+exec

+execrable

+execrableness

+execrate

+execrated

+execrates

+execrating

+execration

+execrative

+executrix

+executrixes

+exegesis

+exegete

+exemption

+exemptions

+exercisable

+exhilarate

+exhilarated

+exhilarates

+exhilarating

+exhilaratingly

+exhilaration

+exhilarative

+exhort

+exhorted

+exhorter

+exhorting

+exhorts

+exhumation

+exhumations

+exhume

+exhumed

+exhumer

+exhumes

+exhuming

+exigent

+exigently

+exodus

+exogamous

+exogamy

+exogenous

+exogenously

+exonerate

+exonerated

+exonerates

+exonerating

+exoneration

+exonerative

+exorciser

+exorcism

+exorcist

+exoskeleton

+exothermic

+exotica

+expansible

+expansionist

+expectable

+expectorant

+expectorate

+expectoration

+expediency

+expellable

+experiential

+experientially

+experimentalism

+experimentalist

+experimentalist's

+experimentalists

+expiable

+expiate

+expiated

+expiates

+expiating

+expiation

+expletive

+expletives

+explicable

+explicate

+explicated

+explicates

+explicating

+explication

+explicative

+explicatively

+exportation

+exposit

+exposited

+expressionism

+expressionist

+expressionistic

+expressionists

+expressionless

+expressionlessly

+expressionlessness

+expressway

+expressways

+expurgate

+expurgated

+expurgates

+expurgating

+expurgation

+extemporaneous

+extemporaneously

+extemporaneousness

+extempore

+extendibility

+extensional

+extensionally

+extensor

+exterminator

+exterminator's

+exterminators

+extern

+externalities

+extirpate

+extirpated

+extirpating

+extirpation

+extirpative

+extolled

+extoller

+extolling

+extort

+extorted

+extorter

+extorting

+extortive

+extorts

+extracellular

+extracellularly

+extraditable

+extralegal

+extralegally

+extramarital

+extraterrestrial

+extravaganza

+extravaganzas

+extrema

+extremism

+extricable

+extricate

+extricated

+extricates

+extricating

+extrication

+extroversion

+extrovert

+extroverted

+extroverts

+extrude

+extruded

+extruder

+extrudes

+extruding

+extrusion

+extrusive

+exuberant

+exuberantly

+exudation

+exude

+exuded

+exudes

+exuding

+exultant

+exultantly

+eyeful

+eyelash

+eyelashes

+eyeless

+eyelet

+eyelets

+eyesore

+eyesore's

+eyesores

+eyeteeth

+f's

+faceplate

+facetious

+facetiously

+facetiousness

+facilitators

+facilitatory

+factious

+factiously

+factiousness

+facto

+factuality

+fad

+fadeout

+fads

+faerie

+faery

+failsafe

+fairgoer

+fairgoers

+fairgrounds

+fairless

+fairway

+fairways

+falafel

+falconry

+falloff

+fallout

+fallouts

+fallow

+fallowness

+familial

+fanatical

+fanaticalness

+fanaticism

+fanfare

+fanfold

+fangled

+fanout

+fantasia

+fantasist

+fantastically

+farcical

+farcically

+farfetched

+farfetchedness

+farina

+farmland

+farmlands

+farmworker

+farmworkers

+farsighted

+farsightedly

+farsightedness

+fascicle

+fascicled

+fascicles

+fasciculate

+fasciculated

+fasciculation

+fasciculations

+fascism

+fascist

+fascists

+fastidious

+fastidiously

+fastidiousness

+fatalistic

+fatalists

+fateful

+fatefully

+fatefulness

+fatherhood

+fatherless

+fatso

+fattier

+fatties

+fattiness

+fatty

+fatuity

+fatuous

+fatuously

+fatuousness

+faucet

+faucets

+faun

+fauna

+fax

+fax's

+faxes

+faze

+fazed

+fazes

+fazing

+fealty

+fearsome

+fearsomely

+fearsomeness

+feasibly

+featherbed

+featherbedding

+featherbrain

+featherbrained

+feathertop

+featherweight

+feathery

+febrile

+feces

+fecund

+fecundability

+fecundity

+federalism

+federalist

+federalists

+federate

+federated

+federates

+federating

+federations

+federative

+federatively

+fedora

+feint

+feinted

+feinting

+feints

+feldspar

+felicitous

+felicitously

+felicitousness

+feline

+felinely

+felines

+fella

+fellas

+felon

+felonious

+feloniously

+feloniousness

+felons

+felony

+feminism

+femme

+femmes

+fencepost

+fend

+fender

+fenders

+fennel

+fermion

+fermion's

+fermions

+fermium

+fernery

+ferret

+ferreted

+ferreter

+ferreting

+ferrets

+ferric

+ferris

+ferro

+ferroelectric

+ferromagnet

+ferromagnetic

+ferrous

+fervid

+fervidly

+fervidness

+fest

+fester

+festered

+festering

+festers

+fetal

+fete

+feted

+fetes

+fetish

+fetishes

+fettle

+fettled

+fettles

+fettling

+feudalistic

+feudatory

+fiance

+fiancee

+fiasco

+fiat

+fiats

+fib

+fibbing

+fibrin

+fibrosis

+fiche

+fictive

+fictively

+fiddlestick

+fiddlesticks

+fide

+fidget

+fidgeted

+fidgeting

+fidgets

+fiducial

+fiducially

+fiduciary

+fief

+fiefdom

+fieldstone

+fieldwork

+fieldworker

+fieldworkers

+fiendish

+fiendishly

+fiendishness

+fierily

+fiesta

+fifths

+figment

+figural

+figurine

+figurines

+filamentary

+filbert

+filberts

+filch

+filched

+filches

+filet

+filets

+filibuster

+filibustered

+filibusterer

+filibustering

+filibusters

+filigree

+filigreed

+fillet

+filleted

+filleting

+fillets

+fillies

+filly

+filmdom

+filmier

+filminess

+filmstrip

+filmstrips

+filmy

+filtrate

+filtrated

+filtrates

+filtrating

+finale

+finale's

+finales

+finalist

+finalists

+finch

+findable

+finesse

+finessed

+finessing

+fingernail

+fingernails

+fingerprint

+fingerprinted

+fingerprinting

+fingerprints

+fingertip

+fingertips

+finial

+finickiness

+finicky

+fink

+finned

+finny

+fireball

+fireballs

+fireboat

+firebreak

+firebreaks

+firebug

+firecracker

+firecrackers

+firefight

+firefighters

+firefighting

+firefights

+firehouse

+firehouses

+firemen

+firepower

+fireproof

+firewall

+firework

+fishier

+fishmeal

+fishmonger

+fishmongers

+fishpond

+fishy

+fissile

+fission

+fissioned

+fissioning

+fissions

+fisticuff

+fisticuffs

+fittest

+fivefold

+fizz

+fizzer

+fizzle

+fizzled

+fizzles

+fizzling

+fjord

+fjords

+flabbergast

+flabbergasted

+flabbergasting

+flabbergastingly

+flabbergasts

+flagellate

+flagellated

+flagellates

+flagellating

+flagellation

+flagman

+flagpole

+flagpoles

+flagstaff

+flagstone

+flail

+flailed

+flailing

+flails

+flair

+flak

+flakier

+flakiness

+flaky

+flam

+flamboyant

+flamboyantly

+flamen

+flamethrower

+flange

+flanged

+flanges

+flapped

+flapper

+flappers

+flashback

+flashbacks

+flashbulb

+flashbulbs

+flashier

+flashiness

+flashy

+flatbed

+flathead

+flatiron

+flatirons

+flatland

+flatlander

+flatlands

+flatulence

+flatulent

+flatulently

+flatworm

+flautist

+flaxseed

+fleawort

+fleck

+flecked

+flecker

+flecking

+flecks

+fledge

+fledges

+fledging

+fletch

+fletched

+fletcher

+fletches

+fletching

+fletching's

+fletchings

+flex

+flexed

+flexing

+flexural

+flexure

+flimsier

+flimsies

+flimsiness

+flimsy

+flintier

+flintiness

+flintless

+flintlock

+flinty

+flipflop

+flippant

+flippantly

+flipped

+flippers

+flipping

+flirtation

+flirtations

+flirtatious

+flirtatiously

+flirtatiousness

+flitting

+flocculate

+flocculated

+flocculates

+flocculating

+flocculation

+floe

+floes

+flog

+flogged

+flogging

+flogs

+floodgate

+floodlight

+floorboard

+floorboards

+flophouses

+flopped

+flopping

+floral

+florally

+florid

+floridly

+floridness

+florist

+florists

+flotation

+flotations

+flotilla

+flotillas

+flounce

+flounced

+flounces

+flouncing

+floury

+flout

+flouted

+flouter

+flouting

+flouts

+flowerpot

+flowstone

+flu

+flub

+flubbed

+flubbing

+flubs

+flue

+fluency

+fluff

+fluffs

+fluke

+fluoresce

+fluorescent

+fluorescer

+fluoresces

+fluoridate

+fluoridated

+fluoridates

+fluoridating

+fluoridation

+fluoridations

+fluoride

+fluorides

+fluorimetric

+fluorinated

+fluorine

+fluorite

+fluorocarbon

+flushable

+fluster

+flustered

+flustering

+flusters

+flutist

+flux

+fluxed

+fluxes

+flyaway

+flycatcher

+flycatchers

+flywheel

+flywheels

+foal

+foals

+foamier

+foaminess

+foamy

+fob

+foible

+foibles

+foist

+foisted

+foisting

+foists

+foldout

+foldouts

+foliate

+foliated

+foliates

+foliating

+foliation

+foliations

+folio

+folios

+folklike

+folksier

+folksiness

+folksong

+folksongs

+folksy

+follicle

+follicles

+follicular

+followup

+followup's

+followups

+foment

+fomented

+fomenter

+fomenting

+foments

+foolhardiness

+foolhardy

+footage

+footages

+footbridge

+footbridges

+footfall

+footfalls

+foothill

+foothills

+footloose

+footmen

+footpad

+footpads

+footpath

+footstool

+footstools

+footwear

+footwork

+fop

+foppery

+foppish

+foppishly

+foppishness

+fops

+forbore

+forebears

+foreclosed

+foreclosing

+forefeet

+forefront

+foreknowledge

+foreknown

+foreleg

+foremen

+forensic

+forensics

+forepart

+forepaws

+forerunner

+forerunners

+foresaw

+foreseeing

+foreshortened

+foreshortening

+forestry

+foreword

+forfeiture

+forfeitures

+forfend

+forfended

+forfending

+forfends

+forgo

+forgoer

+forgoing

+forklift

+formability

+formaldehyde

+formate

+formates

+formic

+formidably

+formulaic

+forsook

+forswear

+forswears

+forthcome

+forthright

+forthrightly

+forthrightness

+fortiori

+fossiliferous

+foulmouth

+foulmouthed

+foundling

+foundlings

+fountainhead

+fourfold

+foursome

+foursomes

+foursquare

+fourths

+fovea

+foxglove

+foxhole

+foxholes

+foxhound

+foxier

+foxiness

+foxtail

+foxy

+foyer

+fracases

+fractionated

+fractionation

+fractious

+fractiously

+fractiousness

+fragmentarily

+fragmentation

+francium

+frankfurter

+frankfurters

+franklin

+fraudulent

+fraudulentness

+frazzle

+frazzled

+frazzles

+frazzling

+freakish

+freakishly

+freakishness

+freeboot

+freebooter

+freebooters

+freeborn

+freedman

+freedmen

+freehand

+freehanded

+freehandedly

+freehold

+freeholder

+freeholders

+freemen

+freestone

+freethinkers

+freewheel

+freewheeled

+freewheeler

+freewheelers

+freewheeling

+freewheelingness

+freewheels

+frenetic

+freon

+fresco

+frescoed

+frescoes

+frescoing

+frescos

+freshwater

+fretted

+fretting

+friable

+friableness

+frictional

+frictionally

+friendlily

+frigid

+frigidly

+frigidness

+frilly

+friskier

+friskiness

+frisky

+fritter

+fritterer

+fritters

+frivolity

+frizzle

+frizzled

+frizzles

+frizzling

+fro

+frolicking

+frontage

+frontal

+frontally

+frontiersman

+frontiersmen

+frostbite

+frostbiting

+frostbitten

+frothier

+frothiness

+frothy

+frowzier

+frowzy

+frugality

+frustum

+fuchsia

+fuck

+fuck's

+fucked

+fucker

+fucker's

+fuckers

+fucking

+fucks

+fudge

+fudged

+fudges

+fudging

+fugue

+fulcrum

+fullback

+fullbacking

+fulminate

+fulminated

+fulminates

+fulminating

+fulmination

+fulminations

+fulsome

+fulsomely

+fulsomeness

+fumigant

+fumigate

+fumigated

+fumigates

+fumigation

+fumigations

+functionalism

+functionalist

+functionalists

+functionary

+fundamentalism

+funereal

+funereally

+fungal

+fungi

+fungible

+fungicides

+fungoid

+funk

+furbish

+furbisher

+furbishes

+furbishing

+furl

+furled

+furlong

+furlongs

+furlough

+furloughed

+furor

+furor's

+furors

+furrier

+furriers

+furring

+furry

+furthermost

+furthest

+fuselage

+fuselages

+fusible

+fusiform

+fusillade

+fusillades

+fussier

+fussily

+fussiness

+fussy

+fustiness

+fusty

+fuzz

+fuzzed

+g's

+gab

+gabbing

+gadfly

+gadgetry

+gaffe

+gaffer

+gaffes

+gaggle

+gagwriter

+gagwriters

+gainful

+gainfully

+gainfulness

+gal

+gala

+galactic

+galen

+galena

+galenite

+gallium

+gallivant

+gallivanted

+gallivanting

+gallivants

+gallonage

+gallstone

+gallstones

+gals

+galvanic

+galvanism

+galvanometer

+galvanometer's

+galvanometers

+gambit

+gambits

+gambol

+gambols

+gamecock

+gamut

+gander

+gangland

+gangling

+ganglion

+gangplank

+gangway

+gangways

+gantries

+gantry

+gardenia

+gardenias

+gargantuan

+gargoyle

+gargoyled

+gargoyles

+garish

+garishly

+garishness

+garnet

+garret

+garrets

+garrulous

+garrulously

+garrulousness

+gasification

+gasifications

+gasified

+gasifier

+gasifiers

+gasifies

+gasify

+gasifying

+gasket

+gaskets

+gaslight

+gaslighted

+gaslights

+gassiness

+gassy

+gastronome

+gastronomes

+gastronomy

+gator

+gauche

+gauchely

+gaucheness

+gaugeable

+gauntlet

+gauntleted

+gauss

+gausses

+gavel

+gawk

+gawker

+gawkier

+gawks

+gawky

+gazelle

+gazelles

+gazette

+gazetted

+gazetteer

+gazetteers

+gazettes

+gazetting

+gee

+geek

+geek's

+geeks

+geest

+geisha

+geishas

+gelable

+gelatine

+gelatinous

+gelatinously

+gelatinousness

+geld

+gelding

+geldings

+gemlike

+genealogies

+genealogists

+genealogy

+genera

+generational

+genesis

+geneticist

+geneticist's

+geneticists

+genie

+genie's

+genies

+genitive

+genitive's

+genitives

+genotype

+genotype's

+genotypes

+gent

+gentian

+gentians

+gentile

+gentiles

+gentility

+gentlemen

+gentlewomen

+gentlewomen's

+gentrification

+gents

+geocentric

+geocentricism

+geochemical

+geochemically

+geochemistry

+geochronology

+geodesic

+geodesics

+geodetic

+geographer

+geographer's

+geographers

+geologic

+geology

+geometer

+geometer's

+geometers

+geometrical

+geometrically

+geometrician

+geomorphological

+geomorphology

+geophysical

+geophysically

+geophysicist

+geophysicists

+geophysics

+geopolitic

+geopolitical

+geopolitically

+geopolitics

+geosynchronous

+gerbil

+geriatric

+geriatrics

+germanium

+germicidal

+germicide

+germicides

+germinal

+germinally

+gerontologist

+gerontologists

+gerontology

+gerrymandering

+gerund

+gerundive

+gestapo

+gestate

+gestated

+gestates

+gestating

+gestation

+gestation's

+gestations

+gesticulate

+gesticulated

+gesticulates

+gesticulating

+gesticulation

+gesticulations

+gesticulative

+gesticulatively

+getaway

+getaways

+geyser

+geysered

+geysering

+geysers

+gherkin

+gherkins

+ghetto

+ghettos

+ghostlike

+ghoul

+ghoulish

+ghoulishly

+ghoulishness

+ghouls

+giantess

+gibber

+gibbered

+gibbering

+gibbers

+gibbet

+gibbeted

+gibbeting

+gibbets

+gibbon

+gibbons

+gibbous

+gibbously

+gibbousness

+gibe

+giber

+gibes

+gibing

+giblet

+giblets

+giddap

+giddily

+gigacycle

+gigacycles

+gigahertz

+gigavolt

+gigawatt

+gigging

+gila

+gilbert

+gimpy

+ginkgo

+ginmill

+ginning

+ginseng

+girlie

+girlish

+girlishly

+girlishness

+gist

+git

+giveaway

+giveaways

+glaciate

+glaciated

+glaciates

+glaciating

+glaciation

+gladden

+gladdened

+gladdening

+gladdens

+gladdy

+gladiator

+gladiators

+gladiolus

+glamorous

+glamorously

+glamorousness

+glandular

+glandularly

+glassless

+glassware

+glasswort

+glaucoma

+glaucous

+glaziers

+glib

+glibly

+glibness

+glim

+gloat

+gloated

+gloater

+gloats

+glob

+globetrotter

+globule

+globulin

+globulins

+glommed

+glottis

+gloveless

+gluey

+glum

+glumly

+glumness

+glut

+gluten

+glutinous

+glutinously

+glutinousness

+gluts

+glutted

+glutting

+glutton

+glutton's

+gluttons

+glyceride

+glycerin

+glycerinate

+glycerinated

+glycerine

+glycerol

+glycol

+glycols

+glyph

+gnarl

+gnarled

+gnarls

+gnash

+gnashes

+gnashing

+gneiss

+gnome

+gnomelike

+gnomes

+gnomonic

+gnostic

+gnu

+gnus

+gob

+gobbledygook

+goddamn

+goddamned

+godfather

+godhead

+godless

+godlessness

+godparent

+godsend

+godsends

+godson

+goggle

+goggled

+goggler

+gogglers

+goggles

+goggling

+goldenrod

+goldenseal

+goldfinch

+goldfish

+goldsmiths

+golly

+gondola

+gondolas

+goober

+goodwill

+gooey

+goof

+goofed

+goofier

+goofiness

+goofing

+goofs

+goofy

+gooseberry

+gopher

+gophers

+gorgon

+goshawk

+gosling

+gossamer

+gourd

+gourmand

+gourmand's

+gourmands

+gourmet

+gourmets

+gout

+governance

+grad

+gradate

+gradated

+gradates

+gradating

+grads

+gradualist

+gradualists

+graffiti

+grail

+grails

+grammarian

+grammarians

+grammatic

+grammaticality

+grandchild

+grandchildren

+granddaughter

+granddaughters

+grandiloquent

+grandiloquently

+grandnephew

+grandnephews

+grandniece

+grandnieces

+grandstand

+grandstanded

+grandstander

+grandstanding

+grandstands

+granola

+grantee

+grantor

+granular

+granularly

+granule

+granules

+granulocytic

+grapefruit

+grapheme

+grasshoppers

+grassland

+grasslands

+grassroots

+gratis

+graven

+gravestone

+gravestones

+graveyard

+graveyards

+gravid

+gravidly

+gravidness

+gravimetric

+gravitate

+gravitated

+gravitates

+gravitating

+gravitations

+gravitative

+graybeard

+graybeards

+greatcoat

+greatcoated

+greatcoats

+greenbelt

+greenery

+greengrocer

+greenwood

+gregarious

+gregariously

+gregariousness

+greyhound

+griddle

+gridiron

+griffin

+grillwork

+grimace

+grimaced

+grimacer

+grimaces

+grimacing

+grime

+grimes

+grimmer

+grinned

+grinning

+grinningly

+grisliness

+grisly

+grist

+gristlier

+gristliness

+gristly

+gristmill

+grittier

+grittiness

+gritty

+grizzle

+grizzled

+grizzles

+grizzling

+groat

+groats

+groggier

+grogginess

+groggy

+groin

+grok

+grokked

+grokking

+groks

+grommet

+groomsmen

+grosbeak

+grottoes

+grouchier

+grouchiness

+grouchy

+groundhog

+groundhog's

+groundhogs

+groundless

+groundlessly

+groundlessness

+groundskeepers

+grout

+grouted

+grouter

+grouting

+grouts

+grovelike

+grubbier

+grubbiness

+grubbing

+grubby

+guano

+guardhouse

+gubernatorial

+guerilla

+guernsey

+guernseys

+guesswork

+guffaw

+guffaws

+guidepost

+guideposts

+guildhall

+guileless

+guilelessly

+guilelessness

+guitarist

+guitarists

+gullet

+gullets

+gullible

+gumbo

+gummier

+gumminess

+gumming

+gummy

+gumption

+gumshoe

+gunboat

+gunfight

+gunfighter

+gunfights

+gunflint

+gunk

+gunky

+gunman

+gunmen

+gunnery

+gunny

+gunshot

+gunsling

+gunslinger

+gunslinging

+gusset

+gussets

+gustiness

+gusto

+gusty

+gutsier

+gutsiness

+gutsy

+gutted

+gutting

+guttural

+gutturalness

+guzzle

+guzzled

+guzzler

+guzzles

+guzzling

+gymnosperm

+gyp

+gypping

+gypsite

+gypsum

+gyrate

+gyrated

+gyrates

+gyrating

+gyro

+gyrocompass

+gyros

+gyroscopic

+h's

+habeas

+haberdasheries

+haberdashery

+habitant

+habitants

+habituate

+habituated

+habituates

+habituating

+habituation

+hacienda

+haciendas

+hackle

+hackled

+hackler

+hackles

+hackling

+hackney

+hackneyed

+hackneying

+hackneys

+hacksaw

+hacksaws

+hackwork

+haddock

+haddocks

+hadron

+hafnium

+haggle

+haggled

+haggler

+haggles

+haggling

+haiku

+hailstone

+hailstorm

+hairdo

+hairdos

+hairdressing

+hairline

+hairpin

+halcyon

+halfback

+halfbacks

+halfhearted

+halfheartedly

+halfheartedness

+halftime

+halibut

+halibuts

+halide

+halides

+halite

+hallelujah

+hallelujahs

+hallucinate

+hallucinated

+hallucinates

+hallucinating

+hallucination

+hallucinations

+hallucinative

+halo

+halocarbon

+halogen

+halogens

+halos

+hammerhead

+hammerless

+hamming

+hamster

+hamsters

+handclasp

+handgun

+handguns

+handhold

+handicapper

+handicapping

+handicraft

+handicrafter

+handicrafts

+handicraftsman

+handicraftsmen

+handleable

+handlebar

+handlebars

+handless

+handmade

+handmaiden

+handout

+handouts

+handrail

+handset

+handsets

+handspike

+handspikes

+handstand

+handstands

+handwrite

+handwrites

+handwritings

+handyman

+handymen

+hangable

+hangman

+hangman's

+hangmen

+hangout

+hangouts

+hank

+hanker

+hankered

+hankerer

+hankering

+hankers

+hansom

+happenstance

+harangue

+harangued

+haranguer

+harangues

+haranguing

+harbinger

+harbingers

+hardboard

+hardboiled

+hardhat

+hardscrabble

+hardshell

+hardtack

+hardtop

+hardtops

+hardwire

+hardwired

+hardwires

+hardwiring

+hardwood

+hardwoods

+hardworking

+harelip

+harelips

+harem

+harmonic

+harmonics

+harpies

+harpist

+harpoon

+harpoon's

+harpooned

+harpooner

+harpooning

+harpoons

+harpsichord

+harpsichordist

+harpsichords

+harpy

+harpy's

+harrumph

+harrumphed

+harrumphes

+harrumphing

+harvestman

+hashish

+hasp

+hasps

+hatchway

+hatless

+hatted

+hatters

+haulage

+haw

+hawing

+hawser

+hawthorn

+hayfield

+hayfields

+hayloft

+hayloft's

+haylofts

+haystack

+haystacks

+hazelnut

+hazelnuts

+headboard

+headboards

+headdress

+headier

+headiness

+headless

+headlessness

+headlight

+headlights

+headmaster

+headquarter

+headquartered

+headroom

+headset

+headsets

+headship

+headsman

+headsmen

+headstand

+headstands

+headstone

+headstones

+headwall

+headwalls

+headwater

+headwaters

+heady

+hearse

+heartbeat

+heartbeats

+heartbreak

+heartbreaking

+heartbreakingly

+heartburn

+heartburning

+heartfelt

+heartland

+heartland's

+heartthrob

+heartthrob's

+heartthrobs

+heathenish

+heathenishly

+heavenward

+heavenwards

+heavyweight

+hebephrenic

+hecatomb

+heck

+heckle

+heckled

+heckler

+hecklers

+heckles

+heckling

+hectares

+hectic

+hector

+hedonism

+hedonist

+hedonistic

+hedonists

+heedful

+heedfully

+heedfulness

+heft

+hefted

+heftier

+heftiness

+hefts

+hefty

+hegemonic

+hegemonies

+hegemony

+heist

+heist's

+heisted

+heister

+heisting

+heists

+helical

+helically

+helices

+helicon

+helicopter

+heliocentric

+heliotrope

+helium

+helix

+helixes

+hellbender

+hellfire

+hellish

+hellishly

+hellishness

+helluva

+helmsman

+helmsmen

+helpmate

+hematite

+hemispheric

+hemispherical

+hemmed

+hemming

+hemoglobin

+hemolytic

+hemorrhage

+hemorrhaged

+hemorrhages

+hemorrhaging

+hemorrhoids

+henning

+henpeck

+henpecked

+henry

+hepatitis

+heptane

+herbal

+herdsman

+hereof

+hereunto

+heritable

+heritor

+hermeneutics

+hermetic

+hermitian

+herpes

+herpetologist

+herpetologists

+herpetology

+herringbone

+hertz

+hertzes

+hesitance

+hesitancy

+heterodyne

+heterogamous

+heterogamy

+heterogeneity

+heterosexual

+heterosexually

+heterosexuals

+heterostructure

+heterozygous

+hewn

+hexachloride

+hexadecimal

+hexadecimally

+hexadecimals

+hexafluoride

+hexagon

+hexagons

+hexameter

+heyday

+hi

+hiatus

+hiatuses

+hibachi

+hibernate

+hibernated

+hibernates

+hibernating

+hibernation

+hick

+hicks

+hideaway

+hierarchal

+hierarchic

+hieratic

+hieroglyphic

+hieroglyphics

+hifalutin

+highball

+highboy

+highfalutin

+highhanded

+highroad

+highs

+hight

+hightail

+highwayman

+highwaymen

+hilarity

+hillbilly

+hillier

+hillman

+hillmen

+hilly

+hindmost

+hindquarters

+hinterland

+hinterlands

+hippies

+hipping

+hippo

+hippodrome

+hippopotamus

+hippos

+hippy

+hipster

+hipsters

+hireling

+hirelings

+histochemic

+histochemical

+histochemistry

+histology

+historicism

+historicity

+historiography

+histrionic

+histrionics

+hitless

+ho

+hoagie

+hoagies

+hoagy

+hoarfrost

+hob

+hobbing

+hobbyhorse

+hobo

+hobos

+hoc

+hock

+hocker

+hocking

+hocks

+hodge

+hodgepodge

+hodges

+hogan

+hogging

+hokey

+hokeyer

+hokeyest

+hokeyness

+holdover

+holdovers

+holdup

+holdups

+hollandaise

+holler

+hollered

+hollering

+hollers

+hollowware

+hollyhock

+hollyhocks

+holmium

+holography

+holster

+holstered

+holstering

+holsters

+holystone

+holystones

+homebound

+homebuilder

+homebuilders

+homebuilding

+homecoming

+homecomings

+homeland

+homemake

+homemaking

+homeowner

+homeowners

+homeownership

+homerists

+homicidal

+homicidally

+homicide

+homicides

+homily

+homo

+homogamy

+homogenate

+homogenates

+homologous

+homologue

+homology

+homonym

+homonym's

+homonyms

+homopolymers

+homos

+homosexual

+homosexually

+homosexuals

+homozygous

+homozygously

+hon

+honeybee

+honeybees

+honeydew

+hong

+honk

+honked

+honker

+honkers

+honkies

+honking

+honks

+honky

+honky's

+hooch

+hoodlum

+hoodlums

+hoofmark

+hoofmarks

+hookup

+hookups

+hookworm

+hooligan

+hooliganism

+hooligans

+hoopla

+hoosegow

+hoosegows

+hooves

+hoppled

+hopples

+hopscotch

+hornier

+horniness

+horny

+horoscope

+horoscopes

+hors

+horsedom

+horseflesh

+horseflies

+horsefly

+horsehair

+horselike

+horsemanship

+horsemen

+horsens

+horseplay

+horseplayer

+horsetail

+horsewoman

+horticulture

+hosiery

+hospice

+hospices

+hostelries

+hostelry

+hotbed

+hotbox

+hotdogs

+hotelman

+hothead

+hotheaded

+hotheadedly

+hotheadedness

+hothouse

+hotrod

+hough

+hourglass

+houseboat

+houseboats

+housebreak

+housebreaker

+housebreakers

+housebreaking

+housebroken

+housekeep

+housewares

+housewives

+hove

+howdy

+hoy

+hubba

+hubbies

+hubbub

+hubby

+huckleberry

+huckster

+huckstered

+huckstering

+hucksters

+hugged

+hugging

+huggings

+hulk

+hulked

+hulking

+hulks

+humanism

+humanist

+humanistic

+humanists

+humanitarian

+humanitarians

+humidistat

+hummingbird

+hummingbirds

+hummock

+hummocks

+humorist

+humorist's

+humorists

+humpback

+humpbacked

+humpbacks

+humus

+hundredfold

+huntress

+hurray

+hurrays

+hurtful

+hurtfully

+hurtfulness

+hurtle

+hurtled

+hurtles

+hurtling

+husbandman

+husbandmen

+huskily

+hutch

+huzzahs

+hyacinths

+hydrant

+hydrants

+hydrate

+hydrated

+hydrates

+hydrating

+hydration

+hydrations

+hydride

+hydrides

+hydro

+hydrocarbon

+hydrocarbons

+hydrochemistry

+hydrochloric

+hydrochloride

+hydroelectric

+hydrofluoric

+hydrogenate

+hydrogenation

+hydrological

+hydrologically

+hydrology

+hydrolysis

+hydrometer

+hydrometer's

+hydrometers

+hydrophilic

+hydrophobia

+hydrophobic

+hydros

+hydrosphere

+hydrostatic

+hydrostatics

+hydrothermal

+hydrothermally

+hydrous

+hydroxide

+hydroxides

+hydroxy

+hydroxyl

+hydroxyl's

+hydroxylate

+hydroxylation

+hydroxyls

+hydroxyzine

+hyena

+hygienic

+hygienics

+hygrometer

+hygrometer's

+hygrometers

+hygroscopic

+hying

+hymen

+hymens

+hymnal

+hyperbola

+hyperbole

+hyperbolically

+hyperboloid

+hyperboloidal

+hypercellularity

+hypercube

+hypercube's

+hypercubes

+hyperemia

+hyperemic

+hyperfine

+hypergamous

+hypergamously

+hypergamy

+hyperplasia

+hypertensive

+hypertrophied

+hypertrophy

+hypervelocity

+hyphenate

+hyphenated

+hyphenates

+hyphenating

+hyphenation

+hyphenations

+hypnosis

+hypnotic

+hypnotically

+hypnotics

+hypoactive

+hypocellularity

+hypocritical

+hypocritically

+hypophyseal

+hypotenuse

+hypotenuses

+hypothalamic

+hypothalamically

+hypothalamus

+hypothermia

+hypothetic

+hypothyroid

+hypothyroidism

+hysterectomy

+hysteria

+hysteric

+hysterics

+i's

+iambic

+ibid

+ibis

+ibises

+icebox

+icicle

+icicles

+iconic

+iconoclasm

+iconoclast

+icosahedral

+icosahedron

+idealist

+idealogical

+ideate

+ideates

+ideation

+idempotent

+idempotents

+identifiability

+ideologist

+ideologists

+idiolect

+idiom

+idiomatic

+idiomaticness

+idioms

+idiosyncratically

+idiotically

+idyll

+idyllic

+iffiness

+iffy

+igloo

+igloos

+igneous

+ignite

+ignited

+igniter

+ignites

+igniting

+ignitions

+ignominious

+ignominiously

+ignoramus

+ileum

+iliac

+ilk

+ilk's

+illegible

+illegitimacy

+illegitimate

+illegitimately

+illimitable

+illimitableness

+illiteracy

+illogic

+illume

+illumed

+illumine

+illumined

+illumines

+illuming

+illusionary

+illusoriness

+illusory

+imagery

+imbecile

+imbecilely

+imbibe

+imbibed

+imbiber

+imbibing

+imbroglio

+imbruing

+imbue

+imbued

+imbuing

+imitable

+imitators

+immanent

+immanently

+immeasurable

+immeasurableness

+immeasurably

+immensities

+immensity

+imminence

+immobile

+immobility

+immoderate

+immoderately

+immoderateness

+immoderation

+immodest

+immodestly

+immodesty

+immunological

+immunologically

+impairment

+impale

+impaled

+impales

+impaling

+impalpable

+impartation

+impartiality

+impassable

+impassableness

+impeccable

+impeccably

+impelled

+impeller

+impellers

+impelling

+impend

+imperceivable

+imperceptible

+imperceptibly

+imperfectability

+imperishable

+imperishableness

+impermeable

+impermeableness

+imperturbable

+impiety

+impish

+impishly

+impishness

+implacable

+implacableness

+implantation

+implausibly

+implementability

+impolite

+impolitely

+impoliteness

+impolitic

+impoliticly

+impoliticness

+imponderable

+imponderableness

+imponderables

+importunate

+importunately

+importunateness

+importune

+importunely

+importuner

+importuners

+importunities

+impost

+imposter

+imposts

+impotency

+impound

+impounded

+impounding

+impoundments

+impounds

+imprecate

+imprecated

+imprecates

+imprecating

+imprecation

+imprecations

+impregnate

+impregnated

+impregnates

+impregnating

+impregnation

+impregnations

+impresario

+impressible

+impressionism

+imprimatur

+improbably

+impropitious

+impropriety

+improvident

+improvidently

+imprudent

+imprudently

+impudence

+impugn

+impugned

+impugner

+impugning

+impugns

+imputation

+imputations

+inaction

+inactivate

+inadvertence

+inalienable

+inanity

+inappeasable

+inarticulate

+inarticulately

+inarticulateness

+inattention

+inaudibility

+inboard

+inbreed

+inbreeder

+inbreeding

+incalculability

+incalculable

+incalculableness

+incandescent

+incandescently

+incant

+incanted

+incapacitate

+incapacitated

+incapacitates

+incapacitation

+incapacity

+incarcerate

+incarcerated

+incarcerates

+incarcerating

+incarceration

+incarnate

+incept

+incepted

+incepting

+inceptive

+inceptively

+inceptor

+incepts

+incest

+incestuous

+incestuously

+incestuousness

+incinerate

+incinerated

+incinerates

+incinerating

+incineration

+incinerations

+incinerator

+incinerators

+incipience

+incipiency

+incise

+incised

+incises

+incising

+incisive

+incisively

+incisiveness

+incisor

+incisor's

+incisors

+incitement

+incitements

+inclemency

+inclement

+inclemently

+inclinometer

+inclinometer's

+inclinometers

+incoercible

+incombustible

+incommensurable

+incommodious

+incommodiously

+incommodiousness

+incommunicable

+incommunicado

+incommutable

+incompetency

+incompressibility

+incondensable

+incongruities

+incongruity

+incongruous

+incongruously

+incongruousness

+inconsistence

+inconsonance

+inconstant

+incontinence

+incontrovertible

+incorporable

+incorporeally

+incorrigible

+incorrigibleness

+incorruptibility

+incorruptible

+increasable

+incriminating

+incubi

+incubus

+inculcate

+inculcated

+inculcates

+inculcation

+inculpable

+incumbent

+incumbents

+incursion

+incursions

+indecipherable

+indecorous

+indecorously

+indecorousness

+indefatigable

+indefatigableness

+indefensible

+indelible

+indelibly

+indelicate

+indelicately

+indelicateness

+indemnification

+indemonstrably

+indenture

+indentured

+indentures

+indenturing

+indestructible

+indestructibleness

+indicant

+indicants

+indict

+indicted

+indicter

+indigent

+indiscoverable

+indiscretion

+indispose

+indisposing

+indisposition

+indisputable

+indisputableness

+indisputably

+indissociable

+indissoluble

+indissolubleness

+indium

+individualism

+individualist

+individualists

+individuate

+individuated

+individuates

+individuating

+individuation

+indolence

+indubitable

+indubitableness

+inducible

+inductee

+inductees

+inductile

+indulgent

+indulgently

+industrialism

+inebriate

+inebriated

+inebriates

+inebriating

+inebriation

+ineffable

+ineffableness

+ineffaceable

+ineffectual

+ineffectually

+ineffectualness

+inefficacious

+inefficaciously

+inefficaciousness

+inegalitarian

+inelastic

+ineligibility

+ineligible

+ineluctable

+inept

+ineptly

+ineptness

+inequitable

+inequivalent

+ineradicable

+inertial

+inertially

+inexpediency

+inexpert

+inexpertly

+inexpertness

+inexpiable

+inexplicit

+inextinguishable

+inextricable

+inextricably

+infamy

+infanticide

+infanticide's

+infantile

+infantryman

+infantrymen

+infatuation

+infauna

+infecund

+infelicitous

+infelicitously

+infelicity

+inferable

+infertile

+infestation

+infestations

+infield

+infield's

+infielder

+infielder's

+infielders

+infinitude

+infirm

+infirmary

+infirmed

+infirmly

+inflammation

+inflammatory

+inflect

+inflected

+inflecting

+inflection

+inflectional

+inflectionally

+inflections

+inflective

+inflects

+inflexed

+infliction

+inflow

+influx

+info

+infra

+infraction

+infrared

+infusible

+infusibleness

+ingenuous

+ingenuously

+ingenuousness

+ingest

+ingested

+ingestible

+ingestion

+ingestive

+ingrain

+ingrate

+ingratiate

+ingratiating

+ingratiatingly

+ingratiation

+inhabitation

+inhalant

+inhalation

+inhibitor

+inhibitory

+inhomogeneous

+inimical

+inimically

+inimitable

+inimitableness

+iniquitous

+iniquitously

+iniquitousness

+injectable

+injunctive

+inlay

+inlayer

+inlaying

+innovators

+innuendo

+innuendoes

+innuendos

+inoculate

+inoculated

+inoculates

+inoculating

+inoculation

+inoculations

+inoculative

+inoperative

+inoperativeness

+inorganically

+inputted

+inquest

+inquisitor

+insatiable

+insatiableness

+inscrutability

+inscrutable

+inscrutableness

+insecticide

+insecticides

+inseminate

+insemination

+insensate

+insensately

+insensateness

+insensibility

+inseparability

+inseparably

+inset

+insincere

+insincerely

+insipid

+insipidly

+insobriety

+insolvency

+insolvent

+insomnia

+insomniac

+insomniacs

+insouciance

+insouciant

+insouciantly

+inspirational

+inspirationally

+instable

+instep

+instill

+instillation

+instilled

+instiller

+instilling

+instinctual

+institutionalist

+instrumentalities

+insubordinate

+insubordinately

+insubordination

+insubstantial

+insufferable

+insular

+insularity

+insularly

+insulin

+insuperably

+insuppressible

+insurgence

+insusceptibility

+intake

+intaking

+integrable

+integrand

+integument

+intellectuality

+intelligentsia

+intendant

+intendants

+intensional

+intensionally

+inter

+interaxial

+intercalate

+intercalated

+intercalates

+intercalating

+intercalation

+intercalative

+intercase

+intercaste

+intercede

+interceder

+intercedes

+intercensal

+interception

+interceptor

+interclass

+intercohort

+intercollegiate

+intercom

+intercontinental

+intercorrelated

+interdenominational

+interdepartmental

+interdepartmentally

+interdict

+interdictive

+interfaith

+interferometer

+interferometer's

+interferometers

+interferometric

+interferometry

+interferon

+intergalactic

+intergeneration

+intergenerational

+interglacial

+intergovernmental

+intergroup

+interindex

+interindustry

+interject

+interjected

+interjecting

+interjects

+interlayer

+interlayering

+interlibrary

+interlingua

+interlining

+interlobular

+interlock

+interlocked

+interlocker

+interlocking

+interlocks

+interlocutor

+interlude

+interludes

+intermarriage

+interment

+intermeshed

+intermetrics

+interminableness

+interminably

+intermission

+intermissions

+intermolecular

+intermolecularly

+internationalist

+internationalists

+internetwork

+interpenetrates

+interplanetary

+interpol

+interposition

+interpretative

+interpretatively

+interpretor

+interpretors

+interprocessor

+interquartile

+interracial

+interred

+interregional

+interregnum

+interrogator

+interrogatories

+interrogators

+interrogatory

+interspecies

+interstellar

+interstice

+interstices

+interstitial

+interstitially

+intersurvey

+intervenor

+interventionist

+intervocalic

+interweaving

+intestate

+intimal

+intonate

+intone

+intoning

+intorsion

+intoxicant

+intra

+intracity

+intraclass

+intracohort

+intradepartmental

+intrafamily

+intragenerational

+intraindustry

+intraline

+intrametropolitan

+intramuscular

+intramuscularly

+intranasal

+intransigence

+intraoffice

+intrapulmonary

+intraregional

+intrasectoral

+intrastate

+intratissue

+intravenous

+intravenously

+intrepid

+intrepidly

+intrepidness

+intro

+introject

+introjected

+introjects

+introversion

+intuitable

+inunction

+inundate

+inundated

+inundates

+inundating

+inundation

+inundations

+inure

+inured

+inuring

+inutile

+invalidism

+invasive

+invasiveness

+invective

+invectively

+invectiveness

+inveigh

+inveigher

+inveigle

+inveigled

+inveigler

+inveigling

+investigatory

+inveterate

+inveterately

+invidious

+invidiously

+invidiousness

+invigorate

+invigorated

+invigorates

+invigorating

+invigoratingly

+invigoration

+inviolability

+inviolable

+inviolate

+inviolately

+inviolateness

+invitational

+invitee

+invitees

+invocable

+invocate

+involute

+involutely

+involution

+involutions

+involutorial

+invulnerability

+iodate

+iodated

+iodating

+iodation

+iodide

+iodinate

+iodinated

+iodinating

+iodination

+ionic

+ionosphere

+ionospheric

+iota

+ipecac

+ipso

+iridium

+ironic

+ironside

+ironsides

+ironstone

+ironwood

+irradiate

+irradiated

+irradiation

+irradiative

+irreconcilable

+irreconcilableness

+irredeemable

+irredeemably

+irredentism

+irredentist

+irrelevancies

+irrelevancy

+irremediable

+irremediableness

+irremovable

+irreparable

+irreparableness

+irreparably

+irreplaceable

+irreplaceableness

+irreproachable

+irreproachableness

+irreproducibility

+irreproducible

+irresistibility

+irresistibly

+irresolute

+irresolutely

+irresoluteness

+irresolution

+irresolvable

+irresponsibility

+irretrievable

+irreverence

+irreverent

+irreverently

+irreversibly

+irrevocable

+irrevocableness

+irrevocably

+irritability

+irritable

+irritableness

+irritably

+irritant

+irritants

+irruption

+irruptions

+isinglass

+isochronal

+isochronally

+isochronous

+isochronously

+isocline

+isocyanate

+isodine

+isolationism

+isolationistic

+isomer

+isomers

+isomorph

+isopleth

+isopleths

+isotherm

+isothermal

+isothermally

+isotherms

+isotonic

+isotopic

+isotropic

+isotropically

+isotropy

+issuant

+itinerant

+itinerantly

+j's

+jabberings

+jackass

+jackboot

+jackbooted

+jackboots

+jackdaw

+jackdaws

+jackknife

+jackpot

+jackpots

+jag

+jagged

+jaggedly

+jaggedness

+jaggers

+jagging

+jaguar

+jalopies

+jalopy

+jamboree

+jangle

+jangled

+jangler

+jangles

+jangling

+janissaries

+janissary

+janitorial

+jasper

+jaspers

+jaundice

+jaundiced

+jaundices

+jaundicing

+jawbone

+jazzier

+jazziness

+jazzmen

+jazzy

+jejune

+jejunely

+jejuneness

+jejunum

+jeopard

+jeopardies

+jeopardy

+jerry

+jess

+jetliner

+jetliners

+jettison

+jibe

+jibed

+jibes

+jibing

+jiffies

+jiffy

+jigger

+jiggered

+jigging

+jiggle

+jiggled

+jiggles

+jiggling

+jigsaw

+jilt

+jilted

+jilter

+jilts

+jimmied

+jimmies

+jimmy

+jimmying

+jinx

+jitter

+jitterbug

+jitters

+jittery

+jive

+jived

+jives

+jiving

+jobbery

+jobbing

+jobholder

+jobholders

+jobless

+joblessness

+jock

+jockey

+jockeyed

+jockeying

+jockeys

+jockstrap

+jockstraps

+jocose

+jocosely

+jocoseness

+jocular

+jocularly

+joey

+joggle

+joggled

+joggler

+joggles

+joggling

+jollities

+jollity

+jonquil

+jonquils

+josh

+joshed

+josher

+joshes

+joshing

+joss

+joule

+jounce

+jounced

+jounces

+jouncing

+journalese

+journaleses

+journeyman

+journeymen

+jovial

+joviality

+jovially

+jowl

+jowled

+jowls

+joyless

+joylessly

+joylessness

+joyride

+joyrider

+joyriding

+joystick

+joysticks

+jubilant

+jubilantly

+jubilate

+jubilated

+jubilates

+jubilating

+jubilation

+jubilations

+judgeship

+judicatory

+judicature

+judicatures

+judo

+jugate

+jugging

+juju

+jujube

+juke

+jukes

+juking

+julep

+juleps

+jumbo

+jumbos

+junkerdom

+junket

+junketed

+junketeer

+junketeering

+junketer

+junketing

+junkets

+junta

+juridical

+juridically

+jurisdictional

+jurisdictionally

+jurisprudence

+jurisprudent

+jurisprudential

+jurisprudentially

+jurist

+jurists

+justiciable

+jute

+jutes

+jutting

+juxtaposition

+k's

+kaboom

+kaleidescope

+kamikaze

+kangaroo

+kangaroos

+kaolin

+kaolinite

+kappa

+karat

+karate

+kazoo

+kazoos

+kcal

+kebob

+keg

+kegs

+kelp

+keno

+ketone

+ketosis

+keyhole

+keyholes

+keynote

+keynoter

+keynotes

+keypunch

+keypunched

+keypuncher

+keypunches

+keypunching

+keystone

+keystones

+khaki

+khan

+kibbutzim

+kibitz

+kibitzer

+kickback

+kickbacks

+kickoff

+kickoffs

+kidder

+kiddie

+kiddies

+kidless

+killable

+killjoy

+kilobaud

+kilobuck

+kilogauss

+kilohertz

+kilohm

+kilojoule

+kiloton

+kilotons

+kilovolt

+kilovolts

+kilowatt

+kilowatts

+kiloword

+kilts

+kimono

+kinematic

+kinematics

+kinesics

+kinetic

+kinetics

+kingbird

+kingfisher

+kinglet

+kingpin

+kink

+kinsmen

+kinsmen's

+kiosk

+kiosks

+kitchenette

+kitchenettes

+kittenish

+kittenishly

+kittenishness

+klaxon

+kleenex

+klystron

+klystrons

+km

+kneecap

+kneecaps

+kneepad

+kneepads

+knick

+knicker

+knickerbocker

+knickers

+knitted

+knitting

+knobby

+knockdown

+knockdowns

+knockout

+knockouts

+knockwurst

+knottier

+knottiness

+knotty

+knuckleball

+knuckleballer

+knurl

+koala

+kohlrabi

+kooks

+kosher

+koshered

+koshering

+kraft

+kraut

+krauts

+krill

+krypton

+kudzu

+kumquat

+kurtosis

+l's

+la

+labial

+labially

+labile

+labiodental

+lackadaisic

+lackey

+lackeyed

+lackeying

+lackeys

+lacrosse

+lacrosses

+lactate

+lactated

+lactates

+lactating

+lactation

+lactational

+lactationally

+lactose

+lacuna

+lacunae

+lacunas

+ladle

+ladled

+ladles

+ladling

+ladylike

+laggard

+laggardly

+laggardness

+laggards

+lagging

+laing

+laissez

+laity

+lakeside

+lamas

+lamentably

+laminate

+laminated

+laminates

+laminating

+lamination

+laminations

+lammed

+lamming

+lampblack

+lamplight

+lamplighter

+lampoon

+lampooned

+lampooner

+lampooning

+lampoons

+lamprey

+lampreys

+landau

+landfill

+landhold

+landholder

+landholders

+landholding

+landholdings

+landless

+landownership

+landslide

+landslides

+languor

+lank

+lankier

+lankiness

+lankly

+lankness

+lanky

+lanthanide

+lanthanum

+lapidary

+lapped

+lapping

+laptop

+laptop's

+laptops

+larceny

+larch

+largemouth

+largesse

+lariat

+larval

+laryngeal

+laryngeally

+larynx

+larynxes

+las

+lascivious

+lasciviously

+lasciviousness

+lasing

+lasso

+lassoed

+lassoer

+lathe

+latitudinal

+latitudinally

+latitudinary

+laud

+laudably

+laudanum

+laudatory

+lauder

+lauds

+laughingstock

+laughingstocks

+laundresses

+laundrymen

+laura

+laureate

+laureated

+laureates

+laureating

+laureation

+lawbreaker

+lawbreakers

+lawbreaking

+lawgiver

+lawgivers

+lawgiving

+lawmakers

+lawmaking

+lawman

+lawmen

+lawrencium

+lax

+laxative

+laxatively

+laxativeness

+laxatives

+laxity

+laxly

+laxness

+layoff

+layperson

+layup

+layup's

+layups

+lazybones

+lb

+lbs

+leach

+leachate

+leaches

+leaching

+leaderless

+leadsman

+leadsmen

+leafhopper

+leakier

+leakiness

+leaky

+leapfrog

+leasehold

+leaseholder

+leatherneck

+leathery

+lebensraum

+lecher

+lechery

+leek

+leery

+leeward

+leewards

+leeway

+lefties

+lefty

+legate

+legated

+legatee

+legates

+legating

+legation

+legations

+legato

+legerdemain

+leggier

+legging

+leggy

+leghorn

+legume

+legumes

+leguminous

+leitmotif

+leitmotiv

+lemming

+lemmings

+lengthily

+lenticular

+leonine

+leper

+lepers

+lesbian

+lesbians

+lesion

+lesions

+lessor

+lethal

+lethality

+lethally

+lethargies

+lethargy

+letterhead

+letterheads

+letterman

+lettermen

+levitate

+levitated

+levitates

+levitating

+levitation

+levities

+levity

+lewis

+lex

+libation

+libations

+libel

+libels

+liberalism

+liberality

+libertarian

+libertarians

+libertine

+libertines

+libidinous

+libidinously

+libidinousness

+librettist

+librettists

+libretto

+libretto's

+librettos

+lice

+licensor

+licentious

+licentiously

+licentiousness

+licit

+licitly

+licorice

+lidding

+lidless

+lieut

+lifeblood

+lifeboat

+lifeboats

+lifeguard

+lifeguards

+lifesaving

+lifespan

+lifespans

+ligament

+ligaments

+ligand

+ligands

+ligature

+ligatured

+ligatures

+ligaturing

+lighthearted

+lightheartedly

+lightheartedness

+lightproof

+lightships

+lignite

+lignum

+likeable

+lilt

+lilting

+liltingly

+liltingness

+limbic

+limbo

+limbos

+limelight

+limerick

+limerick's

+limericks

+limitless

+limitlessly

+limitlessness

+limousine

+limousines

+limpid

+limpidly

+limpidness

+lineage

+lineages

+lineal

+lineally

+linebacker

+linebackers

+lineman

+linemen

+lineup

+lineups

+lingerie

+lingo

+lingua

+lingual

+lingually

+liniment

+liniments

+lipid

+lipid's

+lipids

+liquefaction

+liqueur

+liquidate

+liquidated

+liquidates

+liquidating

+listless

+listlessly

+listlessness

+litanies

+litany

+literalism

+lithium

+lithograph

+lithographer

+lithographers

+lithographs

+lithography

+lithology

+lithosphere

+lithospheric

+litigant

+litigants

+litigious

+litigiously

+litigiousness

+litmus

+litterbug

+littleneck

+littoral

+liturgic

+liturgical

+liturgically

+liturgics

+liturgy

+livability

+liverwort

+livestock

+livid

+lividness

+loadable

+loam

+loamy

+lob

+lobotomy

+lobular

+lobularity

+lobularly

+lobule

+lobules

+locale

+locales

+localisms

+locational

+locationally

+locknut

+locksmith

+locksmithing

+locomotor

+locomotory

+locoweed

+lodestone

+lodgepole

+lodgment

+logarithmic

+loge

+loggerhead

+logion

+logions

+logistical

+logistically

+logjam

+loincloth

+loll

+loller

+lollies

+lolling

+lolly

+longevity

+longhand

+longhorn

+longhorns

+longish

+longitudinal

+longitudinally

+longshoremen

+longstanding

+longterm

+longtime

+looseleaf

+lop

+lope

+loped

+loper

+loping

+lopped

+lopping

+lops

+lopsided

+lopsidedly

+lopsidedness

+loquacious

+loquaciously

+loquaciousness

+loquacity

+lossage

+lossless

+lotion

+lotions

+loudspeaking

+louse

+loused

+louses

+lousewort

+lousing

+lovebird

+lovebirds

+loveless

+lovelessly

+lovelessness

+lovelorn

+lovelornness

+lowboy

+lowdown

+lowercase

+lowercased

+lowercases

+lowercasing

+lowlight

+lowlight's

+lowlights

+loyalist

+loyalists

+lozenge

+lozenged

+lozenges

+lubricate

+lubricated

+lubricates

+lubricating

+lubrications

+lubricative

+lubricious

+lubriciously

+lubricity

+lucent

+lucently

+lucid

+lucidity

+lucidly

+lucidness

+lucrative

+lucratively

+lucrativeness

+lucre

+lug

+luge

+luger

+lugged

+lugging

+lugs

+lulu

+lumbar

+lumberman

+lumbermen

+lumberyard

+lumen

+luminaries

+luminary

+luminescence

+luminescent

+luminosity

+lummox

+lumpier

+lumpiness

+lumpish

+lumpishly

+lumpishness

+lumpy

+lunacy

+lunary

+lunate

+lunated

+lunately

+lunation

+lunchroom

+lunchrooms

+lunchtime

+lunge

+lupine

+lurid

+luridly

+luridness

+lush

+lushes

+lushly

+lushness

+lustful

+lustfully

+lustfulness

+lutanist

+luxe

+luxes

+luxuriance

+luxuriate

+luxuriated

+luxuriating

+lycopodium

+lye

+lymphocyte

+lymphocytes

+lymphoma

+lyrical

+lyrically

+lyricalness

+lyricism

+lyricist

+lyricists

+m's

+ma

+macabre

+macabrely

+machinable

+machination

+machination's

+machinations

+machinelike

+machinist

+machinists

+machismo

+macho

+macintosh

+mack

+mackinaw

+mackintosh

+macrodynamic

+macromolecular

+macrophage

+macrophages

+macroscopically

+macrosimulation

+macrosocioeconomic

+madcap

+madding

+madhouse

+madmen

+madrigal

+madrigaling

+madrigals

+maestro

+magenta

+maggoty

+magi

+magisterial

+magisterially

+magnanimity

+magnanimous

+magnanimously

+magnanimousness

+magnate

+magnates

+magnesia

+magnesite

+magnetite

+magneto

+magnetos

+magnolia

+magnolias

+magnum

+magnums

+magpie

+magpies

+maidenhair

+maidservant

+maier

+mailman

+mailmen

+mainline

+mainlined

+mainliner

+mainliners

+mainlines

+mainlining

+mainstream

+majestically

+maladapt

+maladapted

+maladaptive

+maladjust

+maladjusted

+maladjustive

+maladjustment

+maladjustments

+maladroit

+maladroitly

+malaise

+malaprop

+malapropism

+malarial

+malarious

+malcontent

+malcontent's

+malcontented

+malcontentedly

+malcontentedness

+malcontents

+maledict

+malediction

+malevolence

+malevolencies

+malevolent

+malevolently

+malfeasant

+malformation

+malformations

+malformed

+malign

+malignancies

+malignancy

+maligned

+malignly

+malingering

+mallard

+mallards

+malleable

+malleableness

+malnourished

+malocclusion

+malposed

+malpractice

+maltreat

+mambo

+mambos

+mammalian

+manatee

+mandamus

+mandamused

+mandamuses

+mandamusing

+mandarin

+mandarins

+mandrake

+mandrakes

+manganese

+manhole

+manholes

+mania

+maniacal

+maniacally

+manic

+manicurists

+manikin

+manikins

+manna

+mannequin

+mannequins

+mannerism

+mannerisms

+manorial

+manservant

+manslaughter

+mantlepiece

+mantrap

+marathon

+marathons

+marauders

+margarine

+marginalia

+marginality

+maria

+marina

+marinade

+marinades

+marinas

+marionette

+marionettes

+marital

+maritally

+marksman

+marksmanship

+marlin

+marmalade

+marmalades

+maroon

+marooned

+marquee

+marquees

+marquess

+marquesses

+marred

+marriageable

+marring

+marrowbone

+marrowbones

+marshland

+marshlands

+marshmallow

+marshmallows

+martin

+martingale

+martini

+martinis

+mascara

+mascaras

+mascot

+mascot's

+mascots

+maser

+masque

+masquer

+masquers

+masques

+massless

+mastermind

+masterminded

+masterminding

+masterminds

+mastiff

+mastodon

+mastodons

+matchbook

+matchmake

+materialistic

+materiel

+maternity

+mathematic

+matinee

+matriarch

+matriarchal

+matriculate

+matriculated

+matriculates

+matriculating

+matrimonial

+matrimonially

+matting

+maturate

+maturated

+maturates

+maturating

+maturational

+maturations

+maturative

+maudlin

+maudlinly

+maul

+mauler

+maulers

+mauling

+mauls

+mausoleum

+mausoleums

+mauve

+maverick

+mavericks

+maw

+mawkish

+mawkishly

+mawkishness

+maxima

+maxwell

+mayorship

+meadowland

+meadowsweet

+mealier

+mealies

+mealtime

+mealy

+measle

+measled

+measlier

+measly

+meatier

+meatiest

+meatiness

+meaty

+mecca

+mechanist

+mechanistic

+mechanochemically

+mediator

+mediators

+medicate

+medicated

+medicates

+medicating

+medication

+medications

+medicative

+medico

+medicos

+medievalist

+medievalist's

+medievalists

+mediocre

+mediocrities

+mediocrity

+mediumistic

+medley

+medleys

+meetinghouse

+megahertz

+megalomania

+megalomaniac

+megalopolises

+megaton

+megatons

+megavolt

+megawatt

+megohm

+megohms

+melamine

+melange

+melanin

+melanoma

+melee

+meliorate

+meliorated

+meliorates

+meliorating

+melioration

+meliorations

+meliorative

+melodic

+melodically

+melodramatic

+melodramatics

+memento

+mementoes

+mementos

+memorabilia

+memoriam

+menarche

+menarches

+mendacious

+mendaciously

+mendaciousness

+mendacity

+mendelevium

+menfolk

+menfolks

+menopause

+menstrual

+menstruate

+menstruated

+menstruates

+menstruating

+menstruation

+menstruations

+mensurable

+mensurableness

+mensuration

+mensurations

+mercantile

+mercer

+mercers

+merchantability

+mercurial

+mercurially

+mercurialness

+mercuric

+meretricious

+meretriciously

+meretriciousness

+meringue

+meringues

+meritocracy

+meritocratic

+merlin

+mermaid

+mermaid's

+mermaids

+merman

+merman's

+mermen

+merrymaking

+mesa

+mescaline

+mesmeric

+meson

+mesquite

+metabolic

+metabolism

+metabolisms

+metabolite

+metabolites

+metalliferous

+metallography

+metalloid

+metallurgic

+metallurgical

+metallurgically

+metallurgists

+metalsmith

+metalsmithes

+metalwork

+metalworker

+metalworking

+metalworkings

+metamorphic

+metamorphism

+metamorphose

+metamorphosed

+metaphoric

+metaphosphate

+metaphysic

+meteorite

+meteorites

+meteoritic

+meteoritics

+meteoroid

+meteoroid's

+meteoroids

+meteorological

+methane

+methanol

+methodism

+methyl

+methylene

+meticulous

+meticulously

+meticulousness

+metro

+metronome

+metronomes

+metros

+mettle

+mettled

+mettles

+mettlesome

+mezzo

+mezzos

+miasma

+miasmal

+micro

+microamp

+microanalysis

+microanalytic

+microbial

+microchemistry

+microcosm

+microeconomic

+microfossils

+micrography

+microjoule

+microlevel

+micrometeorites

+micrometeoritic

+micrometer

+micrometer's

+micrometers

+micron

+microns

+microorganism

+microorganisms

+micros

+microscopical

+microscopically

+microscopy

+microsimulation

+microsimulations

+microsomal

+microvolt

+microvolts

+midair

+midas

+midband

+middleman

+middlemen

+middleweight

+middleweights

+midge

+midges

+midi

+midland

+midlander

+midlands

+midlife

+midmorn

+midmorning

+midrange

+midscale

+midsection

+midship

+midshipman

+midshipmen

+midships

+midspan

+midstream

+midterm

+midterm's

+midterms

+midweek

+midweekly

+midwife

+midwifed

+midwifing

+midwives

+midyear

+mignon

+migrant

+migrant's

+migrants

+migratories

+migratory

+mike

+mil

+milieu

+milieus

+militarist

+militate

+militated

+militates

+militating

+militiamen

+milkweed

+millenarian

+millenarianism

+millennia

+millennialism

+millennium

+milliamp

+milliampere

+milliamperes

+millidegree

+millidegrees

+millijoule

+millijoules

+milliners

+millinery

+millivolt

+millivoltmeter

+millivoltmeter's

+millivoltmeters

+millivolts

+milliwatt

+milliwatts

+millwright

+millwrights

+mime

+mimeograph

+mimeographed

+mimeographes

+mimeographing

+mimer

+mimesis

+mimetic

+mimetically

+miming

+mincemeat

+minefield

+mineralogical

+mineralogies

+mineralogist

+mineralogists

+mineralogy

+minesweeper

+minesweepers

+mini

+minidress

+minidresses

+minified

+minifies

+minify

+minifying

+minima

+minimalist

+minimalist's

+minimalists

+minimax

+minis

+miniscule

+miniskirt

+ministerial

+ministerially

+ministrations

+miniver

+minuend

+minuends

+minuet

+minuscule

+minuteman

+minutemen

+minutiae

+mirage

+miraged

+mirages

+miraging

+mirthless

+mirthlessly

+mirthlessness

+misalign

+misaligned

+misaligning

+misalignment

+misalignment's

+misalignments

+misaligns

+misanthrope

+misanthropic

+misbegotten

+misbehave

+misbehaved

+misbehaver

+misbehaves

+misbrand

+misbranded

+misbranding

+misbrands

+miscalculated

+miscarriage

+miscarriages

+miscarried

+miscarries

+miscarry

+miscarrying

+miscegenation

+miscegenations

+miscellanies

+miscellany

+misclassification

+misclassified

+misclassifying

+miscode

+miscoded

+miscodes

+miscoding

+misconstruction

+misconstructions

+miscount

+miscounted

+miscounting

+miscounts

+miscreant

+miscreants

+miscue

+miscue's

+miscues

+misdeed

+misdeeds

+misdemeanant

+misdemeanants

+misdirector

+misdirectors

+misfire

+misfired

+misfires

+misfiring

+misgauge

+misgauged

+misgauges

+misgauging

+misidentification

+misidentified

+misidentifies

+misidentify

+misidentifying

+misinterpretation

+misinterpretations

+misjudge

+misjudged

+misjudges

+misjudging

+misjudgingly

+mismanage

+mismanaged

+mismanages

+mismanaging

+misname

+misnamed

+misnames

+misnaming

+misogynist

+misogynist's

+misogynists

+misogyny

+misplacement

+misplacements

+mispronounce

+mispronounced

+mispronounces

+mispronouncing

+mispronunciation

+misquoted

+misrelated

+misreporting

+misrepresent

+misrepresented

+misrepresenter

+misrepresenting

+misrepresents

+misroute

+misrouted

+misroutes

+misshapen

+misshapenly

+misshapenness

+misshapennesses

+misspecification

+misspecified

+misstatement

+misstatements

+misstep

+mistletoe

+mistook

+mistrial

+miswritten

+mitzvahs

+mixup

+mm

+mobbed

+mobbing

+mobcap

+mobcaps

+mobile

+mobiles

+mobster

+mobsters

+mockingbird

+mockup

+mockups

+mod

+modernism

+modernistic

+modernists

+modicum

+modish

+modishly

+modishness

+mods

+moieties

+moiety

+moire

+molal

+molar

+molars

+moldboard

+molehill

+moll

+mollie

+mollification

+mollifications

+mollified

+mollifies

+mollify

+mollifying

+mollusk

+mollusks

+mollycoddle

+mollycoddled

+mollycoddler

+mollycoddles

+mollycoddling

+molybdenite

+molybdenum

+momenta

+momma

+mommy

+monad

+monadic

+monads

+monarchic

+monasticism

+monaural

+monaurally

+monetarism

+moneylenders

+moneymaking

+mongoose

+mongooses

+monies

+monkish

+monochromatic

+monochromator

+monocle

+monocled

+monocles

+monoclinic

+monocular

+monocularly

+monogamous

+monogamously

+monogamousness

+monogamy

+monolingual

+monolingualism

+monolinguals

+monolith

+monolithically

+monologist

+monologists

+monologue

+monologues

+monomer

+monomer's

+monomeric

+monomers

+monomial

+mononuclear

+monophonic

+monopolistic

+monopolists

+monosyllabic

+monosyllable

+monosyllables

+monotheistic

+monsieur

+monsoon

+monsoons

+monstrosities

+monstrosity

+montage

+montaged

+montages

+montaging

+monumentality

+moo

+moodily

+mooed

+moos

+mope

+mopes

+mopped

+mopping

+moraine

+moralist

+moralistic

+moratorium

+moratoriums

+morbidity

+mordant

+mordantly

+morgen

+morgue

+morgues

+moribund

+morocco

+moronic

+morose

+morosely

+moroseness

+morpheme

+morphemic

+morphine

+morphines

+morphism

+morphism's

+morphisms

+morphologic

+morphophonemic

+morphophonemics

+morris

+mortgagee

+mortgagees

+mortician

+morticians

+mosque

+mosques

+motherhood

+motherland

+moths

+motional

+motivator

+motorman

+motormen

+mottle

+mottled

+mottler

+mottles

+mottling

+mountable

+mountainside

+mountainsides

+mousier

+mousiness

+mousy

+mouthpiece

+mouthpieces

+mucilage

+mucky

+mucus

+mudding

+muddlehead

+muddleheaded

+muddleheadedness

+muddleheads

+mudguard

+mudsling

+mudslinger

+mudslingers

+mudslinging

+muggers

+muggier

+mugginess

+mugging

+muggings

+muggy

+mulatto

+mulattoes

+mulattos

+mulch

+mulched

+mulches

+mulching

+mulct

+mulish

+mulishly

+mulishness

+mull

+mullah

+mullen

+muller

+mulligan

+mulligatawny

+mulling

+multi

+multichannel

+multicollinearity

+multicolumn

+multicomputer

+multicomputer's

+multicomputers

+multidimensionality

+multidisciplinary

+multifaceted

+multifigure

+multifunctioned

+multilateral

+multilaterally

+multimedia

+multimegaton

+multimillionaire

+multinomial

+multiplet

+multiplets

+multipliable

+multipurpose

+multisyllabic

+multitudinous

+multitudinously

+multitudinousness

+multivalent

+multiversity

+mum

+mummification

+mummifications

+mummified

+mummify

+munge

+munged

+munger

+mungers

+munges

+munging

+mungings

+munificent

+munificently

+muon

+muriatic

+murk

+muscovite

+muscovites

+musculature

+mush

+musher

+musicality

+musicianship

+musicologists

+musicology

+muskellunge

+muskmelon

+muskox

+muskoxen

+muss

+mussed

+musses

+mussing

+must've

+mustachio

+mustachioed

+mustachios

+mustang

+mustangs

+mustn't

+mutant

+mutants

+mutational

+mutationally

+mutineer

+mutt

+mutuality

+mycology

+myers

+mylar

+mynah

+myocardial

+myocardium

+myopia

+myopic

+mystification

+mystified

+mystifier

+mystifies

+mystify

+mystifying

+mystifyingly

+mystique

+mythic

+mythographer

+mythographers

+mythography

+mythological

+mythologically

+myths

+n's

+nab

+nabbed

+nabbing

+nadir

+nagged

+nagging

+naggingly

+nameplate

+nameplates

+naphtha

+napped

+napping

+narcissist

+narcosis

+narrate

+narrated

+narrates

+narrating

+narration

+narrations

+narrator

+narrators

+nary

+nasality

+nascent

+nasturtium

+natal

+natalist

+natality

+natch

+nationalism

+nationalisms

+nationalistic

+nationhood

+nattier

+nattiness

+natty

+naturalistic

+nausea

+nauseas

+nauseate

+nauseated

+nauseates

+nauseating

+nauseatingly

+nautical

+nautically

+nautilus

+navel

+navels

+nd

+nearsighted

+nearsightedly

+nearsightedness

+nebulae

+nebular

+nebulous

+nebulously

+nebulousness

+neckline

+necromancer

+necromancers

+necromancy

+necromantic

+necropsy

+necrosis

+necrotic

+nectar

+nectaries

+nectarous

+nectary

+nee

+needlepoint

+negativism

+negativisms

+negativity

+negligee

+negligees

+negligent

+negligently

+negotiant

+negroid

+nelson

+nematic

+nematode

+nematodes

+nemesis

+neoclassic

+neoclassical

+neocortex

+neodymium

+neolithic

+neologism

+neologism's

+neologisms

+neomycin

+neon

+neonatal

+neonatally

+neoned

+neoplasms

+neoprene

+neptunium

+nerveless

+nervelessly

+nervelessness

+nervier

+nerviness

+nervy

+netherworld

+nettlesome

+neuralgia

+neurasthenic

+neuritis

+neuroanatomy

+neurologist

+neurology

+neuromuscular

+neuronal

+neuropathology

+neurophysiology

+neuropsychiatric

+neuroses

+neurosis

+neurotic

+neuter

+neutered

+neuterer

+neuterers

+neutering

+neuterings

+neuters

+neutralism

+neutralist

+neutralists

+neutron

+neutrons

+newel

+newfound

+newfoundland

+newlywed

+newlyweds

+newsboy

+newsboys

+newscast

+newscaster

+newscasters

+newscasting

+newscasts

+newspaperman

+newspapermen

+newsreel

+newsstand

+newsworthiness

+newsworthy

+newton

+nexus

+nexuses

+nichrome

+niggard

+niggardliness

+niggardly

+niggle

+niggled

+niggler

+niggles

+niggling

+nigglingly

+nightcap

+nightclub

+nightclubs

+nightdress

+nighthawk

+nightmarish

+nightmarishly

+nightshirt

+nighttime

+nihilism

+nihilisms

+nihilist

+nihilistic

+nilpotent

+nimbus

+nimbused

+nimbuses

+ninefold

+niobium

+nipped

+nipping

+nippingly

+nipple

+nipples

+nirvana

+nitpick

+nitrate

+nitrated

+nitrates

+nitrating

+nitration

+nitrations

+nitric

+nitride

+nitriding

+nitrite

+nitrogenous

+nitroglycerine

+nitrous

+nm

+nob

+nobelium

+noblemen

+noblesse

+nocturne

+nodal

+nodally

+nodular

+nodule

+nodules

+noisemake

+noisemaker

+noisemakers

+noisemaking

+nominee

+nominees

+nonacid

+nonadjacent

+nonagricultural

+nonbusiness

+noncarbohydrate

+nonchalant

+nonchalantly

+nonchalantness

+noncombatant

+noncommissioned

+noncommittal

+noncommittally

+noncompliance

+nonconformist

+nonconformists

+noncontiguous

+nondiscriminatory

+nondurable

+noneconomic

+nonemergency

+nonequivalence

+nonequivalent

+nonessential

+nonferrous

+nonfiction

+nonionic

+nonlinguistic

+nonliterary

+nonmagical

+nonmetallic

+nonogenarian

+nonpartisan

+nonpayment

+nonperturbing

+nonpoisonous

+nonpolitical

+nonprescription

+nonprofit

+nonracial

+nonrandom

+nonreducing

+nonresident

+nonresidential

+nonresistance

+nonrespondent

+nonrespondents

+nonresponse

+nonsingular

+nonstop

+nonsupervisory

+nonverbal

+nonverbally

+nonveteran

+nonveterans

+nonviolent

+nonviolently

+nonvolunteer

+nonvolunteers

+nonwhite

+noodle

+noodled

+noodles

+noodling

+noontime

+noose

+nooses

+noosing

+noradrenalin

+noradrenaline

+normative

+normatively

+normativeness

+northbound

+northernmost

+northland

+norths

+nosebleed

+nosebleed's

+nosebleeds

+nosier

+nosiness

+nostalgia

+nostalgic

+nostalgically

+nosy

+notary

+notate

+notated

+notates

+notating

+notative

+notoriety

+nouveau

+nouvelle

+nova

+nova's

+novas

+novitiate

+novitiates

+noxious

+noxiously

+noxiousness

+nozzle

+nozzles

+nth

+nuance

+nuanced

+nubile

+nucleate

+nucleated

+nucleation

+nuclei

+nucleic

+nucleoli

+nucleolus

+nuclide

+nude

+nudely

+nudeness

+nuder

+nudes

+nudest

+nudge

+nudged

+nudger

+nudges

+nudging

+nudism

+nudist

+nudists

+nudity

+nugatory

+nugget

+nuggets

+nullity

+numerable

+numerate

+numerated

+numerates

+numerating

+numeration

+numerations

+numerological

+numerology

+numinous

+numismatic

+numismatics

+numismatist

+nutate

+nutated

+nutates

+nutating

+nutation

+nutcrack

+nutcracker

+nutmeg

+nutrient

+nutrients

+nutritional

+nutritionally

+nutritionist

+nutritionists

+nutritious

+nutritiously

+nutritiousness

+nutritive

+nutritively

+nutshell

+nuttier

+nuttiness

+nutty

+nuzzle

+nuzzled

+nuzzles

+nuzzling

+nylon

+nylons

+nymphomania

+nymphomaniac

+nymphomaniacs

+o's

+oaf

+oafs

+oakwood

+oases

+obduracy

+obdurate

+obdurately

+obdurateness

+obeisant

+obeisantly

+obelisk

+obese

+obesity

+obfuscatory

+obit

+obiter

+obituaries

+obituary

+objectification

+objectifications

+objectified

+objectifies

+objectify

+objectifying

+objectivity

+obligational

+obnoxious

+obnoxiously

+obnoxiousness

+oboe

+oboes

+oboist

+obscenities

+obscenity

+obsequies

+obsequious

+obsequiously

+obsequiousness

+obsequy

+observably

+observational

+observationally

+obsess

+obsessed

+obsesses

+obsessive

+obsessively

+obsessiveness

+obsidian

+obsolescent

+obsolescently

+obtrude

+obtruded

+obtruder

+obtrudes

+obtruding

+obtrusive

+obtrusively

+obtrusiveness

+obtuse

+obtusely

+obtuseness

+obtuser

+obtusest

+obverse

+obversely

+ocarina

+occident

+occidental

+occidentally

+occipital

+occipitally

+occlusive

+occult

+occulter

+occultly

+oceanic

+oceanographic

+oceanography

+oceanside

+ocelot

+octagon

+octagonal

+octagonally

+octagons

+octahedron

+octane

+octennial

+octet

+octile

+octillion

+octogenarian

+octoroon

+ocular

+oculist

+odium

+odometer

+odometer's

+odometers

+odyssey

+offal

+offbeat

+offertories

+offertory

+offhand

+offhanded

+offhandedly

+offhandedness

+officeholder

+officeholders

+officemate

+officemates

+officialdom

+offload

+offloaded

+offloading

+offloads

+offramp

+offsetting

+offshoot

+offshore

+offstage

+ogive

+ogled

+ohm

+ohmic

+ohmmeter

+ohmmeter's

+ohmmeters

+ohms

+oilman

+oilmen

+oilseed

+oilseeds

+oldies

+oldster

+oldsters

+oldy

+oleander

+oleanders

+oleomargarine

+oligarchic

+oligarchy

+oligopolistic

+oligopoly

+omega

+omegas

+omelet

+omelets

+omicron

+omni

+omnibus

+omnipotence

+omnipotent

+omnipotently

+oncology

+oncoming

+onetime

+oneupmanship

+onlooker

+onlookers

+onrush

+onrushing

+onslaught

+onslaughts

+ontogeny

+ontological

+ontologically

+ontology

+onus

+onyx

+oodles

+opalescent

+opalescently

+operant

+operantly

+operants

+operatic

+operetta

+ophthalmic

+ophthalmologist

+opinionated

+opinionatedly

+opinionatedness

+opossum

+opposable

+opprobrium

+opthalmic

+opthalmologic

+opthalmology

+opticians

+optimist

+optimists

+optionality

+optometric

+optometrist

+optometrists

+optometry

+opulent

+opulently

+opus

+opuses

+orangutan

+orate

+orated

+orates

+orating

+oratorical

+oratorically

+oratorio

+oratorios

+orchestral

+orchestrally

+orchestrate

+orchestrated

+orchestrater

+orchestrates

+orchestrating

+orchestration

+orchestrations

+ordnance

+ordnances

+oregano

+organdy

+organically

+organismic

+organometallic

+orgasm

+orgasms

+orgiastic

+oriental

+orientally

+oriole

+orioles

+ornate

+ornately

+ornateness

+orneriness

+ornery

+orographic

+orography

+orphanage

+orphanages

+orphanhood

+orthodontic

+orthodontics

+orthodontist

+orthodontists

+orthodoxy

+orthographic

+orthographies

+orthography

+orthonormal

+orthophosphate

+orthophosphates

+osmium

+osmosis

+osmotic

+osprey

+ospreys

+osseous

+osseously

+ossification

+ossifications

+ossified

+ossify

+ostensible

+ostensibly

+ostentatious

+ostentatiously

+ostentatiousness

+osteology

+osteopath

+osteopathic

+osteopaths

+osteopathy

+osteoporosis

+ostracism

+otherworld

+otherworldliness

+otherworldly

+ouch

+oughtn't

+oust

+ousted

+ouster

+ousting

+outage

+outage's

+outages

+outback

+outboard

+outboards

+outclass

+outclassed

+outcrops

+outdated

+outdatedness

+outdistanced

+outdistancing

+outdo

+outdrew

+outface

+outfield

+outfielder

+outfielders

+outfitted

+outflow

+outflows

+outfought

+outfox

+outgeneraled

+outgrip

+outhouse

+outland

+outlander

+outlanders

+outlandish

+outlandishly

+outlandishness

+outlawry

+outliers

+outlying

+outmatched

+outmigration

+outmoded

+outnumber

+outnumbered

+outnumbering

+outnumbers

+outpatient

+outpatients

+outplayed

+outpour

+outpouring

+outpourings

+outreach

+outrigger

+outriggers

+outscoring

+outshone

+outsized

+outsmart

+outsmarted

+outsmarting

+outsmarts

+outspoken

+outspokenly

+outspokenness

+outspread

+outstate

+outstation

+outworn

+ouzo

+ova

+ovate

+ovates

+ovation

+ovationed

+ovationing

+ovations

+overabundance

+overactive

+overage

+overaggressive

+overarching

+overbearing

+overbearingly

+overbearingness

+overburden

+overburdened

+overburdening

+overburdeningly

+overburdens

+overcerebral

+overconfident

+overconfidently

+overconsumption

+overcooked

+overcooled

+overcorrection

+overcurious

+overdeveloped

+overdoing

+overdriving

+overeager

+overeagerly

+overeagerness

+overeat

+overeaten

+overeater

+overeating

+overeducated

+overexcited

+overexploitation

+overexploited

+overexpose

+overextend

+overextended

+overextending

+overextends

+overextension

+overfall

+overfeed

+overfill

+overfilled

+overfilling

+overfills

+overgenerous

+overgrazing

+overgrown

+overhand

+overhanded

+overheat

+overheated

+overheating

+overheats

+overindulged

+overlords

+overloud

+overpaid

+overpayment

+overplayed

+overplaying

+overpopulated

+overpopulation

+overpressure

+overprice

+overpriced

+overprotection

+overprotective

+overran

+overrated

+overreach

+overreached

+overreacher

+overreaches

+overrepresented

+oversample

+oversampled

+oversampling

+oversaturate

+overshoes

+oversize

+oversized

+oversizes

+oversoft

+oversoftness

+overspill

+overstay

+overstepping

+overstraining

+overstrike

+overstrikes

+overstriking

+oversubscribed

+oversupply

+overtaxed

+overwrap

+oviform

+ovulatory

+owlish

+owlishly

+owlishness

+owly

+oxalate

+oxalic

+oxaloacetic

+oxcart

+oxidant

+oxidate

+oxidations

+oxidative

+oxidatively

+oxygenate

+oxygenated

+oxygenates

+oxygenating

+oxygenation

+oxygenations

+oxyhydroxides

+ozone

+p's

+pH

+pacemaker

+pacesetting

+pacifism

+pacifist

+pacifistic

+paddock

+padlock

+padlocked

+padlocks

+padre

+paean

+paeans

+paganism

+pageantry

+pagoda

+pagodas

+paintbrush

+palatability

+palatable

+palatableness

+palatal

+palatally

+palefaces

+palette

+palindrome

+palindromes

+palindromic

+palisade

+palisades

+palladium

+pallet

+palmetto

+palmist

+palpable

+palpably

+palsied

+palsies

+palsy

+palsying

+paltrier

+paltriness

+paltry

+pamper

+pampered

+pamperer

+pampering

+pampers

+panama

+pancreatic

+pandemic

+panicked

+panicky

+panjandrum

+panoplied

+panoply

+panorama

+panoramas

+panoramic

+pantheism

+pantheist

+pantheon

+pantomime

+pantomimed

+pap

+papen

+paperboard

+paperhangers

+paperiness

+paperweight

+paperweights

+papery

+papillary

+papoose

+pappies

+pappy

+papyri

+papyrus

+papyruses

+parable

+parables

+parabola

+parabolic

+paraboloid

+paraboloidal

+paradigmatic

+paradoxic

+parakeet

+parakeets

+parallelepiped

+parallelepipeds

+paramagnet

+paramagnetic

+paramedical

+parametrically

+paranoiac

+paranoiacs

+paranormal

+paranormally

+paraphernalia

+paraplegic

+paraprofessional

+paraprofessionals

+parapsychology

+parasol

+parasols

+parasympathetic

+paratroop

+paratrooper

+paratroopers

+paratroops

+parboil

+parboiled

+parenthetic

+pariah

+parimutuel

+parimutuels

+parishioner

+parishioners

+parkish

+parkland

+parklike

+parkway

+parlance

+parlay

+parlayed

+parley

+parleys

+parliamentarian

+parliamentarians

+parochial

+parochialism

+parochialism's

+parochialisms

+parochially

+parodied

+parodies

+parody

+parolee

+parolees

+parquet

+parqueted

+parqueting

+parrotlike

+parsec

+parsecs

+parsimonious

+parsimoniously

+parsnip

+parsonage

+participial

+participially

+participle

+participles

+particularistic

+particularity

+particulate

+particulates

+partook

+parvenu

+passable

+passband

+passerby

+passersby

+pasta

+pasteboard

+pastel

+pastels

+pasteup

+pastiche

+pastier

+pasties

+pastiness

+pasty

+patchier

+patchiness

+patchy

+patentee

+patentees

+paternalism

+paternalistic

+paternity

+paternoster

+pathless

+pathlessness

+pathogen

+pathogenesis

+pathogenic

+pathogens

+pathologic

+patina

+patinas

+patio

+patios

+patriarchal

+patriarchies

+patriarchy

+patrimonial

+patrimony

+patristic

+patristics

+patrolled

+patrolling

+patrolman

+patrolmen

+patroness

+patted

+patting

+paunch

+paunchier

+paunchiness

+paunchy

+pauper

+pawnshop

+pawnshop's

+pawnshops

+payday

+payload

+payload's

+payloads

+paymaster

+paymasters

+peacemaking

+peacetime

+peacetimes

+peaky

+peasanthood

+pecan

+pecans

+peccadilloes

+peccary

+pectoral

+pectorals

+peculate

+peculated

+peculates

+peculating

+peculation

+pecuniary

+pedagogue

+pedagogy

+pedal

+pedals

+pedant

+pedantry

+peddle

+peddled

+peddles

+peddling

+pediatrician

+pedigree

+pedigreed

+pediment

+pedimented

+peephole

+peepy

+peerage

+peevish

+peevishly

+peevishness

+pegboard

+pegboards

+pegged

+pegging

+pejorative

+pejoratively

+pejoratives

+pelican

+pelicans

+pellagra

+pelvic

+pelvis

+pelvises

+pemmican

+penal

+penally

+penchant

+pendant

+penicillin

+penitential

+penitentially

+penknife

+penknife's

+penknives

+penman

+penmen

+pennant

+pennants

+pentagonal

+pentagonally

+pentecostal

+penultimate

+penultimately

+penurious

+penuriously

+penuriousness

+penury

+peonies

+peony

+peppergrass

+peppermint

+peppermints

+pepperoni

+peppery

+peppier

+peppiness

+pepping

+peppy

+peptidase

+peptidases

+peptide

+peptides

+percept

+percolator

+percolators

+percussion

+percussions

+percussive

+percussively

+percussiveness

+perdition

+perditions

+perfectibility

+perfectible

+perfectionism

+perfidious

+perfidiously

+perfidiousness

+perfidy

+perforate

+perforated

+perforates

+perforating

+perforation

+perforations

+perfumery

+perfunctorily

+perfunctoriness

+perfunctory

+perfusion

+perihelion

+perimeter

+periodicities

+periodicity

+periodontal

+periodontally

+peripatetic

+periphrastic

+periscope

+periscopes

+periwinkle

+periwinkles

+perjure

+perjured

+perjurer

+perjures

+perjuring

+perjury

+perk

+perked

+perkier

+perkiness

+perking

+perks

+perky

+permalloy

+permanency

+permeable

+permeableness

+pernicious

+perniciously

+perniciousness

+peroxide

+perpetuity

+perquisite

+perquisites

+persecutory

+persiflage

+persimmon

+persimmons

+persona

+personae

+perspicacious

+perspicaciously

+perspicaciousness

+perspicuity

+perspire

+perspired

+perspires

+perspiring

+pert

+pertinacious

+pertinaciously

+pertinaciousness

+pertinence

+pertly

+pertness

+pervasion

+perverse

+perversely

+perverseness

+perversion

+perversions

+perversive

+peskier

+pesky

+pessimism

+pessimist

+pessimists

+pesticide

+pesticides

+pestilent

+pestilential

+pestilentially

+pestilently

+pestle

+pestled

+pestles

+pestling

+petite

+petiteness

+petits

+petri

+petrification

+petrified

+petrify

+petrochemical

+petroglyph

+petrol

+petrology

+pettish

+pettishly

+pettishness

+petulance

+petulances

+petulant

+petulantly

+petunia

+peyote

+pfennig

+phagocyte

+phagocytes

+phalanger

+phalanx

+phalanxes

+phantasy

+pharmaceutic

+pharmaceutical

+pharmaceutically

+pharmaceuticals

+pharmaceutics

+pharmacies

+pharmacist

+pharmacists

+pharmacological

+pharmacologically

+pharmacology

+pharmacy

+pharyngeal

+pharynx

+pharynxes

+phenol

+phenolic

+phenotype

+phenyl

+phi

+philander

+philandered

+philanderer

+philanderer's

+philanderers

+philandering

+philanders

+philanthropic

+philanthropies

+philanthropist

+philanthropists

+philanthropy

+philharmonic

+philodendron

+philological

+philologically

+philologists

+philology

+phlegm

+phlox

+phobic

+phoebe

+phoenix

+phonetically

+phonic

+phonics

+phonier

+phonies

+phoniness

+phonologic

+phonological

+phonologically

+phonology

+phony

+phosphide

+phosphine

+phosphines

+phosphor

+phosphoresce

+phosphorescent

+phosphorescently

+phosphors

+phosphorus

+photochemical

+photochemically

+photoelectronic

+photoelectrons

+photoengravers

+photogenic

+photographically

+photoluminescence

+photolysis

+photolytic

+photometric

+photometry

+photomicrograph

+photomicrography

+photon

+photon's

+photons

+photorealism

+photosensitive

+phrasemaking

+phraseologies

+phraseology

+phraseology's

+phylogeny

+physiochemical

+physiognomy

+physiologic

+physiologist

+physiotherapist

+physiotherapy

+phytoplankton

+pianism

+pianissimo

+pianist

+pianistic

+pianists

+pica

+piccolo

+pickaxe

+pickerel

+pickerels

+pickier

+pickoff

+pickoffs

+picky

+picnicked

+picnicker

+picnickers

+picnicking

+picofarad

+picofarads

+picojoule

+piddle

+piddling

+pidgin

+piedmont

+piezoelectric

+piezoelectricity

+pigeonhole

+pigeonholed

+pigeonholes

+pigeonholing

+pigging

+piggish

+piggishly

+piggishness

+piggy

+pigmentation

+pigmentations

+pigpen

+pigpens

+pigroot

+pigskin

+pigsty

+pigtail

+pigtailed

+pilfer

+pilfered

+pilferer

+pilfering

+pilfers

+pilloried

+pillories

+pillory

+pillorying

+pimento

+pimp

+pimping

+pimple

+pimpled

+pimples

+pimplike

+pimply

+pimps

+pinafore

+pinafores

+pinball

+pincushion

+pinhead

+pinheaded

+pinheadedness

+pinheads

+pinhole

+pinholes

+pinkie

+pinkies

+pinkish

+pinkishness

+pinochle

+pintail

+pintails

+pinto

+pinwheel

+pion

+pip

+pipet

+pipette

+piquant

+piquantly

+piquantness

+piracy

+pirouette

+pirouetting

+pistachio

+pistole

+pistoleers

+pitchblende

+pitchfork

+pitchfork's

+pitchforks

+pitchstone

+pitman

+piton

+piton's

+pitons

+pittance

+pittance's

+pittances

+pitting

+pituitary

+pixies

+pixiness

+pixmap

+pixmap's

+pixmaps

+pixy

+pizza

+pizzicato

+placate

+placated

+placater

+placates

+placating

+placation

+placative

+placeable

+placeless

+placelessly

+placenta

+placental

+plagiarism

+plagiarist

+plainclothes

+planeload

+planetaria

+planetarium

+planetesimal

+planetoid

+planetoids

+plankton

+planoconcave

+planoconvex

+plantain

+plaque

+plaques

+plasm

+plastically

+platitude

+platitudes

+platitudinous

+platitudinously

+platonic

+platoon

+platoons

+platted

+plausibly

+playback

+playbacks

+playboy

+playboys

+playhouse

+playhouses

+playoff

+playroom

+playtime

+playwriting

+plaza

+plazas

+pleat

+pleated

+pleater

+pleats

+plenipotentiary

+plenitude

+plenum

+plethora

+pleura

+pleural

+pleuras

+pliable

+pliableness

+pliancy

+pliant

+pliantly

+pliantness

+plink

+plinked

+plinker

+plinking

+plinks

+plodded

+plodding

+ploddingly

+plop

+plopped

+plopping

+plosive

+plover

+plovers

+pluggable

+plummer

+plummet

+plummeted

+plummets

+plunk

+plunker

+plunkers

+plunking

+pluralism

+pluralist

+pluralistic

+pluralists

+plushier

+plushiness

+plushy

+plutonium

+plywood

+pneumatic

+pneumatics

+pock

+pocketful

+pocketknife

+pocketknife's

+pocketknives

+podge

+podger

+podgers

+podia

+podium

+poesies

+poesy

+pogo

+pogrom

+pogroms

+poignancy

+poignant

+poignantly

+poinsettia

+pokerface

+pokerfaced

+pol

+polarimeter

+polarimeter's

+polarimeters

+polarimetry

+polariscope

+polarogram

+polarogram's

+polarograms

+polarograph

+polarography

+polecat

+polemical

+polemically

+policymaker

+policymakers

+policymaking

+polio

+polis

+politburo

+politicking

+politico

+politicos

+polities

+polka

+polka's

+polkas

+pollock

+pollutant

+pollutants

+polonaise

+polonium

+polybutene

+polybutenes

+polychemicals

+polycrystalline

+polyelectrolytes

+polyester

+polyesters

+polyether

+polyethers

+polyethylene

+polygamous

+polygamously

+polygamy

+polygonal

+polygonally

+polygynous

+polyhedra

+polyhedral

+polyhedron

+polyisobutylene

+polyisocyanates

+polymerase

+polymeric

+polymorph

+polymorphic

+polymyositis

+polyphony

+polyphosphate

+polyphosphates

+polypropylene

+polystyrene

+polytechnic

+polytonal

+polytonally

+polyunsaturated

+pomegranate

+pompadour

+pompano

+pompons

+pomposity

+poncho

+pons

+pontiff

+pontifical

+pontificals

+pontificate

+pontificated

+pontificates

+pontificating

+pontification

+pooch

+pooched

+poodle

+pooh

+popcorn

+poplin

+popper

+poppyseed

+popularism

+porcine

+porgy

+pornographer

+pornography

+porosity

+porous

+porously

+porousness

+porpoise

+porpoises

+portage

+portaged

+portaging

+portent

+portentous

+portentously

+portentousness

+portents

+porterhouse

+portfolio

+portfolios

+portmanteau

+portmanteaus

+portraiture

+portrayal

+portrayals

+poseur

+poseurs

+posh

+poshest

+positivism

+positivist

+positivists

+positron

+posse

+posses

+postdate

+postdated

+postdates

+postdating

+postdoctoral

+posteriori

+postfix

+postfixed

+postfixes

+postfixing

+postgraduate

+posthumous

+posthumously

+posthumousness

+postlude

+postludes

+postmarital

+postmark

+postmarked

+postmarks

+postmen

+postmortem

+postoperative

+postoperatively

+postorder

+postpartum

+postponement

+postpositions

+postsecondary

+postvocalic

+postwar

+potable

+potableness

+potage

+potbellied

+potbelly

+potboil

+potboiler

+potboilers

+potency

+pothole

+potholed

+potholing

+potion

+potions

+potlatch

+potlatches

+potluck

+potpourri

+poultice

+poultices

+pow

+powderpuff

+powdery

+practicability

+pragmatism

+pragmatist

+pragmatists

+praiseworthiness

+praiseworthy

+pram

+prams

+praseodymium

+prattle

+prattled

+prattler

+prattles

+prattling

+prattlingly

+praxes

+praxis

+prayerful

+prayerfully

+prayerfulness

+preamble

+preambles

+prearranged

+precautionary

+precess

+precessed

+precesses

+precessing

+precession

+prechlorination

+precipitable

+precocity

+precode

+precoded

+precollege

+precolonial

+preconscious

+precooked

+precut

+predator

+predator's

+predators

+predatory

+predecline

+predestined

+predicator

+predigested

+predilect

+predilection

+predilections

+predispose

+predisposed

+predisposes

+predisposition

+predispositions

+predoctoral

+predominance

+preeminence

+preeminent

+preeminently

+preemployment

+preemptor

+preen

+preener

+preening

+preexistent

+preexisting

+prefab

+prefabricate

+prefabricated

+prefabrication

+prefatory

+prefect

+prefects

+prefecture

+prefectures

+preferment

+prefiguration

+preflight

+preflighted

+preflighting

+preflights

+pregnancies

+pregnancy

+preindustrial

+preinterview

+preisolated

+prejudicial

+prejudicially

+prejudicialness

+preliterate

+premarital

+premaritally

+premarket

+premeditate

+premeditation

+premeditative

+premix

+premixed

+premonition

+premonitions

+premonitory

+preordainment

+prep

+prepackaged

+prepayment

+preponderance

+preponderances

+preponderant

+preponderantly

+preponderate

+preponderately

+preponderating

+preponderation

+prepping

+preprepared

+preprocessing

+prepubescent

+prepublication

+preradiation

+presage

+presaged

+presager

+presages

+presaging

+preschool

+preschooler

+prescience

+prescience's

+prescript

+presentable

+presentableness

+presentational

+presentments

+presoaks

+pressman

+pressmen

+prestidigitate

+prestidigitation

+prestidigitator

+prestigious

+prestigiously

+prestigiousness

+presto

+prestos

+presumable

+presupposition

+presuppositions

+pretest

+pretested

+pretesting

+pretests

+pretrial

+pretzels

+prevision

+previsioned

+previsioning

+previsions

+prewar

+prickle

+prickled

+prickling

+priestess

+priestesses

+prig

+priggish

+priggishly

+priggishness

+prim

+primal

+primate

+primates

+primitivism

+primly

+primness

+primordial

+primordially

+primp

+primping

+printmake

+printmaker

+printmakers

+printmaking

+prismatic

+prissier

+prissiness

+prissy

+pristine

+pristinely

+privateer

+privateer's

+privateers

+probabilist

+probity

+procaine

+processional

+processionally

+procreate

+procreation

+procreative

+procreativity

+procrustean

+proctor

+proctor's

+proctored

+proctoring

+proctors

+prod

+prodded

+prodding

+prodigies

+prodigy

+prof

+profanity

+professorial

+professorially

+professorship

+profligate

+profligately

+profligates

+profoundity

+profundity

+profuse

+profusely

+profuseness

+profusion

+progenitor

+prognoses

+prognosis

+prognosticate

+prognostication

+prognosticative

+prognosticator

+progressivism

+prohibitory

+projectile

+projectiles

+projectionist

+projectionists

+prolate

+prolifically

+prolix

+prolixity

+prolixly

+prolongate

+prolongated

+prolongates

+prolongating

+prolongation

+promethium

+promptitude

+promulgators

+pronto

+proofreader

+proofreading

+proofreads

+propagandist

+propagandistic

+propagandists

+propane

+propellant

+propellants

+propelling

+prophetically

+propinquity

+propionate

+propitiate

+propitiation

+proportionality

+proportionate

+propped

+propping

+proprietorship

+proprietorships

+proprioception

+proprioceptive

+propylene

+prorate

+prorated

+prorating

+proration

+prosaic

+proscenium

+prosceniums

+proscribe

+proscribed

+proscriber

+proscribes

+proscribing

+proscription

+prosecutor

+prosecutors

+prosodies

+prosody

+prostate

+prosthetic

+prosthetics

+prostitute

+prostitutes

+protactinium

+protagonist

+protagonists

+protean

+protease

+proteases

+protectionist

+proteolysis

+proteolytic

+protestant

+protoplasmic

+prototypic

+protozoa

+protozoan

+protract

+protracted

+protractive

+protrusive

+protrusively

+protrusiveness

+protuberance

+protuberant

+provenance

+proverbial

+proverbially

+provident

+providential

+providentially

+providently

+provincialism

+proviso

+provocateur

+provocateurs

+provocative

+provocatively

+provocativeness

+provost

+proxies

+proxy

+prudential

+prudentially

+prurient

+pruriently

+psalmist

+pseudonym

+pseudonym's

+pseudonyms

+psi

+psych

+psychedelic

+psychiatric

+psychic

+psychic's

+psychical

+psychically

+psychics

+psycho

+psychoacoustic

+psychoacoustics

+psychoactive

+psychoanalysis

+psychoanalyst

+psychoanalytic

+psychobiology

+psychocultural

+psycholinguistic

+psycholinguistics

+psychometric

+psychometrics

+psychometry

+psychopath

+psychopathic

+psychophysic

+psychophysical

+psychophysically

+psychophysics

+psychophysiology

+psychos

+psychoses

+psychosis

+psychosomatic

+psychosomatics

+psychotherapeutic

+psychotherapeutics

+psychotherapists

+psychotherapy

+psychotic

+ptarmigan

+puberty

+pubescent

+publicists

+puck

+puckish

+puckishly

+puckishness

+puddly

+pudgier

+pudginess

+pudgy

+pueblo

+pueblos

+puerile

+puerilely

+puffball

+puffballs

+puffery

+puffin

+puffiness

+puffins

+puffy

+puissant

+puissantly

+puke

+puked

+pukes

+puking

+pullover

+pulmonary

+pulsar

+pulsar's

+pulsars

+pulsate

+pulsated

+pulsates

+pulsating

+pulsation

+pulsations

+pulverable

+puma

+puma's

+pumice

+pumiced

+pumicing

+pummel

+pummels

+punctuality

+punctuate

+punctuated

+punctuates

+punctuating

+pundit

+punditry

+pundits

+pungency

+pungent

+pungently

+punk

+punkier

+punkies

+punkiness

+punks

+punky

+punster

+punsters

+pupal

+pupate

+pupated

+pupates

+pupating

+pupation

+puppeteer

+puppeteers

+puppyish

+purgation

+purgative

+purgatory

+purism

+purist

+purists

+puritan

+puritanic

+puritanical

+puritanically

+puritans

+purloin

+purloined

+purloiner

+purloining

+purloins

+purposeless

+purposelessly

+purposelessness

+pursuant

+purvey

+purveyed

+purveying

+purveyor

+purveyors

+purveys

+pus

+pushier

+pushiness

+pushup

+pushy

+pussycat

+putative

+putatively

+putrefy

+putrid

+putridly

+putridness

+putt

+putted

+puttied

+putties

+putty

+puttying

+pyknotic

+pyramidal

+pyramidally

+pyre

+pyridine

+pyrolysis

+pyrometer

+pyrometer's

+pyrometers

+pyrometry

+pyrophosphate

+pyrotechnic

+pyrotechnics

+pyroxene

+pyroxenite

+python

+pythons

+q's

+quackery

+quad

+quadrangle

+quadrangles

+quadrangular

+quadrapole

+quadrennial

+quadrennially

+quadric

+quadriceps

+quadrilateral

+quadrilaterals

+quadrille

+quadrilles

+quadrillion

+quadrillionth

+quadripartite

+quadripartitely

+quadripartition

+quadriplegic

+quadrivium

+quadruplicate

+quadruplicated

+quadruplicates

+quadruplicating

+quadruplication

+quadruplications

+quaff

+quaffer

+quahog

+quantile

+quantiles

+quarryman

+quarrymen

+quarterback

+quarterbacks

+quartermaster

+quartermasters

+quartile

+quartiles

+quartzite

+quasar

+quasar's

+quasars

+quaternaries

+quaternary

+quatrain

+queasier

+queasiness

+queasy

+querulous

+querulously

+querulousness

+quibble

+quibbled

+quibbler

+quibbles

+quibbling

+quiche

+quiches

+quickie

+quickies

+quicklime

+quicksand

+quicksands

+quickstep

+quicksteps

+quiescent

+quiescently

+quiescentness

+quincy

+quinquennial

+quinquennially

+quint

+quintessential

+quintet

+quintets

+quintile

+quintiles

+quintillion

+quintillionth

+quip

+quipping

+quips

+quirk

+quirking

+quirks

+quirt

+quixotic

+quizzical

+quizzically

+quonset

+quorum

+r's

+rabbi

+rabbinical

+rabbinically

+rabid

+rabidly

+rabidness

+rabies

+racetrack

+racetracker

+raceway

+racier

+raciness

+racism

+racist

+racists

+rackety

+racquet

+racquets

+racy

+radian

+radians

+radicalism

+radices

+radii

+radioactive

+radioactively

+radioactivities

+radioactivity

+radioastronomy

+radiocarbon

+radiochemical

+radiochemically

+radiochemistry

+radiographic

+radiography

+radiologic

+radiological

+radiologically

+radioman

+radiomen

+radiometer

+radiometer's

+radiometers

+radiometric

+radiometry

+radionics

+radiophysics

+radiotherapy

+radium

+radon

+raffish

+raffishly

+raffishness

+raffle

+raffled

+raffles

+raffling

+ragging

+ragout

+ragweed

+ragweeds

+railbird

+railbirds

+railhead

+railheads

+raillery

+rainless

+rainstorm

+rainwater

+rajah

+rakish

+rakishly

+rakishness

+ramified

+ramifies

+ramify

+ramifying

+rammed

+ramming

+rampage

+rampaged

+rampages

+rampaging

+rampant

+rampantly

+ramrod

+ramrods

+rancho

+ranchos

+rancid

+rancidity

+rancidness

+rancorous

+rancorously

+randies

+randy

+rangeland

+rangelands

+rangier

+ranginess

+rangy

+rapacious

+rapaciously

+rapaciousness

+rapier

+rapists

+rapped

+rappel

+rapper

+rapper's

+rappers

+rapping

+rapport

+rapprochement

+rarefied

+rarefy

+ratable

+ratchet

+ratchet's

+ratcheted

+ratcheting

+ratchets

+rateable

+ratiocinate

+ratiocinated

+ratiocinates

+ratiocinating

+ratiocination

+ratiocinative

+rationalism

+rationalist

+rationalistic

+rationalists

+rattail

+rattier

+ratty

+raucous

+raucously

+raucousness

+ravish

+ravisher

+ravishes

+ravishing

+ravishingly

+rawboned

+rawhide

+rawhided

+rawhiding

+raze

+razed

+razer

+razes

+razing

+razorback

+rd

+reachability

+reactant

+reactants

+readably

+readership

+readership's

+readjust

+readjuster

+readjusting

+readjustment

+reaffirmation

+reafforest

+reagent

+realtor

+realtors

+realty

+reappearance

+reapplication

+reapportionment

+reappraise

+reappraising

+reassert

+reasserted

+reasserting

+reassurance

+recalcitrant

+recallable

+recant

+recanted

+recappable

+recency

+receptionist

+receptionists

+recertification

+recheck

+rechecking

+recherche

+recherches

+recipiency

+recitative

+recluse

+recluse's

+recluses

+reclusion

+reclusive

+recoilless

+recommence

+recommencing

+recommendable

+recommendatory

+recommittal

+recomposition

+reconciliatory

+recondite

+reconditely

+reconditeness

+recondition

+reconditioning

+reconditionings

+reconditions

+reconfigurability

+reconnaissance

+reconquer

+reconquered

+reconquering

+reconquers

+recontamination

+reconvene

+reconvening

+reconvention

+reconverting

+recopied

+recopies

+recopy

+recoup

+recouped

+recouping

+recoups

+recriminate

+recriminated

+recriminates

+recriminating

+recrimination

+recriminations

+recriminative

+recruitment

+rectification

+rectifications

+rectified

+rectifier

+rectifiers

+rectify

+rectilinear

+rectilinearly

+rectitude

+rectory

+recumbent

+recumbently

+recuperate

+recuperated

+recuperates

+recuperating

+recuperation

+recuperative

+recurred

+recusant

+recuse

+redact

+redactions

+redactor

+redbird

+redbirds

+redbud

+redcoat

+redcoats

+redding

+redecorating

+redecoration

+rededicate

+redemptive

+redeposition

+redhead

+redheaded

+redheader

+redheads

+rediscover

+rediscovering

+rediscovery

+redistricting

+redneck

+rednecked

+rednecks

+redo

+redound

+reduct

+reductionism

+reductive

+redwood

+redwoods

+reedier

+reedy

+reek

+reeked

+reeker

+reeking

+reeks

+reelection

+reemission

+reemission's

+reemissions

+reenact

+reentry

+reenumerate

+reenumeration

+reestimate

+reeve

+reexamination

+refactoring

+refashion

+refectories

+refectory

+referenda

+refinance

+refineries

+refinery

+reflectance

+reflux

+refluxed

+refluxes

+refluxing

+reforestation

+reformability

+reformatories

+reformatory

+reformism

+reformist

+reformists

+refract

+refracted

+refracting

+refraction

+refractive

+refractively

+refractiveness

+refractometer

+refractometer's

+refractometers

+refrigerate

+refrigerated

+refrigeration

+refurbish

+refurbished

+refurbisher

+refurbishing

+regale

+regalia

+regatta

+regattas

+regency

+regimentation

+regionalism

+registrable

+registrant

+registrants

+registrar

+registrars

+registries

+registry

+regressors

+reground

+regulatory

+rehabilitate

+rehabilitated

+rehabilitates

+rehabilitating

+rehabilitation

+rehabilitations

+rehabilitative

+rehearing

+reimbursable

+reimburse

+reimburses

+reimbursing

+reinstitution

+reinterpretation

+reinterview

+reinvest

+reinvestigation

+reinvigoration

+rejigger

+rejoinder

+relativist

+releasable

+relevancy

+reliant

+reliantly

+relict

+religionists

+religiosity

+relocatable

+remake

+remaking

+remand

+remanded

+remanding

+remarriage

+remarry

+remarrying

+rematch

+remediable

+remediableness

+remedial

+reminisce

+reminisced

+reminisces

+reminiscing

+remiss

+remission

+remissly

+remissness

+remit

+remits

+remitted

+remitting

+remorseful

+remorsefully

+remorsefulness

+remorseless

+remorselessly

+remorselessness

+remounting

+remunerate

+remunerated

+remunerates

+remunerating

+remuneration

+remunerations

+remunerative

+remuneratively

+remunerativeness

+renascent

+renaturation

+renature

+renaturing

+renegotiate

+renegotiation

+renewable

+renovate

+renovated

+renovates

+renovation

+renumeration

+renunciate

+renunciation

+renunciations

+renunciative

+reorient

+reorientation

+repacked

+repairable

+repairmen

+repartee

+repatriations

+repayment

+repeatability

+repelled

+repellent

+repellently

+repelling

+repentant

+repentantly

+repertory

+repetitious

+repetitiously

+repetitiousness

+replenishment

+replenishments

+reportage

+reportorial

+reportorially

+reprehensible

+reprehensibleness

+representativity

+reprimand

+reprimanded

+reprise

+reprised

+reprising

+reprobate

+reprobating

+reprobation

+reprobative

+reps

+reptilian

+republicanism

+repugnance

+repugnant

+repugnantly

+resale

+rescaling

+rescind

+rescinded

+rescinder

+researchable

+resemblant

+resettlement

+residency

+residual

+residually

+residuals

+residuary

+residuum

+resilience

+resilient

+resiliently

+resinlike

+resonate

+resonated

+resonates

+resonating

+resonator

+resonators

+respirator

+respirators

+respiratory

+respire

+respiring

+restaurateur

+restitution

+restock

+restorability

+restorative

+restoratively

+restorativeness

+restructurability

+restudy

+resupplied

+resupplies

+resupply

+resupply's

+resupplying

+resurgence

+resurgent

+resuscitate

+resuscitated

+resuscitates

+resuscitating

+resuscitation

+resuscitative

+resuspension

+retaliate

+retaliated

+retaliates

+retaliating

+retaliative

+retaliatory

+retardant

+retardation

+retch

+retching

+retell

+retelling

+retest

+rethink

+rethinker

+rethinking

+rethought

+reticulum

+retiree

+retorsion

+retouching

+retrenching

+retrenchment

+retributed

+retribution

+retroactive

+retrofit

+retrofitting

+retroflection

+retroflex

+retroflexed

+retroflexion

+retrogradations

+retrograde

+retrogradely

+retrograding

+retrogressive

+retrogressively

+retrorocket

+retrovision

+revaluation

+revelatory

+revengeful

+revengefully

+revengefulness

+reverberate

+reverberated

+reverberation

+reverberations

+reverberative

+reverent

+reverie

+reveries

+reversibility

+revet

+revetments

+revisable

+revisionary

+revisionist

+revisionists

+revivalism

+revivified

+revocable

+revolutionists

+revue

+revues

+revulsion

+revved

+revving

+rhapsodic

+rhapsody

+rhenium

+rheology

+rheostat

+rheostats

+rhetorical

+rhetorically

+rhetoricalness

+rhetorician

+rhetoricians

+rheum

+rheumatic

+rheumatics

+rhinestone

+rhinestones

+rhino

+rhinos

+rhinotracheitis

+rho

+rhodium

+rhododendron

+rhododendrons

+rhodolite

+rhodonite

+rhombic

+rhombus

+rhombuses

+ribald

+riboflavin

+ribonucleic

+ribosomal

+ribosome

+ribosomes

+rickets

+rickety

+ricochet

+ricocheted

+ricocheting

+ricochets

+ridable

+riddance

+ridding

+ridgepole

+riflemen

+rigamarole

+rigger

+riggers

+rightist

+rigmarole

+rigmaroles

+rimless

+rimmed

+rimming

+ringlet

+ringlets

+ringside

+ringsiders

+rink

+rinker

+riparian

+risible

+risibles

+riskier

+riskiness

+risky

+riverbank

+riverbanks

+riverboat

+riverfront

+riverine

+roach

+roaches

+roadbed

+roadbeds

+roadblock

+roadblocks

+roadhouse

+roadhouses

+robotism

+rockabye

+rockbound

+rodder

+rodding

+rodent

+rodents

+rodeo

+rodeos

+roebuck

+roebucks

+roentgen

+roguish

+roguishly

+roguishness

+roil

+roiling

+rollback

+rollicking

+rollickingly

+romanticism

+rondo

+rondos

+rood

+rooftop

+rooftops

+rookie

+rookies

+roomful

+roomier

+roominess

+roommate

+roommate's

+roommates

+roomy

+rootless

+rootlessness

+rosaries

+rosary

+roseate

+roseately

+rosebush

+rosemary

+rosette

+rosettes

+roster

+rostrum

+rotogravure

+rotogravures

+rotor

+rotors

+rototill

+rotting

+rotund

+rotunda

+rotundity

+rotundly

+rotundness

+roughish

+roughneck

+roughshod

+roulette

+rouletted

+roulettes

+rouletting

+roundhead

+roundheaded

+roundheadedness

+roundhouse

+roundtable

+roundworm

+roustabout

+rowboat

+rowboats

+rowdier

+rowdies

+rowdiness

+rowdy

+rowel

+rubbery

+rubdown

+rube

+rubella

+rubes

+rubicund

+rubidium

+rubric

+ruckus

+rudderless

+rueful

+ruefulness

+ruminant

+ruminantly

+ruminants

+rummage

+rummaged

+rummager

+rummaging

+rummier

+rummies

+rummy

+rumpus

+runabout

+runabouts

+rundown

+rune

+runes

+runic

+runoff

+runoffs

+runt

+runtiness

+runts

+runty

+runway

+runways

+rupee

+rupees

+rurality

+ruse

+rusk

+rustproof

+rutabaga

+rutabagas

+ruthenium

+rutted

+ruttier

+rutting

+rutty

+s's

+sabbath

+sabbatical

+sabras

+sacral

+sacrament

+sacraments

+sacrilege

+sacrilegious

+sacrilegiously

+sacrosanct

+saddlebag

+saddlebags

+safari

+safekeeping

+saffron

+saga

+sagebrush

+sagged

+sagging

+sailboat

+sailboater

+sailboaters

+sailboating

+sailboats

+sailfish

+sainthood

+salaam

+salacious

+salaciously

+salaciousness

+salamander

+salami

+salamis

+salesgirl

+saleslady

+salesmanship

+saleswomen

+salience

+saliency

+salinger

+salivary

+salivate

+salivated

+salivates

+salivating

+salivation

+saloonkeeper

+salsa

+salsa's

+salsas

+salsify

+saltwater

+salubrious

+salubriously

+salubriousness

+salvageable

+salvo

+salvos

+samovar

+sanatoria

+sanatorium

+sanctimonious

+sanctimoniously

+sanctimoniousness

+sandalwood

+sandbag

+sandbars

+sandblast

+sandblaster

+sandhill

+sandman

+sandpile

+sandpiper

+sanguinary

+sanguineous

+sanitate

+sanitations

+sapped

+sappier

+sappiness

+sapping

+sappy

+sapsucker

+sarcastically

+sarcoma

+sardine

+sardines

+sardonic

+sari

+sartorius

+sashay

+sashayed

+sassafras

+sassing

+satanic

+satiable

+satiate

+satiated

+satiates

+satiating

+satiation

+satiric

+satirical

+satirically

+saturnalia

+saturnine

+saturninely

+saucily

+sauerkraut

+sauna

+sauna's

+saunas

+saute

+sauterne

+sauternes

+savagery

+savoy

+savvied

+savvy

+savvying

+sawdust

+sawyer

+sax

+saxophone

+saxophone's

+saxophones

+saxophonist

+scab

+scabbed

+scabrous

+scabrously

+scabrousness

+scabs

+scalability

+scalpel

+scamp

+scandium

+scapegoat

+scapegoating

+scapegoats

+scapula

+scapular

+scapulars

+scarecrow

+scarface

+scarification

+scarifier

+scarify

+scarred

+scarves

+scat

+scathing

+scathingly

+scatterbrain

+scatterbrained

+scattergun

+scatting

+scavenge

+scavenged

+scavenges

+scavenging

+sceptic

+sceptical

+scepticism

+schism

+schist

+schizoid

+schizomycetes

+schizophrenic

+schmuck

+schnapps

+schoolbook

+schoolbooks

+schoolgirl

+schoolgirlish

+schoolgirls

+schoolmarm

+schoolmate

+schoolmates

+schoolteacher

+schoolwork

+sciatica

+scimitar

+scimitars

+scintillate

+scintillated

+scintillates

+scintillating

+scintillation

+scion

+scions

+sclerosis

+sclerotic

+scoot

+scooted

+scooter

+scooting

+scoots

+scops

+scoreboard

+scoreboards

+scorecard

+scoreless

+scotch

+scrabble

+scrabbled

+scrabbler

+scrabbles

+scrabbling

+scraggly

+scram

+scramming

+scrapbook

+scrapbooks

+scrapping

+scratchier

+scratchiness

+scratchy

+scrawnier

+scrawniness

+scrawny

+screechy

+screed

+screenplay

+screenwriter

+screenwriter's

+screenwriters

+screwball

+screwdriver

+screwdrivers

+screwup

+scrim

+scrimmage

+scrimmaged

+scrimmager

+scrimmages

+scrimmaging

+scrimp

+scrimped

+scrimping

+scrimps

+scriptural

+scripturally

+scriven

+scrivener

+scrollbar

+scrollbar's

+scrollbars

+scrounge

+scrounged

+scrounger

+scroungers

+scrounges

+scrounging

+scrubbed

+scrubber

+scrubbing

+scrumptious

+scrumptiously

+scrupulosity

+scrutable

+scuba

+scuff

+scuffed

+scuffing

+scuffs

+sculptural

+sculpturally

+scurrilous

+scurrilously

+scurrilousness

+scurviness

+scurvy

+seafare

+seafarer

+seafarers

+seafaring

+seafood

+seagull

+seagulls

+seahorse

+sealant

+sealants

+seamanship

+seamanships

+seamier

+seaminess

+seamless

+seamlessly

+seamlessness

+seamstress

+seamstresses

+seamy

+seance

+seaquake

+searchlight

+searchlights

+seaway

+secant

+secants

+secession

+secessionist

+seclude

+secludes

+secluding

+secretariat

+sectarian

+secularism

+secularist

+secularists

+secularity

+sedan

+sedans

+sedate

+sedated

+sedately

+sedateness

+sedates

+sedating

+sedation

+sedative

+sedentary

+sedimentary

+sedimentation

+sedition

+seditious

+seditiously

+seditiousness

+seduction

+seductions

+sedulously

+seedbed

+seedbeds

+seedier

+seediness

+seedless

+seedy

+seepage

+seersucker

+seesaw

+seesawed

+seesawing

+seesaws

+segmental

+segmentally

+segregant

+segregationist

+seismograph

+seismographer

+seismographs

+seismography

+seismological

+seismology

+selectable

+selectional

+selenate

+selenite

+selenium

+selfless

+selflessly

+selflessness

+sellout

+seltzer

+semen

+semi

+semiannual

+semiannually

+semiarid

+semiautomatic

+semicircular

+semidefinite

+semidrying

+semilogarithmic

+seminarian

+seminarians

+semiprofessional

+semiprofessionally

+semiprofessionals

+semipublic

+semiquantitative

+semiquantitatively

+semisecret

+semistructured

+semitic

+semitics

+semitrance

+semitropical

+senatorial

+senile

+senilely

+senor

+senorita

+sensate

+sensately

+sensationalism

+sensual

+sensuality

+sensually

+sensuous

+sensuously

+sensuousness

+sentient

+sentiently

+sentimentalists

+sentimentality

+separability

+sepia

+sept

+septate

+septation

+septennial

+septennially

+septic

+septillion

+septuagenarian

+septum

+sepulchral

+sepulchrally

+sequestration

+sequin

+sequined

+sequins

+sequoia

+serape

+seraph

+seraphim

+serenade

+serenaded

+serenader

+serenades

+serfdom

+serge

+serging

+serological

+serologically

+serology

+serviceability

+serviceman

+servicemen

+serviette

+serviettes

+servitor

+servitors

+servo

+servomechanism

+servomechanisms

+servos

+sesame

+setback

+setbacks

+setscrew

+setscrews

+sevenfold

+severalfold

+severalty

+sewage

+sewerage

+sewn

+sexier

+sexiness

+sextet

+sextillion

+sexton

+sextuple

+sextupled

+sextuplet

+sextupling

+sexy

+shabbily

+shag

+shagging

+shags

+shah

+shakeable

+shakedown

+shakily

+shalom

+shamble

+shambled

+shambling

+shamefacedly

+shampoo

+shampooer

+shampoos

+shamrock

+shank

+shanked

+shards

+sharecrop

+sharecropping

+sharpshoot

+sharpshooter

+sharpshooters

+sharpshooting

+shatterproof

+shaw

+sheathe

+sheave

+sheaving

+shedding

+sheepskin

+sheik

+shenanigan

+shenanigans

+sherbet

+sherlock

+sherries

+sherry

+shibboleth

+shibboleths

+shiftless

+shiftlessly

+shiftlessness

+shill

+shills

+shim

+shimmied

+shimmies

+shimming

+shimmy

+shimmying

+shims

+shinbone

+shindig

+shindig's

+shindigs

+shipbuild

+shipbuilder

+shipman

+shipmate

+shipmates

+shipmen

+shipshape

+shipyard

+shipyards

+shire

+shires

+shirtmake

+shirtmaker

+shirttail

+shivery

+shoddier

+shoddiness

+shoddy

+shoehorn

+shoelace

+shoelaces

+shoemake

+shoemakers

+shoestring

+shoestrings

+shoo

+shoofly

+shooing

+shootout

+shootout's

+shootouts

+shopkeep

+shopworn

+shoreline

+shorelines

+shortfall

+shortfalls

+shortish

+shortsighted

+shortsightedly

+shortsightedness

+shortstop

+showboat

+showcase

+showcase's

+showcased

+showcases

+showcasing

+showdown

+showier

+showiness

+showman

+showmanship

+showmen

+showpiece

+showplace

+showroom

+showy

+shrapnel

+shredded

+shredding

+shrewish

+shrewishly

+shrewishness

+shrift

+shrinkage

+shriver

+shrove

+shrugged

+shrugging

+shuck

+shucker

+shucks

+shuddery

+shuffleboard

+shunned

+shunning

+shunt

+shunted

+shunter

+shunting

+shunts

+shutoff

+shutout

+shuttlecock

+shuttlecocks

+sibilant

+sibilantly

+sic

+sickish

+sickishly

+sickishness

+sickroom

+sidearm

+sidearms

+sideband

+sidebands

+sidecar

+sidecars

+sideline

+sideliner

+sidelines

+sidelong

+sideman

+sidemen

+sidereal

+sidesaddle

+sideshow

+sideshows

+sidestep

+sidestepping

+sidesteps

+sidewall

+sideway

+sidewinder

+sidle

+sidled

+sidles

+sidling

+sienna

+siesta

+sightsee

+sightseeing

+sightseer

+sightseers

+sigma

+sigmas

+signboard

+signpost

+signposted

+signposting

+signposts

+silage

+silica

+silicate

+silicates

+silicide

+silkworm

+silkworms

+silo

+silos

+siltation

+silty

+silversmith

+silversmiths

+silverware

+simile

+simpleminded

+simplemindedly

+simplemindedness

+simpleton

+simulcast

+sinewy

+singe

+singlehanded

+singlehandedly

+singlet

+singsonged

+sinistral

+sinistrally

+sinless

+sinlessly

+sinlessness

+sinter

+sintered

+sinuous

+sinuousities

+sinuously

+sinuousness

+sinus

+sinuses

+sinusoid

+sipped

+sippers

+sipping

+sis

+sisal

+situ

+situs

+sixfold

+sixgun

+sizeable

+sizzle

+sizzled

+sizzler

+sizzling

+skat

+skeet

+skeeter

+skepticism

+sketchbook

+sketchpad

+skid

+skidded

+skidding

+skids

+skiff

+skiffs

+skillet

+skimpier

+skimpiness

+skimpy

+skindive

+skindiving

+skinless

+skinnier

+skinniness

+skinny

+skit

+skits

+skittle

+skullcap

+skullduggery

+skyhook

+skyjack

+skyjacked

+skyjacker

+skyjackers

+skyjacking

+skyline

+skyrocket

+skyscrape

+skyward

+skywave

+skyway

+slag

+slake

+slaked

+slaking

+slalom

+slaloms

+slanderous

+slanderously

+slanderousness

+slapstick

+slatted

+slatting

+slaughterhouse

+slaughterhouses

+slavish

+slavishly

+slavishness

+slaw

+sleazier

+sleaziness

+sleazy

+sledding

+sledgehammer

+sleepwalk

+sleepwalker

+sleety

+sleight

+sleuthing

+slimmer

+slimmers

+slingshot

+slink

+slinked

+slinking

+slinks

+slipstream

+slither

+slithered

+slithering

+slithers

+slitter

+slitters

+slitting

+sliver

+slivered

+slivering

+slivers

+slivery

+slob

+sloe

+slog

+sloganeer

+sloganeering

+slogging

+sloop

+sloops

+sloppily

+slosh

+sloshed

+slothful

+slothfully

+slothfulness

+slough

+sloughed

+sloughing

+sloven

+slovenliness

+slovenly

+slowdown

+sludge

+sludges

+slugged

+slugger

+sluggers

+slugging

+sluice

+sluiced

+sluices

+sluicing

+slumming

+slunk

+slurp

+slurped

+slurping

+slurps

+slurried

+slurries

+slurring

+slurry

+slurrying

+slush

+slyness

+smallish

+smalltime

+smattering

+smatterings

+smiley

+smiley's

+smilies

+smirk

+smirked

+smithereens

+smokehouse

+smokescreen

+smokestack

+smooch

+smooching

+smudge

+smudged

+smudginess

+smudging

+smudgy

+smut

+smuts

+smuttier

+smuttiness

+smutty

+snack

+snacks

+snafu

+snag

+snagged

+snagging

+snags

+snakebird

+snakelike

+snakeroot

+snapback

+snapdragon

+snapdragons

+snappish

+snappishly

+snappishness

+snazzier

+snazzy

+snicker

+snickered

+snickerer

+snickering

+snide

+snidely

+snideness

+snider

+snidest

+sniffle

+sniffled

+sniffler

+sniffles

+sniffling

+snifter

+snip

+snipe

+sniped

+sniper

+sniper's

+snipers

+snipes

+sniping

+snipped

+snipper

+snipper's

+snippers

+snippet

+snippier

+snipping

+snippy

+snips

+snivel

+snob

+snobbery

+snobbish

+snobbishly

+snobbishness

+snobs

+snook

+snooker

+snookers

+snooks

+snoopy

+snorkel

+snorkeled

+snorkeler

+snorkeling

+snotty

+snowball

+snowballed

+snowballing

+snowballs

+snowbank

+snowbank's

+snowbanks

+snowblower

+snowblowers

+snowfall

+snowflake

+snowflakes

+snowmobile

+snowmobiler

+snowmobiling

+snowstorm

+snub

+snubbed

+snubbing

+snubness

+snubs

+snuffboxes

+snuffle

+snuffled

+snuffler

+snuffling

+snugged

+snugging

+snuggly

+soapier

+soapiness

+soapstone

+soapstones

+soapsud

+soapsuds

+soapy

+sobbed

+sobbing

+sobbingly

+sobriety

+sobriquet

+socialistic

+sociality

+socio

+sociocultural

+socioculturally

+sociodemographic

+socioeconomic

+socioeconomically

+socioeconomics

+sociologist

+sociologists

+sociometric

+sociometry

+sodden

+soddened

+soddening

+soddenly

+soddenness

+sodding

+softball

+softwood

+soggier

+sogginess

+soggy

+soiree

+soirees

+soldiery

+solecism

+solenoid

+solenoids

+solicitation

+solicitous

+solicitously

+solicitousness

+solicitude

+solidarity

+soliloquy

+solipsism

+soloist

+soloists

+solstice

+solvating

+solvency

+soma

+somatic

+somebody'll

+someone'll

+somersault

+somersaulting

+somersaults

+sommelier

+sommeliers

+somnolence

+somnolent

+somnolently

+sonata

+sonatas

+songbag

+songbook

+songful

+songfully

+songfulness

+sonic

+sonny

+sonofabitch

+sonorities

+sonority

+sonorous

+sonorously

+sonorousness

+sonuvabitch

+soothsay

+soothsayer

+soothsayers

+soothsaying

+sop

+sophism

+sophist

+sophister

+sophisticate

+sophisticates

+sophistry

+sophomoric

+soporific

+soporific's

+soporifics

+sopping

+soprano

+sopranos

+sops

+sorghum

+sororities

+sorority

+sorrel

+sortie

+soubriquet

+souffle

+soulful

+soulfully

+soulfulness

+soundproof

+soundproofed

+soundproofing

+soundproofs

+sourdough

+southbound

+southeast

+southeaster

+southeasterly

+southeastern

+southernisms

+southernmost

+southland

+southpaw

+southpaws

+southward

+southwards

+southwest

+southwester

+southwesterly

+southwestern

+souvenir

+souvenirs

+sovereignty

+sow

+sowbelly

+sowens

+sower

+sowered

+sowing

+sown

+sox

+soy

+soya

+soybean

+soybeans

+spacecraft

+spacesuit

+spacesuits

+spacious

+spaciously

+spaciousness

+spandrels

+spangle

+spangled

+spangles

+spangling

+spaniel

+spar

+sparkier

+sparkle

+sparkled

+sparkler

+sparkles

+sparkling

+sparky

+sparling

+sparlings

+sparring

+spars

+spasm

+spasms

+spastic

+spatiality

+spatterdock

+spatula

+spavined

+spay

+spayed

+spaying

+speakership

+spearhead

+spearmint

+spec

+specie

+specifiability

+specious

+speciously

+speciousness

+specs

+spectral

+spectrally

+spectralness

+spectrograph

+spectrographically

+spectrography

+spectrometer

+spectrometer's

+spectrometers

+spectrometric

+spectrometry

+spectrophotometer

+spectrophotometer's

+spectrophotometers

+spectrophotometric

+spectrophotometry

+spectroscope

+spectroscopic

+spectroscopy

+specular

+specularity

+specularly

+speedboat

+speedboater

+speedboating

+speedometer

+speedometer's

+speedometers

+speer

+speleological

+speleologist

+speleology

+spellbound

+sperm

+spermatophyte

+sperms

+spew

+spewer

+spewing

+spewings

+spheric

+spherics

+spheroid

+spheroidal

+spheroidally

+spherule

+spherules

+sphinx

+sphinxes

+spic

+spicebush

+spiderwort

+spidery

+spigot

+spigots

+spikier

+spiky

+spillover

+spillover's

+spillovers

+spilt

+spineless

+spinelessly

+spinelessness

+spinier

+spininess

+spinnability

+spinnaker

+spinster

+spiny

+spirituality

+spitfire

+spittle

+splashier

+splashiness

+splashy

+splat

+splattered

+splay

+splayed

+splenetic

+splint

+splinted

+splintery

+splinting

+splints

+splotch

+splotched

+splotches

+splotchy

+splurge

+splurges

+splurging

+splutter

+splutterer

+spoilables

+spoilage

+spokespersons

+spongier

+sponginess

+spongy

+spontaneity

+spoof

+spoonerism

+spoonful

+spoonfuls

+sporadic

+sporadically

+sporadicly

+sportier

+sportiest

+sportiness

+sportsmanship

+sportsmen

+sportswear

+sportswriter

+sporty

+spottier

+spottiness

+spotty

+spousal

+sprain

+sprained

+sprains

+springboard

+sprocket

+sprocketed

+sprocketing

+sprockets

+sprue

+spud

+spume

+spuming

+spumoni

+spunk

+spurge

+spurred

+spurring

+sputnik

+sputniks

+spyglass

+sqrt

+squalid

+squalidly

+squalidness

+squalor

+squamous

+squamously

+squander

+squandered

+squanderer

+squandering

+squanders

+squashier

+squashiness

+squashy

+squatted

+squatter

+squatters

+squatting

+squaw

+squeaky

+squeamish

+squeamishly

+squeamishness

+squeegee

+squeegeed

+squeegees

+squelch

+squelched

+squelcher

+squelches

+squelching

+squirehood

+squirmy

+squirt

+squirted

+squirter

+squirting

+squirts

+squish

+squished

+squishes

+squishier

+squishiest

+squishiness

+squishing

+squishy

+st

+stableman

+stablemen

+staccato

+staccatos

+stackable

+stadium

+stadium's

+stadiums

+stagier

+staginess

+stagnate

+stagnated

+stagnates

+stagnating

+stagnation

+stagy

+stairwell

+stairwells

+stalactite

+stalactite's

+stalactites

+stalag

+stalemate

+stallion

+staminate

+stanchion

+stanchioned

+stanchioning

+stanchions

+standoff

+stank

+stannic

+stannous

+staphylococcus

+starchier

+starchiness

+starchy

+stardom

+stargaze

+stargazer

+stargazes

+stargazing

+starling

+starlings

+starship

+stash

+stashed

+stashes

+stashing

+stasis

+statehood

+stateless

+statelessness

+stateroom

+statesmanlike

+statesmanship

+statesmen

+statewide

+stationarity

+stationeries

+stationery

+stationmaster

+statuary

+statuette

+steamier

+steamily

+steaminess

+steamy

+steelier

+steelies

+steeliness

+steelmaker

+steely

+steeplebush

+steeves

+stein

+steiner

+steiners

+stenography

+stenotype

+stepbrother

+stepchild

+stepchildren

+stepdaughter

+stepfather

+stepladders

+steppe

+steppes

+stepsister

+stepson

+stereography

+stereophonic

+stereoscopy

+stereotypic

+sterility

+sternal

+sternum

+steroid

+steroids

+stethoscope

+stevedore

+stevedores

+stewardess

+stewardesses

+stewardship

+stickle

+stickleback

+stickled

+stickler

+stickling

+stickpin

+stigmata

+stiletto

+stillbirth

+stillbirths

+stillborn

+stilt

+stilted

+stiltedly

+stiltedness

+stilts

+stimulatory

+stingier

+stinginess

+stingy

+stinkpot

+stinky

+stochasticity

+stockbroker

+stockier

+stockiness

+stockpile

+stockpiler

+stockpiling

+stockroom

+stocky

+stodgier

+stodginess

+stodgy

+stoic

+stoichiometric

+stoichiometry

+stoicism

+stoics

+stoke

+stoked

+stoker

+stokes

+stoking

+stolid

+stolidly

+stomachs

+stomp

+stomped

+stomping

+stomps

+stonecutter

+stonecutters

+stonemason

+stonemasons

+stonewall

+stoneware

+stonewort

+stonily

+stooge

+stooges

+stooging

+stopover

+stopovers

+stopwatch

+stopwatches

+storekeep

+storekeeper

+storekeepers

+storeroom

+stormbound

+storyboard

+storyboards

+storyteller

+storytellers

+stowage

+stowages

+straddle

+straddled

+straddler

+straddlers

+straddles

+straddling

+strafe

+strafer

+strafes

+strafing

+straightaway

+strangulate

+strangulated

+strapped

+strapping

+strata

+strategically

+strategist

+strategists

+stratigraphic

+stratigraphy

+stratosphere

+stratospheric

+strawflower

+strawflowers

+streptococcus

+streptomycin

+stressful

+stressfully

+stretchable

+striate

+striated

+striates

+striating

+striation

+stricture

+strictures

+stridency

+strident

+stridently

+strikebreak

+strikebreaker

+strikebreakers

+strikebreaking

+striptease

+stripteaser

+striven

+strongroom

+strongrooms

+strontium

+strop

+strophe

+strophes

+stropped

+stropping

+strops

+structuralist

+structuralists

+strum

+strumming

+strychnine

+stubby

+stucco

+studded

+stultification

+stultify

+stultifying

+stumpage

+stumpy

+stunk

+stunned

+sturgeon

+stutter

+stuttered

+stutterer

+stuttering

+stutters

+styli

+stylist

+stylites

+stylus

+styluses

+stymie

+stymied

+stymies

+styrene

+styrenes

+suable

+suave

+suavely

+suaveness

+suavity

+subaltern

+subareas

+subassembly

+subbing

+subcaste

+subchain

+subclassifications

+subcommand

+subcommands

+subconcept

+subconstituent

+subcontinent

+subcontract

+subcontracting

+subdirectories

+subdirectory

+subdistrict

+subindex

+subjectivist

+subjectivists

+subjugate

+subjugated

+subjugates

+subjugating

+subjugation

+sublease

+sublimate

+sublimated

+sublimates

+sublimating

+subliminal

+subliminally

+subliterary

+sublunary

+submachine

+submersible

+submissive

+submissively

+submissiveness

+submittal

+subnational

+subnet

+subnets

+subnormal

+subnormally

+suboptimal

+subordinator

+subpage

+subparagraph

+subpart

+subparts

+subpoena

+subpoenaed

+subpoenas

+subpopulation

+subpopulations

+subquestion

+subquestion's

+subquestions

+subregion

+subregional

+subregionally

+subregions

+subrogation

+subsample

+subsamples

+subsentence

+subservience

+subservient

+subserviently

+subsistent

+subsocietal

+subsoil

+subsoiler

+subspecies

+substitutionary

+substratum

+subsurface

+subtable

+subtables

+subtended

+subtends

+subterfuge

+subterfuges

+subtest

+subtotals

+subtype

+subtypes

+suburbanite

+suburbanites

+suburbia

+subversive

+subversively

+subversiveness

+subversives

+successorship

+succubus

+suffragette

+suffragettes

+suffuse

+suffused

+suffuses

+suffusing

+suffusion

+suffusive

+suggestibility

+sulfaquinoxaline

+sulfate

+sulfated

+sulfating

+sulfide

+sulfite

+sulfonamide

+sulfonamides

+sulfur

+sulfured

+sulfuric

+sulfuring

+sulfurous

+sulfurously

+sulfurousness

+sulkily

+sullied

+sullies

+sully

+sullying

+sultana

+sumac

+summarily

+summertime

+summitry

+sunbaked

+sunbonnet

+sunburnt

+sunder

+sundered

+sundering

+sunders

+sundial

+sundials

+sunfish

+sunflower

+sunlit

+sunshade

+sunshades

+sunshiny

+sunspot

+suntan

+suntanned

+supercilious

+superciliously

+superciliousness

+superconcept

+supercritical

+superficiality

+superhighways

+superlunary

+supermachine

+supernatant

+supernatural

+supernaturalism

+supernaturally

+supernaturalness

+supernormal

+supernormally

+supernova

+supernova's

+supernovas

+superposable

+superposition

+superpositions

+superpredicate

+supersensitive

+supersensitiveness

+supersonic

+supersonics

+superstructural

+superstructure

+superstructures

+supervene

+supervened

+supine

+supinely

+supineness

+supping

+supplementation

+supplicate

+supplicating

+supposable

+suppressible

+suppressor

+suppressors

+supra

+supranational

+supranationalism

+suprasegmental

+supremacist

+surcease

+surceased

+surceasing

+surcharge

+surcharged

+surcharges

+surcharging

+surfactant

+surfactants

+surfeit

+surfeited

+surfeiter

+surfeits

+surreal

+surrealism

+surrealist

+surrealists

+surreptitious

+surreptitiously

+surreptitiousness

+surrey

+surreys

+surtax

+surveillance

+surveillances

+surveillant

+survivability

+survivalist

+survivalists

+survivorship

+susceptibility

+sushi

+suspensor

+sustainable

+sustainment

+sustenance

+svelte

+sveltely

+svelteness

+swab

+swabbed

+swabbies

+swabbing

+swabby

+swabs

+swaddle

+swaddled

+swaddling

+swag

+swaging

+swami

+swampland

+swampland's

+swamplands

+swank

+swanker

+swankier

+swankiness

+swanky

+swanlike

+swappable

+swart

+swartness

+swash

+swasher

+swastika

+swat

+swatch

+swatches

+swath

+swath's

+swathe

+swathed

+swather

+swathes

+swathing

+swathings

+swats

+swatter

+swatting

+sweatband

+sweatier

+sweatiness

+sweatshirt

+sweatshops

+sweaty

+sweepstake

+sweepstakes

+sweetish

+sweetishly

+sweltering

+swelteringly

+swig

+swigging

+swindle

+swindled

+swindler

+swindles

+swindling

+swingable

+swingier

+swingy

+swinish

+swinishly

+swinishness

+swirlier

+swirly

+swishier

+swishy

+swiss

+switchblade

+switchgear

+switchman

+switchmen

+switchmen's

+swivel

+swivels

+swizzle

+swizzled

+swizzler

+swizzling

+swordfish

+swordplay

+swordplayer

+swordtail

+sycophant

+sycophantic

+sycophantically

+sycophantly

+sycophants

+syllabic

+syllabicity

+syllabification

+syllabify

+syllogistic

+sylvan

+symbiont

+symbolical

+symbolists

+sympathetically

+symphonic

+symposia

+symptomatology

+synagogue

+synagogues

+synaptic

+synchronism

+synchrotron

+syncopate

+syncopated

+syncopation

+syncopative

+syndic

+syndics

+synergy

+synod

+synods

+synonymy

+synoptic

+syphilitic

+syrupy

+sys

+systemic

+tabbies

+tabbing

+tabby

+tableland

+tabletop

+tabletop's

+tabletops

+tabloids

+tabula

+tackiness

+taco

+tacos

+tactful

+tactfully

+tactfulness

+tactic

+tactical

+tactically

+tactlessness

+tactual

+tactually

+tadpoles

+taffeta

+taffies

+taffy

+tailback

+tailgate

+tailgated

+tailgater

+tailgating

+takeoff

+takeoffs

+takeover

+takeovers

+talismanic

+talky

+tallied

+tallies

+tally

+tallyho

+tallying

+talon

+taloned

+talons

+tamable

+tamale

+tamarack

+tamarind

+tambourine

+tamp

+tamping

+tampon

+tangency

+tangerine

+tango

+tangos

+tankard

+tanned

+tannery

+tannin

+tanning

+tantalum

+tao

+taoism

+taoist

+taoists

+taos

+tapeworm

+tapir

+tapirs

+tappet

+tappets

+tarantula

+tarantulas

+tardily

+tarnish

+tarnished

+tarnishes

+tarnishing

+tarp

+tarpapered

+tarpaulin

+tarpaulins

+tarpon

+tarpons

+tarred

+tarring

+tartar

+taskmaster

+tastier

+tastiness

+tasty

+tater

+tattier

+tatting

+tattle

+tattled

+tattler

+tattles

+tattletale

+tattling

+tatty

+tawdrier

+tawdriness

+tawdry

+taxably

+taxiway

+taxiway's

+taxiways

+taxpaying

+teacart

+teacup

+teahouse

+teahouses

+teakettle

+teakwood

+teal

+teals

+teammate

+teammates

+teamster

+teamsters

+teamwork

+teapot

+teapots

+teardrop

+teardrops

+teasel

+teat

+teated

+teats

+tech

+teched

+technetium

+tectonic

+tectonics

+tee

+teeing

+teensier

+teensy

+tees

+teetering

+tektite

+tektites

+telecommunicate

+telegraphy

+telekinesis

+telemeter

+telemeter's

+telemeters

+telemetric

+telemetry

+telepathic

+telepathically

+telepathy

+telephotography

+teleprinter

+teleprocessing

+teleprompter

+telescopic

+telltale

+telltale's

+telltales

+tellurium

+telnet

+telnets

+telomeric

+temerity

+temp

+tempo

+tempos

+temptress

+tenable

+tenableness

+tenacity

+tenancies

+tenancy

+tenderfoot

+tenderloin

+tendon

+tendons

+tenebrous

+tenet

+tenets

+tenfold

+tenon

+tensile

+tensional

+tensionless

+tensorial

+tenspot

+tenths

+tenuous

+tenuously

+tenuousness

+tepees

+tepid

+tepidly

+tepidness

+teratogenic

+teratologies

+teratology

+terbium

+tercel

+terminable

+terminableness

+termini

+terminological

+terminologically

+termite

+termites

+tern

+terpsichorean

+terramycin

+terrapin

+terrapins

+terries

+terry

+terse

+tersely

+terseness

+terser

+tersest

+tertian

+tessellate

+tessellated

+tessellates

+tessellation

+testamentary

+testate

+testator

+testator's

+testators

+testes

+testicular

+testier

+testily

+testimonial

+testimonials

+testiness

+testy

+tetanus

+tether

+tethered

+tethering

+tethers

+tetrachloride

+tetracycline

+tetrafluoride

+tetragonal

+tetragonally

+tetrahalides

+tetrahedra

+tetrahedral

+tetrahedrally

+tetrahedron

+tetrameron

+tetrasodium

+tetravalent

+textural

+texturally

+th

+thallium

+thallophyte

+that'd

+that'll

+theatric

+theatrics

+theism

+theistic

+theocracy

+theoretician

+there'd

+there'll

+therefor

+therefrom

+theretofore

+thereunder

+thermal

+thermally

+thermals

+thermionic

+thermionics

+thermistor

+thermistors

+thermo

+thermocouple

+thermocouples

+thermodynamically

+thermoelastic

+thermoelectric

+thermoformed

+thermoforming

+thermogravimetric

+thermometric

+thermometry

+thermonuclear

+thermopile

+thermoplastic

+thermopower

+thermos

+thermosetting

+thermostable

+thermostatic

+thermostatics

+thesaurus

+thespian

+thespians

+theta

+thetas

+thiamin

+thickish

+thine

+thinned

+thinning

+thinnish

+thiocyanate

+thiouracil

+this'll

+thistledown

+thither

+thoriate

+thoriated

+thorium

+thoroughbred

+thoroughgoing

+thou

+thous

+thousandths

+thrall

+threadbare

+threadbareness

+threefold

+threesome

+thresh

+threshed

+thresher

+threshing

+throatier

+throatiness

+throaty

+throes

+thrombi

+thromboses

+thrombosis

+thrombus

+throwback

+thrum

+thrumming

+thudding

+thuggee

+thulium

+thumbnail

+thumbtack

+thumbtack's

+thumbtacked

+thumbtacking

+thumbtacks

+thunderclap

+thunderclaps

+thunderous

+thunderously

+thunk

+thwack

+thy

+thyratron

+thyroglobulin

+thyroid

+thyroidal

+thyroids

+thyronine

+thyrotoxic

+thyrotrophic

+thyrotrophin

+thyrotropic

+thyrotropin

+thyroxine

+tibia

+tic

+tidbit

+tidbits

+tideland

+tidelands

+tidewater

+tidily

+tiff

+tiffany

+tigress

+tillage

+tilth

+timberland

+timberlands

+timbre

+timepiece

+timeworn

+timothy

+tincture

+tinctured

+tincturing

+tinder

+tine

+tines

+tinfoil

+tinner

+tinplate

+tinsel

+tinselly

+tinsmith

+tinsmiths

+tintable

+tintype

+tinware

+tipoff

+tippier

+tipple

+tippled

+tippler

+tipples

+tippling

+tippy

+tipsier

+tipsiness

+tipsy

+tiptoeing

+tirade

+tirades

+titan

+titanate

+titanic

+titanium

+titans

+titian

+titillate

+titillating

+titillatingly

+titillation

+titillative

+titmouse

+titmouse's

+titrate

+titrated

+titrates

+titrating

+titration

+titular

+titularly

+toadied

+toadies

+toady

+toadying

+toadyism

+tobaggon

+tobaggon's

+tobaggons

+toccata

+today'll

+toddle

+toddled

+toddler

+toddlers

+toddles

+toddling

+toenail

+toenails

+toffee

+tofu

+tog

+togging

+togs

+toilsome

+toilsomely

+toilsomeness

+tokamak

+tollgate

+tollhouse

+toluene

+tomblike

+tombstone

+tombstones

+tome

+tomes

+tomfool

+tommy

+tonal

+tonalities

+tonally

+toneless

+tonelessly

+tonelessness

+tong

+tonger

+tonier

+tonk

+tonks

+tonsillitis

+tony

+toodle

+toolmake

+toolmaker

+toolmakers

+toolmaking

+toolsmith

+toot

+tooted

+tooter

+toothier

+toothily

+toothpaste

+toothy

+tooting

+tootle

+tootled

+tootler

+tootling

+toots

+tootsie

+tootsies

+tootsy

+topaz

+topcoat

+topcoats

+topgallant

+topnotch

+topnotcher

+topocentric

+topographic

+topographical

+topographically

+topographies

+topography

+topped

+toppers

+topping

+toppings

+topside

+topsides

+topsoil

+tori

+tories

+toroid

+toroidal

+toroidally

+toroids

+torpid

+torpidly

+torpor

+torrence

+torsion

+torsional

+torsionally

+torso

+torsos

+tort

+torten

+tortoiseshell

+tortuous

+tortuously

+tory

+tot

+totalistic

+totalitarian

+totalitarianism

+tote

+toted

+totem

+totemic

+toter

+totes

+toting

+tots

+totted

+touchdown

+touchdowns

+touchstone

+touchstones

+toughs

+tourism

+tousle

+tousled

+tousles

+tousling

+tout

+touted

+touter

+touting

+touts

+towboat

+towboats

+towhead

+towheaded

+townhouse

+townsman

+townsmen

+toxic

+traceback

+traceback's

+tracebacks

+tracepoint

+tracepoint's

+tracepoints

+traceried

+tracery

+trachea

+trackage

+trackless

+traction

+tradesmen

+traditionalism

+traditionalistic

+traditionalists

+tragedian

+tragedians

+tragicomic

+trailside

+traineeships

+trainman

+trainman's

+trainmen

+traipse

+traipsing

+traitorous

+traitorously

+tram

+trammel

+trammels

+tramway

+transalpine

+transaminase

+transatlantic

+transcendence

+transcendental

+transcendentalism

+transcendentalists

+transcendentally

+transconductance

+transcultural

+transducer

+transducers

+transduction

+transect

+transected

+transecting

+transects

+transept

+transepts

+transferee

+transferor

+transferors

+transfix

+transfixed

+transfixes

+transfixing

+transfusable

+transfuse

+transfused

+transfusing

+transfusion

+transfusions

+transgressor

+transgressors

+transliterate

+transliteration

+translucence

+translucency

+transmissible

+transmittable

+transmittance

+transmutation

+transmute

+transmuted

+transmutes

+transmuting

+transoceanic

+transom

+transoms

+transpacific

+transpiration

+transpirations

+transplantable

+transplantation

+transportable

+transposable

+transship

+transshipment

+transshipping

+transships

+transversal

+transversally

+transverse

+transversely

+transverses

+transvestite

+transvestitism

+trapdoor

+trapdoors

+trapezium

+trashier

+trashiness

+trashy

+trauma

+traumas

+traversable

+travertine

+trawl

+trawler

+treadle

+treadled

+treadling

+treadmill

+treasonable

+treasonous

+treelike

+trefoil

+trekked

+trekking

+trellis

+trellised

+trellises

+trembly

+tremulous

+tremulously

+tremulousness

+trenchant

+trenchantly

+trencherman

+trenchermen

+trendier

+trendiness

+trendy

+trepidation

+trestle

+trestles

+triable

+triableness

+triad

+triadic

+triamcinolone

+triangulate

+triangulated

+triangulately

+triangulation

+triatomic

+tribesman

+tribesmen

+tribulate

+tribulation

+tribulation's

+tribulations

+trichloroacetic

+trichloroethane

+trichromatic

+trickeries

+trickery

+trickster

+trident

+tridents

+tridiagonal

+triennial

+triennially

+trifluoride

+trig

+trigonal

+trigonally

+trigram

+trigrams

+trilobite

+trilogy

+trimester

+trinitarian

+trinitarians

+trinity

+trio

+triode

+triodes

+trios

+trioxide

+tripartite

+tripartition

+tripe

+triphenylarsine

+triphenylphosphine

+triphenylstibine

+triphosphopyridine

+triplex

+triplicate

+tripod

+tripods

+tripoli

+tripolyphosphate

+tripped

+tripping

+trippingly

+triptych

+trisodium

+tristate

+trisyllable

+trite

+tritely

+triteness

+triter

+tritest

+tritium

+tritium's

+triton

+triumphant

+triune

+trivalent

+trivium

+trodden

+troglodyte

+troika

+trollop

+trombone

+trombone's

+trombones

+trombonist

+troopship

+troopships

+trophic

+tropism

+tropisms

+tropocollagen

+tropospheric

+trotted

+trotter

+trotting

+troughs

+trounce

+trounced

+trounces

+trouncing

+troupe

+trouper

+troupes

+trouping

+troy

+truancy

+truculence

+truculent

+truculently

+trumpery

+trundle

+trundled

+trundler

+trundles

+trundling

+truss

+trusser

+trusses

+trussing

+trusteeship

+trypsin

+tsar

+tsarevich

+tsarina

+tsarism

+tsarist

+tsunami

+tuba

+tubular

+tubularly

+tubule

+tubules

+tugged

+tugging

+tularemia

+tulle

+tum

+tumbrels

+tumid

+tumidly

+tummies

+tummy

+tummy's

+tun

+tuna

+tunas

+tundra

+tuneful

+tunefully

+tunefulness

+tunelessly

+tung

+tungstate

+tungsten

+tupelo

+turbinate

+turbinated

+turbinates

+turbine

+turbines

+turbofan

+turbojet

+turgid

+turgidly

+turgidness

+turk

+turks

+turnabout

+turnaround

+turnarounds

+turnoff

+turnout

+turnouts

+turnpike

+turnpikes

+turnstone

+turntable

+turpitude

+turtleback

+turtlebacks

+turtleneck

+turvy

+tusk

+tusker

+tuskers

+tusks

+tussle

+tussled

+tussles

+tussling

+tut

+tutelage

+tutu

+tuxedo

+tuxedo's

+tuxedoed

+tuxedos

+twaddle

+twaddled

+twaddler

+twaddles

+twaddling

+tweedier

+tweediness

+tweedy

+tweeze

+tweezed

+tweezing

+twelfths

+twiddle

+twiddled

+twiddles

+twiddling

+twigged

+twigging

+twinge

+twinges

+twinging

+twinning

+twirly

+twisty

+twit

+twitchy

+twitting

+twosome

+tycoon

+typeahead

+typeface

+typescript

+typeset

+typesets

+typesetter

+typesetters

+typesetting

+typewrite

+typewriting

+typewritten

+typhoon

+typhus

+typicality

+typo

+typographer

+typological

+typologically

+typologies

+typology

+tyrannic

+tyrannical

+tyrannically

+tyrannicalness

+tyrannicide

+tyrosine

+ulcerate

+ulcerated

+ulcerates

+ulceration

+ulcerations

+ulcerative

+ulster

+ulterior

+ulteriorly

+ultimatum

+ultra

+ultracentrifugally

+ultracentrifugation

+ultracentrifuge

+ultraconservative

+ultrafast

+ultramarine

+ultramodern

+ultrashort

+ultrasonic

+ultrasonically

+ultrasonics

+ultrasound

+ultrastructure

+ultraviolet

+umber

+umbered

+umbering

+umbilical

+umbilici

+umbilicus

+umbilicuses

+umbra

+umbrage

+unaccountable

+unadventurous

+unaggressive

+unallocable

+unambiguity

+unamused

+unanimity

+unappeasable

+unappeasably

+unasterisked

+unbalance

+unbeknownst

+unbend

+unbending

+unbent

+unbind

+unblest

+unbutton

+unbuttoning

+uncap

+unceremonious

+unceremoniously

+unceremoniousness

+uncharacteristic

+uncharitably

+unchastity

+unchristian

+uncircumcised

+unclasping

+uncodable

+uncoiling

+uncombable

+uncomment

+uncommenting

+uncomments

+uncommunicable

+uncommunicative

+unconcern

+uncongeniality

+unconscionable

+unconscionableness

+unconventionality

+uncourageous

+uncousinly

+uncritical

+unction

+undedicated

+undeflected

+undeliverability

+undeliverable

+undependable

+underachievers

+underadjusting

+underarm

+underbedding

+underbelly

+underbracing

+underclassman

+underclassmen

+underclothes

+underclothing

+underconsumption

+undercooked

+undercount

+undercounts

+undercover

+undercurrent

+undercut

+underdeveloped

+underdevelopment

+underdog

+undereducated

+underemployed

+underemployment

+underenumerated

+underenumeration

+undergarments

+undergirding

+undergrowth

+underhanded

+underhandedly

+underhandedness

+underheat

+underlay

+underpaid

+underpins

+underpopulated

+underprivileged

+underrate

+underrated

+underregistration

+underreported

+underreporting

+underrepresentation

+underrepresented

+undersea

+underseas

+undersecretaries

+undersecretary

+undersecretary's

+undershirt

+undershirt's

+undershirts

+undershoot

+undershooting

+undershoots

+undershot

+underside

+underside's

+undersides

+undersize

+undersized

+undersizes

+undersizing

+understate

+understatement

+understatements

+understates

+understating

+understructure

+understructure's

+understructures

+understudies

+understudy

+understudy's

+undertow

+undertow's

+undertows

+undervalued

+underwater

+underwhelm

+underwhelmed

+underwhelming

+underwhelms

+underwood

+undeserved

+undogmatically

+undreamt

+undulate

+undulated

+undulates

+undulating

+undulation

+undulations

+unearth

+unearthed

+unearthing

+unease

+uneconomic

+uneducated

+unemployability

+unencroachable

+unenforceable

+unenforcible

+unenunciated

+unenviable

+unfaded

+unfailing

+unfailingly

+unfailingness

+unfathomable

+unfederated

+unfelt

+unfertile

+unfindable

+unfitting

+unfoldment

+unfrocking

+unfrozen

+unfurl

+unfurled

+ungallant

+unglamorous

+ungodliness

+ungodly

+ungracious

+ungrammaticality

+unhand

+unharmonious

+unheated

+unhelpful

+unhesitant

+unhinge

+unholiness

+unholy

+unhook

+unhooked

+unhooking

+unhurried

+unhurt

+unideal

+unidimensional

+unifilar

+unilateral

+unilaterally

+unimaginative

+unimodal

+unimpeachable

+unimpeachably

+unimposing

+unimpressive

+uninitiate

+uninjectable

+uninominal

+uninterested

+uninvolved

+unipolar

+uniprocessor

+uniprocessor's

+uniprocessors

+unitarian

+unitarianism

+unitarians

+unitary

+univalent

+univariate

+universalism

+universalistic

+unkempt

+unkink

+unlacing

+unlearn

+unlearned

+unliterary

+unloveliness

+unlovely

+unmake

+unmalicious

+unmanliness

+unmanly

+unmarred

+unmask

+unmeasured

+unmeritorious

+unmet

+unmethodical

+unmindful

+unmoving

+unobtrusive

+unobtrusively

+unobtrusiveness

+unorthodox

+unorthodoxy

+unpaintable

+unpalatability

+unpartisan

+unperforated

+unphysical

+unpicturesque

+unpreemphasized

+unpremeditated

+unprepared

+unprocurable

+unproductive

+unprofessional

+unprovocative

+unquestionable

+unquestioning

+unquiet

+unquietly

+unquietness

+unreadiness

+unready

+unreality

+unreason

+unreasoning

+unreasoningly

+unreceptive

+unredeemable

+unreeling

+unreflective

+unrelieved

+unremarkable

+unremitting

+unremittingly

+unremunerated

+unrepentant

+unrepresentative

+unrewarding

+unripe

+unripeness

+unromantic

+unscathed

+unscrew

+unscrewed

+unscrewing

+unseat

+unsee

+unselfconscious

+unselfconsciousness

+unservile

+unshakeable

+unsheathe

+unshed

+unsightly

+unsinkable

+unslaked

+unsold

+unsolder

+unspeaking

+unspecific

+unspectacular

+unsprocketed

+unstilted

+unstriated

+unstuffy

+unsubtle

+unsurmountable

+unsystematic

+unteach

+untellable

+untenable

+untenanted

+unthinking

+untidily

+untraditional

+untrodden

+unutterably

+unvacuolated

+unwaivering

+unwariness

+unwarrantable

+unwary

+unwed

+unweighted

+unwire

+unwomanly

+unworkable

+uparrow

+upbeat

+upbring

+upcome

+upcoming

+upend

+upheaval

+upheavals

+upholstery

+upped

+uppercase

+uppercased

+uppercases

+uppercasing

+upperclassman

+upperclassmen

+uppercut

+upraise

+upraised

+uprise

+upriser

+upriver

+uproarious

+uproariously

+uproariousness

+upsilon

+upslope

+upstanding

+upstandingness

+upstate

+upstater

+upsurge

+upswing

+upswings

+uptake

+uptime

+uptown

+uptrend

+upwind

+uranium

+uranyl

+urbane

+urbanely

+urbanism

+urbanite

+urbanites

+urea

+uremia

+urethane

+urethanes

+urethra

+urgencies

+urgency

+urinal

+urinals

+urinary

+usurer

+usurious

+usuriously

+usuriousness

+usurpation

+usury

+uterine

+utile

+utilitarian

+utopia

+utopianism

+utopias

+vacationland

+vaccinating

+vaccination

+vaccinations

+vaccine

+vaccines

+vaccinia

+vaccinial

+vacuity

+vacuolate

+vacuolated

+vacuolates

+vacuolating

+vacuolation

+vacuole

+vacuoles

+vaginal

+vaginally

+vain

+vainglorious

+vaingloriously

+vaingloriousness

+vainness

+valance

+valanced

+valances

+valedictory

+valuate

+valuated

+valuates

+valuating

+valueless

+valuelessness

+vamp

+vamper

+vampire

+vampires

+vanadium

+vandal

+vandalism

+vandals

+vanguard

+variate

+variated

+variates

+variating

+variegate

+variegated

+variegation

+varistor

+varmint

+vascular

+vasectomies

+vasectomy

+vectorial

+velar

+veldt

+veldt's

+veldts

+vellum

+velour

+velours

+velum

+velvety

+venal

+venally

+vendetta

+vendible

+veneer

+veneerer

+veneering

+venerate

+venerated

+venerates

+venerating

+veneration

+venerations

+venereal

+vengeful

+vengefully

+vengefulness

+venial

+venially

+venialness

+venous

+venously

+ventilator

+venturesome

+venturesomely

+venturesomeness

+venturi

+venturis

+venue

+venue's

+venues

+veracious

+veraciously

+veraciousness

+verandah

+verandahed

+verbatim

+verbiage

+verbosity

+verdant

+verdantly

+veridical

+veridically

+verisimilitude

+verity

+vermiculite

+vermilion

+vermouth

+vernacular

+vernacularly

+vernal

+vernally

+vernier

+vertebra

+vertebrae

+vertebral

+vertebrally

+vertigo

+verve

+vesicle

+vesicles

+vesicular

+vesicularly

+vesper

+vespers

+vestal

+vestally

+vestibule

+vestibuled

+vestments

+vestries

+vestry

+vesture

+vestured

+vestures

+vesturing

+vet

+vetch

+vexatious

+vexatiously

+vexatiousness

+viaduct

+viaducts

+vibes

+vibrancy

+vibrant

+vibrantly

+vibrato

+vibrio

+vibrionic

+vicar

+vicarious

+vicariously

+vicariousness

+viewgraph

+viewgraph's

+viewgraphes

+viewless

+viewlessly

+vigil

+vigilantism

+vindicate

+vindicated

+vindicates

+vindicating

+vindication

+vindicative

+vintner

+vinyl

+viola

+virginal

+virginally

+virgule

+virile

+virility

+virtuosi

+virtuosity

+virulence

+virulent

+virulently

+viscera

+visceral

+viscerally

+viscid

+viscidly

+viscoelastic

+viscoelasticity

+viscometer

+viscometer's

+viscometers

+vise

+vised

+viselike

+vising

+visive

+vitiate

+vitiated

+vitiates

+vitiating

+vitiation

+vitreous

+vitreously

+vitreousness

+vitrification

+vitrify

+vitriol

+vitriolic

+vitro

+vituperative

+vituperatively

+viva

+vivace

+vivacious

+vivaciously

+vivaciousness

+vivacity

+vive

+vivers

+vivification

+vivified

+vivifier

+vivify

+vivo

+vixen

+viz

+vocable

+vocabularian

+vocabularianism

+vocalic

+vocalism

+vocalist

+vocalists

+vocative

+vocatively

+vociferous

+vociferously

+vociferousness

+vocoded

+vocoder

+vodka

+vodka's

+voiceband

+voiceless

+voicelessly

+voicelessness

+voila

+volar

+volcanism

+volition

+volitional

+volitionality

+volitionally

+voltaic

+voltmeter

+voltmeter's

+voltmeters

+voluble

+volubleness

+volumetric

+volumetrically

+voluminous

+voluminously

+voluminousness

+voluptuous

+voluptuously

+voodoo

+voodoos

+voracious

+voraciously

+voraciousness

+voracity

+vortices

+vorticity

+votary

+vouchsafe

+vouchsafed

+vouchsafes

+vouchsafing

+vulpine

+vulturelike

+vying

+wackier

+wackiness

+wacko

+wacko's

+wackos

+wacky

+wad

+wadded

+waddle

+waddled

+waddler

+waddles

+waddling

+wads

+wagged

+wagging

+waggish

+waggishly

+waggishness

+waggle

+waggled

+waggles

+waggling

+wainscot

+wainscoted

+wainscoting

+wainscots

+waistline

+wakeful

+wakefully

+wakefulness

+wakeup

+wale

+waler

+wales

+waling

+walkie

+walkover

+wallaby

+wallboard

+wallies

+wallop

+walloped

+walloper

+walloping

+wallops

+wallpaper

+wallpapers

+wally

+wangle

+wangled

+wangler

+wangles

+wangling

+wapiti

+wapitis

+wardroom

+wardrooms

+warehouseman

+warhead

+warheads

+warless

+warmhearted

+warmheartedly

+warmheartedness

+warmish

+warmonger

+warmongering

+warmongers

+warmup

+warren

+warrener

+warreners

+warrens

+wartime

+wartimes

+warty

+washbasin

+washboard

+washbowl

+washcloths

+washier

+washout

+washy

+waspish

+waspishly

+waspishness

+wastebasket

+wastebaskets

+wasteland

+wastelands

+wastewater

+wastrel

+wastrels

+watchband

+watchdog

+watchmake

+watchmaker

+watchmakers

+watchmaking

+watchmen

+watchpoints

+watercourse

+waterfront

+waterline

+waterlines

+waterloo

+waterman

+watermelon

+watershed

+watersheds

+waterside

+watersider

+watertight

+watertightness

+watt

+wattage

+wattages

+wattle

+wattled

+wattles

+wattling

+watts

+waveguide

+waveguides

+wavenumber

+wavier

+waviness

+wavy

+waxwork

+waxworks

+waylaid

+weaponless

+weaponry

+weatherbeaten

+weatherproof

+weatherproofness

+weatherstrip

+webbing

+wedlock

+weediness

+weedy

+weightier

+weightiness

+weightlessness

+weighty

+weirdo

+weirdos

+weirs

+wellbeing

+welsh

+welsher

+welt

+welter

+weltered

+weltering

+welts

+werewolf

+werewolf's

+werewolves

+westbound

+wetland

+wetlands

+wham

+whamming

+what'd

+what're

+whatnot

+whee

+wheedle

+wheedled

+wheedles

+wheedling

+wheelbarrows

+wheelbase

+wheelchair

+wheelchair's

+wheelhouse

+wheelie

+wheeze

+wheezed

+wheezes

+wheezier

+wheeziness

+wheezing

+wheezy

+whelk

+where'd

+where're

+whereabout

+wherefore

+wherefores

+whereof

+whereon

+wheresoever

+wherewith

+whet

+whets

+whetted

+whetting

+whiff

+whiffle

+whiffled

+whiffler

+whiffles

+whiffling

+whig

+whigs

+whimsey

+whimseys

+whinnied

+whinnies

+whinny

+whinnying

+whiplash

+whiplashes

+whippet

+whipsaw

+whipsawed

+whir

+whirlies

+whirligig

+whirly

+whiskies

+whistleable

+whiteface

+whitehead

+whitetail

+whitey

+whither

+who'd

+who'll

+whoa

+whodunit

+whodunit's

+whodunits

+whomsoever

+whoosh

+whop

+whoppers

+whopping

+whosoever

+wicket

+wickets

+widowhood

+widthwise

+wiener

+wieners

+wigging

+wiggle

+wiggled

+wiggler

+wiggles

+wiggling

+wiggly

+wigmaker

+wildcatter

+wildfire

+wildlife

+wilful

+wilfully

+wilily

+willowy

+wimp

+wimp's

+wimpier

+wimpiest

+wimps

+wimpy

+winch

+winched

+wincher

+winches

+winchester

+winching

+windbag

+windbags

+windbreak

+windbreaks

+windfall

+windless

+windlessly

+windlessness

+windowless

+windowpane

+windowpanes

+windowsill

+windshield

+windstorm

+windup

+windward

+windwardly

+winemake

+winemaster

+winery

+wineskin

+wingback

+wingman

+wingmen

+wingspan

+wingtip

+winkle

+winkled

+winkles

+winkling

+winless

+winnow

+winnower

+wino

+winos

+winsome

+winsomely

+winsomeness

+wintertime

+winy

+wireman

+wiremen

+wiseacre

+wisecrack

+wisecracked

+wisecracker

+wisenheimer

+wishbone

+wishy

+wispy

+witter

+witting

+wittingly

+wive

+wiving

+wizen

+wizened

+wobble

+wobbled

+wobbler

+wobbles

+wobbliness

+wobbling

+wobbly

+woebegone

+woebegoneness

+wok

+woken

+wold

+wolfish

+wolfishly

+wolfishness

+won

+woodcarver

+woodchopper

+woodchoppers

+woodcut

+woodcutters

+woodgrain

+woodgraining

+woodhen

+woodlot

+woodruff

+woodshed

+woodside

+woodwind

+woodyard

+woolgather

+woolgatherer

+woolgathering

+wop

+wops

+wordlessly

+workday

+workhouses

+workingmen

+workmanlike

+workout

+workouts

+workpiece

+workpieces

+workplace

+workplace's

+workplaces

+worksheet

+worksheets

+workspace

+workspaces

+worktable

+wormier

+wormy

+worsen

+worsened

+worsening

+worsens

+would've

+wow

+wracking

+wraith

+wraparound

+wrathful

+wrathfully

+wrathfulness

+wreathe

+wreaths

+wrier

+wriest

+wright

+wrinkly

+wristband

+wrongdoer

+wrongdoing

+wrongful

+wrongfully

+wrongfulness

+wry

+wryly

+xenon

+xenophobia

+xerography

+xterm

+xterm's

+xylem

+xylene

+xylophone

+xylophones

+yacht

+yachters

+yachting

+yachts

+yachtsman

+yachtsmen

+yaks

+yang

+yap

+yapping

+yardage

+yarmulke

+yarrow

+yaw

+yawed

+yawing

+yawl

+yaws

+yearbook

+yeastier

+yeastiness

+yeasty

+yen

+yeomanry

+yeshiva

+yesteryear

+yin

+yip

+yipping

+yodel

+yodels

+yoga

+yogi

+yogurt

+yogurt's

+yokel

+yokels

+yolk

+yolks

+yore

+youngish

+youths

+yow

+yowl

+yr

+ytterbium

+yttrium

+yucca

+yule

+yup

+zag

+zagging

+zags

+zealot

+zeitgeist

+zestful

+zestfully

+zestfulness

+zestier

+zesty

+zeta

+zetas

+zig

+zigged

+zigging

+zigzagged

+zigzagging

+zilch

+zing

+zinger

+zings

+zip

+zipped

+zipper

+zippered

+zippers

+zipping

+zips

+zircon

+zirconium

+zloty

+zlotys

+zodiacal

+zombie

+zombies

+zoologist

+zoologists

+zoology

+zounds

+zymurgy

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.2 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.2
new file mode 100644
index 0000000..d3ec471
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.2
@@ -0,0 +1,37616 @@
+AAA

+AAAS

+AC

+ACS

+AK

+AL

+AR

+ASTM

+AZ

+Aarhus

+Abbott

+Abbott's

+Abel

+Abelian

+Abelson

+Abelson's

+Aberdeen

+Aberdeen's

+Abernathy

+Abernathy's

+Abidjan

+Abos

+Abram

+Abram's

+Abyssinia

+Abyssinians

+Acadia

+Accra

+Achaean

+Ackley

+Actaeon

+Acton

+Acton's

+Adair

+Adair's

+Addis

+Adelaide

+Adelaide's

+Adele

+Adele's

+Adelia

+Adelia's

+Aden

+Aden's

+Adkins

+Adler

+Adler's

+Adlerian

+Adolph

+Adolph's

+Adolphus

+Adrian

+Adrian's

+Adrienne

+Adrienne's

+Aeneas

+Aeolus

+Aerobacter

+Aeschylus

+Aesop

+Afrikaner

+Agamemnon

+Agee

+Agee's

+Agnew

+Agnew's

+Agricola

+Agway

+Ahmedabad

+Aida

+Aida's

+Aiken

+Aiken's

+Ainu

+Aitken

+Aitken's

+Akers

+Aladdin

+Alastair

+Alberich

+Albrecht

+Albrecht's

+Albright

+Albright's

+Alcestis

+Alcmena

+Alcott

+Alcott's

+Aldebaran

+Aldrich

+Aldrich's

+Aleutian

+Alexei

+Alexei's

+Alexis

+Alfonso

+Alfonso's

+Alfred

+Alfred's

+Alfredo

+Alfredo's

+Algenib

+Alger

+Alger's

+Algonquian

+Algonquin

+Algonquin's

+Ali

+Alison

+Alison's

+Allegra

+Allis

+Allyn

+Allyn's

+Almaden

+Almaden's

+Alpert

+Alpert's

+Alpheratz

+Alphonse

+Alphonse's

+Alsop

+Alsop's

+Altair

+Altair's

+Alton

+Alton's

+Alva

+Alva's

+Amerada

+Amharic

+Amman

+Ammerman

+Ammerman's

+Amontillado

+Anabel

+Anabel's

+Anacreon

+Analects

+Anatole

+Anatole's

+Anatolian

+Andalusia

+Andrea

+Andrea's

+Andrei

+Andrei's

+Andromache

+Angelica

+Angelica's

+Anglophile

+Anglophiliac

+Anglophilic

+Anglophilism

+Anglophily

+Anglophobe

+Anglophobic

+Annale

+Annalen

+Annalist

+Annalistic

+Annette

+Anselm

+Anselm's

+Anselmo

+Anselmo's

+Antaeus

+Antilles

+Anton

+Anton's

+Antonio

+Antonio's

+Antwerp

+Apetalous

+Appleby

+Appleby's

+Apr

+Aquila

+Aquila's

+Arachne

+Arachne's

+Arapaho

+Arcadian

+Arden

+Arden's

+Arequipa

+Argentinian

+Argive

+Arlen

+Armata

+Armco

+Armenia

+Arragon

+Arrhenius

+Artemia

+Artie

+Artie's

+Arturo

+Arturo's

+Ashmolean

+Asilomar

+Asilomar's

+Assam

+Astarte

+Aston

+Aston's

+Asuncion

+Atchison

+Atchison's

+Athabascan

+Atlantica

+Atropos

+Attlee

+Atwater

+Atwater's

+Atwood

+Atwood's

+Auberge

+Auberge's

+Aubrey

+Aubrey's

+Audrey

+Audrey's

+Auerbach

+Auerbach's

+Aug

+Auriga

+Avernus

+Avery

+Avery's

+Avignon

+Aylesbury

+Azerbaijan

+Azerbaijan's

+Azores

+BEMA

+BIS

+BITNET

+BMW

+BP

+Baden

+Baden's

+Baffin

+Bahrein

+Bahrein's

+Baird

+Baird's

+Baja

+Bakhtiari

+Baku

+Balboa

+Balfour

+Baltimorean

+Bamako

+Banach

+Banbury

+Banbury's

+Bangui

+Barbour

+Barbour's

+Barhop

+Barlow

+Barlow's

+Barnes

+Barnet

+Barnett

+Barnett's

+Barnhard

+Barnhard's

+Barnum

+Barr

+Barr's

+Barrett

+Barrett's

+Barrington

+Barrington's

+Barton

+Barton's

+Basel

+Basque

+Basque's

+Batchelder

+Batchelder's

+Bateman

+Bateman's

+Bathurst

+Bathurst's

+Bator

+Battelle

+Battelle's

+Bausch

+Bayda

+Bayport

+Bayport's

+Bayreuth

+Beardsley

+Beardsley's

+Beckman

+Beckman's

+Beebe

+Beebe's

+Beecham

+Beecham's

+Beijing

+Bela

+Bela's

+Belize

+Bellamy

+Bellamy's

+Bellingham

+Bellingham's

+Bellini

+Bellini's

+Belshazzar

+Belshazzar's

+Benares

+Benelux

+Benelux's

+Benton

+Benton's

+Beograd

+Berea

+Berea's

+Berenices

+Beresford

+Beresford's

+Bergen

+Bergen's

+Bergland

+Bergland's

+Berglund

+Berglund's

+Bergman

+Bergman's

+Bergstrom

+Bergstrom's

+Berman

+Berman's

+Bernardino

+Bernardino's

+Bernardo

+Bernardo's

+Bernet

+Bernet's

+Bernhard

+Berniece

+Bernini

+Bertie

+Bertram

+Bertram's

+Berwick

+Berwick's

+Betsey

+Betsey's

+Bette

+Bette's

+Bhagavadgita

+Bialystok

+Biggs

+Bilbao

+Billiken

+Billikens

+Biltmore

+Biltmore's

+Bini

+Biochimica

+Biometrika

+Biophysica

+Birgit

+Birmingham

+Bismark

+Bismark's

+Bissau

+Bizet

+Bizet's

+Blackfoot

+Blackfoot's

+Blackfoots

+Blaine

+Blaine's

+Blanchard

+Blanchard's

+Bleeker

+Blenheim

+Blinn

+Blinn's

+Bloch

+Bloch's

+Blomberg

+Blomberg's

+Blomquist

+Blomquist's

+Blum

+Blumenthal

+Blumenthal's

+Blythe

+Blythe's

+Boarsh

+Boca

+Boca's

+Bodleian

+Boeotia

+Boeotian

+Bohemianism

+Bois

+Boonton

+Bootes

+Boris

+Bosch

+Bosporus

+Boucher

+Bourbaki

+Bowditch

+Bowditch's

+Bowdoin

+Bowen

+Bowen's

+Boxford

+Boyd

+Boyd's

+Boyle

+Boyle's

+Boylston

+Boylston's

+Bragg

+Brahmaputra

+Brahmsian

+Brandt

+Brandt's

+Brasstown

+Brazzaville

+Bremen

+Bremen's

+Brendan

+Brendan's

+Brennan

+Brennan's

+Brenner

+Brenner's

+Brent

+Brest

+Brest's

+Breton

+Brett

+Brett's

+Brewster

+Brewster's

+Brice

+Bridget

+Bridget's

+Brie

+Briggs

+Briggs's

+Brighton

+Brighton's

+Brillouin

+Brindisi

+Brisbane

+Brisbane's

+Broglie

+Broglie's

+Bromfield

+Bromfield's

+Bromley

+Bromley's

+Brookline

+Brookline's

+Bruckner

+Bruckner's

+Bruegel

+Bruegel's

+Brumidi

+Brumidi's

+Brunswick

+Brunswick's

+Buchenwald

+Buchenwald's

+Buckley

+Buckley's

+Bucknell

+Bucknell's

+Buena

+Buenos

+Bujumbura

+Burke

+Burkes

+Burlington

+Burlington's

+Burnham

+Burtt

+Burtt's

+Buttrick

+Buxtehude

+Buxtehude's

+Buxton

+Byrd

+CA

+CBS

+CDR

+CERN

+CSNET

+CT

+CUNY

+CURVET

+CZ

+Cabot

+Cabot's

+Cady

+Caesarian

+Caesarian's

+Cahill

+Cajun

+Cajun's

+Cajuns

+Calais

+Caldwell

+Caldwell's

+Caleb

+Caleb's

+Calhoun

+Calhoun's

+Calkins

+Callaghan

+Callaghan's

+Callahan

+Callahan's

+Callan

+Callan's

+Calvert

+Calvert's

+Calvin

+Calvin's

+Cambrian

+Camden

+Camden's

+Camembert

+Cameron

+Cameron's

+Cameroon

+Cameroun

+Cameroun's

+Camilla

+Campbell

+Canaan

+Canaan's

+Canfield

+Canfield's

+Canopus

+Cantabrigian

+Capitoline

+Caputo

+Carboloy

+Carbone

+Cardiff

+Cardiff's

+Carey

+Carey's

+Cargill

+Cargill's

+Carib

+Carlin

+Carlin's

+Carlisle

+Carlisle's

+Carlo

+Carlsbad's

+Carlsbads

+Carmela

+Carmen

+Carmen's

+Carolingian

+Carpathia

+Carpathians

+Carr

+Carr's

+Carrara

+Carroll

+Carroll's

+Carruthers

+Casanova

+Casanova's

+Castillo

+Castillo's

+Castroism

+Catalonia

+Catherwood

+Catherwood's

+Caviness

+Cayley

+Cayley's

+Cayuga

+Cayuga's

+Cecropia

+Cedric

+Celebes

+Celia

+Celia's

+Celt

+Centrex

+Cepheus

+Cesare

+Cesare's

+Chadwick

+Chadwick's

+Chandigarh

+Chao

+Chao's

+Charlemagne

+Charlemagne's

+Charlemagnes

+Charon

+Charon's

+Charta

+Chartres

+Chatham

+Chatham's

+Chatsworth

+Chatsworth's

+Chauncey

+Chauncey's

+Chelsea

+Chelsea's

+Cheney

+Cheney's

+Cheryl

+Chiang

+Chiang's

+Chimique

+Chinatown

+Chinatown's

+Chloe

+Chou

+Chou's

+Christensen

+Christensen's

+Christiana

+Christiana's

+Christianson

+Christianson's

+Christina

+Christina's

+Christmastime

+Christoffel

+Christoph

+Christoph's

+Chungking

+Cindy

+Cindy's

+Clapeyron

+Clarendon

+Clarendon's

+Clausius

+Clayton

+Clayton's

+Clifton

+Clifton's

+Clotho

+Co

+Cobb

+Cobb's

+Cochran

+Cochran's

+Cochrane

+Cochrane's

+Coddington

+Coddington's

+Cody

+Cody's

+Coffey

+Coffey's

+Cole

+Cole's

+Colette

+Colette's

+Collins

+Colombo

+Colombo's

+Cominform

+Compagnie

+Compton

+Compton's

+Conakry

+Conant

+Conant's

+Congolese

+Conklin

+Conklin's

+Conley

+Conley's

+Connally

+Connally's

+Connors

+Constantine

+Constantine's

+Convair

+Convair's

+Conway

+Conway's

+Cooke

+Cooke's

+Cooley

+Cooley's

+Copernican

+Corbett

+Corbett's

+Corcoran

+Corcoran's

+Corey

+Corey's

+Corinth

+Coriolanus

+Cornelia

+Cornelia's

+Cornelian

+Cornelius

+Coronado

+Corsica's

+Cortez

+Corvus

+Corydoras

+Cosgrove

+Cosgrove's

+Cottrell

+Cottrell's

+Coulter

+Coulter's

+Courtney

+Courtney's

+Cowan

+Cowan's

+Crispin

+Crispin's

+Croatia

+Croydon

+Croydon's

+Cruickshank

+Cruickshank's

+Cruz

+Culbertson

+Culbertson's

+Cummings

+Cummins

+Curran

+Curran's

+Curtis

+Cushing

+Cushing's

+Custer

+Custer's

+Cuvier

+Cuzco

+Cyclades

+Cyrillic

+Czerniak

+Czerniak's

+DA's

+DC

+DFL

+DMA

+DOD

+Dacca

+Dacca's

+Dada

+Dadaistic

+Dahl

+Dahl's

+Dahomey

+Dahomey's

+Dailey

+Dailey's

+Dairylea

+Daley

+Daley's

+Dalhousie

+Dalzell

+Dalzell's

+Damocles

+Damon

+Damon's

+Dana

+Dana's

+Danubian

+Darcy

+Darcy's

+Darius

+Darwinistic

+Daryl

+Daryl's

+Datamation

+Daugherty

+Daugherty's

+Davison

+Davison's

+Daytona

+Daytona's

+DeKastere

+Deane

+Deane's

+Deanna

+Deanna's

+Decatur

+Decatur's

+Dee

+Dee's

+Deimos

+Deirdre

+Deirdre's

+Deirdres

+Del

+Delaney

+Delaney's

+Delano

+Delano's

+Delia

+Delia's

+Della

+Della's

+Delmarva

+Delphically

+Delphinus

+Demeter

+Deneb

+Deneb's

+Denebola

+Denton

+Denton's

+Dependance

+Derek

+Derek's

+Detroit

+Dhabi

+Dickerson

+Dickerson's

+Dido

+Dido's

+Diebold

+Diebold's

+Dietz

+Diocletian

+Dirichlet

+Dixon

+Dixon's

+Dnieper

+Dnieper's

+Dobbs

+Dodd

+Dodd's

+Dodson

+Dodson's

+Doherty

+Doherty's

+Dolan

+Dolan's

+Domenico

+Domenico's

+Dominick

+Dominick's

+Dominique

+Dominique's

+Doneck

+Doneck's

+Dooley

+Dooley's

+Dorcas

+Doreen

+Doreen's

+Doria

+Doria's

+Doric

+Doric's

+Dorothea

+Dorothea's

+Dorset

+Dorset's

+Dortmund

+Dortmund's

+Dowling

+Dowling's

+Draco

+Draco's

+Draconian

+Dravidian

+Driscoll

+Driscoll's

+Drummond

+Drummond's

+Dubhe

+Dubhe's

+Dudley

+Dudley's

+Dugan

+Dugan's

+Duma

+Duma's

+Dunbar

+Dunbar's

+Dundee

+Dundee's

+Dunedin

+Dunedin's

+Dunlop

+Dunlop's

+Dunn

+Dunn's

+Duquesne

+Durango

+Durango's

+Durer

+Durkin

+Durkin's

+Durrell

+Durrell's

+Durward

+Durward's

+Dusenbury

+Dusenbury's

+Dutton

+Dutton's

+Dwyer

+Dwyer's

+ECG

+EDT

+EEOC

+ERDA

+ESC

+EST

+Eagan

+Eagan's

+Earthman

+Earthman's

+Earthmen

+Earthmen's

+Eaton

+Eaton's

+Eben

+Eben's

+Eccles

+Ecole

+Edmonds

+Edmondson

+Edmondson's

+Edmonton

+Edmonton's

+Eduardo

+Eduardo's

+Effie

+Effie's

+Egan

+Egan's

+Egyptology

+Ehrlich

+Ehrlich's

+Eire

+Eire's

+Eisner

+Eisner's

+Ekstrom

+Ekstrom's

+Eldon

+Eldon's

+Eleazar

+Eleazar's

+Elena

+Elena's

+Elgin

+Elgin's

+Elinor

+Elinor's

+Elisha

+Elisha's

+Ellwood

+Ellwood's

+Elsevier

+Elsevier's

+Elton

+Elton's

+Elwood

+Elwood's

+Ely

+Ely's

+Elysee

+Elysee's

+Emil

+Emil's

+Emile

+Emile's

+Emilio

+Emilio's

+Emmett

+Emmett's

+Engels

+Engle

+Engle's

+Enid

+Enid's

+Ephesus

+Erastus

+Erato

+Erato's

+Erika

+Erika's

+Erlenmeyer

+Erlenmeyer's

+Erskine

+Erskine's

+Esmark

+Esmark's

+Esposito

+Esposito's

+Essen

+Essen's

+Estella

+Estella's

+Estes

+Estonia

+Estonia's

+Etruria

+Eumenides

+Euridyce

+Euridyce's

+Euterpe

+Euterpe's

+Evensen

+Everglade

+Everhart

+Everhart's

+FAA

+FAQ

+FAQ'S

+FL

+FM

+FMC

+FPC

+FSF

+FSF'S

+FTC

+Faber

+Faber's

+Fabian

+Fabian's

+Fafnir

+Fafnir's

+Fahey

+Fahey's

+Falkland

+Falklands

+Fallopian

+Falmouth

+Falmouth's

+Farkas

+Farnsworth

+Farnsworth's

+Fayette

+Fayette's

+Feeney

+Feeney's

+Fenton

+Fenton's

+Ferber

+Ferber's

+Ferguson

+Ferguson's

+Fermat

+Fermat's

+Ferreira

+Ferrer

+Ferrer's

+Fiji

+Fiji's

+Fijian

+Fijian's

+Fijians

+Finley

+Finley's

+Fischbein

+Fischbein's

+Fiske

+Fiske's

+Fizeau

+Fizeau's

+Flagler

+Flagler's

+Flo

+Flo's

+Fogarty

+Foley

+Foley's

+Fomalhaut

+Fomalhaut's

+Fontaine

+Fontaine's

+Forsythe

+Forsythe's

+Fortescue

+Fortescue's

+Foss

+Francine

+Francine's

+Francoise

+Francoise's

+Frankel

+Frankel's

+Fraser

+Fraser's

+Fredericksburg

+Fredericksburg's

+Fredericton

+Fredericton's

+Fredholm

+Fredholm's

+Freemason

+Freetown

+Freetown's

+Freya

+Freya's

+Friedrich

+Friedrich's

+Friesland

+Friesland's

+Frisian

+Fruehauf

+Fruehauf's

+Frye

+Frye's

+Fujitsu

+Fujitsu's

+Fulbright's

+Fulbrights

+Fulton

+Fulton's

+Furman

+Furman's

+GA

+GAO

+GCD

+GE

+GMT

+GOP

+GPO

+GU

+Gaberones

+Gabon

+Gabon's

+Gaines

+Galatia

+Galatia's

+Galen

+Galen's

+Galilean

+Galileo

+Galileo's

+Gallagher

+Gallagher's

+Galt

+Galt's

+Galway

+Galway's

+Gambia

+Gambia's

+Gandhi

+Gandhi's

+Gandhian

+Gannett

+Gannett's

+Garrisonian

+Garth's

+Gaspee

+Gaspee's

+Gaulle

+Gaulle's

+Gautama

+Gegenschein

+Geigy

+Geigy's

+Geminid

+Gemma

+Genesco

+Genoa

+Genoa's

+Ghanian

+Gil

+Gil's

+Gilchrist

+Gilchrist's

+Gilead

+Gilead's

+Gilmore

+Gilmore's

+Gina

+Gina's

+Gino

+Gino's

+Ginsberg

+Ginsberg's

+Ginsburg

+Ginsburg's

+Giuliano

+Giuliano's

+Giuseppe

+Giuseppe's

+Glaswegian

+Glidden

+Glidden's

+Gloriana

+Gloriana's

+Gobi

+Gobi's

+Goddard

+Goddard's

+Godfrey

+Godfrey's

+Godwin

+Godwin's

+Goff

+Goff's

+Goldfield

+Goldstine

+Goldstine's

+Goleta

+Goleta's

+Gonzalez

+Goode

+Goode's

+Goren

+Goren's

+Gorton

+Gorton's

+Gothically

+Gottfried

+Gottfried's

+Gouda's

+Gould

+Gould's

+Graff

+Graff's

+Greene

+Greene's

+Greenpeace

+Greenpeace's

+Greer

+Greer's

+Gresham

+Gresham's

+Grimaldi

+Grimaldi's

+Grinch

+Grinch's

+Griswold

+Griswold's

+Gruyere

+Guardia

+Guelph

+Guenther

+Guenther's

+Guerin

+Guilford

+Guilford's

+Guinevere

+Guinevere's

+Gujarat

+Gujarati

+Gullah

+Gunther

+Gunther's

+Gurkha

+Gurkha's

+Gustafson

+Gustafson's

+Gustav

+Gustav's

+Gustave

+Gustave's

+Gustavus

+Gwyn

+Gwyn's

+HDL

+Haag

+Haag's

+Haas

+Haberman

+Haberman's

+Habib

+Habib's

+Hadamard

+Haddad

+Haddad's

+Hadley

+Hadley's

+Hadrian

+Hagen

+Hagen's

+Hager

+Hager's

+Hagstrom

+Hagstrom's

+Hahn

+Hahn's

+Haines

+Haley

+Haley's

+Halley

+Halley's

+Halsey

+Halsey's

+Halstead

+Halstead's

+Halverson

+Halverson's

+Hamal

+Hamal's

+Hamburg

+Hamlin

+Hamlin's

+Handel

+Handel's

+Haney

+Haney's

+Hanford

+Hanford's

+Hankel

+Hankel's

+Hanley

+Hanley's

+Hanlon

+Hanlon's

+Hanna

+Hanna's

+Hapsburg

+Hapsburg's

+Harbin

+Harbin's

+Harlan

+Harlan's

+Harley

+Harley's

+Harmon

+Harmon's

+Harmonist

+Harmonistic

+Harmonistically

+Harriman

+Harriman's

+Harrington

+Harrington's

+Hathaway

+Hathaway's

+Hatteras

+Hattiesburg

+Hattiesburg's

+Haugen

+Haugen's

+Hausa

+Hausa's

+Hausdorff

+Hausdorff's

+Havilland

+Havilland's

+Hayden

+Hayden's

+Healey

+Healey's

+Healy

+Healy's

+Hebe

+Hebrides

+Hebrides's

+Hecate

+Hecate's

+Heckman

+Heckman's

+Heidegger's

+Heine

+Heine's

+Heinrich

+Heinrich's

+Helga

+Helga's

+Hellespont

+Helvetica

+Hempstead

+Hempstead's

+Henley

+Henley's

+Hennessy

+Henri

+Henri's

+Hermann

+Hermann's

+Hernandez's

+Hertzog

+Hertzog's

+Hesse

+Hesse's

+Hester

+Hester's

+Hetman

+Hetman's

+Hettie

+Hettie's

+Hetty

+Hetty's

+Heusen

+Heusen's

+Heuser

+Heuser's

+Hewett

+Hewett's

+Hewitt

+Hewitt's

+Hiatt

+Hiatt's

+Hibbard

+Hibbard's

+Hickman

+Hickman's

+Higgins

+Hildebrand

+Hildebrand's

+Himalaya

+Himalaya's

+Hindustan

+Hindustan's

+Hines

+Hinman

+Hinman's

+Hippocrates

+Hippocratic

+Hiroshi

+Hiroshi's

+Hirsch

+Hitlerian

+Hitlerism

+Hitlerite

+Hitlerites

+Hoagland

+Hoagland's

+Hobart

+Hobart's

+Hodge

+Hodge's

+Hodgkin

+Hodgkin's

+Hoff

+Hoff's

+Hogan

+Hogan's

+Holcomb

+Holcomb's

+Hollingsworth

+Hollingsworth's

+Holloway

+Holloway's

+Holm

+Holm's

+Holman

+Holman's

+Holmdel

+Holmdel's

+Honshu

+Honshu's

+Hopi's

+Horus

+Hottentot

+Hottentot's

+Houdaille

+Houdaille's

+Houghton

+Houghton's

+Hoyt

+Hoyt's

+Hrothgar

+Hrothgar's

+Hubbard

+Hubbard's

+Hubbell

+Hubbell's

+Huber

+Huber's

+Huffman

+Huffman's

+Huggins

+Hummel

+Hummel's

+Hun

+Huntington

+Huntington's

+Huntley

+Huntley's

+Hurd

+Hurd's

+Hurdies

+Hurwitz

+Huston

+Huston's

+Huxtable

+Huxtable's

+Hyades

+Hyde

+Hyde's

+Hyman

+IA

+ICL

+IEE

+IGN

+IL

+INTERAMA

+IOT

+IQ

+IR

+IRAF

+IRS

+Ian

+Ian's

+Ibn

+Ida

+Ida's

+Ifni

+Igor's

+Ike

+Ike's

+Ilona

+Ilyushin

+Imagen

+Imagen's

+Indo

+Indochinese

+Indoeuropean

+Indus

+Informatica

+Inman

+Inman's

+Ira

+Iranian

+Iranian's

+Iranians

+Iraqi's

+Iraqis

+Irrawaddy

+Irvin

+Irvin's

+Irwin

+Isaacson

+Isaacson's

+Isabella

+Isabella's

+Isadore

+Isadore's

+Isaiah

+Isaiah's

+Isis

+Islamabad

+Islamabad's

+Isolde

+Isolde's

+Istvan

+Istvan's

+Ito

+Ito's

+Iverson

+Iverson's

+JACM

+Jablonsky

+Jablonsky's

+Jacobi

+Jacobi's

+Jacobson

+Jacobson's

+Jacobus

+Jaeger

+Jaeger's

+Jaime

+Jaime's

+Jamie

+Jamie's

+Janos

+Jansenist

+Jansenist's

+Jarvin

+Jarvin's

+Jed

+Jed's

+Jensen

+Jensen's

+Jeres

+Jesuitism

+Jewell

+Jewell's

+Jewett

+Jewett's

+Jimenez

+Jo

+Jo's

+Johanna

+Johanna's

+Johnston

+Johnston's

+Jolla

+Jolla's

+Judaica

+Judd

+Judd's

+Judder

+Juddered

+Juddering

+Judders

+Judson

+Judson's

+Jugoslavia

+Jul

+Jun

+Jung

+Jung's

+Jura

+Jura's

+Juras

+Jutland

+Jutland's

+KS

+KY

+Kahn

+Kahn's

+Kajar

+Kajar's

+Kalmuk

+Kalmuk's

+Kamchatka

+Kamikaze

+Kamikaze's

+Kampala

+Kampala's

+Kampuchea

+Kampuchea's

+Kane

+Kane's

+Kannada

+Kaplan

+Kaplan's

+Karachi

+Karachi's

+Karamazov

+Karamazov's

+Karp

+Karp's

+Kashmir

+Kaskaskia

+Katharine

+Katharine's

+Katowice

+Katowice's

+Katrina

+Katrina's

+Katz

+Kauffman

+Kauffman's

+Kaufman

+Kaufman's

+Keck

+Keck's

+Kelsey

+Kelsey's

+Kemp

+Ken

+Ken's

+Kendall

+Kendall's

+Kennan

+Kennan's

+Kenney

+Kenney's

+Kenton

+Kenton's

+Kenyon

+Kenyon's

+Kernighan

+Kernighan's

+Kerouac

+Kerouac's

+Kerr

+Kerr's

+Kessler

+Kessler's

+Keyes

+Khartoum

+Khartoum's

+Kidde

+Kidde's

+Kieffer

+Kieffer's

+Kiewit

+Kiewit's

+Kigali

+Kigali's

+Kikuyu

+Kikuyu's

+Kilgore

+Kilgore's

+Kilimanjaro

+Kilimanjaro's

+Kimball

+Kimball's

+Kimberly

+Kimberly's

+Kinney

+Kinney's

+Kinshasha

+Kinshasha's

+Kiowa

+Kirchner

+Kirchner's

+Kirov

+Kirov's

+Kitakyushu

+Kitakyushu's

+Klux

+Knapp

+Knapp's

+Knauer

+Knauer's

+Knightsbridge

+Knightsbridge's

+Knossos

+Knott

+Knott's

+Knowlton

+Knowlton's

+Kobayashi

+Kochab

+Kochab's

+Konrad's

+Koppers

+Koran

+Koran's

+Kovacs

+Kovic

+Kovic's

+Kowalewski

+Kowalewski's

+Kowalski

+Kowalski's

+Kowloon

+Krebs

+Krieger

+Krieger's

+Kristin

+Kristin's

+Kronecker

+Kronecker's

+Kruse

+Kruse's

+Kuhn

+Kuhn's

+Kumar

+L'vov

+LDL

+LSI

+LTV

+Laban

+Laban's

+Lacerta

+Lacerta's

+Lachesis

+Lagos

+Laguerre

+Lahore

+Lahore's

+Laidlaw

+Laidlaw's

+Lamar

+Lamar's

+Lamarck

+Lamborghini

+Lamborghini's

+Lamborghinis

+Lana

+Lana's

+Lancelot

+Lancelot's

+Lang

+Lang's

+Langmuir

+Langmuir's

+Lanka

+Lanka's

+Lao

+Larkin

+Larkin's

+Laszlo

+Laszlo's

+Lateran

+Lateran's

+Latinity

+Latrobe

+Latrobe's

+Latvia

+Latvia's

+Laue

+Laue's

+Laughlin

+Laughlin's

+Laurent

+Laurent's

+Lausanne

+Lausanne's

+Lavoisier

+Lavoisier's

+Layton

+Layton's

+Leander

+Leander's

+Lear

+Leeuwenhoek

+Leeuwenhoek's

+Legendre

+Legendre's

+Lehman

+Lehman's

+Leibniz

+Leipzig

+Leipzig's

+Leland

+Leland's

+Lemuel

+Len

+Len's

+Lena

+Lena's

+Lennon

+Lennon's

+Lennox

+Lennox's

+Lenore

+Lenore's

+Leonid

+Leonid's

+Lesotho

+Lesotho's

+Lethe

+Lethe's

+Letitia

+Letitia's

+Leviable

+Levin

+Levin's

+Levitt

+Levitt's

+Lew

+Lew's

+Libby

+Libby's

+Libreville

+Libreville's

+Lieberman's

+Ligget

+Ligget's

+Liggett

+Liggett's

+Lila

+Lila's

+Lilian

+Lilian's

+Lillian

+Lillian's

+Lilly

+Liman

+Lin

+Lin's

+Lind

+Lind's

+Lindbergh

+Lindbergh's

+Lindholm

+Lindholm's

+Lindquist

+Lindquist's

+Lindsay

+Lindsay's

+Lindsey

+Lindsey's

+Lindstrom

+Lindstrom's

+Linnaeus

+Linton

+Lippincott

+Lippincott's

+Lipschitz

+Lipscomb

+Lipscomb's

+Lise

+Lise's

+Lissajous

+Lithuania

+Liverpudlian

+Lodowick

+Lodowick's

+Loeb

+Loeb's

+Loire

+Loki

+Loki's

+Lomb

+Lomb's

+Lombardy

+Lombardy's

+Lome

+Loomis

+Loren

+Loren's

+Lori

+Lori's

+Lorinda

+Lorinda's

+Lotte

+Lotte's

+Lou

+Lou's

+Lounsbury

+Lounsbury's

+Lourdes

+Louvre

+Lowe

+Lowe's

+Lowry

+Lowry's

+Lubell

+Lubell's

+Ludlow

+Ludlow's

+Luis

+Lumpur

+Lund

+Lund's

+Lundberg

+Lundberg's

+Lundquist

+Lundquist's

+Lura

+Lusaka

+Lusaka's

+Lutz

+Luzon

+Luzon's

+Lykes

+Lyman

+Lyman's

+Lyra

+Lyra's

+Lysenko

+Lysenko's

+MDs

+MIPS

+MN

+MO

+MRI

+Mabel

+Mabel's

+MacDougall

+MacDougall's

+MacMahon

+MacMahon's

+Macadamia

+Macassar

+Macaulayan

+Macaulayism

+Macaulayisms

+Macdougall

+Macdougall's

+Machiavellian

+Mackey

+Mackey's

+Maddox

+Madeira

+Madhya

+Madsen

+Madsen's

+Mae

+Mae's

+Mafiosi

+Magellanic

+Magnuson

+Magnuson's

+Magog

+Magog's

+Maharashtra

+Mahayana

+Mahayanist

+Mahoney

+Mahoney's

+Majorca

+Majorca's

+Malabar

+Malabar's

+Malagasy

+Malagasy's

+Malawi

+Malawi's

+Malden

+Malden's

+Maldive

+Maldive's

+Maldives

+Mali

+Mali's

+Maloney

+Maloney's

+Malraux

+Malthus

+Malton

+Malton's

+Manchuria

+Manley

+Manley's

+Mann

+Mann's

+Manuel

+Manuel's

+Mar

+Marc

+Marc's

+Marceau

+Marceau's

+Marcel

+Marcello

+Marcello's

+Marcia

+Marcia's

+Marcie

+Marcie's

+Marco

+Marco's

+Margaret

+Margaret's

+Margery

+Margery's

+Margo

+Margo's

+Marissa

+Marissa's

+Marjory

+Marjory's

+Markham

+Markham's

+Markism

+Markism's

+Marxian

+Maserati

+Maserati's

+Maseratis

+Mateo

+Mateo's

+Matson

+Matson's

+Matsumoto

+Matsumoto's

+Mattson

+Mattson's

+Maurine

+Maurine's

+Mavis

+May

+Mayer

+Mayer's

+Mayo

+Mayo's

+McCallum

+McCallum's

+McCann

+McCann's

+McCarty

+McCarty's

+McConnel

+McConnel's

+McCormick

+McCormick's

+McCullough

+McCullough's

+McDowell

+McDowell's

+McElroy

+McElroy's

+McGee

+McGee's

+McGillicuddy

+McGillicuddy's

+McGinnis

+McGinty

+McGinty's

+McGowan

+McGowan's

+McHugh

+McHugh's

+McKenna

+McKenna's

+McKeon

+McKeon's

+McMahon

+McMahon's

+McMullen

+McMullen's

+McNally

+McNally's

+McNulty

+McNulty's

+Mcadams

+Mcallister

+Mcallister's

+Mcbride

+Mcbride's

+Mccabe

+Mccabe's

+Mccall

+Mccall's

+Mccallum

+Mccallum's

+Mccann

+Mccann's

+Mccarthy

+Mccarthy's

+Mccarty

+Mccarty's

+Mccauley

+Mccauley's

+Mcclain

+Mcclain's

+Mcclellan

+Mcclellan's

+Mcclure

+Mcclure's

+Mccluskey

+Mccluskey's

+Mcconnel

+Mcconnel's

+Mcconnell

+Mcconnell's

+Mccormick

+Mccormick's

+Mccoy

+Mccoy's

+Mccracken

+Mccracken's

+Mccullough

+Mccullough's

+Mcdaniel

+Mcdaniel's

+Mcdermott

+Mcdermott's

+Mcdonald

+Mcdonald's

+Mcdonnell

+Mcdonnell's

+Mcdougall

+Mcdougall's

+Mcdowell

+Mcdowell's

+Mcelroy

+Mcelroy's

+Mcfadden

+Mcfadden's

+Mcfarland

+Mcfarland's

+Mcgee

+Mcgee's

+Mcgill

+Mcgill's

+Mcginnis

+Mcgovern

+Mcgovern's

+Mcgowan

+Mcgowan's

+Mcgrath

+Mcgrath's

+Mcgraw

+Mcgraw's

+Mcgregor

+Mcgregor's

+Mcguire

+Mcguire's

+Mchugh

+Mchugh's

+Mcintosh

+Mcintosh's

+Mcintyre

+Mcintyre's

+Mckay

+Mckay's

+Mckee

+Mckee's

+Mckenna

+Mckenna's

+Mckenzie

+Mckenzie's

+Mckeon

+Mckeon's

+Mckesson

+Mckesson's

+Mckinley

+Mckinley's

+Mckinney

+Mckinney's

+Mcknight

+Mcknight's

+Mclaughlin

+Mclaughlin's

+Mclean

+Mclean's

+Mcleod

+Mcleod's

+Mcmahon

+Mcmahon's

+Mcmillan

+Mcmillan's

+Mcmullen

+Mcmullen's

+Mcnally

+Mcnally's

+Mcnaughton

+Mcnaughton's

+Mcneil

+Mcneil's

+Mcnulty

+Mcnulty's

+Mcpherson

+Mcpherson's

+Medford

+Medford's

+Medusan

+Meg

+Meg's

+Meier

+Meier's

+Meiji

+Melcher

+Melcher's

+Melpomene

+Melpomene's

+Mendel

+Mendel's

+Mendelian

+Menorca

+Menzies

+Merck

+Merck's

+Merritt

+Merritt's

+Mervin

+Mervin's

+Mesopotamia

+Metcalf

+Metcalf's

+Methuen

+Methuen's

+Metrecal

+Metzler

+Metzler's

+Michel

+Michel's

+Michele

+Michele's

+Michelle

+Michelle's

+Millikan

+Millington

+Milne

+Miltonian

+Miltonism

+Miltonist

+Mindanao

+Mindanao's

+Minos

+Minot's

+Minotaur

+Minotaur's

+Minsk

+Minsk's

+Minsky

+Minsky's

+Mirfak

+Mirfak's

+Mizar

+Mizar's

+Moe

+Moe's

+Moen

+Moen's

+Mogadiscio

+Moghul

+Mohammedanism

+Mohr

+Moiseyev

+Moiseyev's

+Moldavia

+Moloch

+Moluccas

+Mona

+Mona's

+Monash

+Mongolianism

+Monmouth

+Monmouth's

+Monoceros

+Monongahela

+Monongahela's

+Montenegrin

+Montenegrin's

+Monteverdi

+Monteverdi's

+Montmartre

+Montmartre's

+Montrachet

+Montrachet's

+Moran

+Moran's

+Moresby

+Moresby's

+Morley

+Morley's

+Morrill

+Morrill's

+Morris

+Morrissey

+Morrissey's

+Moser

+Moser's

+Moulton

+Moulton's

+Mouton

+Moyer

+Moyer's

+Mpc

+Mt

+Mudd

+Mudd's

+Mueller

+Mueller's

+Muenster

+Mukden

+Mukden's

+Muong

+Muong's

+Muzo

+Muzo's

+Mynheer

+Myra

+Myra's

+Mysore

+NC

+NCO

+NE

+NH

+NIH

+NIMH

+NJ

+NM

+NMR

+NNE

+NNW

+NRC

+NTIS

+NV

+NW

+NY

+NYC

+NYT

+NYU

+Nadine

+Nadine's

+Nagoya

+Nagoya's

+Nagy

+Nagy's

+Nair

+Nair's

+Nakayama

+Narbonne

+Narbonne's

+Narragansett

+Narragansett's

+Nate's

+Neal

+Nebuchadnezzar

+Nebuchadnezzar's

+Ned

+Ned's

+Neff

+Neff's

+Nehru

+Nehru's

+Neil

+Neil's

+Nell

+Nell's

+Nellie

+Nellie's

+Nelsen

+Nelsen's

+Ness

+Neva

+Neva's

+Nevins

+Newbold

+Newbold's

+Newton

+Newton's

+Nguyen

+Nguyen's

+Niamey

+Niamey's

+Nibelung

+Nicholls

+Nicosia

+Nicosia's

+Niger

+Niger's

+Nikko

+Nikko's

+Nikolai

+Nikolai's

+Nineveh

+Noetherian

+Nolan

+Nolan's

+Noll

+Noll's

+Nora

+Nora's

+Nordhoff

+Nordhoff's

+Nordic

+Nordstrom

+Nordstrom's

+Noreen

+Noreen's

+Northrop

+Northrop's

+Northrup

+Northrup's

+Nostrand

+Nostrand's

+Nov

+Novak

+Novak's

+Novosibirsk

+Novosibirsk's

+Nubia

+Nubia's

+Nyquist

+Nyquist's

+O'Neill

+O'Neill's

+OSF

+OSF'S

+Oceania

+Oct

+Odin

+Ojibwa

+Olav

+Olav's

+Olduvai

+Oligocene

+Olin

+Olin's

+Olivier

+Olivier's

+Onondaga

+Onondaga's

+Ophiucus

+Oresteia

+Oresteia's

+Orestes

+Orin

+Orinoco

+Orion

+Orion's

+Orkney

+Orkney's

+Orly

+Orono

+Orono's

+Orphically

+Orr

+Orr's

+Orville

+Orville's

+Osgood

+Osgood's

+Osiris

+Otis

+Ott

+Ott's

+Ouagadougou

+PR

+PVC

+Palladian

+Palo

+Panamanian

+Pandanus

+Pangaea

+Paoli

+Paoli's

+Papua

+Papua's

+Paraguayan

+Paraguayan's

+Paraguayans

+Paramus

+Pareto

+Pareto's

+Parke

+Parke's

+Parkinsonian

+Parmesan

+Parr

+Parr's

+Parrs

+Parsi

+Parsifal

+Parsifal's

+Parthia

+Paso

+Paterson

+Paterson's

+Patti

+Patti's

+Paulo

+Paulo's

+Paulus

+Pavlovian

+Paz

+Peale

+Peale's

+Pease

+Peiping

+Peloponnese

+Pembroke

+Pembroke's

+Penelope

+Penelope's

+Penh

+Penrose

+Pentateuch

+Percival

+Percival's

+Periclean

+Perilla

+Perle

+Perle's

+Permian

+Perseid

+Persephone

+Persephone's

+Peter

+Peters

+Phelps

+Phillip

+Phillip's

+Phipps

+Phobos

+Phoenicia

+Phoenicia's

+Pickett

+Pickett's

+Pict

+Piedfort

+Piedmont

+Pilate

+Pinsky

+Pinsky's

+Piotr

+Piotr's

+Piraeus

+Piscataway

+Piscataway's

+Pizarro

+Pl

+Pollard

+Pollard's

+Poly

+Polyhymnia

+Polynesia

+Polynesia's

+Polys

+Ponce

+Ponchartrain

+Ponchartrain's

+Poole

+Poole's

+Porte

+Porte's

+Portia

+Porto

+Posner

+Posner's

+Poynting

+Poynting's

+Pradesh

+Prado

+Pretorian

+Priam

+Pritchard

+Pritchard's

+Procter

+Procter's

+Proserpine

+Proserpine's

+Protista

+Provence

+Pugh

+Punic

+Punjab

+Punjab's

+Punjabi

+Pusan

+Pusan's

+Pusey

+Pusey's

+Putnam

+Putnam's

+Pyle

+Pyle's

+Pyongyang

+Pyongyang's

+Pyotr

+Pyotr's

+QED

+QM

+Qatar

+Qatar's

+Queensland

+Queensland's

+Quezon

+Quezon's

+Quichua

+Quirinal

+Quito

+Quito's

+Quixotism

+RFI

+RNA

+Rabat

+Rabat's

+Rabin

+Rabin's

+Rae

+Rae's

+Rafferty

+Rafferty's

+Ragusan

+Raman

+Raman's

+Ramo

+Ramo's

+Ranier

+Ranier's

+Rankin

+Rankin's

+Rankine

+Raritan

+Raritan's

+Rastus

+Ratfor

+Raul

+Raul's

+Recife

+Recife's

+Redmond

+Redmond's

+Redondo's

+Regis

+Reid

+Reid's

+Remy

+Rena

+Rena's

+Renault

+Renault's

+Rene

+Rene's

+Rensselaer

+Rensselaer's

+Reub

+Reub's

+Reykjavik

+Reykjavik's

+Rhineland

+Rhoda

+Rhoda's

+Rhode

+Rica

+Ricanism

+Rico

+Riemannian

+Riga

+Rigel

+Rigel's

+Riordan

+Riordan's

+Rocco

+Rochford

+Romanesque

+Romeldale

+Roquemore

+Rosenblum

+Rosenblum's

+Rosenthal

+Rosenthal's

+Rosenzweig

+Rosenzweig's

+Rothschild

+Rothschild's

+Rourke

+Rowe

+Rowe's

+Roxbury

+Roxbury's

+Royce

+Rubaiyat

+Ruben

+Ruben's

+Rubin

+Rubin's

+Rudolf

+Rudolf's

+Rudyard

+Rudyard's

+Runge

+Russo

+Russo's

+Ruthful

+Ruthfully

+Ruthfulness

+Rwanda

+Rwanda's

+Rydberg

+Rydberg's

+SC

+SCM

+SD

+SE

+SIAM

+SIDS

+SIGABRT

+SIGALRM

+SIGBUS

+SIGCHLD

+SIGCLD

+SIGCONT

+SIGEMT

+SIGFPE

+SIGHUP

+SIGILL

+SIGINT

+SIGIO

+SIGIOT

+SIGKILL

+SIGPIPE

+SIGPROF

+SIGQUIT

+SIGSEGV

+SIGSTOP

+SIGSYS

+SIGTERM

+SIGTRAP

+SIGTSTP

+SIGTTIN

+SIGTTOU

+SIGURG

+SIGUSR

+SIGVTALRM

+SIGWINCH

+SIGXCPU

+SIGXFSZ

+SOS

+SSE

+SST

+SSW

+SUNY

+SW

+Sabina

+Sabina's

+Sachs

+Sachsen

+Sadler

+Sadler's

+Sagittarius

+Sal

+Salesian

+Salina

+Salina's

+Salish

+Salle

+Sally

+Salton

+Samaritan

+San

+Sana

+Sanborn

+Sanborn's

+Sanderling

+Santo

+Santos

+Sappho

+Sappho's

+Saracen

+Saracen's

+Saracens

+Saran

+Sardinia

+Sardinia's

+Sarge's

+Satanism

+Satanist

+Saturnism

+Saul

+Saul's

+Sault

+Savoy

+Savoyard

+Savoyards

+Scala

+Scala's

+Scarborough

+Scarlatti

+Scarlatti's

+Scarsdale

+Scarsdale's

+Schantz

+Scheherazade

+Scheherazade's

+Schiller

+Schiller's

+Schlesinger

+Schlesinger's

+Schloss

+Schnabel

+Schnabel's

+Schoenberg

+Schoenberg's

+Schofield

+Schofield's

+Schottky

+Schottky's

+Schuyler

+Schuyler's

+Schuylkill

+Schwab

+Schweitzer

+Schweitzer's

+Seagram

+Seagram's

+Sean

+Sean's

+Sebring

+Sebring's

+Segovia

+Seidel

+Selena

+Selena's

+Selkirk

+Selkirk's

+Selwyn

+Selwyn's

+Sep

+Sepoy

+Serbia

+Serbia's

+Sergei

+Sergei's

+Serpens

+Seth

+Seth's

+Seton

+Severn

+Severn's

+Sextans

+Seychelles

+Shafer

+Shafer's

+Shaffer

+Shaffer's

+Shannon

+Shantung

+Shari

+Shari's

+Sharpe

+Shattuck

+Shattuck's

+Shea

+Shedir

+Sheehan

+Sheehan's

+Shepard

+Sheppard

+Sheppard's

+Sheri

+Sheri's

+Sherrill

+Sherrill's

+Shipley

+Shiva

+Shiva's

+Shmuel

+Shockley

+Shockley's

+Shoshone

+Shoshone's

+Shu

+Shu's

+Shulman

+Shulman's

+Sian

+Sian's

+Sibley

+Siegel

+Siegel's

+Sieglinda

+Sieglinda's

+Siegmund

+Siegmund's

+Siemens

+Siena

+Sifford

+Siggraph

+Sigil

+Simla

+Simonson

+Simonson's

+Sims

+Sinbad

+Sinbad's

+Singborg

+Sino

+Sitar

+Sitarist

+Skopje

+Slavonic

+Slocum

+Slocum's

+Slovakia

+Slovakia's

+Slovenia

+Slovenia's

+Smalley

+Smalley's

+Smithson

+Smithson's

+Smyrna

+Smyrna's

+Smythe

+Soc

+Societe

+Soddy

+Solon

+Soloviev

+Somalia

+Sommerfeld

+Sommerfeld's

+Sonenberg

+Sony

+Sony's

+Southernwood

+Southey

+Spacewar

+Spaulding

+Spaulding's

+Speakerphone

+Spector's

+Spica

+Spicas

+Spiro

+Spiro's

+Spitz

+Sposato

+Sprague

+Sprague's

+Sproul

+Sproul's

+Sri

+Sri's

+Stahl

+Stahl's

+Stanhope

+Stanhope's

+Stargate

+Stargate's

+Staunton

+Steele

+Steele's

+Steen

+Steen's

+Stefan

+Stefan's

+Stendhal

+Stendler

+Sternberg

+Sternberg's

+Stone

+Stone's

+Storey

+Storeyed

+Storeys

+Stratton

+Stratton's

+Strickland

+Strickland's

+Strindberg

+Strom

+Strom's

+Sturbridge

+Sturbridge's

+Sturm

+Sturm's

+Stylar

+Subapically

+Sumeria

+Sumner

+Sumner's

+Sus

+Svetlana

+Svetlana's

+Swansea

+Swansea's

+Swarthout

+Swarthout's

+Swink

+Sykes

+Sylow

+Sylvie's

+Synge

+Szilard

+TA

+TN

+TOEFL

+TTY

+TWX

+TX

+Talmudism

+Tamil

+Tanaka

+Tanaka's

+Tananarive

+Tarbell

+Tarbell's

+Tartary

+Tass

+Taurus

+Tegucigalpa

+Tegucigalpa's

+Terpsichore

+Terpsichore's

+Terre

+Terre's

+Tesseract

+Thalia

+Thalia's

+Thayer

+Thayer's

+Thea

+Thea's

+Thermofax

+Thessalonian

+Thessalonians

+Thessaly

+Thetis

+Thomistic

+Thomistic's

+Thorstein

+Thrace

+Thrace's

+Thracian

+Thuban

+Thuban's

+Tientsin

+Tientsin's

+Tina

+Tina's

+Tirana

+Tirana's

+Tito's

+Toby

+Toby's

+Tom

+Tom's

+Tomlinson

+Tomlinson's

+Tompkins

+Tories

+Torrance

+Torrance's

+Tory

+Transite

+Transite's

+Transputer

+Transvaal

+Transvaal's

+Transylvania's

+Trevelyan

+Trevor

+Triangulum

+Triassic

+Trichinella

+Trichinella's

+Triplett

+Triplett's

+Trobriand

+Troy

+Truk

+Tutankhamen

+Tutenkhamon

+Twombly

+Twombly's

+Tyburn

+Tyburn's

+Tyrannosaurus's

+Tzeltal

+UK

+USGS

+USIA

+USN

+UT

+UV

+Ukraine

+Ukraine's

+Ulan

+UniPlus

+UniPlus's

+UniSoft

+UniSoft's

+Urania

+Urdu

+Uri

+Uris

+Urquhart

+Utrecht

+Utrecht's

+VA

+VAX

+VT

+Vaduz

+Valery

+Valery's

+Valletta

+Valletta's

+Valois

+Valparaiso

+Vancement

+Vanderpoel

+Vanderpoel's

+Varitype

+Varitype's

+Vasquez

+Vasquez's

+Vassar

+Vassar's

+Vaughan

+Vaughan's

+Veda

+Veda's

+Veganism

+Vella

+Vella's

+Veneto

+Veneto's

+Verde

+Verde's

+Verderer

+Verdi

+Verdi's

+Verna

+Verna's

+Versatec

+Versatec's

+Vesuvius

+Vida

+Vida's

+Vientiane

+Vientiane's

+Vikram

+Vinci

+Vinci's

+Virgil

+Virgil's

+Vito

+Vito's

+Volterra

+Volterra's

+Voss

+Vought

+Vought's

+Vreeland

+Vreeland's

+Vulcanism

+WA

+WAC

+WI

+WV

+WY

+Waals

+Wadsworth

+Wadsworth's

+Wagnerian

+Wahl

+Wahl's

+Waite

+Waite's

+Waldron

+Waldron's

+Wallis

+Waltham

+Waltham's

+Wappinger

+Wappinger's

+Warburton

+Watanabe

+Watanabe's

+Webb

+Webb's

+Wehr

+Wehr's

+Wei

+Wei's

+Weierstrass

+Weisenheimer

+Weller

+Welles

+Welton

+Werther

+Werther's

+Whalen

+Whalen's

+Whatley

+Whatley's

+Whitaker

+Whitaker's

+Whitehorse

+Whitehorse's

+Wightman

+Wightman's

+Wilkie

+Wilkie's

+Wilkins

+Willa

+Willa's

+Willis

+Wiltshire

+Wiltshire's

+Winchester

+Wisenheimer

+Witt

+Witt's

+Wittgenstein

+Wittgenstein's

+Wolfe

+Wolfe's

+Wolff

+Wolff's

+Wong

+Wong's

+Woodstock

+Woodstock's

+Woody

+Woody's

+Wotan

+Wotan's

+Wu

+Wu's

+Wyatt

+Wyatt's

+Wyeth

+Wyeth's

+Wylie

+Wylie's

+Wynn

+Wynn's

+Xenakis

+Xhosa

+Yankton

+Yankton's

+Yaounde

+Yaounde's

+Yarmouth

+Yarmouth's

+Yellowknife

+Yellowknife's

+Yellowstone

+Yellowstone's

+Yorkshire

+Yorkshire's

+Yost

+Yost's

+Zagreb

+Zagreb's

+Zambia

+Zambia's

+Zan

+Zan's

+Zoe

+Zoe's

+Zorn

+ab

+abacterial

+abacus

+abacuses

+abandonee

+abashment

+abatis

+abatises

+abattoir

+abaxial

+abbacy

+abbas

+abberations

+abbreviator

+abdicable

+abdicator

+abduce

+abduced

+abducens

+abducent

+abducentes

+abducing

+abeam

+abecedarian

+aberrance

+aberrancy

+aberrated

+aberrational

+abetment

+abhorrence

+abidance

+abiogenesis

+abiogenetic

+abiogenetical

+abiogenetically

+abiogenist

+abiological

+abiologically

+abiotic

+abiotically

+abjuration

+ablaut

+abloom

+abluted

+ablutionary

+abnegate

+abnegates

+abnegation

+abnegator

+aboil

+abolishable

+abolitionary

+abolitionism

+abomasal

+abominably

+abominator

+abominators

+aboral

+aborally

+abortifacient

+abortionist

+abortionists

+abovementioned

+abracadabra

+abradable

+abradant

+abreact

+abridgement

+abrin

+abroach

+abruption

+abscise

+abscised

+abscisin

+abscising

+abscission

+absinth

+absolutism

+absolutist

+absolutistic

+absorbability

+absorbable

+absorbance

+absorbancy

+absorbant

+absorbtions

+absorptance

+absorptional

+abstemious

+abstentious

+abstractable

+abstractional

+abstrict

+abstriction

+abstrictions

+abstrusity

+absurdism

+absurdist

+absurdum

+abubble

+abuilding

+abutilon

+abuttals

+abuzz

+abyssal

+academe

+academical

+academicism

+academism

+acanthocephalan

+acanthopterygian

+acanthus

+acanthuses

+acarpellous

+acarpelous

+acatalectic

+acaulescence

+acaulescent

+accelerando

+accentless

+acceptation

+accessary

+accessibleness

+accessional

+accessorial

+acciaccatura

+accidence

+accidentalism

+accidentalist

+accipiter

+acclivity

+accommodational

+accommodator

+accommodators

+accompanyist

+accompanyists

+accomplishable

+accordionist

+accordionists

+accostable

+accountantship

+accreditable

+accrete

+accreted

+accreting

+accretionary

+accretive

+accruable

+accruement

+acculturational

+acculturationist

+accumbency

+accumbent

+accumulable

+accurses

+accursing

+accurst

+accusatory

+accusor

+accustomation

+acedia

+acellular

+acentric

+acephalous

+acerb

+acerbate

+acerbic

+acerbically

+acerbity

+acervate

+acervately

+acervation

+acetal

+acetaldehyde

+acetamide

+acetaminophen

+acetification

+acetifier

+acetify

+acetonic

+acetous

+acetyl

+acetylate

+acetylation

+acetylative

+acetylenic

+achier

+achiest

+achiness

+achromat

+achromatically

+achromaticity

+achromatism

+achy

+acidhead

+acidiferous

+acidifiable

+acidification

+acidifier

+acidify

+acidimeter

+acidimeter's

+acidimeters

+acidimetric

+acidimetry

+acidulant

+acidulate

+acidulation

+acidulent

+acinus

+acock

+acold

+acquaintanceship

+acquirement

+acquisitional

+acquisitionist

+acquisititious

+acquitment

+acquittance

+acridity

+acrobacy

+acrobatically

+acrocentric

+acrodont

+acronymic

+acronymically

+acropetal

+acropetally

+acrophobia

+acrophobic

+acrostic

+acrostical

+acrostically

+actability

+actable

+actinolite

+actionable

+actionably

+actionless

+activistic

+actorish

+actuary

+aculeate

+acuminate

+acumination

+acupuncture

+acyl

+acylate

+acylated

+acylates

+adamance

+adamancy

+adamantine

+adaptaplex

+adaptational

+adaptationally

+adaptitude

+adaptivity

+adaxial

+addable

+addible

+addlepated

+addressor

+adducible

+adenine

+adenoid

+adenoidal

+adenoids

+adenoma

+adenomatous

+adenosine

+adherend

+adhesional

+adiabaticlly

+adieux

+adipic

+adipose

+adiposity

+adject

+adjudicator

+adjudicatory

+adjunction

+adjuration

+adjuratory

+adjustability

+adjustmental

+adjutancy

+adjuvant

+adle

+adman

+admeasure

+admeasurement

+administrant

+administrational

+administrationist

+admirability

+admissive

+admitter

+admitters

+admonitorily

+admonitory

+adoptability

+adoptable

+adoptee

+adoptees

+adoptianism

+adoptianist

+adoptionism

+adoptionist

+adorability

+adorably

+adoze

+adposition

+adrenalin

+adrenergic

+adrenocortical

+adscititious

+adsorbability

+adsorbable

+adsorbent

+adulator

+adulatory

+adulterant

+adulterator

+adulteress

+adulteresses

+adulterine

+adultlike

+adust

+advection

+advections

+advective

+adventuresome

+adventuresomeness

+adventuress

+adventuresses

+adventurism

+adventurist

+adventuristic

+adventurists

+adversative

+adversatively

+advertence

+advertency

+advertent

+advertently

+advocator

+adynamic

+adz

+adze

+aeolotropic

+aeolotropy

+aeonian

+aeonic

+aerialist

+aerie

+aerier

+aerily

+aero

+aeroballistic

+aeroballistics

+aerobatic

+aerobatics

+aerobe

+aerobically

+aerobiological

+aerobiologically

+aerobiology

+aerobiosis

+aerobiotic

+aerobiotically

+aerodynamical

+aerodynamically

+aerodynamicist

+aerodyne

+aeroembolism

+aerogene

+aerogenes

+aerogram

+aerogram's

+aerograms

+aerographer

+aerography

+aerolite

+aerolith

+aerolitic

+aerological

+aerologist

+aerology

+aeromagnetic

+aeromechanics

+aeromedical

+aeromedicine

+aerometeorograph

+aerometer

+aerometer's

+aerometers

+aeronaut

+aeroneurosis

+aeronomer

+aeronomic

+aeronomical

+aeronomics

+aeronomist

+aeropause

+aerosphere

+aerostat

+aerostatics

+aerothermodynamics

+aery

+aesthesiometer

+aesthesiometer's

+aesthesiometers

+afeard

+afeared

+affability

+affably

+affaire

+affaires

+affectability

+affectable

+affectate

+affectional

+affectionally

+affectionless

+affectivity

+affectless

+affectlessness

+affiance

+affiant

+afficionado

+affine

+affined

+affinely

+affirmable

+affirmance

+affixable

+affixal

+affixation

+affixial

+affixment

+affluency

+afflux

+affray

+affusion

+afghani

+aficionada

+aflatoxin

+aflutter

+afreet

+afrika

+afrikaans

+afterburner

+afterburners

+aftercare

+afterclap

+afterdamp

+afterdeck

+afterimage

+afterpiece

+aftertaste

+aftertax

+aftertime

+afterword

+afterworld

+agamete

+agamic

+agamically

+agapeic

+agapeically

+agave

+agaze

+ageing

+agelong

+agendaless

+agendum

+agene

+agenesis

+agentry

+aggie

+aggies

+agglutinability

+agglutinogen

+agglutinogenic

+aggradation

+aggrade

+aggregational

+aggress

+aggressivity

+agio

+agios

+agitational

+agitato

+agitprop

+aglare

+aglitter

+agnate

+agnatic

+agnatically

+agnation

+agnomen

+agnosticism

+agon

+agone

+agonic

+agonist

+agonistic

+agonistical

+agonistically

+agonists

+agoraphobia

+agoraphobic

+agouti

+agrarianism

+agreeability

+agriculturalist

+agriculturist

+agrimony

+agriology

+agrobiological

+agrobiologically

+agrobiology

+agrologic

+agrological

+agrologically

+agrologist

+agrology

+agronomic

+agronomical

+agronomically

+agronomics

+agronomist

+agronomy

+aground

+aguish

+aguishly

+ahistoric

+ahistorical

+ahold

+aidman

+aigrette

+ailanthus

+aile

+airbrush

+airburst

+airbus

+aircrew

+airdrome

+airfreight

+airglow

+airmanship

+airmobile

+airpost

+airscrew

+airsick

+airsickness

+airstream

+airwave

+airwaves

+airworthiness

+airworthy

+aitch

+alabastrine

+alack

+alacritous

+alai

+alamogordo

+alarmism

+alary

+alate

+alated

+alation

+alb

+albedo

+albinic

+albinism

+albino

+albinotic

+albuminoid

+albuminous

+alcaic

+alcazar

+alchemic

+alchemical

+alchemically

+alchemist

+alchemistic

+alchemistical

+alcoholically

+alcoholometer

+alcoholometer's

+alcoholometers

+alcoholometry

+aldermanic

+aldrin

+aleatoric

+aleatory

+alehouse

+alembic

+alexandrine

+alexandrite

+alexia

+alfa

+algal

+algebraist

+algicidal

+algicide

+algid

+algidity

+algin

+algophobia

+alia

+alicyclic

+alidade

+alienability

+alienable

+alienage

+alienator

+alienee

+alienism

+alienist

+alienor

+aliform

+alightment

+alimentary

+alimentation

+alimentative

+aline

+alinement

+aliphatic

+aliquot

+aliquot's

+aliquots

+alizarin

+alk

+alkahest

+alkahestic

+alkalescence

+alkalescent

+alkalify

+alkalimeter

+alkalimeter's

+alkalimeters

+alkalimetry

+alkalinity

+alkaloidal

+alkalosis

+alla

+allan

+allegate

+allegorist

+allelic

+allelism

+allelomorph

+alleluia

+allemand

+allergen

+allergenic

+allergist

+allery

+alleviatory

+allheal

+alliaceous

+allium

+allocatable

+allocution

+allogamous

+allogamy

+allogeneic

+allograft

+allograph

+allographic

+allomerism

+allomerous

+allometric

+allometry

+allomorph

+allomorphic

+allomorphism

+allonge

+allons

+allopath

+allopathic

+allopathically

+allopathy

+allopatric

+allopatrically

+allopatry

+allophane

+allopurinol

+allosteric

+allosterically

+allotee

+allotransplant

+allotransplantation

+allotrope

+allotropically

+allotropy

+allottee

+allottees

+allotype

+allotypic

+allotypically

+allotypy

+allover

+allseed

+alluvion

+allyl

+allylic

+almandine

+almandite

+almsgiver

+almsgiving

+almshouse

+alogical

+alogically

+aloin

+alongshore

+alpaca

+alpenglow

+alpenstock

+alpestrine

+alphameric

+alphamerical

+alphamerics

+alphanumerical

+alphanumerically

+alpinism

+alpinist

+alright

+altarpiece

+altazimuth

+alterability

+alterably

+alterate

+alterative

+alterman

+altern

+althea

+altimetry

+altitudinal

+altitudinous

+altocumulus

+altricial

+alumina

+aluminate

+aluminosilicate

+aluminous

+alunite

+alveolate

+alveolation

+alyssum

+alytical

+amah

+amalgamator

+amanita

+amanuenses

+amaranth

+amassment

+amative

+amatively

+amativeness

+amaurosis

+amaurotic

+amazonite

+ambage

+ambages

+ambagious

+ambassadorial

+ambassadorship

+ambassadress

+ambergris

+ambidexterity

+ambience

+ambiences

+ambit

+ambitionless

+ambiversion

+ambiversive

+ambivert

+ambrotype

+ambsace

+ambulacral

+ambulacrum

+ambulate

+ambulation

+ambulatorily

+ambushment

+ameliorator

+amelioratory

+amenabilities

+amenability

+amenably

+amendable

+amendatory

+amende

+ament

+amentia

+amerce

+amercement

+amerciable

+amercing

+ametropia

+ametropic

+ami

+amiability

+amiably

+amicability

+amidships

+amiens

+amine

+amis

+amitosis

+amitotic

+amitotically

+amitrole

+ammino

+ammoniacal

+ammoniate

+ammoniation

+ammonification

+ammonifier

+ammonify

+ammonite

+ammonites

+ammonitic

+ammonoid

+amnesia

+amnesiac

+amnesic

+amnestic

+amnia

+amniocentesis

+amnion

+amniote

+amniotic

+amoeban

+amoebiasis

+amoebic

+amoebocyte

+amoeboid

+amoralism

+amoretto

+amorphism

+amort

+amphibia

+amphibole

+amphibolite

+amphibolitic

+amphioxis

+amphioxus

+amphipathic

+amphiploid

+amphipod

+amphitheatric

+amphitheatrical

+amphitheatrically

+amphitropous

+amplexicaul

+amplexus

+amplidyne

+ampul

+ampule

+amputator

+amputee

+amra

+amuck

+amygdaloid

+amylolytic

+ana

+anabaptism

+anabasis

+anabatic

+anabiosis

+anabiotic

+anabolic

+anabolism

+anachronic

+anachronous

+anachronously

+anaclitic

+anacoluthic

+anacoluthically

+anaculture

+anadiplosis

+anaerobe

+anaerobically

+anaerobiosis

+anaglyphic

+anagrammatic

+anagrammatical

+anagrammatically

+analemma

+analemma's

+analemmas

+analeptic

+analgesia

+analgetic

+analogic

+analogist

+analphabet

+analphabetic

+analphabetism

+analysand

+anaphase

+anaphasic

+anaphylaxis

+anaplasia

+anaplastic

+anarch

+anarchism

+anarchistic

+anarcho

+anastasia

+anastigmat

+anastrophe

+anatomist

+anatoxin

+anatropous

+ancestress

+anchoress

+anchoret

+anchoritic

+anchoritically

+anchorless

+anchorman

+ancientry

+andalusite

+andante

+andantino

+andesine

+andesite

+andesitic

+andiron

+andradite

+androgen

+androgenic

+androgyny

+android

+anecdotage

+anecdotalist

+anecdotalists

+anecdotic

+anecdotical

+anecdotically

+anecdotist

+anemograph

+anemographic

+anemometric

+anemometrical

+anent

+aneroid

+aneurism

+aneurysm

+aneurysmal

+anfractuosity

+anfractuous

+angary

+angelical

+angelically

+angerless

+angina

+anginal

+anginose

+angiocardiographic

+angiocardiography

+anglesite

+angleworm

+anglia

+anglice

+anglicism

+angularity

+angulation

+ani

+anile

+animalcular

+animalcule

+animalculum

+animalism

+animalist

+animalistic

+animality

+animallike

+animist

+animistic

+animus

+aniseed

+aniseikonia

+anisette

+anisotropically

+anisotropism

+ankerite

+ankh

+anklebone

+anklebones

+anklet

+annelid

+annexational

+annexationist

+annexe

+annihilator

+annihilatory

+annotator

+annotators

+annuary

+annuitant

+annularity

+annulate

+annulated

+annulately

+annulation

+annulet

+annuli

+annunciatory

+annunicates

+anodal

+anodally

+anodically

+anodyne

+anodynic

+anointment

+anomalistic

+anomalistical

+anomer

+anomeric

+anonym

+anorectic

+anoretic

+anorexigenic

+anorthic

+anorthite

+anorthitic

+anorthosite

+anosmia

+anosmic

+anovulant

+anovulatory

+anoxemia

+anoxemic

+anoxia

+anoxic

+anserine

+antecede

+antecedence

+antecessor

+antechamber

+antechambers

+antechoir

+antediluvian

+antefix

+antefixal

+anteing

+antemortem

+antenatal

+antennal

+antennule

+anteroom

+anterooms

+anthelion

+anthesis

+anthill

+anthologist

+anthracitic

+anthracnose

+anthrax

+anthrop

+anthropic

+anthropical

+anthropocentric

+anthropocentrically

+anthropocentricity

+anthropogenesis

+anthropogenetic

+anthropography

+anthropoid

+anthropometrical

+anthropometrically

+anthropomorphism

+anthropomorphist

+anthropopathism

+anthropophagous

+anthropophagus

+anthropophagy

+anthroposophy

+antiaircraft

+antianxiety

+antibiosis

+antibiotically

+antiblack

+antiblackism

+antically

+anticancer

+anticancerous

+anticatalyst

+anticholinergic

+anticipant

+anticipants

+anticipatable

+anticipator

+anticlerical

+anticlericalism

+anticlimactical

+anticlimactically

+anticlimax

+anticlimaxes

+anticlinal

+anticline

+anticlockwise

+anticoagulant

+anticoagulate

+anticodon

+anticonvulsant

+anticonvulsive

+antidepressant

+antiderivative

+antidiuretic

+antidotal

+antidotally

+antienzyme

+antiestablishment

+antifertility

+antiform

+antifouling

+antifriction

+antifungal

+antigenic

+antigenically

+antigenicity

+antiglobulin

+antigorite

+antigravity

+antihemophilic

+antihistamine

+antihistaminic

+antihypertensive

+antiknock

+antileukemic

+antilitter

+antilog

+antilogarithm

+antilogarithms

+antimacassar

+antimacassars

+antimagnetic

+antimalarial

+antimalarials

+antimedieval

+antimedieval's

+antimedievals

+antimetabolite

+antimitotic

+antimonial

+antimonic

+antimonious

+antineoplastic

+antineutrino

+antineutron

+antinodal

+antinode

+antinovel

+antinovelist

+antinucleon

+antioxidant

+antiparasitic

+antiparticle

+antipathetic

+antipathetically

+antiperiodic

+antiperiplanar

+antipersonnel

+antiphlogistic

+antiphon

+antiphonary

+antiphony

+antiphrasis

+antipodal

+antipodean

+antipoetic

+antipollution

+antipope

+antiproton

+antipyretic

+antipyrine

+antiquarianism

+antirheumatic

+antirrhinum

+antisemite

+antisemite's

+antisemites

+antisepsis

+antiseptically

+antispasmodic

+antistrophe

+antistrophic

+antistrophically

+antitank

+antitoxic

+antitrades

+antitubercular

+antituberculous

+antitumor

+antitumoral

+antitussive

+antivenin

+antiviral

+antivitamin

+antonym

+antonymic

+antonymous

+antonyms

+antonymy

+antrorse

+antrorsely

+anywise

+aortal

+aortic

+aortographic

+aortography

+apalachicola

+apartmental

+apathetically

+apatite

+apeak

+apelike

+aperient

+aperiodically

+aperitif

+aphaeresis

+aphaeretic

+aphanite

+aphanitic

+aphasiac

+aphelion

+aphetic

+aphetically

+aphides

+aphorist

+aphoristic

+aphoristically

+aphotic

+aphrodisiac

+aphrodisiacal

+aphyllous

+aphylly

+apian

+apiarian

+apiarist

+apices

+apiculate

+apicultural

+apiculture

+apiculturist

+aplacental

+aplanatic

+aplasia

+aplastic

+apocalyptical

+apocalyptically

+apocalypticism

+apocalyptism

+apocalyptist

+apocarpous

+apocarpy

+apochromatic

+apocope

+apocrine

+apodal

+apodeictic

+apodictic

+apodictically

+apodosis

+apodous

+apogamic

+apogamous

+apogean

+apolitical

+apolitically

+apollinaire

+apologie

+apologue

+apolune

+apomixis

+apomorphine

+aponeurosis

+aponeurotic

+apoplectic

+apoplectically

+apoplexy

+aport

+aposematic

+aposematically

+apostasy

+apostleship

+apostolate

+apostolicity

+apostrophic

+apothecial

+apothecium

+apothegm

+apothegmatic

+apothegmatical

+apothegmatically

+apothem

+apotropaic

+apotropaically

+appaloosas

+apparitional

+appealability

+appealable

+appeasable

+appellee

+appendant

+appendectomy

+appendicular

+apperceive

+apperception

+apperceptive

+appestat

+appetence

+appetency

+appetent

+applaudable

+applaudably

+applicatory

+appointe

+appomattox

+apport

+appose

+apposed

+apposing

+appositional

+appositionally

+appraisement

+appreciator

+appreciatory

+apprehensibly

+appressed

+approbatory

+approvable

+approvably

+approx

+approximable

+approximant

+appurtenant

+apractic

+apraxia

+apraxic

+apriority

+apsidal

+apsides

+apterous

+apteryx

+aptitudinal

+aptitudinally

+apyrase

+aquacade

+aquaculture

+aquafortis

+aqualunger

+aquamarine

+aquanaut

+aquaplane

+aquaplaner

+aquarelle

+aquarellist

+aquarist

+aquatically

+aquatint

+aquatinter

+aquatintist

+aquavit

+aquicultural

+aquiculture

+aquidneck

+aquiferous

+aquilegia

+aquiline

+aquilinity

+aquiver

+arability

+arachnoid

+arbitrable

+arbitrageur

+arbitral

+arbitrament

+arbitrational

+arboreous

+arborescence

+arborescent

+arborescently

+arboriculture

+arboriculturist

+arborist

+arborist's

+arborists

+arborvitae

+arbovirus

+arbritrary

+arbutus

+arcanum

+arccos

+arccosine

+archae

+archaist

+archaistic

+archangelic

+archbishopric

+archdeacon

+archdeaconate

+archdeaconry

+archdiocesan

+archducal

+archduchess

+archduchy

+archduke

+archdukedom

+archegonial

+archetypal

+archetypally

+archfiend

+archipelagic

+architectonically

+architrave

+archivolt

+archon

+archpriest

+archway

+arclength

+arco

+arcsin

+arctan

+arctically

+arcuate

+arcuately

+arcuation

+areal

+areally

+areaway

+areola

+areolar

+areolate

+areolation

+areole

+argent

+argentic

+argentiferous

+argentine

+argentite

+argentous

+arger

+argillaceous

+arginine

+argos

+argosy

+argufier

+argufy

+argumentum

+argyle

+argyll

+arhat

+aria

+arianist

+arianists

+arithmetician

+armamentarium

+armentieres

+armillaria

+armless

+armlet

+armlike

+armoire

+armorial

+armorially

+armorist

+armorist's

+armorists

+armorless

+armrest

+armsful

+aromatically

+aromaticity

+arpanet

+arras

+arrearage

+arrestant

+arrestment

+arrhythmia

+arrhythmic

+arrhythmical

+arrhythmically

+arris

+arrises

+arriviste

+arrondissement

+arrowwood

+arrowworm

+arrowy

+arsenical

+arsenious

+arsenite

+arsis

+arsonist

+arsonous

+arte

+artefact

+artefacts

+artemisia

+arteriogram

+arteriogram's

+arteriograms

+arteriographic

+arteriography

+arteriolosclerosis

+arteritis

+arthritic

+arthritically

+arthropathy

+arthrosis

+arthrospore

+arthrosporic

+articular

+artilleryman

+artily

+artiodactyl

+artiste

+artmobile

+arum

+aryl

+asap

+asbestosis

+asbestus

+ascendable

+ascendance

+ascendence

+ascendible

+ascensional

+ascensive

+ascertainment

+ascesis

+ascetical

+ascetically

+ascidian

+ascidium

+ascites

+ascitic

+ascomycetes

+ascorbate

+ascospore

+ascosporic

+ascosporous

+ascus

+asdic

+asepsis

+aseptically

+asexual

+asexually

+ashcan

+ashcans

+ashless

+ashmen

+ashram

+asininity

+askant

+askesis

+aslant

+aslope

+asparagine

+aspartate

+aspartic

+aspartokinase

+aspectual

+aspencade

+aspencades

+asperges

+asperse

+aspersed

+aspersing

+asphaltic

+asphaltite

+asphaltum

+aspheric

+aspherical

+asphodel

+asphyxiator

+aspiate

+aspidistra

+assagai

+assai

+assailable

+assassinator

+assegai

+assemblagist

+assemblyman

+assemblywoman

+assentation

+assentor

+assessable

+asseverate

+asseveration

+asseverative

+assignability

+assignat

+assignational

+assignor

+assimilability

+assimilable

+assimilationism

+assimilator

+assimilatory

+assize

+assizer

+assizers

+assizes

+associateship

+assoil

+assoilment

+assortative

+assuagement

+assuasive

+assumable

+assumably

+assumpsit

+assumptive

+assurgent

+assuror

+astaires

+astarboard

+astatic

+astatically

+astaticism

+asteriated

+asteriskless

+asterism

+asterisms

+astern

+asthenia

+asthenic

+asthenosphere

+asthmatic

+asthmatically

+astigmat

+astigmatically

+astir

+astonied

+astrachan

+astragal

+astragalus

+astrakhan

+astrobiological

+astrobiologist

+astrobiology

+astrocyte

+astrocytic

+astrocytoma

+astrodome

+astrol

+astrolabe

+astrologer

+astrologer's

+astrologers

+astrological

+astrologically

+astrology

+astron

+astronautical

+astronautically

+astronavigation

+astrophotography

+astrosphere

+aswarm

+aswirl

+aswoon

+asymptomatic

+asynapsis

+async

+asyndetic

+asyndetically

+asyndeton

+ataractic

+ataraxic

+atari

+atavism

+atavist

+atavistically

+ataxia

+ataxic

+atelectasis

+atelier

+atheistical

+atheistically

+athenaeum

+atheneum

+athirst

+athletically

+athwartship

+athwartships

+atilt

+atinate

+atingle

+atlantes

+atman

+atment

+atmometer

+atmometer's

+atmometers

+atmospherically

+atmospherium

+atomicity

+atomism

+atomist

+atomistic

+atomistically

+atomistics

+atonalism

+atonalist

+atonalistic

+atonality

+atonic

+atonicity

+atony

+atopic

+atopy

+atremble

+atresia

+atrial

+atrioventricular

+atrip

+atrium

+atriums

+atropine

+attachable

+attackman

+attainability

+attainder

+attaint

+attar

+attemptable

+atticism

+attis

+attorn

+attorneyship

+attornment

+attractable

+attractant

+attractivity

+attrited

+attritional

+attunement

+atune

+atwitter

+atypic

+atypicality

+auctorial

+aud

+auden

+audient

+audile

+auding

+audiofrequencies

+audiofrequency

+audiogenic

+audiophile

+auditable

+audivi

+augend

+augite

+augitic

+augmentable

+augmentative

+augmentor

+augury

+auk

+auld

+aunthood

+auntlike

+aurar

+aureate

+aureola

+auricle

+auricula

+auricular

+auriculate

+aurochs

+aurorae

+auroral

+aurorean

+aurous

+auscultatory

+auslander

+auspicate

+austenite

+austral

+australite

+australopithecine

+authoress

+authorial

+autoantibody

+autobahn

+autobiographer

+autobus

+autocade

+autocatalysis

+autocatalytic

+autocephalous

+autochthonous

+autoclave

+autoclaved

+autocoder

+autocratical

+autocross

+autocueing

+autodidact

+autodidactic

+autodyne

+autoecious

+autoeciously

+autoecism

+autoerotic

+autoerotically

+autoeroticism

+autoerotism

+autogamous

+autogamy

+autogenesis

+autogenetic

+autogenetically

+autogenic

+autogenous

+autogenously

+autogiro

+autograft

+autographic

+autographically

+autography

+autogyro

+autohypnosis

+autohypnotic

+autoimmune

+autoimmunity

+autoinfection

+autoinoculation

+autointoxication

+autoloading

+autologous

+autolysate

+autolysin

+autolysis

+autolytic

+automaker

+automanipulation

+automanipulative

+automat

+automatable

+automaticity

+automatism

+automatist

+automobil

+automobilist

+automorphism

+autonomically

+autonomist

+autoparagraph

+autophyte

+autophytic

+autophytically

+autoplastic

+autoplastically

+autoplasty

+autoradiogram

+autoradiogram's

+autoradiograms

+autoradiograph

+autoradiographic

+autoradiography

+autorotate

+autorotation

+autorotational

+autosexing

+autosomal

+autosomally

+autosome

+autosuggest

+autosuggestible

+autosuggestion

+autotable

+autotelic

+autotetraploid

+autotetraploidy

+autotomic

+autotomous

+autotomy

+autotransplant

+autotransplantation

+autotroph

+autotrophic

+autotrophically

+autotrophy

+autunite

+aux

+auxesis

+auxetic

+auxetically

+auxil

+auxin

+auxinic

+auxinically

+auxotroph

+auxotrophic

+auxotrophy

+avaliable

+avast

+avatar

+avaunt

+avec

+avellan

+avellane

+aventail

+aventine

+aventino

+aventurine

+averment

+avesta

+aviarist

+aviatress

+aviculture

+aviculturist

+avidin

+avifauna

+avifaunal

+avifaunally

+avifaunistic

+avigation

+avirulent

+avitaminosis

+avitaminotic

+avocate

+avocational

+avocationally

+avocet

+avoirdupois

+avouchment

+avowal

+avulse

+avulsing

+avulsion

+avuncular

+awardable

+awardee

+aweary

+aweather

+aweigh

+aweless

+awestricken

+awestruck

+awhirl

+awless

+awn

+awnless

+awoken

+axal

+axel

+axenic

+axenically

+axiality

+axil

+axile

+axilla

+axillar

+axillary

+axisymmetric

+axisymmetrical

+axisymmetrically

+axisymmetry

+axletree

+axman

+ayin

+azathioprine

+azeotropic

+azide

+azido

+azine

+azonal

+azote

+azurite

+azusa

+babblement

+baboonish

+babushka

+babysat

+baccate

+bacchanal

+bacchanalia

+bacchanalian

+bacchant

+bacchante

+bacchantes

+bacchantic

+bacchic

+bacciferous

+baci

+bacillar

+bacillary

+bacitracin

+backbite

+backbiter

+backcountry

+backcourt

+backcourtman

+backcross

+backfield

+backfire

+backfired

+backfires

+backfiring

+backgammon

+backgammon's

+backhoe

+backhouse

+backless

+backpedal

+backrest

+backsaw

+backseat

+backset

+backslap

+backslapper

+backslide

+backslider

+backspin

+backstay

+backstretch

+backstroke

+backswept

+backswing

+backsword

+backwash

+backwoodsman

+bactericidal

+bactericidally

+bactericide

+bacterin

+badinage

+bafflement

+bagful

+baggily

+bagley

+bagman

+baguette

+bailable

+bailee

+baileefe

+bailie

+bailiffship

+bailiwick

+bailment

+bailor

+bailsman

+bainite

+bairn

+baize

+bakeshop

+balderdash

+baldhead

+baldheaded

+baldish

+baldpate

+balefire

+balenciaga

+balkline

+ballade

+balladeer

+balladic

+balladist

+balladry

+ballcarrier

+balletic

+balletomane

+balletomania

+ballfield

+ballfield's

+ballgown

+ballgown's

+ballista

+ballistically

+balloonist

+ballottement

+ballyhooey

+balmily

+baloney

+balsamic

+baluster

+bam

+bambino

+bamboozle

+bamboozled

+bamboozlement

+bamboozles

+bamboozling

+banality

+banausic

+bancroft

+bandana

+bandanna

+bandbox

+bandeau

+bandeaux

+bandgap

+banditry

+banditti

+bandleader

+bandmaster

+bandoleer

+bandolier

+bandsman

+baneberry

+bangish

+bangtail

+banjoes

+banjoist

+bankable

+bankbook

+bankbooks

+bankroll

+bankroller

+bankside

+banneret

+bannerette

+bannister

+bannisters

+bannock

+banns

+banquette

+bantamweight

+bantling

+banyan

+banzai

+baobab

+barbarianism

+barbarically

+barbarism

+barbate

+barbe

+barberry

+barbershop

+barbitone

+barbudo

+barbudos

+barbwire

+bareback

+barebacked

+bareheaded

+bareheadedness

+bareknuckle

+bareknuckled

+bargeboard

+bargeman

+bariatrician

+bariatrics

+baric

+baritonal

+barkier

+barkless

+barky

+barleycorn

+barmaid

+barman

+barmier

+barmy

+barny

+barogram

+barogram's

+barograms

+barograph

+barographic

+barometrical

+barometrically

+barometry

+baronage

+baronetage

+baronetcy

+barramunda

+barramundi

+barranca

+barranco

+barrater

+barrator

+barratry

+barre

+barrelful

+barrelhouse

+barrelsful

+barrio

+barrister

+barristers

+barron

+barroom

+barrooms

+barware

+barycentric

+baryon

+baryon's

+baryonic

+baryons

+basaltic

+bascom

+bascule

+baseborn

+baselevel

+basementless

+basepoint

+baserunning

+bashaw

+basicity

+basidial

+basidiomycete

+basidiomycetes

+basidiomycetous

+basidiospore

+basidiosporous

+basidium

+basie

+basification

+basify

+basilary

+basileis

+basilica

+basilican

+basinal

+basinet

+basipetal

+basipetally

+basketful

+basketlike

+basketry

+basketwork

+basler

+baslot

+basophil

+basophile

+basophilia

+bassi

+bassis

+bassist

+bassoon

+bassoon's

+bassoonist

+bassoonist's

+bassoonists

+bassoons

+bast

+bastardy

+bastile

+bastille

+batboy

+bate

+bateau

+batfish

+batfowl

+bathhouse

+bathhouses

+bathometer

+bathometer's

+bathometers

+bathtubful

+bathwater

+batista

+batiste

+batman

+batrachian

+batrachotoxin

+batsman

+batt

+battailous

+battalia

+batteau

+battement

+battier

+battiness

+battlewagon

+battu

+battue

+batty

+batwing

+baubee

+baudrons

+baulk

+baulked

+baulking

+baulks

+baum

+bauxitic

+bawcock

+bawd

+bawden

+bawdily

+bawdry

+bayadere

+bayaderka

+bayanihan

+bazon

+bazooka

+bazookas

+bea

+beachboy

+beachboys

+beachcomb

+beachcomber

+beachcombers

+beachfront

+beachside

+beachwear

+beachy

+beadroll

+beadwork

+beale

+beall

+beame

+beamish

+beamishly

+beamy

+beanball

+beanie

+bearability

+bearbaiting

+bearberry

+beardown

+bearskin

+beastie

+beatie

+beatifically

+beatless

+beauchamps

+beauclerk

+beaverboard

+beaverton

+bebopper

+bechance

+becket

+beckett

+becloud

+bedabble

+bedaub

+bedaubing

+bedchamber

+bedclothes

+bede

+bedeck

+bedevilment

+bedew

+bedfellow

+bedim

+bedimmed

+bedimming

+bedlamite

+bedouin

+bedplate

+bedrid

+bedroll

+bedsore

+beduin

+beduins

+beebread

+beefcake

+beefeater

+beefwood

+beekeeper

+beekeeping

+beelike

+beeline

+beerier

+beery

+beestings

+beeswax

+beeves

+befoh

+befool

+beforehandedness

+beforetime

+begat

+begetter

+begone

+begrime

+begrimed

+begriming

+beguilement

+beguine

+behaviorist

+behaviorist's

+behavioristically

+behaviorists

+behemoth

+behemothic

+behindhand

+behoof

+beigy

+bel

+belaud

+beldam

+beldame

+beleaguer

+belge

+belike

+belittlement

+belive

+bellbird

+belligerency

+bellpull

+bellum

+bellwood

+bellwort

+bellyband

+belowground

+beltless

+belton

+beltway

+beluga

+beluga's

+bemadden

+bemaddening

+bemire

+bemock

+bemusement

+benchmar

+benday

+benedictory

+benefaction

+benefactress

+benefic

+beneficiate

+beneficiation

+benefitted

+benefitting

+benight

+benignancy

+benignant

+benignantly

+benignity

+benthal

+benthic

+benthonic

+benthos

+bentonite

+bentonitic

+benumb

+bepaint

+beplaster

+bequeathal

+berberine

+berceuse

+berceuses

+bergamot

+beringer

+bernardine

+berne

+berrylike

+berteros

+berto

+beseem

+besetment

+beshrew

+besmear

+besom

+besot

+besotter

+bespatter

+bespoken

+besprent

+besprinkle

+bestead

+besteaded

+besteading

+bestiality

+bestiary

+bestrew

+bestride

+bestrides

+bestriding

+bestsellerdom

+betaine

+betake

+betel

+bethink

+betimes

+betony

+betted

+betweenbrain

+betweentimes

+betweenwhiles

+bewigged

+bewitchery

+bewitchment

+bewray

+bey

+biassed

+biassin

+biassing

+biathlon

+bibb

+bibber

+bibbery

+bibcock

+bibelot

+bibelots

+bibless

+biblicism

+biblicist

+bibliographer

+bibliolater

+bibliolatrous

+bibliolatry

+bibliology

+bibliomania

+bibliomaniac

+bibliomaniacal

+bibliopegic

+bibliopegically

+bibliopegist

+bibliopegistic

+bibliopegy

+bibliophilic

+bibliophilism

+bibliophilist

+bibliophily

+bibliopole

+bibliopolic

+bibliopolist

+bibliotheca

+bibliothecal

+bibliotic

+bibliotics

+bibliotist

+bibulous

+bibulously

+bibulousness

+bicameralism

+bicapsular

+bicentenary

+bicentric

+bicentricity

+bichloride

+bichrome

+bicipital

+biconcavity

+biconditional

+biconvexity

+bicorne

+bicornuate

+bicultural

+biculturalism

+bicuspid

+bicuspidate

+bicyclic

+bicyclist

+biddability

+biddably

+bidet

+bidialectal

+bidialectalism

+bierce

+bietnar

+bifacial

+biff

+bifid

+bifidity

+bifidly

+bifilar

+bifilarly

+biflagellate

+biform

+bigamist

+bigamous

+bigamously

+bigamy

+bigeminal

+bigeminy

+bigeneric

+bigeye

+biggety

+biggin

+bigging

+biggish

+biggity

+bighead

+bigheaded

+bighearted

+bigheartedly

+bigheartedness

+bighorn

+bighorn's

+bighorns

+bigmouthed

+bignonia

+bigwig

+bijou

+bijouterie

+bikeway

+bilabiate

+bilateralism

+bilbo

+bilboa

+bilgier

+bilgy

+bilharziasis

+biliary

+bilious

+biliously

+biliousness

+billable

+billfold

+billfold's

+billfolds

+billhead

+billhook

+billionaire

+billon

+billowy

+billposter

+billposting

+billycock

+bilobal

+bilobed

+bilocular

+biloculate

+bimanual

+bimanually

+bimester

+bimestrial

+bimetal

+bimillenary

+bimillenial

+bimodality

+bimorphemic

+binational

+bindweed

+bine

+bingle

+binnacle

+binned

+binning

+binocularity

+bint

+binucleate

+binucleated

+bio

+bioactive

+bioassay

+bioastronautical

+bioastronautics

+biocatalyst

+biocatalytic

+biocenology

+biocenosis

+biocenotic

+biochemic

+biocidal

+biocide

+bioclean

+bioclimatic

+biocoenosis

+biocoenotic

+biodegradability

+biodegradable

+biodegradation

+biodegrade

+bioecological

+bioecologist

+bioecology

+bioelectric

+bioelectrical

+bioelectricity

+bioengineering

+bioenvironmental

+bioflavonoid

+biog

+biogen

+biogenesis

+biogenetic

+biogenetically

+biogenic

+biogeochemical

+biogeochemistry

+biogeographic

+biogeographical

+biogeography

+biographee

+bioinstrumentation

+biologism

+biologistic

+bioluminescence

+bioluminescent

+biomacromolecule

+biomacromolecules

+biomaterial

+biome

+biometrical

+biometrically

+biomolecular

+bionic

+bionics

+bionomic

+bionomical

+bionomically

+bionomics

+biopolymer

+biopolymers

+biosatellite

+bioscientific

+bioscientist

+biosynthesis

+biosynthetic

+biosynthetically

+biosystematic

+biosystematist

+biosystematy

+biota

+biotechnological

+biotechnology

+biotelemetric

+biotelemetry

+biotin

+biotite

+biotitic

+biotope

+biotransformation

+biotron

+biotype

+biotypic

+biovular

+bipack

+biparental

+biparentally

+bipartisanism

+bipartisanship

+bipedal

+biphenyl

+bipinnate

+bipinnately

+bipod

+bipolarity

+bipropellant

+biquadratic

+biracialism

+biradial

+biramous

+birchbark

+birdbrain

+birdbrained

+birdcage

+birdcage's

+birdcages

+birdcall

+birdhouse

+birdieback

+birdieing

+birdlime

+birdman

+birdyback

+bireme

+biretta

+birgitta

+birk

+birkhead

+birkie

+birl

+birler

+birr

+birse

+birthmark

+birthroot

+birthstone

+birthwort

+biscayne

+bisectional

+bisectionally

+bisexuality

+bistort

+bistro

+bistroic

+bistros

+bisulfate

+bisulfide

+bisulfite

+bitartrate

+bitchery

+bitchier

+bitchily

+bitchiness

+bitchy

+bitstock

+bitsy

+bitt

+bitted

+bitterish

+bitterweed

+bitting

+bittock

+bitty

+bituminoid

+bivalent

+biyearly

+biz

+blabber

+blabbered

+blabbering

+blabby

+blackamoor

+blackamoors

+blackcap

+blackcock

+blackdamp

+blackface

+blackfin

+blackfish

+blackfly

+blackguard

+blackguard's

+blackguardism

+blackguardly

+blackguards

+blackhander

+blackhead

+blackheart

+blackish

+blackland

+blackleg

+blackmer

+blackpoll

+blacksnake

+blacktail

+blackthorn

+blacktop

+blacktop's

+blacktops

+blackwash

+blackwater

+bladderlike

+blakey

+blamably

+blameful

+blamefully

+blancmange

+blandish

+blandisher

+blandishment

+blandishments

+blanketflower

+blanketlike

+blanton

+blarney

+blasingame

+blastema

+blastematic

+blastemic

+blastie

+blastment

+blastula

+blastula's

+blastular

+blastulas

+blastulation

+blat

+blate

+blatted

+blatter

+blazonry

+bleachable

+bleakish

+blearily

+blench

+blende

+blether

+blevins

+blimpishly

+blimpishness

+blindfish

+blindworm

+blintz

+blintze

+blipping

+blique

+blistery

+blithesome

+blithesomely

+blizzardy

+blobbing

+blockbuster

+blockbusters

+blockbusting

+blockhead

+blockheads

+blockish

+blockishly

+blondish

+bloodcurdling

+bloodcurdlingly

+bloodfin

+bloodguilt

+bloodguiltiness

+bloodguilty

+bloodily

+bloodletting

+bloodline

+bloodline's

+bloodlines

+bloodmobile

+bloodred

+bloodstock

+bloodstone

+bloodsucker

+bloodsucking

+bloodthirstily

+bloodthirstiness

+bloodthirsty

+bloodworm

+bloodwort

+bloomy

+bloop

+blooper

+bloops

+blossomy

+blotchily

+blotchy

+blotter

+blotty

+blouson

+blowfly

+blowgun

+blowhard

+blowhole

+blowout

+blowpipe

+blowsy

+blowtube

+blowy

+blowzy

+blubbery

+blucher

+bluebeard

+bluebell

+bluebottle

+bluecoat

+bluefin

+blueing

+bluejack

+bluenose

+bluepoint

+bluesman

+bluestem

+bluestone

+bluesy

+bluet

+bluetongue

+blueweed

+bluey

+blume

+blunderbuss

+blurrily

+blushful

+blusterous

+blutwurst

+blyth

+boardlike

+boardman

+boardmanship

+boardroom

+boardsmanship

+boardwalk

+boart

+boatel

+boatels

+boatmanship

+boatsmanship

+boaz

+bobber

+bobbery

+bobbinet

+bobbsey

+bobeche

+bobrow

+bobsledder

+bobstay

+bobtail

+bobtailed

+bocaccio

+bocci

+boccie

+bod

+bodacious

+bodaciously

+bodega

+bodement

+bodenheim

+bodiless

+bodkin

+bodysurf

+bodysurfer

+bodywork

+boehmer

+boehmite

+boer

+boff

+boffin

+boffo

+boffola

+boffos

+bogartian

+bogeyman

+bogeyman's

+boggs

+bogie

+bogle

+boheme

+bohlen

+boies

+boite

+boites

+bola

+boland

+bolas

+bolases

+bole

+bolero

+bolet

+boletus

+boliou

+bollard

+bollix

+bollworm

+bolometric

+bolometrically

+boloney

+boltrope

+bolus

+bombardier

+bombardiers

+bombardon

+bombastically

+bombazine

+bombe

+bombinate

+bombination

+bombshell

+bombsight

+bombus

+bon

+bonbon

+bondable

+bondholder

+bondmaid

+bondman

+bondstone

+bondwoman

+bonefish

+bonehead

+boneheaded

+boneless

+boneset

+bonesetter

+boney

+boneyard

+bonfiglio

+bongoes

+bongoist

+bonham

+bonheur

+bonhomie

+bonkers

+bonne

+bonner

+bonnily

+bonnor

+bonsai

+bonspiel

+bontempo

+bonze

+bonzer

+boobify

+boodle

+booger

+boogerman

+boogeyman

+bookbindery

+bookful

+booklist

+bookmaker

+bookmakers

+bookmaking

+bookman

+bookmark

+bookmark's

+bookmarker

+bookmarkers

+bookmarks

+bookmobile

+bookmobiles

+bookselling

+bookstall

+bookworm

+bookworm's

+bookworms

+booky

+boomier

+boomlet

+boomy

+boondocks

+boondoggle

+boondoggler

+boondoggling

+boonies

+bootee

+bootie

+bootjack

+bootlace

+bootle

+bootless

+bootlessly

+bootlessness

+bootlick

+bootlicker

+bootprint

+boozily

+boozy

+bopper

+bora

+borage

+borak

+borane

+borazon

+bordel

+bordereau

+boreal

+boresight

+boresights

+borglum

+boride

+borland

+borneol

+boronic

+bort

+bosomy

+bosonic

+bosphorus

+bosque

+bosquet

+bossdom

+bossism

+bostitch

+bot

+botan

+botchwork

+botchy

+botel

+botheration

+bots

+bottlecap

+bottlecap's

+bottlecaps

+bottleful

+bottomland

+bottomry

+botulinal

+botulinum

+boucle

+boudoir

+bouffe

+bougainvillaea

+bougainvillea

+bougie

+bouillabaisse

+bouldery

+boule

+boulevardier

+bouleversement

+boulez

+boulle

+bouncily

+bounderish

+bounderishly

+bountiful

+bountifully

+bountifulness

+bourbonism

+bourdon

+bourg

+bourgeoise

+bourgeoisify

+bourgeon

+bourguiba

+bourn

+bourse

+bouse

+bousing

+boustrophedon

+bouton

+boutonniere

+bouvardier

+bouvier

+bouzouki

+bovinity

+bowan

+bowelless

+bowerbird

+bowerbird's

+bowerbirds

+bowery

+bowes

+bowfin

+bowfront

+bowhead

+bowknot

+bowlder

+bowleg

+bowlegged

+bowlful

+bowmen

+bowse

+bowsprit

+bowwow

+bowyer

+boxful

+boxhaul

+boxlike

+boxthorn

+boyar

+boyard

+boyars

+bozo

+bozos

+brabble

+brabbled

+brabbling

+brachial

+brachiate

+bract

+bradded

+bradding

+braggart

+braggest

+braggy

+brahma

+brail

+braillewriter

+braincase

+brainish

+brainless

+brainlessly

+brainlessness

+brainpan

+brainpower

+brainsick

+brainsickly

+brainstem

+brainstem's

+brainstems

+brainteaser

+braise

+braised

+braiser

+braises

+braising

+brakeless

+braky

+branchia

+branchial

+branchiate

+branchless

+branchlet

+branchy

+brandel

+brandin

+brandling

+brank

+branks

+brannon

+brant

+brants

+branum

+braque

+braques

+brassard

+brassbound

+brasserie

+brassica

+brassily

+brattice

+brattiness

+brattish

+brattishing

+brattle

+brattled

+brattling

+bratty

+brava

+bravoes

+braw

+braweling

+brawle

+brawlier

+brawly

+brawnier

+brawnily

+brawniness

+brawny

+brazos

+breadbasket

+breadbaskets

+breadroot

+breadstuff

+breadthways

+breadthwise

+breadwinning

+breakfront

+breakneck

+breakoff

+breakout

+bream

+breams

+breastbone

+breaststroke

+breaststroker

+breathability

+breccia

+breccias

+brecciate

+brecciation

+breechblock

+breechcloth

+breechclout

+breechloader

+breeks

+breezeless

+breezeway

+bregma

+bregmatic

+breviaries

+breviary

+brewage

+briard

+bribable

+bricating

+brickbat

+brickle

+bricktop

+brickwork

+bridewell

+bridgeboard

+bridgeless

+briefless

+brien

+briery

+brigadoon

+brigand

+brigand's

+brigandage

+brigandine

+brigandism

+brigands

+brightwork

+brill

+brilliantine

+brimless

+brimmer

+brinded

+bringdown

+brinkley

+brinksmanship

+brio

+brioche

+briolette

+briquet

+briquette

+brisance

+brisant

+brisket

+brisling

+brist

+bristlecone

+bristlecone's

+bristlecones

+bristlelike

+bristletail

+brit

+broadax

+broadcloth

+broadleaf

+broadminded

+broadsheet

+broadsword

+broadtail

+broadwife

+brocatelle

+brochette

+brockage

+brocket

+brockle

+brocoli

+brogue

+broider

+broidery

+brokenhearted

+brollies

+brolly

+bromate

+bromated

+bromating

+bromegrass

+bromeliad

+bromelin

+bromic

+bromidic

+brominate

+bromination

+bromism

+bromo

+bromos

+bronchialy

+broncobuster

+brontosaur

+brontosaurus

+bronzy

+broomball

+broomballer

+broomcorn

+broome

+broomrape

+broths

+brougham

+broughams

+broun

+brownnose

+brownnoser

+brownout

+brownshirt

+brownstone

+brownstones

+browny

+browsability

+broxodent

+bruit

+brunet

+brushability

+brushback

+brushcut

+brushland

+brushstroke

+brushstroke's

+brushstrokes

+brushup

+brushwood

+brusk

+brusquerie

+brut

+bruxelles

+bruxism

+bryophyta

+bryophyte

+bryozoa

+bs

+bubby

+buccal

+buccaneer

+buccaneer's

+buccaneerish

+buccaneers

+bucer

+buckbean

+buckeroo

+bucketsful

+buckhead

+buckman

+bucko

+buckoes

+bucksaw

+buckshee

+bucktail

+buckthorn

+bucktooth

+bucky

+bucolically

+budder

+buddle

+budgeteer

+budgie

+budlong

+bufferred

+buffi

+buffo

+buffoonery

+buffoonish

+buffos

+bugatti

+bugbear

+bugeye

+buggery

+bughouse

+bugleweed

+bugloss

+bugseed

+builtin

+bulba

+bulbaceous

+bulbar

+bulbil

+bulbous

+bulbously

+bulbul

+bulginess

+bulgur

+bulgy

+bulkily

+bulla

+bullace

+bullae

+bullbaiting

+bullbat

+bulldogger

+bullfight

+bullfighter

+bullfighting

+bullhorn

+bullnecked

+bulloch

+bullock

+bullocky

+bullous

+bullpout

+bullring

+bullrush

+bullrush's

+bullrushes

+bullterrier

+bullwhack

+bullwhip

+bullyrag

+bumbershoot

+bumboat

+bumbry

+bumkin

+bumpier

+bumpily

+bumpiness

+bumpkin

+bumpkin's

+bumpkinish

+bumpkinly

+bumpkins

+bumpy

+bunchily

+bunchy

+bunco

+bund

+bundist

+bundoora

+bundy

+bung

+bunger

+bunghole

+bunglesome

+bunko

+bunkos

+bunkum

+buntline

+buoyance

+burbank

+burbly

+burdock

+bureaucratically

+bureaux

+buret

+burette

+burettes

+burgage

+burgee

+burglarious

+burglariously

+burgonet

+burgoo

+burgoos

+burin

+burking

+burladero

+burle

+burlily

+burlingame

+burnable

+burne

+burnes

+burnoose

+burnous

+burnout

+burrier

+burrstone

+burry

+bursae

+bursal

+bursar

+bursary

+burse

+burseed

+bursty

+burthen

+burweed

+busbies

+busby

+bushbuck

+bushbucks

+bushelage

+bushelman

+bushfire

+bushily

+bushland

+bushland's

+bushman

+businesswoman

+businesswoman's

+businesswomen

+busk

+busker

+buskin

+busload

+busload's

+busloads

+busty

+busybody

+busywork

+butadiene

+butanol

+buteo

+butterfingered

+butterfingers

+butterfish

+butterflyer

+butterless

+butterscotch

+butterweed

+butterwort

+butties

+buttinski

+buttinsky

+buttonball

+buttonbush

+buttonhook

+buttonless

+buttonwood

+buttony

+buttstock

+butty

+butut

+butylate

+butylation

+butylene

+butyraceous

+butyral

+butyraldehyde

+butyric

+bwana

+byelaw

+byelaws

+byinge

+bylot

+byname

+bypast

+byplay

+byre

+bystreet

+cabala

+cabalism

+cabalist

+cabalistic

+caballed

+caballero

+caballing

+cabbala

+cabbie

+cabbies

+cabby

+cabinetmaking

+cabinetwork

+cablegram

+cablegram's

+cablegrams

+cablet

+cableway

+cabman

+caboodle

+caboose

+cabotage

+cabriole

+cabriolet

+cabstand

+cachalot

+cachectic

+cachepot

+cachet

+cachou

+cacodemon

+cacodemonic

+cacogenesis

+cacogenic

+cacogenics

+cacographical

+cacography

+cacophonous

+cacophonously

+cacuminal

+cadastral

+cadastrally

+cadastre

+cadaveric

+cadaverine

+caddie

+caddis

+caddish

+caddishly

+caddishness

+cade

+cadency

+cadential

+cadetship

+caducean

+caduceus

+caducity

+caducous

+caffeinic

+caftan

+cageling

+cagier

+cagily

+caginess

+cagy

+cahier

+caiman

+caisson

+caitiff

+cajolement

+cajolery

+cakewalk

+cakewalker

+calabash

+calaboose

+calamine

+calamint

+calamite

+calamus

+calash

+calcaneal

+calcaneum

+calcaneus

+calcic

+calcific

+calcifuge

+calcifugous

+calcimine

+calcination

+calcine

+calcined

+calcining

+calcinosis

+calcitic

+calcomp

+calculably

+calculatingly

+calculous

+caldera

+caldron

+caleche

+calender

+calenderer

+calendric

+calendrical

+calends

+calendula

+calenture

+calflike

+calif

+caliginous

+caliphal

+calk

+calker

+calla

+callant

+callback

+callboy

+calligraphic

+calligraphically

+calligraphist

+callose

+callosity

+callus

+calluses

+calmative

+calomel

+calorically

+calorific

+calorimetrically

+calory

+calotte

+calque

+caltech

+calthrop

+caltrop

+caltrops

+calumniator

+calumnious

+calumniously

+calypsonian

+calyx

+camarilla

+cambial

+cambium

+cambric

+camelback

+cameleer

+camelia

+camellia

+camelopard

+cameralism

+cameralist

+camise

+camisole

+caml

+camlet

+camomile

+camorra

+camorrista

+camouflageable

+camouflagic

+campanile

+campanologist

+campanology

+campanula

+campanulate

+campcraft

+campership

+camphene

+camphine

+camphor

+camphoraceous

+camphorate

+camphorated

+camphoric

+campily

+campiness

+campion

+campobello

+camporee

+campos

+campstool

+campy

+camshaft

+camshafts

+canalboat

+canaliculate

+canard

+canasta

+cancan

+cancroid

+candela

+candelabra

+candelabrum

+candent

+candescence

+candescent

+candida

+candidature

+candleholder

+candlepin

+candlepins

+candlepower

+candlepowers

+candlesnuffer

+candlewick

+canebrake

+canescent

+caneware

+canful

+canicular

+cankerous

+cankerworm

+canna

+cannel

+cannibalic

+cannily

+cannonade

+cannoneer

+cannonry

+canoeing

+canoeist

+canoeist's

+canoeists

+canoness

+canonicity

+canorous

+canorously

+canorousness

+canst

+cantabile

+cantata

+cantatas

+canterelle

+canthi

+canthus

+cantillate

+cantillation

+cantina

+cantle

+cantles

+cantonal

+cantonment

+cantus

+canty

+canute

+canvaslike

+capelet

+capella

+capeskin

+capet

+capework

+capful

+capias

+capillarity

+capitalistically

+capitan

+capitate

+capitates

+capitation

+capitular

+capitulary

+capitulum

+capo

+capon

+caporal

+capper

+cappers

+cappy

+capriccio

+caprification

+caprine

+capriole

+capsular

+capsulate

+capsulated

+capt

+captainship

+captan

+captionless

+captivator

+capuchin

+capybara

+carabao

+carabid

+carabineer

+carabiner

+carabinero

+carabinier

+carabiniere

+caracole

+carafe

+carapace

+carapace's

+carapaces

+carat

+caravanner

+caravansary

+caravel

+carbarn

+carbaryl

+carbazole

+carbolated

+carboline

+carboniferous

+carbonium

+carbonless

+carbonous

+carbonylic

+carboxy

+carboxyl

+carboxylate

+carboxylation

+carboxylic

+carbuncular

+carburet

+carburetion

+carburetor

+carburetors

+carcase

+carcinogenesis

+carcinogenicity

+carcinoid

+cardamom

+cardialgia

+cardigan

+cardigan's

+cardigans

+cardinalship

+cardiogram

+cardiogram's

+cardiograms

+cardiograph

+cardiographer

+cardiographic

+cardiographs

+cardiography

+cardioid

+cardioid's

+cardioids

+cardiological

+cardiologist

+cardiopathy

+cardiopulmonary

+cardiorespiratory

+cardiotonic

+cardiovasculatory

+cardplayer

+cardsharp

+cardsharper

+careerist

+careerists

+carefuller

+carefullest

+carfare

+carful

+carhop

+caribe

+caricatural

+carioca

+cariole

+carious

+carle

+carling

+carlsbad

+carmaker

+carnallite

+carne

+carnelian

+carney

+carnivore

+caroche

+carom

+carotene

+carousal

+carousel

+carousel's

+carousels

+carpal

+carpellary

+carpetbag

+carpetbag's

+carpetbagged

+carpetbagger

+carpetbagger's

+carpetbaggers

+carpetbaggery

+carpetbagging

+carpetbags

+carpi

+carpospore

+carposporic

+carpus

+carrefour

+carriageway

+carriageways

+carriole

+carronade

+carroty

+carrousel

+carryall

+carryon

+carryout

+carsick

+cartage

+cartel

+cartilaginous

+cartload

+cartloads

+cartogram

+cartogram's

+cartograms

+cartographical

+cartomancy

+cartop

+carty

+caruncular

+carunculate

+carunculated

+casa

+casaba

+casaba's

+casabas

+cascara

+caseate

+caseation

+casebearer

+casemate

+caseous

+casern

+caserne

+cashable

+cashbook

+cashless

+casque

+cassaba

+cassava

+cassino

+cassite

+castaway

+casteism

+castigator

+castigators

+castoff

+castoffs

+castrate

+castrated

+castrater

+castraters

+castrates

+castrating

+castration

+castrato

+castrator

+castrators

+castratory

+casuistic

+casuistical

+casuistry

+catabolic

+catabolically

+catabolism

+catabolite

+catachresis

+catachresti

+catachrestic

+catachrestical

+cataclysm

+cataclysmal

+catacomb

+catacombic

+catadromous

+catafalque

+catalatic

+catalectic

+catalepsy

+cataleptic

+cataleptically

+catalpa

+catamaran

+catamount

+cataplasm

+cataplastic

+cataplexy

+cataractal

+catarrh

+catarrhal

+catarrhally

+catastasis

+catatonic

+catawba

+catboat

+catcall

+catchall

+catchee

+catchment

+catchpenny

+catchpole

+catchpoll

+catchup

+cate

+catechesis

+catechetical

+catechin

+catechismal

+catechist

+catechistic

+catena

+catenary

+catenulate

+cateran

+catercorner

+cateress

+caterwaul

+cates

+catface

+catfacing

+catgut

+catharses

+cathartic

+cathead

+cathect

+cathectic

+cathedra

+cathexes

+cathexis

+cathodically

+catholically

+catholicate

+catholicity

+cathouse

+cation

+cationic

+cationically

+cations

+catkin

+catnap

+catnaps

+catoptric

+catoptrically

+catoptrics

+catted

+cattily

+catting

+caudal

+caudally

+caudate

+caudated

+caudation

+caudillo

+caudle

+caul

+cauldron

+cauldrons

+caulescent

+caulicle

+caulicles

+cauline

+causeless

+causerie

+causey

+causeys

+caustically

+causticity

+cautery

+cavalierism

+cavalryman

+cavernicolous

+caviare

+cavies

+cavitary

+cavitate

+cavitation

+cay

+cayman

+cc

+ceasefire

+ceasefire's

+cedarn

+cedarwood

+ceil

+ceilometer

+ceilometer's

+ceilometers

+ceinture

+celandine

+celebrator

+celebrators

+celeriac

+celiac

+celibacy

+cellarage

+cellarages

+cellaret

+cellarets

+cellarette

+cellarettes

+cellularity

+cellule

+celluloid

+celluloid's

+cellulosic

+cementation

+cementite

+cementitious

+cenobite

+cenobitic

+cenobitical

+cenogenetic

+cenogenetically

+cenospecies

+cenotaph

+cense

+censer

+censing

+censorious

+censoriously

+censoriousness

+censurable

+cental

+centare

+centaurea

+centaury

+centavo

+centenarian

+centesimal

+centesimo

+centiare

+centillion

+centime

+centimo

+centner

+cento

+centones

+centra

+centrale

+centralism

+centralist

+centralistic

+centralists

+centric

+centrically

+centricity

+centriole

+centrism

+centroidal

+centromere

+centromeric

+centrosome

+centrosomic

+centrosphere

+centrosymmetric

+centrum

+centum

+centurion

+cephalad

+cephalic

+cephalically

+cephalometric

+cephalometry

+cepstrum

+ceraceous

+ceramicist

+ceramist

+ceramium

+cere

+cerebellar

+cerebroside

+cerebrosides

+cerebrovascular

+cerebrum

+cerement

+ceremonialism

+ceremonialist

+ceremonialists

+ceres

+cereus

+cering

+cernuous

+certes

+certifiably

+certificatory

+cerumen

+ceruminous

+ceruse

+cervices

+cervine

+cervix

+cervixes

+cesarean

+cesarian

+cesspit

+cesspool

+cesta

+cesti

+cetacean

+cetacean's

+cetaceans

+cf

+chaffey

+chaffy

+chainomatic

+chalcedonic

+chalcedony

+chalcid

+chalcocite

+chaldron

+chalet

+chalkboard

+chalone

+chambray

+chambrays

+chameleon

+chameleonic

+chameleons

+chamfron

+chamfrons

+chammy

+chamoix

+chamomile

+champak

+champertous

+champerty

+champlainian

+chanceful

+chancel

+chancellery

+chancellorship

+chancellorships

+chancellory

+chancels

+chancre

+chancres

+chancroid

+chancroidal

+chancrous

+chandelle

+chandler

+chandlery

+changeful

+changefully

+changefulness

+changeless

+changelessly

+changelessness

+changeling

+channing

+chanson

+chanteuse

+chanteuses

+chantier

+chanties

+chanty

+chaotically

+chapati

+chapbook

+chape

+chapeau

+chapeaus

+chapeaux

+chapelles

+chaperonage

+chapfallen

+chapiter

+chaplaincies

+chaplaincy

+chaplet

+chapleted

+chaplets

+chaplinesque

+charabanc

+characin

+characterful

+characterless

+characterological

+characterologically

+charactery

+charade

+charades

+charcuterie

+chard

+chare

+charier

+charily

+chariness

+charioteer

+charioteers

+charism

+charismata

+charisms

+charlatan

+charlatanism

+charlatanry

+charmless

+charnel

+charnock

+charring

+chartularies

+chartulary

+charwoman

+chary

+chassepot

+chasseur

+chasten

+chastened

+chastener

+chastening

+chateaubriand

+chatelain

+chatelaine

+chatelaines

+chatelains

+chatoyance

+chatoyancy

+chatoyant

+chattahoochee

+chatterbox

+chatterboxes

+chattily

+chauffers

+chaussure

+chaussures

+chauvinistically

+cheapie

+cheapish

+cheapishly

+cheapskate

+cheapskates

+checkerberry

+checkless

+checkmark

+checkmarks

+checkmate

+checkmated

+checkmates

+checkmating

+checkoff

+checkrein

+checkroom

+checkrooms

+checkrow

+cheddar

+cheekful

+cheekily

+cheep

+cheeps

+cheerio

+cheeseburger

+cheeseburgers

+cheesecake

+cheesecake's

+cheesecakes

+cheesecloths

+cheesemaker

+cheesemakers

+cheesemaking

+cheeseparer

+cheeseparing

+cheeseparings

+cheetahs

+chefdom

+chekhov

+chelatable

+chelonian

+chemiluminescence

+chemiluminescent

+chemische

+chemism

+chemisorb

+chemisorption

+chemoautotrophic

+chemoautotrophically

+chemoautotrophy

+chemoprophylaxis

+chemoreception

+chemoreceptive

+chemoreceptivity

+chemoreceptor

+chemoreceptors

+cheng

+chenille

+cherishable

+cheroot

+cherrylike

+cherrystone

+chert

+cherubic

+cherubically

+cherublike

+chervil

+chervils

+chessboard

+chessboards

+chessman

+chessmen

+chestful

+chestier

+chesty

+cheveron

+cheviot

+chevrotain

+chewable

+chewy

+chi

+chiaroscurist

+chiaroscuro

+chiasma

+chiasmatic

+chiasmus

+chiaus

+chicalote

+chicaning

+chichi

+chickasaws

+chickenhearted

+chickpea

+chickpea's

+chickpeas

+chickweed

+chickweeds

+chicle

+chicos

+chidden

+chieftaincies

+chieftaincy

+chieftainship

+chiffonier

+chignon

+childbed

+childbirths

+chilies

+chillily

+chimaera

+chimere

+chimerical

+chimerically

+chimerism

+chimneypiece

+chimp

+chimps

+chinaware

+chinbone

+chinch

+chine

+chines

+chinoiserie

+chinos

+chinquapin

+chintzier

+chintzy

+chirographer

+chirographic

+chirographical

+chirography

+chiromancer

+chiromancy

+chiropodist

+chiropodists

+chiropody

+chiropractic

+chiropter

+chiropteran

+chirpily

+chirpy

+chirrup

+chirruped

+chirruping

+chirrups

+chit

+chitchat

+chitin

+chitinous

+chitlings

+chiton

+chits

+chitter

+chittered

+chittering

+chitterlings

+chitters

+chivalric

+chivied

+chivvied

+chivvy

+chivvying

+chivy

+chloral

+chlordane

+chloric

+chlorinity

+chlorite

+chloritic

+chlorobenzene

+chlorohydrin

+chlorophyllose

+chlorophyllous

+chloroplatinate

+chockablock

+chocolaty

+choirboy

+choky

+choler

+choleraic

+choleric

+choline

+cholinergic

+chondrite

+choosey

+chopfallen

+chophouse

+choppily

+chopstick

+chopsticks

+choreman

+choreographically

+choric

+chorically

+chorine

+chorister

+chorizo

+chorographic

+chorography

+choryza

+chowderhead

+chowderheaded

+chowhound

+chowtime

+chrestomathy

+christsake

+chromatically

+chromaticism

+chromaticity

+chromatid

+chromatin

+chromatographically

+chromatolytic

+chromide

+chrominance

+chromo

+chromosomal

+chromosome

+chromosome's

+chromosomes

+chromosomic

+chromospheric

+chronical

+chronicity

+chronogram

+chronogram's

+chronogrammatic

+chronogrammatical

+chronograms

+chronographic

+chronographs

+chronologer

+chronologers

+chronologic

+chronologist

+chronologists

+chronometer

+chronometer's

+chronometers

+chronometric

+chronometrical

+chronometrically

+chronometry

+chronoscope

+chronoscopes

+chrysolite

+chubbily

+chuckhole

+chucklehead

+chuckleheaded

+chuckleheads

+chucklesome

+chuckwalla

+chuff

+chuffed

+chuffier

+chuffing

+chuffy

+chugalug

+chugger

+chummily

+chumship

+chunkily

+churchgoer

+churchianity

+churchless

+churchmanship

+churchy

+churlish

+churlishly

+churlishness

+chutist

+chutists

+chutzpa

+chutzpah

+cigarillo

+cigarillos

+ciliary

+cincture

+cindery

+cinemagoer

+cinemagoers

+cinematically

+cinematograph

+cinematographer

+cinematographic

+cinematographical

+cinematographically

+cinematography

+cinquefoil

+ciphertext

+ciphony

+circadian

+circinate

+circinately

+circuital

+circuity

+circulatable

+circulator

+circulators

+circumambient

+circumambiently

+circumambulate

+circumambulates

+circumcircle

+circumfluent

+circumfluous

+circumfuse

+circumfused

+circumfuses

+circumfusing

+circumfusion

+circumfusions

+circumjacent

+circumlocutory

+circumlunar

+circumnavigate

+circumnavigated

+circumnavigates

+circumnavigating

+circumnavigation

+circumnavigations

+circumnavigator

+circumnavigators

+circumscissile

+circumscription

+circumstantiality

+circumstantiate

+circumstantiated

+circumstantiates

+circumstantiating

+circumvallate

+circumvallated

+circumvallates

+circumvallating

+circumvallation

+circumvallations

+circumvolution

+circumvolutions

+circusy

+cirque

+cirques

+cirrhoses

+cirrhosis

+cirrhotic

+cirrous

+cirrus

+cislunar

+cist

+cit

+citable

+citational

+citified

+citify

+citizeness

+citral

+citronella

+civically

+civie

+civies

+civilists

+civvy

+clabber

+clack

+clacker

+clackers

+clacks

+cladophora

+clamant

+clamantly

+clambake

+clambakes

+clammily

+clamorist

+clamorist's

+clamorists

+clampdown

+clangorous

+clangorously

+clansman

+clansmen

+clapper

+clappers

+claptrap

+claque

+claques

+clarinetist

+clarinettist

+clarridge

+classicalism

+classicalist

+classicality

+classicism

+classicistic

+classificatorily

+clausal

+claustral

+clavichord

+clavichordist

+clavicular

+clavier

+clavierist

+clavieristic

+claybank

+clayey

+clayish

+clayware

+cleanable

+cleanhanded

+clearable

+clef

+clef's

+clefs

+clemens

+clemente

+clepe

+cleped

+clepes

+cleping

+clericalism

+clericalist

+clerkship

+cleverish

+clevis

+clientage

+cliental

+cliffhanger

+cliffy

+climacteric

+climactically

+climatologist

+climatologists

+climbable

+cline

+clines

+clingy

+clinometric

+clinometry

+clipsheet

+cliquey

+cliquish

+cliquishly

+cliquishness

+clitoral

+clitoric

+clitoris

+cloaca

+cloacal

+cloche

+clocklike

+cloddy

+clodhopping

+cloistral

+cloistress

+clonal

+clonally

+clonic

+clonicity

+clonk

+clonked

+clonking

+clonks

+clop

+clopped

+clopping

+clops

+closable

+closeable

+closefisted

+closemouthed

+closeout

+closetful

+clotheshorse

+clothespin

+clothespress

+cloths

+cloudily

+cloudland

+cloudlet

+cloudlets

+cloven

+cloverleaf

+cloverleaves

+clownery

+clownish

+clownishly

+clownishness

+clubable

+clubbable

+clubber

+clubbier

+clubbiness

+clubby

+clubfoot

+clubfooted

+clueing

+clumpy

+clunk

+clunked

+clunker

+clunking

+clunks

+clustery

+clutchy

+coact

+coaction

+coactive

+coadapted

+coadjutrices

+coadjutrix

+coadunate

+coadunated

+coadunates

+coadunating

+coadunation

+coagulability

+coagulant

+coagulants

+coagulase

+coalification

+coalify

+coalitionist

+coapt

+coaptation

+coaptation's

+coapted

+coapting

+coapts

+coarctate

+coarctation

+coarticulation

+coarticulatory

+coastguard

+coastguardman

+coastguardsman

+coastland

+coastward

+coastwards

+coastwise

+coatrack

+coatroom

+cob

+cob's

+cobaltic

+cobby

+cobelligerent

+cobia

+cobs

+cobwebbed

+cobwebby

+coca

+cocainism

+cocci

+coccidiosis

+cochairman

+cochairmen

+cochise

+cockade

+cockaded

+cockamamie

+cockatrice

+cockerel

+cockfight

+cockfight's

+cockfighting

+cockfights

+cockhorse

+cockily

+cockney

+cockneyish

+cockneyism

+cockneys

+cockshy

+coco

+coconscious

+coconsciousness

+coconspirator

+coconspirators

+cocos

+cocurricular

+codable

+codeclination

+codefendant

+codeine

+codeless

+codeposit

+codetermination

+codex

+codger

+codices

+codicillary

+codifiability

+codling

+codomain

+codominant

+codon

+codpiece

+codpieces

+coeducational

+coeducationally

+coenzyme

+coequality

+coercivity

+coeternal

+coeternally

+coeternity

+coeval

+coevality

+coevolution

+cofeature

+coffeehouse

+coffle

+coffles

+cofunction

+cogency

+cogged

+cogging

+cogitable

+cogito

+cognitional

+cognitivity

+cognomen

+cognoscenti

+cogwheel

+cogwheels

+cohabitant

+cohabitants

+coheir

+coheiress

+cohesionless

+coho

+cohomology

+cohosh

+coidentity

+coif

+coiffeur

+coiffeuse

+coiffing

+coign

+coilability

+coinsurance

+coinsure

+coinsurer

+coition

+coitional

+col

+colasanto

+coldblood

+coldhearted

+coldheartedly

+coldheartedness

+coldish

+coleslaw

+coli

+colic

+colitis

+coll

+collaborationism

+collaborationist

+collaborationists

+collage

+collages

+collagist

+collagists

+collarless

+collaterality

+colleagueship

+colleaguesmanship

+collectable

+collectivism

+collectivist

+collectivistic

+collectivistically

+collectivists

+collectivity

+collectorate

+collectorates

+collectorship

+collegial

+collegiality

+collegially

+collegium

+collet

+collieries

+colliery

+colligate

+colligation

+colligative

+collimator

+collisional

+collisionally

+collocate

+collocates

+collocational

+collodion

+collogue

+collogued

+colloguing

+colloq

+colloquiality

+colloquist

+colloquoy

+colloquy

+collusive

+collusively

+colluvial

+colly

+colog

+cologarithm

+colonelcy

+colonialistic

+colonic

+colophon

+colophony

+colossi

+colossus

+colossuses

+colostomy

+colostral

+colostrum

+coltsfoot

+columbine

+columniation

+columnistic

+colza

+com

+comae

+comaker

+combinability

+combinate

+combinative

+combinatory

+comblike

+combust

+combuster

+combustibility

+combustibly

+combusting

+combustive

+combustor

+combustors

+comedie

+comedienne

+comediennes

+comedown

+cometic

+comfier

+comfit

+comfits

+comfortless

+comfy

+comicality

+comique

+comity

+commandable

+commandership

+commandery

+commemorator

+commemorators

+commendably

+commensal

+commensalism

+commensally

+commensurability

+commensurably

+commentate

+commentates

+commercialist

+commercialistic

+commie

+commination

+comminatory

+comminute

+comminuted

+comminution

+commissar

+commissariat

+commissionaire

+commissionership

+commissural

+commissure

+commix

+commixture

+commode

+commodes

+commonage

+commonalty

+commonsense

+commonsensible

+commonsensibly

+commonsensical

+commonweal

+commove

+commoved

+commoves

+commoving

+communalism

+communalist

+communalists

+communalities

+communality

+communard

+communards

+communese

+communicability

+communicableness

+communicably

+communicatee

+communicatory

+communistically

+communitarian

+communitarianism

+commutator

+commutators

+comoving

+compactible

+compactify

+companionably

+companionate

+companionway

+companionways

+comparatist

+comparativist

+compart

+compartmental

+compartmentation

+compartmentations

+compassable

+compassionless

+compatability

+compatriotic

+compeer

+compellation

+compeller

+compend

+compendious

+compendiously

+compendiousness

+compensability

+compensational

+compensator

+compensators

+compere

+compered

+compering

+competitory

+complacence

+compleat

+complected

+complemental

+complementarily

+comples

+complexation

+complexional

+complexometric

+complexometry

+compliancy

+complicacy

+complice

+complimentarily

+compline

+complot

+compo

+componential

+componentry

+compos

+compoundable

+comprehendible

+comprehensibly

+compressional

+comprisable

+comprisal

+comprisals

+comptrollership

+compulsorily

+compunctious

+compurgation

+compurgations

+compurgator

+computerite

+computerlike

+computernik

+comradery

+comsat

+comsummatively

+concavity

+concealable

+conceivability

+conceivableness

+concentrically

+concentricity

+conceptacle

+conceptional

+conceptualism

+conceptualist

+conceptualistic

+conceptualistically

+conceptus

+concernment

+concertante

+concertgoer

+concerti

+concertmeister

+concessional

+concessionary

+concessive

+concessively

+conciliar

+conciliarly

+concinnity

+concoction

+concomitance

+concordat

+concorde

+concrescence

+concrescences

+concrescent

+concretionary

+concretism

+concretist

+concretistic

+concubinage

+concupiscence

+concupiscent

+concupiscible

+concuss

+concussed

+concusses

+concussing

+concussive

+concussively

+condemnable

+condemnor

+condensable

+condensational

+condescendence

+condign

+condignly

+condimental

+conditionable

+conditionality

+condolatory

+condole

+condoled

+condoling

+condom

+condominial

+condonable

+condonation

+condor

+conductibility

+conductible

+conductimetric

+conductometric

+conductorial

+conductress

+conduplicate

+conduplication

+confab

+confabbed

+confabbing

+confabulator

+confabulatory

+confection

+confectionary

+confectioner

+confectioners

+confections

+confederal

+confederalist

+confederalists

+conferential

+conferment

+conferments

+conferral

+conferrals

+confessable

+confessionalism

+confessionalist

+confetti

+confidante

+confidantes

+configural

+configurate

+configurated

+configurates

+configurating

+configurational

+configurationally

+configurative

+confirmability

+confirmable

+confirmational

+confiscable

+confiscatable

+confiscator

+confiscators

+conflagrant

+conflagrate

+conflagrated

+conflagrates

+conflagrator

+conflagrators

+conflagratory

+conflate

+conflated

+conflates

+conflating

+conflation

+conflations

+conflatrate

+conflatrating

+conflictful

+confliction

+conflictions

+conflictless

+conflictual

+confluence

+confluences

+conflux

+confluxes

+confocal

+conformable

+conformably

+conformism

+confraternities

+confraternity

+confrere

+confreres

+confrontal

+confrontationism

+confrontationist

+confusional

+confutation

+confutations

+confutative

+confutator

+confutators

+cong

+conga

+congealment

+congelation

+congelations

+congener

+conger

+congeries

+conglomeratic

+conglomerator

+conglutinate

+conglutinated

+conglutinates

+conglutinating

+conglutination

+congratulator

+congregant

+congregational

+congregator

+congretants

+congruency

+conicity

+conjugacy

+conjugality

+conjugant

+conjugants

+conjugational

+conjugationally

+conjunctional

+conjunctionally

+conjunctiva

+conjunctival

+conjunctivitis

+conjuration

+conjurations

+conjuror

+connate

+connately

+connatural

+connaturality

+connaturally

+connectable

+connectible

+connectional

+connelly

+conniption

+connivent

+connivery

+connoisseurship

+connotational

+connubialism

+connubiality

+conscienceless

+conscribe

+conscribed

+conscribes

+conscribing

+consecrator

+consecratory

+consecution

+consentaneous

+consentaneously

+conservancy

+conservational

+conservatorial

+consignable

+consignation

+consignee

+consignment

+consignor

+consistorial

+consistory

+consociate

+consociation

+consociational

+consol

+consolatory

+consolette

+consolidator

+consolidators

+consols

+consonancy

+conspecific

+conspectus

+conspectuses

+conspicuity

+conspiration

+conspirational

+conspirations

+constabulary

+constellate

+constellatory

+constipate

+constipated

+constipates

+constipating

+constipation

+constitutionalism

+constitutionalist

+constitutionless

+constringe

+constringed

+constringent

+constringes

+constringing

+construable

+construal

+constructionist

+constructivism

+constructivist

+consubstantial

+consubstantiate

+consubstantiation

+consuetude

+consuetudinary

+consulship

+consultancies

+consultancy

+consultantship

+consultor

+consumerism

+consumerist

+consumership

+consummator

+consummatory

+contagium

+containerboard

+contaminator

+contemplator

+contemporaneity

+contemporarily

+contemptibly

+contendere

+conterminous

+conterminously

+contestation

+contexture

+contingence

+continua

+continuate

+continuated

+continuates

+continuating

+continuative

+continuatively

+continuator

+continuo

+contortionist

+contortionistic

+contortionists

+contrabandist

+contrabassist

+contrabassoon

+contractibility

+contractible

+contractile

+contractility

+contractional

+contracture

+contradictable

+contradictious

+contradictor

+contradistinct

+contradistinctive

+contradistinctively

+contradistinguish

+contrail

+contralateral

+contralto

+contraoctave

+contraposition

+contrapuntal

+contrapuntally

+contrapuntist

+contrarieties

+contrariety

+contrarious

+contrariwise

+contrastable

+contrasty

+contravariant

+contretemps

+controllership

+controllerships

+controlment

+controlments

+controversialism

+controversialist

+controvert

+controverted

+controverter

+controverting

+controverts

+contumacious

+contumaciously

+contumelious

+contumeliously

+contuse

+contused

+contuses

+contusing

+conurbation

+conurbations

+convect

+convected

+convecting

+convectional

+convective

+convector

+convectors

+convects

+conveniency

+conventicle

+conventicler

+conventionalism

+conventionalist

+conventioneer

+conventual

+conventually

+convergency

+conversable

+conversance

+conversancy

+conversional

+convertibly

+convertiplane

+convertor

+conviviality

+convocate

+convocational

+convolutional

+convulsant

+convulsionary

+cony

+cooch

+cookout

+cookouts

+cookshack

+cookshop

+cookware

+coolish

+coomb

+coombs

+coonskin

+cooperage

+cooperationist

+coot

+cootie

+copacetic

+coparcenary

+coparcener

+copartner

+copartnership

+copeck

+copemate

+copesetic

+copesmate

+copestone

+copilot

+coplanarity

+copliots

+copperas

+copperplate

+coppice

+copping

+copra

+coprinus

+coprocessor

+coprocessor's

+coprocessors

+coproduct

+coproduct's

+coproducts

+coprolite

+coprolitic

+copula

+copulas

+copulate

+copulated

+copulates

+copulating

+copulation

+copulative

+copulatively

+copulatory

+copyboy

+copycat

+copycats

+copycatted

+copycatting

+copydesk

+copyhold

+copyholder

+copyreader

+coquet

+coquetry

+coquettish

+coquettishly

+coquettishness

+coquina

+coralberry

+coralline

+corbel

+cordate

+cordately

+cordiality

+cordiform

+cordless

+cordwain

+cordwainer

+cordwainery

+cordwood

+corecipient

+corelate

+corelation

+coreligionist

+corequisite

+corespondent

+corkboard

+corkboards

+corkier

+corky

+cornball

+corncob

+corncrib

+corneal

+corneous

+cornerman

+cornerways

+cornerwise

+cornetist

+cornettist

+cornhusking

+cornice

+corniced

+cornices

+corniche

+cornicing

+cornification

+cornily

+cornstalk

+cornucopian

+cornwallis

+corolla

+corollate

+coronagraph

+coronograph

+corpocracies

+corpocracy

+corpora

+corporality

+corporatism

+corporatist

+corporativism

+corporator

+corporeity

+corporis

+corposant

+corpulencies

+corpulency

+corpuscle

+corpuscle's

+corpuscles

+corpusculated

+corpuscule

+corpuscules

+corrade

+corraded

+corrading

+corrasion

+corrasions

+corrasive

+correctional

+correctitude

+correlatable

+correlational

+correspondency

+corresponsive

+corrigenda

+corrigibility

+corrigibly

+corroborant

+corroborator

+corroborators

+corroboratory

+corroboree

+corruptibility

+corruptibly

+corruptionist

+corsair

+corse

+corsica

+corsican

+cortege

+corteges

+corticate

+corticated

+cortices

+corticoid

+corvallis

+cos

+cosec

+coset

+cosh

+cosher

+cosigner

+cosmetician

+cosmeticians

+cosmetologist

+cosmetologists

+cosmetology

+cosmo

+cosmochemical

+cosmochemistry

+cosmogenic

+cosmogonic

+cosmogonical

+cosmogonist

+cosmogony

+cosmographer

+cosmographic

+cosmographical

+cosmographically

+cosmography

+cosmologic

+cosmonaut

+cosmopolite

+cosmopolitism

+cosponsorship

+cosset

+cosseted

+cosseting

+cossets

+costa

+costal

+costless

+costlessly

+costmary

+costumery

+costumey

+costumier

+cote

+coterie

+coteries

+cotillon

+cotman

+cotoneaster

+cotta

+cottagey

+cottontail

+cottontail's

+cottontails

+cotty

+couldst

+councilmanic

+countability

+countdown

+countdown's

+countdowns

+counteraction

+counterblow

+counterchallenge

+counterchange

+countercheck

+countercurrent

+countercurrently

+counterespionage

+counterfoil

+counterintelligence

+counterirritant

+countermarch

+countermove

+countermovement

+counteroffensive

+counteroffer

+counterpane

+counterplan

+counterplea

+counterplot

+counterpose

+counterposed

+counterposes

+counterposing

+counterpunch

+counterpuncher

+counterreformation

+counterrevolutionaries

+counterrevolutionary

+counterrevolutionary's

+counterrevolutionist

+countershaft

+countershafts

+countersign

+countersignature

+counterspy

+counterstatement

+countertenor

+countertenors

+counterterrorism

+counterterrorist

+counterthreat

+counterthreat's

+counterthreats

+countertrend

+counterview

+countryfied

+countryish

+countryseat

+countrywoman

+countywide

+coupal

+couplement

+courtmartial

+couscous

+cousinage

+cousinhood

+cousinship

+couth

+couture

+couturier

+couturiere

+covalence

+covalency

+covenantal

+covenantee

+covenantor

+covent

+coventry

+coverless

+coverture

+covertures

+covetable

+covey

+coveys

+cowage

+cowbane

+cowcatcher

+cowman

+cowmen

+cowpea

+cowry

+cox

+coypu

+cozily

+cpr

+crabber

+crabbier

+crabby

+crabwise

+crackajack

+crackdown

+crackerjack

+craftily

+craftsmanlike

+craftsperson

+craftswoman

+craftswomen

+cragged

+craggily

+cragsman

+crammer

+crampon

+crampon's

+crampons

+craneman

+cranemen

+cranial

+cranially

+craniate

+crape

+crapper

+crapping

+crappy

+crapshooter

+crapulous

+crashworthiness

+crashworthy

+crassitude

+craterlet

+crayonist

+creakily

+creamily

+creaseless

+creatural

+creaturehood

+creche

+creches

+creditability

+cree

+creepage

+creese

+creighton

+crematorium

+crenate

+crenated

+crenately

+crenation

+crenelle

+crenulate

+crenulated

+crenulation

+creosol

+creosote

+crepey

+crepitant

+crepitate

+crepitation

+crepuscle

+crepuscular

+crepuscule

+crepy

+crescentic

+crescive

+crescively

+cresol

+cresset

+crestal

+crestless

+cretinism

+cretonne

+crevasse

+crewelwork

+crewless

+crewmember

+crewmembers

+cribbage

+cribbage's

+cribber

+cribriform

+crick

+criminate

+criminating

+crimination

+criminological

+criminologically

+criminologist

+criminology

+criminous

+crimpier

+crimpy

+crinoid

+crinoline

+crispier

+crispiness

+crispy

+criticaster

+croaky

+croatian

+crocket

+crocketed

+crocodilian

+croissant

+croissants

+cronyism

+crookback

+crookbacked

+cropland

+cropland's

+croplands

+croquet

+croquette

+crore

+crossability

+crossbearer

+crossbill

+crossbones

+crossbow

+crossbowman

+crossbred

+crossbreed

+crosscurrent

+crosscurrents

+crosscut

+crosslet

+crosslink

+crosslink's

+crosslinks

+crosspatch

+crosspiece

+crosstown

+crosstree

+crosswind

+crotchet

+crotcheted

+crotcheting

+crotchets

+croton

+croup

+croupous

+croupy

+crouse

+crouton

+crowberry

+crowfeet

+crowkeeper

+crownet

+cruciate

+cruciately

+crucifer

+cruciferous

+cruciform

+cruciformly

+crudded

+crudding

+crueller

+cruellest

+cruet

+cruller

+crumbier

+crumby

+crumpet

+crupper

+crustacea

+crustaceous

+crustal

+crustier

+crustification

+crustily

+crustiness

+crustose

+crusty

+crybaby

+crymotherapy

+cryobiological

+cryobiologically

+cryobiologist

+cryobiologists

+cryobiology

+cryogen

+cryogenically

+cryogeny

+cryolite

+cryonic

+cryonics

+cryophilic

+cryoscope

+cryoscopic

+cryoscopy

+cryosurgery

+cryotherapy

+cryotron

+cryptal

+cryptical

+cryptically

+crypto

+cryptogenic

+cryptogrammic

+cryptograph

+cryptographically

+cryptos

+cryst

+cubage

+cubature

+cubbies

+cubby

+cubical

+cubically

+cubicle

+cubiform

+cubistic

+cubit

+cuboid

+cuboidal

+cuckold

+cuckoldry

+cucullate

+cucullated

+cucullates

+cucurbit

+cuddleback

+cuddlesome

+cuddy

+cueing

+cuffless

+cuke

+culation

+cullender

+culminant

+culotte

+culottes

+culpably

+cultch

+cultic

+cultigen

+cultism

+cultivability

+cultivar

+cultivars

+cultivatable

+cumbrous

+cumbrously

+cumbrousness

+cumulous

+cunctation

+cunctative

+cuneate

+cuneately

+cuneiform

+cunner

+cunnilinctus

+cunnilingus

+cunt

+cupbearer

+cupcake

+cuplike

+cupola

+cuppier

+cuppy

+cupreous

+cupriferous

+cuprite

+cupsful

+cupular

+cupulate

+cupule

+curability

+curatorial

+curatorship

+curbstone

+cureless

+curet

+curettage

+curette

+curetted

+curettement

+curetting

+curite

+curium

+curlew

+curmudgeon

+curmudgeonly

+curricle

+currie

+curriery

+currish

+currishly

+cursorial

+curst

+curtailment

+curtal

+curtesy

+curtilage

+curule

+curvacious

+curveball

+curvilineal

+curvy

+cushily

+cushionless

+cushiony

+cuspate

+cuspated

+cuspid

+cuspidate

+cuspidated

+cuspidation

+cuspidor

+cussword

+cusswords

+custodianship

+custodianships

+customshouse

+cutability

+cutaround

+cutaway

+cutch

+cutesy

+cutey

+cuteys

+cuticle

+cuticles

+cuticular

+cutie

+cutler

+cutlery

+cutline

+cutover

+cutpurse

+cutset

+cuttable

+cutup

+cutups

+cutwater

+cutwork

+cybernated

+cybernation

+cybernetical

+cybernetically

+cybernetician

+cyberneticist

+cyborg

+cycad

+cyclamate

+cyclitol

+cyclo

+cycloaddition

+cyclometer

+cyclometer's

+cyclometers

+cyclonic

+cyclonically

+cyclorama

+cyclos

+cyclotomic

+cyclotron

+cygnet

+cygnet's

+cygnets

+cymbalist

+cymbalists

+cynosure

+cypher

+cyphers

+cystamine

+cysteine

+cystic

+cytaster

+cytokinin

+cytologic

+cytological

+cytologically

+cytologist

+cytolysin

+cytolytic

+cytopathogenicity

+cytophilic

+cytoplasmic

+cytoplasmically

+cytosine

+cytostatic

+cytostatically

+cytotoxicity

+cytotoxin

+cytotropic

+dabber

+dabbers

+dachshunde

+dactylus

+daedal

+daff

+daft

+dafter

+daftest

+daftly

+daftness

+daggerman

+daguerreotype

+daguerreotype's

+daguerreotypes

+daguerreotypic

+daguerreotypy

+dahlia

+dahlias

+daimon

+daimones

+daimonic

+daimons

+daiquiri

+daiquiris

+dairymaid

+daishiki

+dali

+dalliance

+dalloway

+dallyes

+dalmatian

+dalmatians

+dalmatic

+damnable

+damnableness

+damnably

+damnatory

+damndest

+damnify

+dampish

+damselflies

+damselfly

+danceability

+danceable

+dander

+dandiacal

+dandiacally

+dandification

+dandify

+dandle

+dandled

+dandling

+dandruff

+dandruffy

+dandyish

+dandyishly

+dandyism

+dandys

+danseur

+daphnia

+daredevil

+daredevilry

+daredevils

+daredeviltry

+dareful

+daresay

+darkish

+darkle

+darkroom

+darkrooms

+darksome

+darlington

+darrow

+darry

+datable

+datamedia

+dataswitch

+dataswitches

+datcap

+dateable

+dateless

+datetime

+datura

+daughterless

+dauphin

+dauphine

+davit

+daybook

+daydreamlike

+daylong

+daymare

+dayroom

+dayrooms

+daystar

+db

+de

+deacidification

+deacidify

+deactivator

+deadbeat

+deadeye

+deadfall

+deadlight

+deadpan

+deadpanner

+deaerate

+deaerates

+deaeration

+dealate

+dealated

+dealates

+dealation

+dealership

+deaminate

+deamination

+deanery

+deanship

+deathblow

+deathless

+deathlessly

+deathlessness

+deathsman

+deathwatch

+debark

+debarkation

+debarks

+debarment

+debasement

+debatement

+debator

+debators

+debauchee

+debone

+deboner

+debones

+deboning

+debouch

+debouchment

+debouchure

+debtless

+debutant

+decadency

+decagon

+decagram

+decahedron

+decalcification

+decalcify

+decalcomania

+decalescence

+decalogue

+decalogues

+decametric

+decamp

+decampment

+decamps

+decanol

+decantation

+decapitate

+decapitates

+decapitating

+decapitation

+decapitator

+decapod

+decapod's

+decapods

+decarbonate

+decarbonated

+decarbonates

+decarbonating

+decarbonation

+decarbonator

+decasyllabic

+decasyllable

+deceivable

+deceivableness

+decelerator

+decennium

+deceptional

+decerebrate

+decerebrated

+decerebrates

+decerebrating

+decerebration

+deciare

+decidua

+decidual

+deciduate

+decillion

+decipherable

+decipherment

+decistere

+deckhand

+deckhouse

+deckle

+declarable

+declarant

+declass

+declasse

+declensional

+declensionally

+declinable

+declinate

+declinational

+declivitous

+decoct

+decocted

+decocting

+decoction

+decoctions

+decocts

+decollate

+decollated

+decollates

+decollating

+decollation

+decollations

+decolonise

+decommission

+decompensate

+decompensation

+decompensatory

+deconcentrate

+deconcentrator

+decondition

+decongest

+decongestant

+decongestion

+decongestive

+deconsecrate

+deconsecration

+decontaminate

+decontaminates

+decontaminating

+decontamination

+decontaminations

+deconvolution

+deconvolve

+decorticator

+decorticators

+decoupage

+decoupages

+decremental

+decrepid

+decrepit

+decrepitate

+decrepitation

+decrepitly

+decrepitude

+decrescendo

+decrescent

+decretal

+decretals

+decretive

+decretory

+decrial

+decrials

+decryptograph

+decsystem

+dectape

+decumbent

+decuple

+decurved

+decussate

+decussately

+decussation

+decwriter

+dedicator

+dedicatory

+dedifferentiate

+dedifferentiated

+dedifferentiation

+deedless

+deejay

+defalcate

+defalcation

+defalcator

+defamation

+defamatory

+defat

+defeasance

+defeasibility

+defeasible

+defeature

+defeatured

+defeatures

+defeaturing

+defector

+defector's

+defectors

+defendable

+defensibility

+defensibly

+deferential

+deferentially

+deferral

+defervescence

+defervescences

+defervescent

+defial

+defibrillation

+defibrillator

+defilement

+definably

+definement

+definitude

+deflagrate

+deflagrated

+deflagrates

+deflagrating

+deflagration

+deflationary

+deflator

+deflexed

+defloration

+deflorations

+deflower

+defoamer

+defoamers

+defoe

+defoliant

+defoliate

+defoliated

+defoliates

+defoliating

+defoliation

+defoliator

+deforce

+deforcement

+deforciant

+deforest

+deforester

+deformative

+defraudation

+defrayable

+defrayal

+defrayals

+defrock

+defuse

+defused

+defusing

+defyed

+defys

+degas

+degassing

+degauss

+degaussed

+degausses

+degaussing

+degeneracy

+degranulation

+degressive

+degressively

+dehydrase

+dehydrator

+deism

+deist

+deistic

+deistical

+deistically

+dejeuner

+dejeuners

+delaminate

+delamination

+delate

+delated

+delates

+delating

+delation

+delator

+delectability

+delectably

+delectate

+delegacy

+delft

+delict

+delightsome

+delightsomely

+delimitate

+delimitative

+delineament

+delineaments

+delineator

+deliquesce

+deliquescent

+delist

+deliverability

+dellwood

+delphine

+delphinium

+deltaic

+delusional

+delusionary

+delusory

+demagog

+demagogic

+demagogical

+demagogically

+demagogism

+demagoguery

+demagogy

+demandable

+demandant

+demantoid

+demark

+demarkation

+dementia

+demential

+demi

+demigoddess

+demijohn

+demission

+demitasse

+demiurge

+democratique

+demographiques

+demolishment

+demolitionist

+demoniacal

+demoniacally

+demonian

+demonical

+demonically

+demonology

+demonstrability

+demonstrational

+demonstrationist

+demotic

+demount

+demounted

+demounting

+demounts

+demulcent

+demure

+demurely

+demureness

+demurrage

+demurral

+demystified

+demystifies

+demystify

+demystifying

+denaturant

+denaturation

+denaturational

+denazification

+denazify

+dendriform

+dendrite

+dendrite's

+dendrites

+dendritic

+dendroid

+dendrologic

+dendrological

+dendrologist

+dendrology

+deneen

+denegation

+denervate

+denervated

+denervates

+denervating

+denervation

+denigrator

+denigratory

+denitrification

+denitrify

+denominational

+denominationalism

+denominationalist

+denotement

+denouncement

+densification

+densify

+densimeter

+densimeter's

+densimeters

+densimetric

+dentate

+dentated

+dentately

+dentation

+denticle

+denticulate

+denticulated

+denticulately

+denticulation

+dentiform

+dentifrice

+dentigerous

+dentil

+dentin

+dentinal

+dentine

+dentition

+dentulous

+denudation

+denudational

+denudement

+denumerably

+denunciatory

+denys

+deontological

+deontologist

+deontology

+deoxidation

+deoxycholate

+deoxygenation

+deoxyribose

+depigmentation

+depilate

+depilated

+depilates

+depilating

+depilation

+depilatory

+deplane

+deplaned

+deplanes

+deplaning

+depletable

+depone

+deponed

+deponent

+depones

+deponing

+depopulate

+depopulation

+depopulator

+deportable

+depositional

+depravation

+depravations

+depravement

+deprecatorily

+depreciator

+depreciators

+depreciatory

+depredate

+depredated

+depredates

+depredating

+depredation

+depredator

+depredators

+depredatory

+depressily

+depressor

+depthless

+derailment

+derate

+derating

+deration

+derisory

+derivational

+derma

+dermal

+dermatoid

+dermatologic

+dermatological

+dermatologist

+dermatology

+dermatosis

+derogatorily

+derrickman

+derrickmen

+desalination

+desalting

+descendible

+descension

+descrating

+desecrator

+desertic

+desex

+deshabille

+desiccant

+desiccate

+desiccated

+desiccates

+desiccation

+desiccative

+desiccator

+desiderate

+desideration

+desiderative

+designatory

+designee

+designment

+desistance

+deskman

+desolator

+desorb

+desorbable

+desorbed

+despicable

+despicableness

+despisement

+despiteful

+despitefully

+despitefulness

+despiteous

+despiteously

+despoilment

+despondence

+despondences

+despotically

+destructibility

+destructible

+destructionist

+destructivity

+desultorily

+detab

+detachability

+detachably

+detainee

+detainment

+detectability

+detectaphone

+detent

+determent

+determents

+determinably

+determinantal

+determinator

+determinist

+deterrer

+detestably

+dethrone

+dethronement

+detinue

+detonabilities

+detonability

+detonatable

+detonational

+detoxicant

+detoxicants

+detoxicate

+detoxicated

+detoxicates

+detoxicating

+detoxication

+detoxicator

+detoxification

+detoxified

+detoxifies

+detoxify

+detoxifying

+detraction

+detractions

+detrain

+detrained

+detraining

+detrainment

+detrains

+detritus

+detumescence

+detumescences

+detumescent

+deuterate

+deuterated

+deuterates

+deuterating

+deuteration

+deuterations

+deuteron

+deuteron's

+devaluate

+devaluations

+devastator

+devastators

+developable

+deverbative

+devest

+deviancies

+deviancy

+deviationism

+deviationist

+deviator

+deviators

+devilkin

+devilment

+devilments

+devilry

+deviltry

+devisability

+devisable

+devisal

+devisee

+devisor

+devitrification

+devitrify

+devoir

+devoirs

+devolution

+devolutionary

+devolutionist

+devotement

+dewater

+dewatered

+dewaterer

+dewatering

+dewaters

+dewily

+deworm

+dexedrine

+dexterous

+dexterously

+dexterousness

+dextral

+dextrality

+dextrally

+dextrine

+dextro

+dextrose

+dextrose's

+dey

+dharma

+diabolism

+diabolist

+diachronically

+diachrony

+diaconal

+diaconate

+diacritic

+diacritic's

+diacritics

+diadromous

+diagnoseable

+diagnostical

+diagnostically

+diagrammatical

+diakinesis

+diakinetic

+dialectician

+dialecticians

+dialectological

+dialectologically

+dialectologist

+dialectology

+dialogic

+dialogical

+dialogically

+dialogist

+dialogistic

+dialup

+dialup's

+dialups

+dialytic

+diamagnet

+diamagnetism

+diamagnets

+diametral

+diametrical

+dianne

+diapason

+diapause

+diapausing

+diaphaneity

+diaphone

+diaphragmatic

+diaphragmatically

+diaphragmic

+diapositive

+diarchy

+diarist

+diaspora

+diaspore

+diastole

+diastolic

+diastrophic

+diastrophically

+diastrophism

+diathermic

+diathetic

+diation

+diatomaceous

+diatomite

+diatonically

+diatropic

+diatropism

+diatropisms

+dibble

+dibs

+dicarboxylic

+dicey

+dichondra

+dichotic

+dichotically

+dichotomist

+dichroic

+dichroism

+dichroitic

+dichromat

+dichromate

+dichromatic

+dichromatism

+dichromats

+dicier

+dickcissel

+dicta

+dictionally

+dicyclic

+didact

+didactical

+didactically

+didacticism

+dieing

+diel

+dieldrin

+dieresis

+dietarily

+dietetically

+diety

+dieu

+dieux

+diffeomorphic

+diffeomorphism

+differentia

+diffusional

+difluoride

+digamma

+digenesis

+digenetic

+digestibility

+digitalin

+digitate

+digitated

+digitately

+digitation

+digitigrade

+digitonin

+digressional

+digressionary

+dihybrid

+dihydroxy

+dijon

+dilapidator

+dilatability

+dilatable

+dilatational

+dilatometer

+dilatometer's

+dilatometers

+dilatometric

+dilatometry

+dilatorily

+dildo

+dildos

+dilemmatic

+dilemmatical

+dilettanti

+dilettantish

+dilettantism

+dilettantist

+dillydally

+diluent

+dilutor

+diluvial

+dimaggio

+dimeric

+dimerism

+dimerous

+dimeter

+dimeter's

+dimeters

+dimethoxymethane

+diminishable

+diminishment

+diminuendo

+diminuendo's

+diminuendos

+diminutional

+dimmable

+dimorphic

+dimorphism

+dimorphous

+dimout

+dimply

+dimwit

+dimwits

+dimyristoyl

+dinette

+dingbat

+dingbats

+dingdong

+dingily

+dingle

+dinkey

+dinnerless

+dinning

+dinosaurian

+dinosauric

+diogenes

+dion

+dioptometer

+dioptometer's

+dioptometers

+dioptometry

+dioptric

+dioptrics

+dioramic

+diorite

+diphase

+diphasic

+diphenyl

+diphtherial

+diphtherian

+diphtheritic

+diphtheroid

+diphthongal

+diplex

+diploid

+diploid's

+diploids

+diploidy

+diplomate

+diplomatically

+diplomatist

+dipod

+dipolar

+dipperful

+dipropellant

+dipsomania

+dipsomaniac

+dipsomaniacal

+dipstick

+diptych

+directionless

+directorial

+dirigible

+dirigibles

+disaccharide

+disaccharides

+disaccord

+disaccustom

+disadvantageous

+disadvantageously

+disadvantageousness

+disaffect

+disaffirm

+disaffirmance

+disaffirmation

+disagreeability

+disagreeably

+disallowance

+disannul

+disapprovative

+disarrange

+disarrangement

+disarranges

+disarticulate

+disarticulation

+disassociate

+disassociated

+disassociates

+disassociating

+disassociation

+disavowable

+disbandment

+disbarment

+disburden

+disburdenment

+discardable

+discernable

+dischargeable

+dischargee

+disciform

+disciplinable

+disciplinal

+disciplinarian

+disciplinarily

+disciplinarity

+disclamation

+disco

+disco's

+discographer

+discographic

+discographical

+discographically

+discography

+discoid

+discoidal

+discoidin

+discombobulate

+discomfiture

+discomfitures

+discomfortable

+discomfortably

+discommend

+discommendable

+discommendation

+discommode

+discommodes

+discommoding

+discompose

+discomposed

+discomposedly

+discomposure

+disconfirm

+disconfirmation

+disconform

+disconformable

+disconformity

+disconsolate

+disconsolately

+disconsolateness

+disconsolation

+discontentment

+discophile

+discordance

+discordances

+discordancy

+discos

+discountenance

+discourageable

+discourtesy

+discoverable

+discreditable

+discreditably

+discriminability

+discriminably

+discriminational

+discriminator

+discriminatorily

+discriminators

+discussable

+discussible

+disembark

+disembarkation

+disembarrass

+disembodiment

+disembody

+disembowelment

+disenchant

+disenchanter

+disenchanting

+disenchantingly

+disencumber

+disencumbrance

+disendow

+disendower

+disendowment

+disentanglement

+disenthralled

+disenthralling

+disequilibrate

+disequilibration

+disestablish

+disestablished

+disestablishment

+disestablishmentarian

+disesteem

+disestimation

+disfeature

+disfeaturement

+disfigurement

+disfigurements

+disfranchise

+disfranchised

+disfranchisement

+disfranchises

+disfranchising

+disfrock

+disfunction

+disfurnish

+disfurnishment

+disgorgement

+disgruntlement

+disguisement

+dishabille

+disharmonic

+disharmonious

+dishcloth

+disheartenment

+disheartenments

+dishrack

+dishracks

+dishy

+disincentive

+disincline

+disinclined

+disinclines

+disinclining

+disinfect

+disinfectant

+disinfectants

+disinfected

+disinfecting

+disinfection

+disinfects

+disinfest

+disinfestant

+disinfestation

+disinfested

+disinfesting

+disinfests

+disinflation

+disinflationary

+disingenuous

+disingenuously

+disingenuousness

+disinhibition

+disinhibitory

+disinsectization

+disintegrator

+disintegrators

+disinter

+disintered

+disintering

+disinterment

+disinters

+disintoxication

+disinvest

+disinvestment

+disjuncture

+disklike

+dislicense

+dislicensed

+dislicenser

+dislicenses

+dislicensing

+dislikable

+dislikably

+dislikeable

+dislimn

+dismantlement

+dismast

+dismember

+dismembering

+dismission

+disoblige

+disobliger

+disoblingingly

+disorient

+disorientation

+disownment

+dispart

+dispassion

+dispensability

+dispensable

+dispensational

+dispensatory

+dispeople

+dispersant

+dispirit

+dispirited

+dispiritedly

+dispiritedness

+dispiriting

+dispirits

+dispiteous

+displaceable

+displant

+displode

+disploded

+displodes

+disploding

+displosion

+disport

+disportment

+disporves

+disposability

+dispositive

+dispossess

+dispossesses

+dispossessing

+dispossessor

+disposure

+disposures

+dispraise

+dispraiser

+dispraisingly

+dispread

+disprize

+disproof

+disprovable

+disputation

+disputatious

+disputatiously

+disputatiousness

+disquantity

+disraeli

+disrate

+disregardful

+disrelate

+disrelated

+disrelation

+disrelish

+disremember

+disremembrance

+disreputability

+disreputably

+disrespectability

+disrespectable

+disrespectful

+disrespectfully

+disrespectfulness

+dissatisfactory

+dissatisfies

+dissatisfy

+dissatisfying

+dissector

+disseminator

+disseminators

+dissentient

+dissention

+dissert

+dissertate

+dissertator

+disserve

+dissever

+disseverance

+disseverment

+dissidence

+dissimilate

+dissimilated

+dissimilates

+dissimilating

+dissimilation

+dissimilative

+dissimilatory

+dissimilitude

+dissimulate

+dissimulator

+dissociability

+dissocial

+dissociant

+dissolubility

+dissoluble

+dissolute

+dissolutely

+dissoluteness

+dissolvable

+dissolvent

+dissuasion

+dissuasive

+dissuasively

+dissuasiveness

+dissyllable

+dissymmetric

+dissymmetry

+distemperate

+distemperature

+distensibility

+distensible

+distent

+distention

+distinguishability

+distinguishably

+distortional

+distractibility

+distractible

+distrain

+distrainable

+distrainer

+distrainor

+distraint

+distrait

+distressful

+distressfully

+distressfulness

+distributary

+distributee

+distrustful

+distrustfully

+distrustfulness

+disubstituted

+disunionist

+disunite

+disutility

+disvalue

+disyllabic

+dithery

+divagate

+divagation

+divaricate

+divarication

+divergencies

+divergency

+diversionist

+divertissement

+divertissements

+divestment

+dividable

+divinatory

+divisibility

+divisionism

+divisionist

+divorcement

+divot

+divulgence

+divulsion

+divvy

+dixiecrats

+dobbin

+doberman

+dobson

+doc

+docent

+docetic

+docility

+dockage

+dockhand

+dockworker

+doctorless

+doctorship

+doctrinairism

+documental

+documentale

+documentalist

+documentarian

+documentarily

+documentarist

+documentational

+dodder

+doddered

+dodderer

+doddering

+dodders

+doddery

+dodecyl

+dodgery

+dodgy

+dodington

+dodo

+dodo's

+dodos

+dogbane

+dogberry

+dogcart

+dogcatcher

+doge

+dogface

+dogfight

+dogfights

+dogfish

+doggerel

+doggery

+doggie

+doggier

+doggies

+doggish

+doggishly

+doggishness

+doggy

+doglike

+dogmatical

+dogmaticalness

+dogmatist

+dogmatist's

+dogmatists

+dogwatch

+doilies

+doily

+doit

+doited

+dolce

+dolesome

+dollhouse

+dollish

+dollishly

+dollishness

+dollop

+dollop's

+dolloped

+dolloping

+dollops

+dolorous

+dolorously

+dolorousness

+domical

+domicil

+domiciliary

+domiciliate

+domiciliation

+dominical

+dona

+donator

+donee

+doneness

+dong

+donner

+donut

+doodad

+doodlebug

+doohickey

+doomful

+doomfully

+doomsayer

+doomster

+doorjamb

+doorless

+doormat

+doornail

+doorplate

+doorpost

+doorsill

+doorstop

+dooryard

+dopester

+dopey

+dopier

+dopiness

+doppelganger

+dopy

+dormancy

+dormice

+dormie

+dormouse

+dormouse's

+dormy

+dosimetric

+doss

+dossal

+dosser

+dotal

+dotter

+dotterel

+dottier

+dottily

+dottiness

+dotty

+doublespeak

+doublethink

+doubletree

+douce

+douche

+doughboy

+doughface

+doughier

+doughlike

+doughnuttery

+doughtier

+doughtily

+doughtiness

+doughty

+doughy

+dovecot

+dovecote

+dovekie

+dovish

+dovishness

+dowdily

+dowdyish

+dowitcher

+downcourt

+downhaul

+downhearted

+downheartedly

+downheartedness

+download

+downloaded

+downloading

+downloads

+downrange

+downriver

+downshift

+downstage

+downstate

+downstater

+downstroke

+downswing

+downtime

+dozier

+doziness

+dozy

+drabber

+drabbest

+drabbing

+drabble

+drabbled

+drabbling

+draftable

+draggier

+draggle

+draggled

+draggling

+draggy

+dragline

+dragonet

+dragonish

+dragster

+drainpipe

+drainpipes

+dramalogue

+dramamine

+dramaturge

+dramaturgic

+dramaturgical

+dramaturgically

+dramshop

+drapability

+drapable

+drapeability

+drapeable

+drat

+dratted

+dratting

+drawable

+drawbar

+drawdown

+drawee

+drawerful

+drawknife

+drawnwork

+drawplate

+drawstring

+drawstring's

+drawstrings

+drawtube

+dray

+drayage

+drayman

+drayman's

+draymen

+draymen's

+dreamful

+dreamfully

+dreamfulness

+dreamland

+dreamworld

+drear

+drearily

+dreck

+dressage

+dressmake

+driblet

+driftage

+driftier

+driftweed

+driftwood

+driftwood's

+drifty

+drillability

+drillable

+drillmaster

+drinkability

+dripless

+dripper

+drivable

+driveable

+drivel

+driveline

+driverless

+drolleries

+drollery

+drolly

+dropkick

+dropkicker

+droplight

+droppage

+dropperful

+dropshot

+dropsy

+drossy

+droughtiness

+droughty

+drouth

+drownd

+drownded

+drownding

+drubber

+drugget

+drugmaker

+druidess

+druidic

+druidical

+druidism

+drumbeat

+drumbeater

+drumbeating

+drumfire

+drumlike

+drumlin

+drumroll

+drumstick

+drumsticks

+drunkometer

+drunkometer's

+drunkometers

+drupe

+dryable

+dryad

+dryasdust

+drylot

+drypoint

+drys

+drysalter

+drysaltery

+du

+dualist

+dualistic

+dualistically

+dubber

+dubbing

+dubiety

+dubiosity

+dubitable

+dubitation

+dubuque

+ducal

+ducally

+duckbill

+duckbilled

+duckboard

+duckfooted

+duckier

+duckpin

+duckweed

+duckweed's

+duckweeds

+ducky

+duclos

+ductility

+ductless

+ductule

+dudgeon

+dudish

+dudishly

+duende

+duenna

+duennaship

+duetted

+duetting

+duffle

+dugong

+dulcimer

+dulcimore

+dulgence

+dulles

+dullish

+dullishly

+dullsville

+dulness

+dulse

+dumbstruck

+dumbwaiter

+dumbwaiters

+dumdum

+dumka

+dumpily

+dumpish

+dumpling

+dumpling's

+dumplings

+dumpo

+dumpster

+dumpster's

+dumpsters

+dunderhead

+dunderheaded

+duneland

+dunelike

+dungaree

+dunghill

+dungy

+dunkel

+dunne

+duo

+duodecimal

+duodecimo

+duodenal

+duodenum

+duologue

+duomo

+duomos

+duopolistic

+duos

+dupery

+duple

+duplicitous

+duplicitously

+dupont

+duponts

+durance

+durometer

+durometer's

+durometers

+duros

+duskily

+dustcover

+dustheap

+dustily

+dustin

+dustless

+dustlike

+dustman

+dustpan

+dustpans

+dustup

+dutchess

+duteous

+duverger

+dwarfishly

+dwarfishness

+dwarfism

+dwarflike

+dyadically

+dyarchy

+dyeability

+dyeable

+dyerear

+dyestuff

+dyewood

+dynamist

+dynamistic

+dynamitic

+dynamometer

+dynamometer's

+dynamometers

+dynamometric

+dynamometry

+dynamotor

+dynapolis

+dynast

+dynastically

+dynasts

+dynatron

+dyne

+dynode

+dynodes

+dysenteric

+dysfunction

+dysfunctional

+dysgenesis

+dysgenic

+dysgenics

+dyslexia

+dyslexic

+dyslogistic

+dyslogistically

+dyspepsia

+dyspeptically

+dysphagia

+dysphagic

+dysphasia

+dysphasic

+dysphonia

+dysphonic

+dysphoria

+dysphoric

+dysplasia

+dysplastic

+dystrophic

+eV

+eaglet

+eagre

+earache

+eardrop

+eardrops

+earflap

+earful

+earldom

+earlobe

+earlock

+earmuff

+earmuffs

+earp

+earpiece

+earplug

+earthborn

+earthbound

+earthily

+earthlike

+earthling

+earthshaker

+earthshaking

+earthshakingly

+earthshine

+earthstar

+earthward

+earthwards

+earthwork

+earthworks

+earwax

+earwig

+earwigged

+earwigging

+earwitness

+easeful

+easefully

+easthampton

+eastwick

+easure

+eatery

+ebullience

+ebulliency

+ebullition

+eccentrically

+ecclesial

+ecclesiasticism

+ecclesiological

+ecclesiology

+ecdysiast

+ecdysis

+ecesis

+ech

+echidna

+echinulate

+echinulation

+echoey

+echoic

+echolocation

+eclat

+eclecticism

+eclogue

+eclosion

+ecol

+ecologic

+ecologist

+econometrically

+econometrician

+econometrist

+ecophysiological

+ecophysiology

+ecospecies

+ecospecific

+ecosphere

+ecotone

+ecotype

+ecotypic

+ecotypically

+ecru

+ecstatically

+ectoblast

+ectoblastic

+ectoderm

+ectodermal

+ectodermic

+ectogenic

+ectogenous

+ectomere

+ectomeric

+ectomorph

+ectomorphic

+ectoparasite

+ectoparasitic

+ectopic

+ectoplasm

+ectoplasmic

+ectotherm

+ectothermic

+ectotrophic

+ectotropic

+ecumenicalism

+ecumenicism

+ecumenicity

+ecumenism

+eczema

+eczematous

+edacious

+edacity

+edaphic

+edaphically

+edentate

+edentulous

+edgeless

+edgewater

+edgeways

+edgewood

+edgily

+edibility

+edictal

+edificatory

+editable

+editress

+eduard

+educability

+educable

+educationalist

+educationalists

+educationist

+educible

+eduction

+eductor

+eductors

+edulcorate

+edwardine

+eeg

+eellike

+eely

+eeriness

+eery

+effacement

+effectivity

+effectuality

+effeminacy

+effervesce

+effervescence

+effervescent

+effervescently

+efficacity

+efflorescence

+efflrescent

+effluence

+effortful

+effortfully

+effrontery

+effulgence

+effulgent

+eft

+egad

+egads

+egerton

+egestion

+egestive

+eggbeater

+eggcup

+eggnog

+eglantine

+egocentrically

+egocentricity

+egocentrism

+egoism

+egoist

+egoistic

+egoistical

+egoistically

+egoists

+egomania

+egomaniac

+egomaniacal

+egomaniacally

+egomaniacs

+egression

+eichmann

+eiderdown

+eidetically

+eidolon

+eigenfunction

+eigenfunctions

+eigenspace

+eighths

+eightyfold

+ein

+eine

+ejaculatory

+ejecta

+ejectable

+ejectment

+ekistic

+ekistics

+elapid

+elastase

+elastin

+elastomeric

+elaterite

+elbowroom

+elderberry

+eldership

+elecroencephalographic

+electability

+electable

+electioneer

+electioneerer

+electret

+electriques

+electroacoustic

+electroacoustically

+electroacoustics

+electroanalysis

+electroanalytic

+electroanalytical

+electrocardiographic

+electrocardiographically

+electrocardiography

+electrochemical

+electrochemically

+electrochemistry

+electroconvulsive

+electrocorticogram

+electrocorticogram's

+electrocorticograms

+electrodeposit

+electrodeposition

+electrodialysis

+electrodialytic

+electrodynamometer

+electrodynamometer's

+electrodynamometers

+electroencephalograph

+electroencephalography

+electroform

+electrogenesis

+electrogenic

+electrogram

+electrogram's

+electrograms

+electrohydraulic

+electrohydraulically

+electrojet

+electrokinetic

+electrokinetics

+electroless

+electrologist

+electroluminescence

+electroluminescent

+electrolytically

+electromagnetic

+electromagnetically

+electromechanical

+electromechanically

+electrometallurgy

+electrometer

+electrometer's

+electrometers

+electromotive

+electromyogram

+electromyogram's

+electromyograms

+electromyographical

+electronegative

+electronegativity

+electronography

+electrooculogram

+electrooculogram's

+electrooculograms

+electrophilic

+electrophoretic

+electrophoretically

+electrophoretogram

+electrophoretogram's

+electrophoretograms

+electrophotographic

+electrophotography

+electrophysiologic

+electrophysiological

+electrophysiologically

+electrophysiologist

+electrophysiology

+electroplate

+electroplater

+electropositive

+electroretinogram

+electroretinogram's

+electroretinograms

+electroretinograph

+electroretinographic

+electroretinography

+electroscope

+electrostatically

+electrosurgery

+electrosurgical

+electrothermal

+electrothermally

+electrothermic

+electrotonic

+electrotonically

+electrotype

+electrotyper

+electrovalence

+electrovalent

+electrowinning

+electrum

+electuary

+elegancy

+elegiacal

+elegiacally

+elegit

+elementarily

+elephantiasis

+elevenfold

+elfish

+elfishly

+elicitation

+elicitor

+elide

+elided

+elides

+eliding

+eligibly

+eliminable

+elisp

+elitism

+elitist

+elitists

+elixir

+ell

+elle

+ellie

+elliot

+elocutionary

+elocutionist

+elocutionists

+elopement

+elroy

+eluant

+elucidator

+elucubrate

+elucubrated

+elucubrates

+elucubrating

+elucubration

+eluent

+elutriate

+elutriator

+eluvial

+eluviate

+eluviation

+eluvium

+elver

+elvis

+elvish

+elysium

+elytron

+elytrum

+em

+emanational

+emancipationist

+emancipator

+emarginate

+emarginated

+emargination

+emasculator

+embalmment

+embarkation

+embarkment

+embarrassable

+embassage

+embattlement

+embay

+embayment

+embeddable

+embedment

+embitter

+embitterment

+embitters

+emblaze

+emblazed

+emblazes

+emblazing

+emblazon

+emblazoned

+emblazoner

+emblazoning

+emblazonment

+emblazonry

+emblazons

+emblematical

+emblematically

+emblements

+embolic

+embolism

+embolismic

+embosom

+embossable

+embossment

+embouchure

+embowed

+embowel

+embracement

+embraceor

+embracery

+embranchment

+embrangle

+embranglement

+embrasure

+embrittlement

+embrocate

+embrocated

+embrocates

+embrocating

+embrocation

+embroglio

+embroilment

+embrown

+embrue

+embryogenesis

+embryogenetic

+embryogenic

+embryogeny

+embryol

+embryologic

+embryological

+embryologically

+embryologist

+embryonal

+embryonally

+embryonated

+embryonically

+embryotic

+emceeing

+emendate

+emendation

+emendator

+emendatory

+emeriti

+emersed

+emerses

+emersion

+emetic

+emetically

+emigre

+emigre's

+emigree

+eminency

+emir

+emissive

+emollient

+emollients

+emote

+emoted

+emotes

+emoting

+emotionalist

+emotionalistic

+emotionless

+emotionlessness

+emotive

+emotively

+emotivity

+empanel

+empanels

+empathetic

+empennage

+emperies

+emperorship

+empery

+emphasization

+emphasization's

+emplacement

+emplane

+empoison

+empoisonment

+empowerment

+empressement

+emprise

+emptyhanded

+empurple

+empurpled

+empurpling

+ems

+emu

+emulous

+emulously

+emulousness

+emulsible

+emulsifiable

+emulsive

+emunctory

+en

+enactor

+enamelware

+enamine

+encage

+encapsule

+encapsules

+encasement

+encash

+encashment

+encaustic

+enceinte

+encephalic

+encephalitic

+encephalitogenic

+encephalogram

+encephalogram's

+encephalograms

+encephalon

+enchainment

+enchase

+enchased

+enchasing

+enchilada

+encipherment

+encirclement

+enclasp

+enclitic

+encomia

+encompassment

+encrimson

+encrustation

+encyst

+encystation

+encystment

+endamage

+endangerment

+endarch

+endarchy

+endbrain

+endemically

+endergonic

+endermic

+endermically

+endexine

+endite

+endleaf

+endlong

+endmost

+endobiotic

+endoblast

+endoblastic

+endocardial

+endochondral

+endocrine

+endocrinologic

+endocrinological

+endocrinologist

+endocrinology

+endocytic

+endocytosis

+endocytotic

+endoderm

+endodermal

+endodermis

+endodontia

+endodontic

+endodontically

+endodontics

+endodontist

+endoenzyme

+endoergic

+endoerythrocytic

+endogamic

+endogen

+endogenic

+endogeny

+endolymph

+endolymphatic

+endometrial

+endometriosis

+endometrium

+endomitosis

+endomorph

+endomorphic

+endomorphism

+endomorphy

+endonuclease

+endoparasite

+endoparasitism

+endophyte

+endophytic

+endoplasm

+endoplasmic

+endorsable

+endorsee

+endoscope

+endoscopic

+endoscopically

+endoscopy

+endoskeletal

+endoskeleton

+endosmosis

+endosmotic

+endosmotically

+endospermic

+endospermous

+endospore

+endosporic

+endosporous

+endosteal

+endosteally

+endosternite

+endosteum

+endostyle

+endosymbiosis

+endotherm

+endothermal

+endotoxic

+endotoxin

+endotracheal

+endotrophic

+endotropic

+endozoic

+endpaper

+endue

+endued

+enduing

+endways

+endwise

+enemata

+enfant

+enfants

+enfeeblement

+enfetter

+enfever

+enflame

+enflamed

+enflames

+enflaming

+enfold

+engild

+engineroom

+enginerooms

+enginery

+engird

+engirdle

+englacial

+englut

+englutted

+engluttin

+engorgement

+engr

+engraft

+engrailed

+engrain

+engrammic

+engrossment

+engulf

+engulfment

+enhalo

+enharmonic

+enharmonically

+enigmatical

+enigmatically

+enisle

+enjambement

+enjambment

+enkindle

+enlace

+enlacement

+enlistee

+enmeshment

+ennoblement

+enol

+enolase

+enolic

+enologist

+enology

+enplane

+enrapt

+enregister

+enrobe

+enroot

+ens

+ensample

+ensanguine

+ensconce

+ensconces

+ensconcing

+enscroll

+enserf

+enserfment

+ensheathe

+enshrine

+enshrined

+enshrinement

+enshrines

+ensiform

+ensilage

+ensile

+ensiled

+ensiling

+ensional

+ensnarl

+ensolite

+ensoul

+ensphere

+enswathe

+entablature

+entablement

+entablements

+ente

+entendre

+entente

+enterable

+enteral

+enterally

+enteric

+enthronement

+enticement

+entoderm

+entodermal

+entodermic

+entoil

+entoiled

+entombment

+entomological

+entomophagous

+entomophilous

+entomophily

+entrail

+entrails

+entrainment

+entrancement

+entrappingly

+entreatment

+entrustment

+entryway

+entwinement

+entwist

+enucleate

+enucleated

+enucleating

+enucleation

+enunciator

+enunciators

+envelopment

+envelopments

+environmentalism

+environmentalist

+environmentalists

+envisionin

+envoi

+envois

+enwheel

+enwind

+enwinding

+enwrap

+enwreathe

+enzymic

+enzymically

+enzymologist

+eon

+eon's

+eons

+eosine

+epaulette

+ephemerality

+epical

+epically

+epicardial

+epicardium

+epicarp

+epicene

+epicenism

+epicentral

+epicureanism

+epicurism

+epicurus

+epidemical

+epidemically

+epidemicity

+epidemiologic

+epidemiologist

+epidermal

+epigrammatical

+epigrammatically

+epigrammatism

+epigrammatist

+epigraphic

+epigraphical

+epigraphically

+epigraphist

+epigraphy

+epileptically

+epimorphism

+epiphanous

+epiphenomenal

+epiphenomenally

+epiphyseal

+epiphysis

+epiphyte

+epiphytic

+episcope

+episiotomy

+episodical

+episodically

+episomal

+episomally

+episome

+epistasy

+epistatic

+epistemic

+epistemically

+epistemologist

+epistolary

+epistoler

+epistrophe

+epitaphial

+epitaphic

+epithetic

+epithetical

+epode

+epodes

+eponymous

+equability

+equably

+equalitarian

+equalitarianism

+equational

+equationally

+equatorward

+equerries

+equerry

+equestrienne

+equiangular

+equiangularity

+equicaloric

+equilibrator

+equilibrators

+equilibratory

+equilibrist

+equilibristic

+equimolal

+equimolar

+equinoctial

+equipage

+equipoise

+equipollence

+equipollent

+equipollently

+equiponderant

+equiponderate

+equipotential

+equiprobable

+equitability

+equitant

+equitation

+equivalency

+equivocality

+equivocate

+equivocated

+equivocates

+equivocating

+equivocator

+equivoke

+equivoque

+eradicably

+eradicator

+eradicators

+eradictions

+erasabilities

+erasability

+erectable

+erectile

+erectility

+erelong

+erenow

+erewhile

+erewhiles

+erg

+ergative

+ergograph

+ergometer

+ergometer's

+ergometers

+ergometric

+ergonomic

+ergonomics

+ergonomist

+ergonovine

+ergosterol

+ergot

+ergotamine

+ergotic

+ergotism

+ergotropic

+erodibility

+erogenic

+erogenous

+erose

+erosely

+erosional

+erosionally

+erosivity

+erotical

+eroticism

+eroticist

+erotism

+erotogenic

+erratical

+erraticism

+errorless

+eruptible

+escalade

+escalader

+escalades

+escalator

+escalators

+escalatory

+escallop

+escallops

+escapement

+escapements

+escapism

+escapologist

+escapology

+escargot

+escarp

+escheat

+escherichia

+eschewal

+escot

+esculent

+esemplastic

+esker

+esophageal

+esoterica

+esoterically

+esotericism

+esp

+espadrille

+espagnol

+espanol

+esperance

+espial

+espresso

+espressos

+essayist

+essayistic

+essentialism

+essentialist

+essentiality

+establishable

+establishmentarian

+establishmentarianism

+esteemable

+ester

+estop

+estopped

+estopping

+estral

+estray

+estrogen

+estrogenic

+estrogenically

+estrone

+estrous

+estrum

+estrus

+estuarial

+esurience

+esuriency

+esurient

+esuriently

+etagere

+etatism

+etatist

+etch

+etcher

+etches

+etching

+ether

+ether's

+ethereality

+etheric

+etherish

+etherlike

+ethers

+ethicality

+ethician

+ethicians

+ethnical

+ethnobiological

+ethnobiology

+ethnocentric

+ethnocentrically

+ethnocentricity

+ethnocentrism

+ethnographer

+ethnographical

+ethnographically

+ethnol

+ethnologic

+ethnological

+ethnologically

+ethnologist

+ethnomusicology

+ethological

+ethologist

+ethoxy

+ethylate

+ethylation

+ethylenic

+ethylenically

+ethylic

+ethynyl

+etude

+etudes

+etui

+etymologist

+etymologists

+eucaryotic

+eucharistic

+euchre

+euclidian

+eucre

+eugenically

+eugenicist

+euglena

+euhemerism

+euhemerist

+euhemeristic

+euhemeristically

+eukaryote

+eukaryotic

+eulogist

+eulogistic

+eulogistically

+eulogium

+eumorphic

+eunuchism

+euphemistic

+euphemistically

+euphonically

+euphonious

+euphoniously

+euphoniousness

+euphonium

+euphorbia

+euphorically

+euphotic

+euphuism

+euphuist

+euphuistic

+euphuistically

+euplastic

+eurhythmic

+eurhythmics

+europeanish

+eurythmic

+eurythmics

+eurythmy

+eurytopic

+eurytopicity

+eustatic

+eutectic

+euthanasic

+euthenics

+euthenist

+eutherian

+euthyroid

+eutrophic

+eutrophication

+eutrophy

+eux

+evacuator

+evacuee

+evacuees

+evadable

+evagination

+evaluable

+evanesce

+evanesced

+evanescence

+evanesces

+evanescing

+evangel

+evangeline

+evangelistically

+evanishment

+evaporativity

+evaporator

+evaporators

+evaporite

+evaporitic

+evapotranspiration

+evection

+evenfall

+eventless

+everblooming

+eversible

+eversion

+eversions

+evert

+everyplace

+evictee

+evictees

+evictor

+evictors

+evidentiary

+evildoing

+evincible

+eviscerate

+eviscerated

+eviscerates

+eviscerating

+evisceration

+evitable

+evocator

+evocators

+evolutionarily

+evolutionism

+evolutionist

+evolvable

+evolvement

+evulsion

+evulsions

+evzone

+ewen

+exacta

+exactable

+exactor

+exactors

+exaggerator

+exaggerators

+exagitates

+examinant

+examinants

+examinational

+examinatorial

+examinee

+examinees

+exanimate

+exanimated

+exanimates

+exanimating

+excavational

+excavator

+excavators

+exceptionability

+exceptionable

+exceptionably

+exceptionality

+excerption

+excerptions

+excerptor

+excerptors

+exchangeability

+exchangee

+exchangees

+excide

+excided

+excides

+exciding

+excipient

+exciseman

+excitant

+excitants

+excitative

+exciton

+excitor

+exclave

+exclaves

+exclosure

+exclosures

+excludability

+excludable

+excludible

+exclusionist

+exclusionists

+excogitate

+excogitation

+excogitative

+excommunicator

+excrement

+excrement's

+excremental

+excrementitious

+excrements

+excrescency

+excrescent

+excrescently

+excreta

+excretal

+exculpate

+exculpated

+exculpates

+exculpating

+exculpation

+exculpations

+excurrent

+excursionist

+excursionists

+excursive

+excursively

+excursiveness

+excusatory

+execrably

+execrator

+execrators

+executant

+executorial

+executory

+executrices

+exegetic

+exegetical

+exegetically

+exegetics

+exegetist

+exemplarily

+exemplarity

+exenterate

+exenterated

+exenterates

+exenterating

+exenteration

+exenterations

+exercitation

+exergonic

+exeunt

+exfoliate

+exfoliated

+exfoliates

+exfoliating

+exfoliation

+exfoliative

+exhalant

+exhalants

+exhalation

+exhalations

+exhalent

+exhalents

+exhaustibility

+exhaustivity

+exhaustless

+exhaustlessly

+exhaustlessness

+exhibitionism

+exhibitionist

+exhibitionistic

+exhibitory

+exhilarant

+exhortative

+exhortatory

+exigence

+exiguity

+exiguous

+exiguously

+exiguousness

+exilic

+existentialistic

+existentialistically

+exobiological

+exobiologist

+exobiology

+exocrine

+exocyclic

+exodermis

+exodontia

+exodontist

+exoergic

+exogamic

+exonuclease

+exorbitance

+exorbitances

+exorcistic

+exorcistical

+exordial

+exordium

+exoskeleta

+exoskeletal

+exosmosis

+exosmotic

+exosphere

+exospheric

+exospore

+exostosis

+exoteric

+exotericaly

+exothermal

+exothermically

+exotically

+exoticism

+exotism

+expansibility

+expansile

+expansional

+expansionary

+expansionistic

+expansivity

+expatiate

+expatiated

+expatiates

+expatiating

+expatiation

+expatriate

+expatriated

+expatriates

+expatriating

+expatriation

+expecially

+expectably

+expectance

+expectative

+expedience

+expediential

+expeditionary

+expeditor

+expellee

+expeller

+expellers

+expendability

+expertism

+expiator

+expiatory

+expiratory

+expiry

+explanative

+explanatively

+explanatorily

+explant

+explantation

+explants

+expletory

+explicably

+explicator

+explicatory

+explodent

+exploitative

+exploitatively

+explorational

+explorative

+exploratively

+explosibility

+explosible

+expo

+exportability

+exportable

+expos

+expositional

+expositor

+expostulate

+expostulation

+expostulatory

+expressage

+expressional

+expressionistically

+expropriator

+expropriators

+expulsive

+expunction

+expurgator

+expurgatorial

+expurgatory

+exsanguinate

+exsanguination

+exscind

+exsert

+exserted

+exsertile

+exsertion

+exsertions

+exsiccate

+exsiccation

+exstipulate

+ext

+extemporal

+extemporally

+extemporaneity

+extemporarily

+extemporary

+extendable

+extensile

+extensionality

+extensity

+extensometer

+extensometer's

+extensometers

+extenuator

+extenuatory

+exteriority

+exterminatory

+extermine

+externalism

+externality

+externship

+exteroceptive

+exteroceptor

+exterritorial

+exterritoriality

+extinguishable

+extinguishment

+extoll

+extolment

+extortionary

+extortionate

+extortionately

+extrachromosomal

+extracorporeal

+extracorporeally

+extracranial

+extractability

+extractable

+extractible

+extradite

+extradites

+extradition

+extradoses

+extragalactic

+extrajudicial

+extrajudicially

+extralimital

+extralinguistic

+extralinguistically

+extrality

+extramundane

+extramural

+extramurally

+extranuclear

+extrapolator

+extrasensory

+extrasystole

+extrasystolic

+extraterritorial

+extraterritoriality

+extrauterine

+extravagancy

+extravagate

+extravasate

+extravasation

+extravascular

+extravehicular

+extraversion

+extraversive

+extravert

+extraverted

+extremis

+extremum

+extrinsically

+extrorse

+extrorsely

+extrudability

+extrudable

+exuberate

+exudate

+exudative

+exultance

+exultancy

+exurban

+exurbanite

+exurbia

+exuviation

+eyebolt

+eyebright

+eyecup

+eyedropper

+eyedropperful

+eyehole

+eyelike

+eyeliner

+eyepatch

+eyepoint

+eyepopper

+eyeshade

+eyeshot

+eyespot

+eyestalk

+eyestrain

+eyestrings

+eyetooth

+eyewash

+eyewink

+eyre

+eyrie

+fabricant

+fabricator

+fabricators

+fabular

+fabulist

+facedown

+facement

+facepiece

+facepieces

+facetted

+faceup

+facies

+facilitator

+facticity

+factional

+factionalism

+factionally

+factitious

+factitiously

+factitiousness

+factitive

+factitively

+factorable

+factorage

+factorship

+factotum

+factualism

+factualist

+factualists

+facture

+factures

+facula

+facultative

+facultatively

+faddish

+faddishness

+faddism

+faddist

+faddists

+fadeaway

+fadeless

+fadelessly

+fagging

+faggot

+faggoting

+faggots

+faience

+failsoft

+fainthearted

+faintheartedly

+faintheartedness

+faintish

+faintishness

+fairground

+fairish

+fairishly

+fairlead

+fairleader

+fairview

+fairylike

+faitour

+fakery

+fakir

+falcate

+falcated

+falciform

+falconet

+falderal

+falk

+fallback

+fallibly

+falsetto

+falsettos

+familism

+famishment

+fancywork

+fandango

+fane

+fanion

+fanlight

+fanlike

+fanner

+fantastical

+fantasticality

+fantasticalness

+fantasticate

+fantasticated

+fantasticates

+fantasticating

+fantastication

+fantod

+fanwise

+farad

+farceur

+farcicality

+farmhand

+farmhands

+farmstead

+farmsteading

+faro

+farrow

+farseeing

+farthermost

+fasces

+fascia

+fascial

+fasciated

+fasciation

+fascicular

+fascicularly

+fascicule

+fasciculus

+fascinator

+fascinators

+fascistic

+fascistically

+fashionabilities

+fashionability

+fashionmonger

+fastball

+fastball's

+fastballs

+fastuous

+fastuously

+fatalism

+fatalist

+fatalistically

+fatback

+fathead

+fatheaded

+fatheadedness

+fatherlike

+fathomable

+fathomless

+fathomlessly

+fathomlessness

+fatigability

+fatigable

+fatling

+fatted

+fatting

+fattish

+faulknerian

+faultfinder

+faultfinding

+faultily

+faunal

+faunally

+faunistic

+faunistically

+fauntleroy

+fauvism

+fauvist

+faux

+favonian

+fawkes

+fawny

+fay

+featherhead

+featherheaded

+featherless

+featherman

+febrific

+fecal

+feckless

+fecklessly

+fecklessness

+feckly

+feculence

+feculent

+fecundate

+fecundated

+fecundates

+fecundating

+fecundation

+fecundations

+feebleminded

+feeblemindedly

+feeblemindedness

+feedlot

+feedstock

+feedstuff

+feeing

+feetfirst

+feist

+feistier

+feisty

+feldspathic

+felicific

+felicitate

+felicitated

+felicitates

+felicitating

+felicitation

+felicitator

+felinity

+fellable

+fellah

+fellatio

+fellation

+fellations

+fellini

+fellowman

+felones

+felonry

+felsite

+felsitic

+felspar

+feministic

+feminity

+femoral

+fenceless

+fencelessness

+fenestral

+fenestrate

+fenestrated

+fenestrates

+fenestration

+fennec

+fenny

+fenugreek

+feral

+ferdinando

+ferial

+ferine

+fering

+ferity

+fermentable

+fermentative

+fernlike

+ferny

+ferrate

+ferrety

+ferriage

+ferriferous

+ferrimagnet

+ferrimagnetic

+ferrimagnetically

+ferrimagnetism

+ferritic

+ferromagnetism

+ferrotype

+ferruginous

+ferrule

+ferryboat

+ferryman

+fervency

+fescue

+fess

+festinate

+festinately

+festination

+festoon

+festoonery

+festoons

+feta

+fetation

+feterita

+fetishism

+fetishist

+fetishistic

+fetlock

+fetlocks

+fetologist

+fetology

+fetor

+fettuccine

+feudalist

+feudality

+feudist

+feverous

+feverously

+fey

+feyness

+fez

+fezes

+fezzes

+fibber

+fibration

+fibriallating

+fibril

+fibrillar

+fibrillate

+fibrillated

+fibrillates

+fibrillation

+fibrilliform

+fibrillose

+fibrils

+fibronectin

+fibrovascular

+fibula

+fibular

+fichu

+fictile

+fictioneer

+fictioneering

+fictionist

+ficus

+fiddleback

+fiddlehead

+fideism

+fideist

+fideistic

+fidel

+fidgetiness

+fidgety

+fidging

+fie

+fieldfare

+fieldstrip

+fiftyfold

+figaro

+figurable

+figurate

+figuration

+figurations

+figurehead

+filamentous

+filar

+filaria

+filarial

+filature

+filiation

+filiform

+filigreeing

+filippo

+fille

+filles

+fillip

+fillips

+fillment

+filmcard

+filmic

+filmically

+filmily

+filmmake

+filmmaker

+filmmakers

+filmmaking

+filmography

+fils

+filterability

+filterable

+filthily

+filtrable

+filum

+fimbria

+fimbrial

+fimbriate

+fimbriated

+fimbriates

+fimbriation

+finagle

+finagled

+finagler

+finagles

+finagling

+finback

+finery

+finespun

+fingerboard

+fingerlike

+fingerling

+fingerpost

+finical

+finically

+finicalness

+finicking

+finis

+finitude

+finlike

+finning

+fiord

+fiori

+firebird

+firebox

+firebrand

+firebrick

+fireclay

+firedamp

+fireguard

+fireless

+firelock

+fireplug

+fireplugs

+fireroom

+firetrap

+firma

+firmamental

+firstborn

+firstfruits

+firstling

+firstlings

+fisc

+fishability

+fishable

+fishbowl

+fishhook

+fishkill

+fishnet

+fishplate

+fishplates

+fishtail

+fishway

+fishwife

+fishyback

+fissility

+fissionability

+fissionable

+fissional

+fissiparous

+fissiparously

+fissiparousness

+fistfight

+fistful

+fistic

+fistnote

+fitment

+fixable

+fixity

+fixups

+fizzy

+flabbily

+flabellate

+flaccid

+flaccidity

+flaccidly

+flack

+flacon

+flagellant

+flagellantism

+flagellants

+flagellar

+flageolet

+flagger

+flagitious

+flagitiously

+flagitiousness

+flagon

+flagrance

+flagrancies

+flagrancy

+flamb

+flamboyance

+flamboyancy

+flamenco

+flameout

+flameproof

+flamingo

+flammability

+flan

+flan's

+flapdoodle

+flapjack

+flappy

+flareback

+flashboard

+flashgun

+flashguns

+flashily

+flashover

+flashovers

+flashtube

+flatboat

+flatcap

+flatcar

+flatfeet

+flatfoot

+flatfooted

+flatfoots

+flatted

+flatting

+flattish

+flattop

+flatulency

+flatus

+flatware

+flatwise

+flatwork

+flaunty

+flaxier

+flaxy

+flay

+fleabag

+fleabane

+flection

+flective

+fledermaus

+fleeringly

+fleischman

+fleisher

+fleshment

+fleshpot

+fleshpots

+flexile

+flexion

+flexographic

+flexographically

+flexography

+flexor

+flexuous

+flexuously

+flibbertigibbet

+flibbertigibbety

+flickery

+flightier

+flightily

+flightiness

+flightless

+flighty

+flimflam

+flimflammed

+flimflammer

+flimflamming

+flimsily

+flintily

+flintlike

+flippancy

+flipper

+flirty

+flitted

+flitter

+flivver

+floatage

+floatation

+floatplane

+floaty

+floc

+flogger

+floodlit

+floodplain

+floodwall

+floodwater

+floodwater's

+floodwaters

+floodway

+flooey

+floorage

+floorwalker

+floozie

+floozies

+floozy

+flophouse

+flopover

+flopovers

+flopper

+floppers

+florescence

+florescent

+floret

+floriate

+floriated

+floriation

+floriations

+florican

+floricultural

+floriculturally

+floriculture

+floriculturist

+floridity

+floriferous

+floriferously

+floriferousness

+florigen

+florigenic

+floristic

+floristically

+floristics

+floristry

+floruit

+flossier

+flossy

+flotage

+flotsam

+flouncy

+flowage

+flowerage

+floweret

+flowerlike

+fluctuant

+fluegelhorn

+fluidal

+fluidally

+fluidextract

+fluidic

+fluidics

+fluidounce

+fluidram

+flukey

+flukier

+fluky

+flume

+flumed

+flumes

+fluming

+flummery

+flummox

+flump

+flumped

+flumping

+flumps

+flunkeys

+flunky

+fluor

+fluorescein

+fluorimeter

+fluorimeter's

+fluorimeters

+fluorimetry

+fluorinate

+fluorinates

+fluorinating

+fluorination

+fluorinations

+fluoroscopic

+fluorspar

+flutelike

+flutterboard

+fluttery

+fluvial

+fluviatile

+fluxion

+fluxional

+flyblown

+flyboat

+flyboats

+flyby

+flybys

+flyleaf

+flyman

+flyover

+flyovers

+flypaper

+flypast

+flypasts

+flyspeck

+flyswatter

+flytier

+flyting

+flyway

+flyweight

+foamflower

+foamless

+fobbing

+focusless

+fodgel

+foeman

+fogbound

+fogey

+fogeys

+fogger

+foggest

+foghorn

+foghorns

+fogies

+fogless

+fogy

+fogyish

+fogyism

+foilsman

+foldable

+foldaway

+foldboat

+foldboater

+foldboating

+folderol

+folia

+foliaceous

+folic

+folkish

+folkishness

+folkloric

+folklorish

+folklorist

+folkloristic

+folksily

+folksinger

+folksinger's

+folksingers

+folksinging

+folktale

+folktale's

+folktales

+folkway

+folkways

+folliculate

+folliculated

+followership

+followeth

+fomentation

+fomentations

+fondue

+fondues

+fontal

+fontana

+foodless

+foodlessness

+foolery

+foolhardily

+foolscap

+foolscap's

+footboard

+footboards

+footboy

+footboys

+footcandle

+footcloth

+footgear

+footle

+footled

+footler

+footles

+footless

+footlessly

+footlessness

+footlight

+footlights

+footlike

+footling

+footlocker

+footmark

+footpace

+footrace

+footrest

+footrests

+footrope

+footropes

+footslog

+footslogger

+footslogs

+footsore

+footsoreness

+footstall

+footwall

+footway

+footways

+footy

+foozle

+foozled

+fopping

+fora

+foraminifera

+forbiddance

+forbidder

+forbode

+forborne

+forbye

+forceless

+forceps

+forcepslike

+fordable

+fordo

+forebear

+forebode

+foreboded

+foreboder

+forebodes

+forebrain

+foreclose

+forecloses

+foreclosure

+foredeck

+forefeel

+forefoot

+foregather

+forehand

+forehanded

+forehandedly

+forehandedness

+foreignism

+forejudge

+foreknow

+forelady

+foreland

+forelimb

+forelock

+foremanship

+foremast

+foremasts

+foremother

+forename

+forenamed

+forenames

+forensical

+forensically

+foreordain

+foreordained

+foreordaining

+foreordains

+foreordination

+forepassed

+forepast

+forepaw

+forepeak

+foreplay

+forequarter

+forequarters

+forereach

+forerun

+foresaid

+foresail

+foreshadow

+foreshadowed

+foreshadower

+foreshadowing

+foreshadows

+foreshank

+foresheet

+foreshore

+foreshorten

+foreshortens

+foreshow

+foreside

+foresightful

+foreskin

+forespeak

+forestage

+forestal

+forestation

+forestay

+forestial

+foreswear

+foresworn

+foretaste

+foretellable

+forethoughtfully

+forethoughtfulness

+forethougtful

+foretime

+foretoken

+forevermore

+forewoman

+foreworn

+foreyard

+forfeitable

+forgather

+forgeability

+forgeable

+forgetter

+forgiveable

+forgiveably

+forgoes

+forgone

+forjudge

+forkful

+forkier

+forklike

+forky

+forma

+formable

+formalin

+formalist

+formalistic

+formalistically

+formational

+formfitting

+formful

+formidability

+formless

+formlessly

+formlessness

+formulaically

+formulary

+formyl

+fornicate

+fornicated

+fornicates

+fornicating

+fornications

+fornicator

+fornicators

+forrader

+forrarder

+forsooth

+forspent

+forswore

+forsworn

+fortalice

+fortin

+fortman

+fortuity

+fortyfold

+forwent

+forworn

+fossate

+fossorial

+fosterage

+fosterite

+fosterling

+fosterlings

+fou

+foudroyant

+foundational

+foundationally

+foundationless

+founderous

+foundress

+foundrous

+fourdrinier

+foxily

+foxtrot

+foxtrot's

+foxtrots

+fracas

+fracted

+fractionate

+fractionates

+fractionating

+fractionations

+fractionator

+fractionators

+frag

+fragged

+fragging

+fragility

+fragmental

+fragmentally

+fragmentate

+fragmentated

+fragmentates

+fragmentating

+fragmentations

+fragrancy

+frags

+framable

+frambesia

+frameable

+franca

+francaise

+francesca

+francesco

+franchisee

+franchisor

+francie

+francois

+frangibility

+frangible

+frangipani

+frankincense

+frankpledge

+franny

+frap

+frappe

+frapping

+frat

+frater

+fraternalism

+fratricidal

+fratricide

+fraudulence

+frayne

+freakier

+freaky

+freckly

+fredrick

+freeboard

+freedwoman

+freehearted

+freeheartedly

+freeload

+freeloader

+freemasonry

+freestanding

+freestyle

+freethink

+freethinker

+freethinking

+freewill

+freida

+freightage

+frenchification

+frenchify

+frenetically

+frequence

+frequentation

+frequentations

+frequentative

+frequentatives

+freshet

+fretwork

+friability

+friary

+fribble

+fribbled

+fribbles

+fribbling

+fricassee

+fridge

+fridge's

+fridges

+frig

+frigging

+frigidity

+frigorific

+frillery

+fringier

+fringy

+frippery

+friskily

+frisson

+frissons

+frit

+fritillary

+frito

+fritted

+fritting

+frivol

+frizz

+frizzier

+frizzily

+frizziness

+frizzlier

+frizzly

+frizzy

+frogman

+frogmen

+frolick

+frolicked

+frolicks

+frolicsome

+frolicsomely

+frolicsomeness

+frond

+frond's

+fronded

+frondeur

+frondose

+frondosely

+fronds

+frontality

+frontispiece

+frontispieces

+frontless

+fronton

+frostily

+frostwork

+frothily

+froths

+frottage

+froufrou

+froward

+frowardly

+frowardness

+frowsier

+frowstier

+frowsty

+frowsy

+fructification

+fructifications

+fructify

+fructose

+fructose's

+fructoses

+fructuous

+fructuously

+fruitage

+fruitcake

+fruitier

+fruitlet

+fruity

+frump

+frumpier

+frumpish

+frumps

+frumpy

+fryer

+ft

+ftp

+ftper

+ftpers

+ftping

+ftpings

+ftps

+fucose

+fucus

+fuddle

+fuddled

+fuddles

+fuddling

+fugacity

+fugal

+fugally

+fuguist

+fulbright

+fulcra

+fulgent

+fulgently

+fulgurant

+fulgurate

+fulgurated

+fulgurates

+fulgurating

+fulguration

+fulgurations

+fulgurous

+fuliginous

+fuliginously

+fullmouthed

+fulminant

+fulminator

+fulminators

+fulness

+fum

+fumarate

+fumarole

+fumigator

+fumigators

+fumy

+funambulist

+functionalistic

+functionless

+functorial

+fundament

+fundamentalistic

+fundraiser

+fundraiser's

+fundraisers

+fundraising

+funerary

+fungibility

+fungicidal

+fungicidally

+fungicide

+fungiform

+fungo

+fungoes

+fungous

+funicular

+funiculus

+funigating

+funkier

+funkiness

+funky

+funnelform

+funning

+funnyman

+furbearer

+furbelow

+furcate

+furcated

+furcately

+furcates

+furcating

+furcation

+furcations

+furcula

+furcular

+furfural

+furless

+furloughs

+furmity

+furriery

+furtherance

+furuncle

+furuncular

+furunculosis

+furunculous

+furze

+fusee

+fusee's

+fusees

+fusibility

+fusil

+fusile

+fusileer

+fusilier

+fusionist

+fussbudget

+fussbudgety

+fusspot

+fustian

+fustians

+fustigate

+fustigated

+fustigates

+fustigating

+fustigation

+fustigations

+fustily

+futilitarian

+futilitarianism

+futureless

+futurism

+futuristic

+futuristically

+futurity

+gabber

+gabbier

+gabble

+gabbled

+gabbler

+gabbles

+gabbling

+gabbro

+gabby

+gaberdine

+gabfest

+gabfests

+gadabout

+gadabouts

+gadded

+gadder

+gadding

+gadgeteer

+gadgeteers

+gadgety

+gadolinium

+gadwall

+gadzooks

+gaff

+gaffs

+gaga

+gage

+gages

+gagger

+gagman

+gagmen

+gagster

+gagsters

+gaillardia

+gaingiving

+gainless

+gainlessness

+gainsay

+gainsayer

+galactopyranose

+galactopyranoside

+galactopyranosides

+galactopyranosyl

+galactose

+galahad

+galavant

+gallberry

+gallbladder

+galleon

+galleons

+gallet

+gallied

+gallinule

+gallopade

+gallow

+gallus

+galluses

+galore

+galosh

+galoshed

+galoshes

+galoshing

+galumph

+galvanically

+galvanometric

+gam

+gamekeeper

+gamekeepers

+gamesmanship

+gamesome

+gamesomely

+gamesomeness

+gamester

+gamete

+gamete's

+gametes

+gametic

+gametically

+gamey

+gamic

+gamier

+gamily

+gamin

+gamine

+gaminess

+gamming

+gammon

+gamy

+ganglioside

+gangliosides

+gangplow

+gangrenous

+gangsterism

+gannet

+gantlet

+gapping

+gappy

+gar

+garageman

+garagemen

+garde

+gardenful

+garlicky

+garnett

+garnishable

+garnishee

+garnishees

+garnishment

+garnishments

+garniture

+garnitures

+garotte

+garrote

+garroted

+garroter

+garrotes

+garroting

+garrots

+garrulity

+garth

+gasbag

+gasholder

+gashouse

+gaslit

+gasogene

+gasolene

+gasolier

+gasolinic

+gasometer

+gasometer's

+gasometers

+gasses

+gasset

+gast

+gastight

+gastightness

+gastness

+gastral

+gastrectomy

+gastrin

+gastritis

+gastrogenic

+gastrogenous

+gastronomic

+gastronomical

+gastronomically

+gastronomist

+gastrulate

+gastrulation

+gasworker

+gasworks

+gat

+gatefold

+gatekeeper

+gatekeeper's

+gatekeepers

+gatepost

+gatsby

+gaucherie

+gaucheries

+gaud

+gauded

+gaudery

+gaudily

+gauding

+gauds

+gaugeably

+gaum

+gaums

+gauntley

+gaur

+gauzelike

+gauzily

+gauziness

+gauzy

+gavotte

+gavottes

+gawkily

+gawkish

+gawkishly

+gawkishness

+gayety

+gazebo

+gazebo's

+gazebos

+gazpacho

+gazpacho's

+gearbox

+gearless

+gearshift

+geary

+gecko

+geegaw

+geezer

+gehrig

+gelant

+gelate

+gelated

+gelates

+gelating

+gelation

+gelid

+gelidity

+gelidly

+gelin

+geminal

+geminally

+geminate

+geminately

+gemination

+gemmate

+gemmated

+gemmates

+gemmating

+gemmation

+gemming

+gemsbok

+gemstone

+gemstone's

+gemstones

+gendarme

+gendarmerie

+genealogical

+genealogically

+genealogist

+generable

+generale

+generalship

+generalships

+generatrix

+genetical

+geniality

+genic

+genically

+geniculate

+geniculated

+geniculately

+genii

+genital

+genital's

+genitalia

+genitalic

+genitally

+genitals

+genocidal

+genocide

+genocides

+genome

+genome's

+genomes

+genotypic

+genotypical

+genotypically

+genotypicity

+genteelism

+gentilesse

+gentlefolk

+gentlefolks

+gentlemanlike

+gentlemanlikeness

+gentrice

+genuflect

+genuflected

+genuflecting

+genuflection

+genuflectory

+genuflects

+geocentrically

+geochemist

+geochronologic

+geochronological

+geochronologically

+geochronologist

+geochronometric

+geochronometry

+geode

+geode's

+geodes

+geodesist

+geodesy

+geodetical

+geodetically

+geoduck

+geohydrologic

+geohydrology

+geomagnetic

+geomagnetically

+geomagnetism

+geomancy

+geomantic

+geomorphic

+geophyte

+geopolitician

+geoponic

+geoponics

+georgic

+geoscience

+geostrategic

+geostrategist

+geostrategy

+geostrophic

+geostrophically

+geothermal

+geothermally

+geothermic

+geotropic

+geotropically

+geotropism

+geriatrician

+geriatricians

+geriatrist

+germania

+germfree

+germier

+germinability

+germproof

+germy

+gerome

+gerontic

+gerontocracy

+gerrymander

+gerrymandered

+gerundial

+gestational

+gesticulator

+gesticulators

+gesticulatory

+gestural

+getatable

+getup

+getups

+gewgaw

+ghastful

+ghastfully

+ghazal

+ghazals

+ghee

+ghostwrite

+ghostwriter

+ghosty

+gianthood

+gianthoods

+giantism

+giantisms

+giantlike

+gib

+gibberellin

+gibbing

+gibbosity

+gibby

+giddings

+gigantesque

+gigantically

+gigantism

+gigantisms

+giggly

+gigolo

+gigot

+gigots

+gildas

+gimbal

+gimbals

+gimcrackery

+gimlet

+gimlet's

+gimlets

+gimmal

+gimmickry

+gimmicky

+gimp

+gingersnap

+gingery

+gingko

+gioconda

+giraffish

+girlhood

+girlhoods

+girly

+girn

+giro

+gismo

+gismos

+givable

+gizzard

+gizzard's

+gizzards

+glaciologic

+glaciological

+glaciologist

+glaciology

+glacis

+gladded

+gladding

+gladiatorial

+gladiola

+gladsome

+gladsomely

+gladsomeness

+glady

+glandered

+glandless

+glans

+glarier

+glary

+glassblower

+glassblowing

+glassful

+glasshouse

+glassily

+glassine

+glassmaker

+glassmaking

+glasswork

+glassworker

+glassworks

+glazier

+glaziery

+gleamy

+gleanable

+gleesome

+glibber

+glibbest

+glioma

+glissade

+glittery

+gloam

+gloamed

+gloaming

+gloams

+globalism

+globalist

+globalists

+glom

+glomerular

+glomerulate

+glomming

+gloms

+glossarial

+glossarist

+glossily

+glossographer

+glossolalia

+gluconyl

+glucopyranosyl

+glucosamine

+glueing

+gluily

+glumaceous

+glummer

+glummest

+glutamate

+glutamic

+glutamine

+gluteal

+gluttonous

+gluttonously

+gluttonousness

+gluttony

+glyceryl

+glycine

+glycocholate

+glycocholates

+glycoconjugate

+glycoconjugates

+glycodeoxycholate

+glycodeoxycholates

+glycogen

+glycolipid

+glycolipids

+glycopeptide

+glycopeptides

+glycoprotein

+glycoproteins

+glycosidase

+glycosidases

+glycosidic

+glycosphingolipid

+glycosphingolipids

+glycosyl

+glycosylate

+glycosylated

+glycosylates

+glycosylation

+glynn

+gnarly

+gnatty

+gneissic

+gnomic

+gnomish

+gnomon

+gnosticism

+goalie

+goalkeeper

+goalpost

+goaltender

+goaltending

+goatish

+goatlike

+gobbledegook

+godchild

+goddaughter

+godded

+godding

+godforsaken

+godhood

+godkin

+godling

+godot

+godwit

+goethite

+gog

+goggly

+gogo

+goitrogen

+goitrogenic

+golda

+goldbeater

+goldbeating

+goldbrick

+goldbug

+goldeneye

+golem

+gomez

+gonad

+gonad's

+gonadal

+gonadotropic

+gonads

+gondolier

+gondoliers

+goo

+goodish

+goodnight

+goodwife

+goofball

+goofily

+googol

+googolplex

+goon

+gooseflesh

+gooseneck

+goosenecked

+goosey

+gorget

+gorgonian

+gorgously

+gorier

+gorse

+gory

+gossamery

+gossipry

+gossipy

+goucher

+gouda

+goulash

+gourde

+gourmandism

+gouty

+governable

+governessy

+governmentalism

+governmentalist

+governorate

+governorates

+governorship

+goyish

+goys

+grabbier

+grabble

+grabbled

+grabbler

+grabbles

+grabbling

+grabby

+graceless

+gracelessly

+gracelessness

+gracie

+gracileness

+gracility

+grackle

+gradable

+gradational

+gradationally

+gradeless

+gradiometer

+gradiometer's

+gradiometers

+gradualism

+graduator

+graftage

+grafton

+grainier

+graininess

+grainy

+gramicidin

+gramophone

+gramophone's

+gramophones

+gramps

+grandad

+grandaddy

+grandam

+grandame

+granddad

+grande

+grandee

+grandiloquence

+grandiosity

+grandioso

+grandparental

+grandparenthood

+grandsire

+grandsires

+grangerism

+granitic

+granivorous

+grantable

+grantsman

+grantsmanship

+granulator

+granulite

+granulitic

+granulocyte

+granulocytes

+grapeshot

+graphemic

+graphemically

+graphemics

+graphitic

+graphological

+graphologist

+graphology

+graphophone

+grapier

+grapnel

+grapy

+gras

+grasshopper

+grasshopper's

+grasslike

+grata

+graticule

+gratin

+gratulating

+graveless

+gravesend

+gravidity

+gravimeter

+gravimeter's

+gravimeters

+gravimetrically

+gravimetry

+gravitometer

+gravitometer's

+gravitometers

+graviton

+graviton's

+gravitons

+gravure

+grayish

+grayling

+graylings

+graywacke

+grazable

+grazeable

+grazier

+graziers

+greaseless

+greasepaint

+greasepaints

+greaseproof

+greasewood

+greasily

+greathearted

+greatheartedly

+greatheartedness

+greave

+greaves

+grebe

+greenback

+greenbacker

+greenbackism

+greengrocery

+greenhorn

+greenlet

+greenling

+greenroom

+greensward

+greentree

+greenware

+greeny

+gregarine

+gregarinian

+gremlin

+gremlin's

+gremlins

+gremmie

+gremmies

+gremmy

+grenadier

+grenadine

+grenier

+grep

+grewsome

+greylag

+gridlock

+gridlock's

+griefless

+grievant

+grillage

+grille

+grillroom

+grimier

+grimines

+grimmest

+grimy

+gringo

+gringos

+grinner

+grippe

+grippy

+gris

+gristle

+grith

+gritted

+grittily

+gritting

+grog

+groggily

+grogshop

+groomsman

+groot

+groovier

+groovy

+grosse

+grossular

+grossularite

+grotesquerie

+grotesquery

+grouch

+grouch's

+grouched

+grouches

+grouchily

+grouching

+groundling

+groundmass

+groundnut

+groundout

+groundsel

+groundsheet

+groundskeep

+groundwater

+groupable

+groupie

+groupie's

+groupies

+groupoid

+grubber

+grubbily

+grubstake

+grubstaker

+gruel

+grumbly

+grummet

+grump

+grumped

+grumpier

+grumpily

+grumpiness

+grumping

+grumps

+grumpy

+grunion

+gruntle

+gruntled

+gruntles

+gruntling

+grusky

+gryphon

+gtad

+guacamole

+guadalupe

+guanidine

+guanine

+guarantor

+guardant

+guardrail

+guardroom

+guardsman

+guava

+guck

+gudgeon

+guerdon

+guesstimate

+guff

+guggle

+guggled

+guggles

+guggling

+guhleman

+guidable

+guideway

+guignol

+guildship

+guildsman

+guileful

+guilefully

+guilefulness

+guillemot

+guillotine

+guillotine's

+guillotined

+guillotines

+guillotining

+guimet

+guimpe

+guisard

+gul

+gules

+gullable

+gullibly

+gulosity

+gumboil

+gumdrop

+gumdrop's

+gumdrops

+gummatous

+gummed

+gummer

+guncotton

+gundog

+gunlock

+gunmetal

+gunnar

+gunnysack

+gunplay

+gunpoint

+gunpowdery

+gunrunner

+gunrunning

+gunsel

+gunship

+gunsmith

+guppies

+guppy

+gurney

+gurneys

+gushier

+gushily

+gushiness

+gushy

+gustation

+gustative

+gustativeness

+gustatorial

+gustatorially

+gustatorily

+gustatory

+gustily

+gustoes

+gutless

+gutlessness

+guttate

+guttation

+guttersnipe

+guttersnipish

+guttier

+gutturalism

+gutty

+gymkhana

+gymnastically

+gymnosophist

+gypseous

+gyral

+gyrational

+gyrator

+gyrators

+gyratory

+gyre

+gyrene

+gyrfalcon

+gyrofrequency

+gyromagnetic

+gyron

+gyroplane

+gyroscopically

+gyrostat

+haberdasher

+habiles

+habiliment

+habilitate

+habilitated

+habilitates

+habilitating

+habilitation

+habilitations

+habitability

+habitably

+habitude

+habitudes

+habitus

+hac

+hackberry

+hackmatack

+hackstaff

+hadal

+haddix

+hade

+hades

+hadst

+hafiz

+haft

+haggadic

+haggadist

+haggadistic

+haggis

+haggish

+hagiographies

+hagiography

+hagiography's

+hah

+hairbreadth

+hairbrush

+haircloth

+haircutter

+haircutting

+hairlike

+hairpiece

+hairsbreadth

+hairsplitter

+hairsplitting

+hairspring

+hairspring's

+hairsprings

+hairstreak

+hairstyle

+hairstyle's

+hairstyles

+hairstyling

+hairstylist

+halberdier

+halfpennies

+halfpenny

+halftone

+halidom

+halitosis

+halliard

+halliards

+hallinan

+hallo

+halloo

+halloos

+halluces

+hallucinational

+hallucinatory

+hallucinogen

+hallucinogenic

+hallucinogens

+hallucinosis

+halma

+halocline

+haloes

+halogenate

+halogenation

+halogenous

+halomorphic

+halomorphism

+halpern

+haltere

+halvah

+halyard

+hamate

+hamey

+hammerlock

+hammertoe

+hammett

+hammier

+hammily

+hamminess

+hammy

+hamstring

+hamstrung

+handball

+handbill

+handbreadth

+handcar

+handcart

+handcraft

+handcraftman

+handcraftsman

+handcrank

+handcranks

+handfast

+handfasting

+handgrip

+handleless

+handline

+handlist

+handmaid

+handpick

+handpicked

+handpress

+handprint

+handprint's

+handprints

+handsaw

+handsbreadth

+handsful

+handshook

+handspring

+handsprings

+handwaving

+handwheel

+handwheels

+handwork

+handworker

+handwoven

+handwrought

+hangdog

+hangnail

+hangnail's

+hangnails

+hangtag

+hangup

+hankie

+hankies

+hanky

+hant

+hanter

+haole

+hapchance

+hapgood

+haphazardry

+haploid

+haploidy

+haplology

+happenchance

+happing

+hardback

+hardbake

+hardball

+hardboot

+hardbound

+hardcase

+hardcopies

+hardcopy

+hardcover

+hardcovers

+hardfisted

+hardfistedness

+hardhanded

+hardhandedness

+hardhead

+hardheaded

+hardheadedly

+hardheadedness

+hardhearted

+hardheartedly

+hardheartedness

+hardihood

+hardiment

+hardmouthed

+hardpan

+hardstand

+hardstanding

+harebrain

+harebrained

+harelipped

+harlequin

+harlequinade

+harlotry

+harmonica

+harmonica's

+harmonical

+harmonically

+harmonicalness

+harmonicas

+harmonium

+harridan

+harrumphs

+harvestable

+harvesttime

+haskell

+haskins

+hassock

+hassocks

+hast

+hastate

+hastately

+hatband

+hatbox

+hatchability

+hatchable

+hatcheck

+hatchling

+hatchment

+hatchments

+hatchure

+hatter

+hatting

+haulageway

+haulaway

+haulier

+hauser

+hausfrau

+hautboy

+hautboys

+haute

+hauteur

+haversack

+haversack's

+haversacks

+havocked

+havocking

+hawkish

+hawkishly

+hawkishness

+haycock

+hayfork

+haymaker

+haymaking

+haymow

+hayrack

+hayrick

+hayride

+hayseed

+hayseeds

+haywire

+haywood

+hazily

+headachy

+headband

+headcount

+headfirst

+headforemost

+headgroup

+headgroup's

+headgroups

+headhunter

+headily

+headlock

+headman

+headman's

+headmastership

+headmen

+headmen's

+headmistress

+headmost

+headnote

+headpiece

+headpin

+headrest

+headsail

+headshrinker

+headspring

+headstall

+headstock

+headstream

+headstrong

+headwaiter

+headwind

+headwind's

+headwinds

+headword

+headwork

+healths

+heartbroken

+hearthstone

+heartrending

+heartrendingly

+heartsease

+heartsick

+heartsickness

+heartsome

+heartsomely

+heartsore

+heartstring

+heartstrings

+heartwarming

+heartwood

+heathendom

+heathenism

+heathenry

+heathery

+heathless

+heathlike

+heathman

+heatless

+heatstroke

+heavyhearted

+heavyheartedly

+heavyheartedness

+heavyset

+hebdomad

+hebdomadal

+hebdomadally

+hebetation

+hebetude

+hebetudinous

+hectare

+hectically

+hectograph

+hectographic

+hedda

+heddle

+heddler

+hedgehop

+hedgehopper

+hedgepig

+hedgerow

+hedonic

+hedonically

+hedonics

+hedonistically

+hee

+heelball

+heelless

+heelpiece

+heeltap

+heftily

+hegel

+heidegger

+heigh

+heinze

+heirless

+heirloom

+heirship

+heiser

+heldentenor

+heliacal

+heliacally

+helicoid

+helicoidal

+helicopt

+helicopted

+helicopters

+helicopting

+heliochrome

+heliogram

+heliogram's

+heliograms

+heliograph

+heliographer

+heliographic

+heliography

+heliogravure

+heliolatrous

+heliolatry

+heliometer

+heliometer's

+heliometers

+heliometric

+heliometrically

+heliophyte

+heliopolis

+heliostat

+heliotaxis

+heliotropic

+heliotropically

+heliotropism

+heliozoan

+heliozoic

+helipad

+heliport

+helistop

+hellbox

+hellbroth

+hellcat

+hellebore

+hellgrammite

+hellhole

+hellhound

+hellion

+helmetlike

+helmsmanship

+helot

+helotism

+helotry

+helpmeet

+helve

+helved

+helves

+helving

+hemacytometer

+hemacytometer's

+hemacytometers

+hemal

+hematic

+hematin

+hematinic

+hematoblast

+hematoblastic

+hematocrit

+hematogenous

+hematologic

+hematological

+hematologist

+hematology

+hematoma

+hematophagous

+hemihedral

+hemihedrally

+hemihydrate

+hemihydrated

+hemimetabolic

+hemimetabolism

+hemimetabolous

+hemimorphic

+hemimorphism

+hemimorphite

+hemiparasite

+hemiparasitic

+hemiplegia

+hemiplegic

+hemispheral

+hemline

+hemmer

+hemoblast

+hemodynamically

+hemodynamics

+hemoflagellate

+hemoglobinic

+hemoglobinopathy

+hemoglobinous

+hemolymph

+hemolysin

+hemophilia

+hemophiliac

+hemophilic

+hemoprotein

+hemoptysis

+hemorrhagic

+hemorrhoid

+hemorrhoidal

+hemosiderin

+hemostasis

+hemostatic

+hempel

+hemus

+henae

+henbane

+henceforward

+hendecasyllabic

+hendecasyllable

+hendiadys

+hendrix

+henequen

+henna

+hennery

+henotheism

+henotheist

+henotheistic

+hent

+hep

+heparin

+hepatic

+hepatica

+hepatocellular

+hepatocyte

+hepatocyte's

+hepatocytes

+hepatoma

+heptagon

+heptagonal

+heptameter

+heptameter's

+heptameters

+heraldic

+heraldically

+heraldry

+herbaceous

+herbage

+herbalist

+herbarium

+herbicidal

+herbicidally

+herbicide

+herbicide's

+herbicides

+herblike

+herdic

+herdlike

+herdsmen

+hereaway

+hereaways

+hereditament

+hereditarian

+hereditarianism

+hereditarily

+hereinabove

+hereinbefore

+hereinbelow

+hereon

+heretical

+heretically

+hereticalness

+hereto

+hereunder

+hereupon

+heritability

+hermaphrodite

+hermaphrodite's

+hermaphrodites

+hermaphroditic

+hermaphroditically

+hermaphroditism

+hermatypic

+hermeneutic

+hermeneutical

+hermeneutically

+hermetical

+hermetically

+hermeticism

+hermetism

+hermetist

+hermitage

+hermitage's

+hermitages

+hermitism

+hern

+hernandez

+hernia

+hernia's

+hernial

+hernias

+herniate

+herniated

+herniates

+herniating

+herniation

+herniations

+heroical

+heroicomic

+heroicomical

+heroinism

+heronry

+herpesvirus

+herpetic

+herpetologic

+herpetological

+herpetologically

+herrington

+hersey

+herty

+hesiometer

+hesiometer's

+hesiometers

+hest

+heterarchy

+heterecious

+hetero

+heteroatom

+heteroautotrophic

+heterocycle

+heterocyclic

+heterocyst

+heterodox

+heterodoxy

+heteroecious

+heteroecism

+heterogamete

+heterogametic

+heterogenesis

+heterogenetic

+heterogeny

+heterogonic

+heterogony

+heterograft

+heterologously

+heterology

+heterolysis

+heterolytic

+heteromorphic

+heteromorphism

+heteromorphous

+heteronomous

+heteronomously

+heteronomy

+heterophil

+heterophile

+heterophony

+heterophyllous

+heterophylly

+heterophyte

+heterophytic

+heteroploid

+heteroploidy

+heteropolar

+heteropolarity

+heteropterous

+heteroscedasticity

+heterosexuality

+heterosis

+heterotic

+heterotopic

+heterotroph

+heterotrophic

+heterotrophically

+heterotypic

+heterotypical

+heterozygosis

+heterozygosity

+heterozygote

+hexad

+hexade

+hexadic

+hexagram

+hexahedron

+hexahydrate

+hexahydrated

+hexahydrite

+hexamethonium

+hexane

+hexaploid

+hexaploidy

+hexapod

+heywood

+hibernal

+hibernator

+hibiscus

+hickok

+hidalgo

+hidebound

+hidrosis

+hidrotic

+hie

+hieing

+hierarch

+hieratically

+hieroglyph

+hieroglyphical

+hieroglyphically

+higgle

+higgled

+higgler

+higgles

+higgling

+highbinder

+highborn

+highbred

+highbrow

+highbrowed

+highbrowism

+highline

+highlines

+hilding

+hillary

+hillocky

+hillyer

+hilum

+himation

+hindbrain

+hindquarter

+hingism

+hinkle

+hipbone

+hipped

+hipper

+hippest

+hippie

+hippocampal

+hippocampus

+hippocras

+hippogriff

+hipsterism

+hirey

+hirsute

+hirsuteness

+hirsutism

+hirsutulous

+hist

+histaminase

+histamine

+histaminergic

+histaminic

+histidine

+histologic

+histological

+histologically

+histologist

+histolysis

+histolytic

+histopathologic

+histopathological

+histopathologically

+histopathologist

+histopathology

+histophysiologic

+histophysiological

+histophysiology

+histoplasmosis

+historicist

+historiographer

+historiographic

+historiographical

+historiographically

+histrionically

+hithermost

+hitherward

+hiveless

+hmm

+hoarsen

+hoarsened

+hoarsening

+hobbledehoy

+hobday

+hobgoblin

+hobnail

+hobnailed

+hobnob

+hobnobbed

+hobnobber

+hobnobbing

+hobnobs

+hockaday

+hocus

+hocused

+hocusing

+hocussed

+hocussing

+hod

+hodad

+hodaddy

+hodoscope

+hoecake

+hoedown

+hoeing

+hogback

+hoggish

+hoggishly

+hoggishness

+hogshead

+hogwash

+hoi

+hoising

+hoistman

+hoistmen

+hokan

+hoke

+hokeypokey

+hoking

+hokum

+holabird

+holandric

+holandry

+holdall

+holdalls

+holdback

+holdfast

+holdout

+holdouts

+holeable

+holey

+holidaymaker

+holily

+holism

+holistically

+hollas

+hollo

+holloa

+holloware

+holoblastic

+holoblastically

+hologamous

+hologamy

+holograph

+holographic

+holographically

+hologynic

+hologyny

+holohedral

+holometabolism

+holometabolous

+holomyarian

+holophrastic

+holophytic

+holotype

+holotypic

+holozoic

+holt

+holzman

+hombre

+homburg

+homebody

+homebred

+homegrown

+homelike

+homeobox

+homeroom

+homesite

+homestretch

+hometown

+homey

+homeyness

+homier

+homiletic

+homiletical

+homiletically

+homiletics

+hominess

+hominid

+hominoid

+hominy

+homocercal

+homochromatic

+homoerotic

+homoeroticism

+homogametic

+homogamic

+homogamous

+homogeny

+homograft

+homograph

+homographic

+homoiotherm

+homoiothermal

+homoiothermic

+homolog

+homologate

+homologation

+homological

+homologically

+homolographic

+homolysis

+homolytic

+homomorphy

+homonuclear

+homonymic

+homonymous

+homonymously

+homonymy

+homoousian

+homophile

+homophobia

+homophone

+homophonic

+homophonous

+homophony

+homophyly

+homoplastic

+homoplastically

+homoplasy

+homopolar

+homopolymer

+homopteran

+homopterous

+homorganic

+homoscedastic

+homoscedasticity

+homosexuality

+homosporous

+homospory

+homothallic

+homothallism

+homotopy

+homotransplant

+homotransplantation

+homozygosis

+homozygosity

+homozygote

+homozygotic

+homunculi

+homunculus

+homy

+honcho

+honchos

+hondo

+honied

+honkeys

+honkie

+honoraria

+honorarily

+honorarium

+honorific

+honorific's

+honorifically

+honorifics

+hoodlike

+hoodlumish

+hoodlumism

+hoodoo

+hoodooism

+hoodoos

+hooey

+hoofbeat

+hoofprint

+hoofprint's

+hoofprints

+hookah

+hookey

+hookeys

+hooklet

+hooky

+hootch

+hootenanny

+hophead

+hopi

+hoplite

+hopple

+hora

+horary

+hord

+horehound

+horizonal

+hormonal

+hormonally

+hormonelike

+hornbeam

+hornbeams

+hornbill

+hornbills

+hornblende

+hornless

+hornlessness

+hornlike

+hornmouth

+hornpipe

+hornpipe's

+hornpipes

+hornswoggle

+hornswoggled

+hornswoggles

+hornswoggling

+horntail

+hornwort

+horologer

+horologic

+horological

+horologist

+horologists

+horology

+horrent

+horrific

+horrifically

+horsecar

+horsehide

+horselaugh

+horsemint

+horseradish

+horseradishes

+horseshit

+horsewhip

+horsewomen

+horsey

+horsier

+horsily

+horsiness

+horsy

+hortative

+hortatively

+hortatory

+horticultural

+horticulturally

+horticulturist

+hosanna

+hostel

+hosteler

+hostels

+hostler

+hotblood

+hotchpot

+hotchpotch

+hotelier

+hotfeet

+hotfoot

+hotfoot's

+hotfoots

+hotshot

+hottish

+houri

+housebound

+houseboy

+houseboys

+houseclean

+housecleaner

+housecleaning

+housecoat

+housedress

+housefather

+housefathers

+housefront

+houseful

+houseguest

+houseless

+houselessness

+houselights

+housemaid

+housemaids

+houseman

+housemate

+housemate's

+housemates

+housemother

+housemothers

+houseplant

+houseroom

+houseward

+housewarming

+housewifery

+howbeit

+howsoever

+howsomever

+hoyden

+hoydenish

+hoyle

+hubcap

+hubcap's

+hubcaps

+hubristic

+hubristically

+huck

+huckaback

+hucksterism

+hud

+huey

+huff

+huffier

+huffiness

+huffish

+huffy

+hugeous

+hugeously

+huggable

+hugger

+huggers

+hullabaloo

+hullabalooed

+hullabalooing

+hullabaloos

+hullo

+humanistically

+humanitarianism

+humankind

+humanlike

+humanoid

+humbug

+humbugged

+humbuggery

+humbugging

+humdinger

+humdrum

+humectant

+humeral

+humeri

+humerus

+humic

+humidor

+humification

+humifications

+humified

+hummable

+hummer

+hummocky

+humoresque

+humorism

+humorism's

+humorisms

+humoristic

+humoristical

+humoristical's

+humoristicals

+humoristics

+humph

+humpier

+humpty

+humpy

+hunchback

+hunchback's

+hunchbacked

+hunchbacks

+hundredweight

+hundredweights

+hup

+hurley

+hurly

+hurtless

+hurty

+hussar

+hussies

+hussy

+hustings

+hutzpah

+huzzah

+hyacinthine

+hyaena

+hyaenas

+hyalin

+hyaline

+hyalite

+hyaloid

+hyaloplasm

+hybridism

+hybridity

+hybris

+hydra

+hydrangea

+hydranth

+hydrator

+hydraulical

+hydrazide

+hydrazine

+hydric

+hydrically

+hydrobiological

+hydrobiologist

+hydrobiology

+hydrocarbonaceous

+hydrocarbonic

+hydrocarbonous

+hydrocephalic

+hydrocephalus

+hydrocephaly

+hydrocyanic

+hydrodynamical

+hydrodynamically

+hydrodynamicist

+hydroelectrically

+hydroelectricity

+hydrofoil

+hydroformer

+hydroforming

+hydrographer

+hydrographic

+hydrographically

+hydrography

+hydroid

+hydrokinetic

+hydrokinetics

+hydrolase

+hydrologic

+hydrologist

+hydrolysate

+hydrolytic

+hydrolytically

+hydromagnetic

+hydromagnetics

+hydromancy

+hydromechanical

+hydromechanics

+hydrometric

+hydrometrical

+hydrometry

+hydromorphic

+hydronic

+hydronically

+hydronium

+hydropathic

+hydropathically

+hydropathy

+hydroperoxide

+hydrophane

+hydrophile

+hydrophobicity

+hydrophone

+hydrophyte

+hydrophytic

+hydroplane

+hydroplaner

+hydroponic

+hydroponically

+hydroponics

+hydroscope

+hydrosere

+hydrosol

+hydrosolic

+hydrospace

+hydrospheric

+hydrostatical

+hydrostatically

+hydrosulfide

+hydrosulfite

+hydrotactic

+hydrotherapy

+hydrothorax

+hydrotropic

+hydrotropically

+hydrotropism

+hydroxylic

+hydroxyproline

+hydrozoan

+hyenic

+hyenoid

+hygienically

+hygienist

+hygienists

+hygrograph

+hygrometric

+hygrometry

+hygrophyte

+hygrophytic

+hygroscope

+hygroscopically

+hygroscopicity

+hyla

+hymenal

+hymeneal

+hymeneally

+hymenial

+hymenium

+hymnary

+hymnbook

+hymnody

+hymnology

+hyperacid

+hyperacidity

+hyperactive

+hyperactivity

+hyperbaric

+hyperbarically

+hyperbolical

+hyperbolist

+hyperborean

+hypercharge

+hypercritic

+hypercritical

+hypercritically

+hypercriticism

+hypereutectic

+hyperglycemia

+hyperglycemic

+hyperirritability

+hyperirritable

+hyperkeratosis

+hyperkeratotic

+hyperkinesis

+hyperkinetic

+hypermeter

+hypermeter's

+hypermeters

+hypermetric

+hypermetrical

+hypermetropia

+hypermetropic

+hypermetropical

+hypermetropy

+hypermnesia

+hypermnesic

+hypermorph

+hypermorphic

+hypermorphism

+hyperon

+hyperope

+hyperopia

+hyperopic

+hyperostosis

+hyperostotic

+hyperparasite

+hyperparasitic

+hyperparasitism

+hyperphagia

+hyperphysical

+hyperphysically

+hyperpituitarism

+hyperpituitary

+hyperplane

+hyperplanes

+hyperplastic

+hyperploid

+hyperploidy

+hypersensitive

+hypersensitiveness

+hypersensitivity

+hypersonic

+hypersonically

+hyperspace

+hypersurface

+hypertension

+hyperthermia

+hyperthermic

+hyperthyroid

+hyperthyroidism

+hypertonic

+hypertonicity

+hypertrophic

+hyperventilation

+hypha

+hyphal

+hyphenless

+hypnagogic

+hypnoanalysis

+hypnogenesis

+hypnogenetic

+hypnogenetically

+hypnogogic

+hypnoid

+hypnoidal

+hypnoses

+hypnotherapy

+hypnotism

+hypnotist

+hypnotists

+hypo

+hypocaust

+hypocentral

+hypochlorite

+hypochlorous

+hypochondria

+hypochondriac

+hypochondriacal

+hypochondriacally

+hypocoristic

+hypocoristical

+hypocoristically

+hypocritic

+hypocycloid

+hypodermically

+hypodermis

+hypoglycemia

+hypoglycemic

+hypoiodite

+hypomorphic

+hypos

+hypotension

+hypotensive

+hypothalmus

+hypothecate

+hypothecation

+hypothecator

+hypothenuse

+hypothermal

+hypothermic

+hypotonic

+hypotonically

+hypotonicity

+hypotrophy

+hypoxemia

+hypoxemic

+hypoxia

+hypoxic

+hypsography

+hypsometer

+hypsometer's

+hypsometers

+hypsometric

+hypsometry

+hysteretic

+hysteron

+iambus

+iambuses

+iatrogenic

+ibero

+ibex

+ibidem

+iceblink

+icebound

+icebreaker

+icecap

+icecap's

+icecaps

+icefall

+icehouse

+iceless

+iceman

+iceman's

+icemans

+ichneumon

+ichorous

+icily

+ickier

+icky

+iconically

+iconicity

+iconoclastic

+iconoclastically

+iconographer

+iconographic

+iconographical

+iconographically

+iconography

+iconolatry

+iconological

+iconology

+iconoscope

+icosahedra

+idealess

+idealistically

+ideality

+idealless

+idealogy

+ideational

+ideationally

+idem

+identic

+ideogram

+ideogram's

+ideogramic

+ideogrammatic

+ideogrammic

+ideograms

+ideograph

+ideographic

+ideographically

+ideography

+ideolect

+ideologic

+ideologue

+ideologues

+ideomotor

+ides

+idetic

+idiographic

+idiolectal

+idiomatically

+idiomorphic

+idiomorphically

+idiopathic

+idiopathically

+idioplasm

+idioplasmatic

+idioplasmic

+idiotical

+idioticalness

+idiotism

+idolater

+idolatrous

+idolatrously

+idolatrousness

+idyllically

+idyllist

+ie

+ignescent

+ignitable

+ignitible

+ignitor

+ignitron

+ignobility

+ignobly

+ignominiosness

+ignominy

+ignorable

+igor

+iguana

+ikon

+ilial

+illation

+illative

+illatively

+illaudable

+illaudably

+illegibility

+illegibly

+illiberal

+illiberalism

+illiberality

+illiberally

+illiberalness

+illimitability

+illimitably

+illiquid

+illiquidity

+illite

+illitic

+illogicality

+illon

+illuminable

+illuminance

+illuminant

+illuminati

+illuminator

+illuminators

+illuminism

+illuminist

+illus

+illusional

+illusionism

+illusionist

+illusionistic

+illusorily

+illust

+illustrational

+illuvial

+illuviate

+illuviation

+illuvium

+ilmenite

+im

+imaginal

+imaginarily

+imaginate

+imagism

+imagist

+imagistic

+imagistically

+imago

+imam

+imamate

+imaret

+imbecilic

+imbecility

+imbed

+imbibition

+imbibitional

+imbitter

+imbosom

+imbricate

+imbricately

+imbrication

+imbrown

+imbrue

+imbrued

+imbrute

+imbruted

+imbruting

+imdtly

+ime

+imidazole

+imide

+imidic

+imido

+imine

+imino

+imipramine

+imit

+imitational

+imitator

+immaculacy

+immane

+immanence

+immanency

+immanentism

+immanentist

+immanentistic

+immaterialism

+immaterialist

+immateriality

+immaturel

+immedicable

+immedicably

+immensurable

+immerge

+immerged

+immergence

+immerging

+immersible

+immesh

+immethodical

+immethodically

+immigrational

+imminency

+immingle

+immiscibility

+immiscible

+immiscibly

+immitigable

+immitigableness

+immitigably

+immittance

+immix

+immixture

+immoderacy

+immolate

+immolation

+immolator

+immoralist

+immotile

+immotility

+immunochemical

+immunochemically

+immunochemistry

+immunoelectrophoresis

+immunofluorescence

+immunofluorescent

+immunogenesis

+immunogenetic

+immunogenetically

+immunogenetics

+immunogenic

+immunogenically

+immunogenicity

+immunohematological

+immunohematology

+immunologic

+immunologist

+immunopathologic

+immunopathological

+immunopathologist

+immunopathology

+immunosuppression

+immunosuppressive

+immunotherapy

+immunotoxin

+immunotoxins

+immure

+immured

+immurement

+immures

+immuring

+immutability

+immutably

+impala

+impalement

+impalpability

+impalpably

+impanel

+imparadised

+imparity

+impartable

+impartible

+impartibly

+impartment

+impassability

+impassably

+impassibility

+impassible

+impassibly

+impassivity

+impeachable

+impeachment

+impeccability

+impecuniosity

+impecunious

+impecuniously

+impecuniousness

+impellor

+impendent

+impenitence

+impenitent

+impenitently

+imperate

+imperator

+imperatorial

+imperceptibility

+imperceptive

+imperceptiveness

+imperceptivity

+imperfectivity

+imperforate

+imperforated

+imperforates

+imperialistic

+imperialistically

+imperilment

+imperishability

+imperishably

+impermanency

+impermeability

+impermeably

+impermissibility

+impermissibly

+impersonality

+impersonator

+impertinence

+impertinency

+imperturbably

+impetrate

+impetrated

+impetrates

+impetrating

+impetration

+impetrations

+impetuosity

+impingement

+implacability

+implacably

+implantable

+implausibility

+implead

+implemental

+implode

+imploded

+implodes

+imploding

+implosion

+implosions

+implosive

+implosively

+impolitical

+impolitically

+imponderability

+imponderably

+importable

+importancy

+importunity

+imposthume

+imposture

+impoundment

+impracticability

+impracticably

+imprecatory

+impregnability

+impregnably

+impregnator

+impregnators

+impressibility

+impressibly

+impressionability

+impressionably

+impressional

+impressionistically

+imprimis

+imprisonable

+improbability

+improvability

+improvable

+improvably

+improvidence

+improvisator

+improvisatorial

+improvisatory

+improvisor

+imprudence

+impudicity

+impugnable

+impuissance

+impuissant

+imputability

+imputable

+imputative

+imputatively

+inadmissibly

+inadvertency

+inalienability

+inalienably

+inalterability

+inalterably

+inamorata

+inanition

+inapparent

+inappetence

+inapplicably

+inapposite

+inappositely

+inappositeness

+inaptitude

+inaugurator

+inaugurators

+inbound

+inbreathe

+incalculably

+incalescence

+incalescences

+incalescent

+incandesce

+incandesced

+incandescence

+incandesces

+incandescing

+incantational

+incantatory

+incapability

+incapacitator

+incardination

+incarnadine

+incase

+incaution

+incendiarism

+incertitude

+incessancy

+inchoate

+inchoately

+inchoateness

+inchoative

+inchoatively

+inchworm

+inchworm's

+inchworms

+incitant

+incitants

+incitation

+inclinable

+inclinational

+inclip

+includable

+includible

+incog

+incogitable

+incogitant

+incognita

+incognito

+incombustibility

+incommensurability

+incommensurably

+incommode

+incommodity

+incommunicability

+incommunicably

+incommunicative

+incommutably

+incompliant

+incompressibly

+incomputably

+inconceivability

+inconcinnity

+incondite

+inconscient

+inconsecutive

+inconsequence

+inconsequent

+inconsequentiality

+inconsolably

+inconsonant

+inconsumable

+inconsumably

+incontestability

+incontestably

+incontinency

+incontinent

+incontrovertibly

+inconveniency

+inconvertibly

+inconvincible

+incoordinate

+incoordination

+incorporator

+incorporeal

+incorporeity

+incorrigibility

+incorrigibly

+incorrupt

+incorrupted

+incorruptibly

+incorruptly

+incorruptness

+increate

+incrementalism

+incrementalist

+incrementalists

+increscent

+incriminate

+incriminated

+incriminates

+incrimination

+incriminatory

+incross

+incrossbred

+incrust

+incrustation

+incubational

+incubatory

+incudes

+inculcator

+inculpate

+inculpation

+inculpative

+inculpatory

+incult

+incumbency

+incumber

+incunabulum

+incurability

+incuriosity

+incurious

+incuriously

+incuriousness

+incurrence

+incurrent

+incurrer

+incurvate

+incurvated

+incurvates

+incurvating

+incurvation

+incurvature

+incurve

+incus

+incuse

+indagate

+indagation

+indagator

+indamine

+indecency

+indeclinable

+indecorum

+indefatigability

+indefatigably

+indefeasibility

+indefeasible

+indefeasibly

+indefectibility

+indefectible

+indefectibly

+indefensibility

+indefensibly

+indefinability

+indefinably

+indefinity

+indehiscence

+indehiscent

+indelibility

+indelicacy

+indemnifier

+indemnify

+indemonstrable

+indention

+independency

+indescribably

+indestructibility

+indestructibly

+indeterminably

+indeterminist

+indexical

+indican

+indicational

+indicatory

+indicia

+indictable

+indiction

+indictor

+indifferency

+indifferentism

+indifferentist

+indigen

+indigence

+indigene

+indigenes

+indigestibility

+indign

+indigotin

+indisciplinable

+indiscrete

+indiscussible

+indissociably

+indissolubility

+indissolubly

+indistinguishability

+indistinguishably

+indite

+indited

+inditer

+inditing

+indivertible

+indivertibly

+individualistically

+indivisibly

+indocile

+indocility

+indoctrinator

+indole

+indomitability

+indomitably

+indrawn

+indubitability

+indubitably

+inducibility

+indue

+indult

+indurate

+induration

+indurative

+indwell

+indweller

+indwelling

+inebriant

+inebriety

+inedible

+ineducability

+ineducable

+ineffability

+ineffably

+ineffaceability

+ineffaceably

+ineffectuality

+inelasticity

+inelegance

+ineliminable

+ineluctability

+ineluctably

+ineludible

+inenarrable

+ineptitude

+inequivalve

+inequivalved

+ineradicability

+ineradicably

+inerrancy

+inerrant

+inertance

+inestimably

+inexhaustibility

+inexhaustibly

+inexistence

+inexorability

+inexpedience

+inexpiably

+inexplicability

+inexpugnable

+inexpugnableness

+inexpugnably

+inexpungible

+inextinguishably

+inextricability

+infall

+infanta

+infantilism

+infantility

+infarct

+infarcted

+infarction

+infatuate

+infatuated

+infatuations

+infaunal

+infectivity

+infector

+infecundibility

+inferrer

+inferrible

+infestant

+infiltrator

+infiltrators

+infinitival

+inflammability

+inflammably

+inflammatorily

+inflationism

+inflationist

+inflator

+inflexion

+inflictor

+inflorescence

+inflorescences

+inflorescent

+informatics

+informatory

+infract

+infractor

+infrahuman

+infrangibility

+infrangible

+infrangibleness

+infrangibly

+infrasonic

+infraspecific

+infrastructural

+infrequence

+infrequency

+infundibular

+infundibulate

+infusibility

+infusoria

+infusorial

+infusorian

+ingather

+ingathering

+ingenue

+ingle

+ingratiatory

+ingress

+ingression

+ingressive

+ingressiveness

+ingrowing

+inguinal

+ingurgitate

+ingurgitation

+inhabitancy

+inhalational

+inhalator

+inharmonic

+inharmony

+inherence

+inheritability

+inhumanity

+inhumation

+inhume

+inhumed

+inhumes

+inhuming

+inimitably

+initialism

+initiatory

+initio

+injectant

+injector

+injectors

+injunct

+inkhorn

+inkiness

+inkle

+inkstand

+inkwell

+inky

+inmost

+innard

+innersole

+innerspring

+innervate

+innervated

+innervates

+innervating

+innervation

+innervational

+innerve

+innkeeper

+innkeeper's

+innkeepers

+innocency

+innominate

+innovational

+innovator

+innovatory

+innumerous

+inobservance

+inobservant

+inoculant

+inoculativity

+inoculator

+inoculum

+inoffensive

+inoffensively

+inoffensiveness

+inoperculate

+inosculate

+inosculated

+inosculates

+inosculating

+inosculation

+inositol

+inotropic

+inpatient

+inphase

+inpour

+inquisitional

+inquisitorial

+inquisitorially

+inrush

+insalubrious

+insalubrity

+insanitation

+insatiability

+insatiably

+insatiate

+insatiately

+insatiateness

+inscriptional

+inscriptive

+inscriptively

+inscroll

+inscrutably

+insculp

+inseam

+insectan

+insectary

+insecticidal

+insecticidally

+insectifuge

+insectile

+insectivore

+insectivore's

+insectivores

+insectivorous

+insectivory

+inseminator

+insentience

+insentient

+insertional

+insessorial

+insetted

+inshore

+insignificancy

+insinuator

+insipidity

+insistency

+insolate

+insolation

+insole

+insolubly

+insolvably

+insoul

+inspan

+inspectorate

+inspectorship

+insphere

+inspirator

+inspiratory

+inspirit

+inspissate

+inspissated

+inspissation

+inspissator

+instalment

+instalments

+instancy

+instantaneity

+instar

+instate

+instating

+instauration

+instil

+instillment

+instils

+institutionalism

+institutor

+instructorship

+instructress

+instrumentalism

+instrumentality

+insubstantiality

+insufferableness

+insufferably

+insufficience

+insufflate

+insufflated

+insufflates

+insufflating

+insufflation

+insufflator

+insugently

+insulant

+insularism

+insupportably

+insuppressibly

+insurability

+insurable

+insurgency

+insurmountably

+insuror

+insurrectional

+insurrectionary

+insurrectionist

+insusceptibly

+intaglio

+intangibility

+integrability

+integrality

+integrationist

+integrator

+integumental

+integumentary

+intellection

+intellectualism

+intellectualist

+intellectualistic

+intellectus

+intelligential

+intendance

+intendment

+intenerate

+inteneration

+intentionality

+intepupillary

+interactant

+interactional

+interatomic

+interbrain

+interbreed

+intercalary

+intercellular

+intercellularly

+intercession

+intercessional

+intercessor

+intercessory

+interclavicle

+interclavicular

+intercolumniation

+intercommunion

+intercomputer

+interconversion

+interconvert

+interconvertibility

+interconvertible

+intercooler

+intercostal

+intercostally

+intercrisis

+intercrop

+intercross

+intercultural

+interculturally

+intercurrent

+intercurrently

+intercut

+interdenominationalism

+interdental

+interdentally

+interdepend

+interdiction

+interdictor

+interdictory

+interdiffuse

+interdiffusion

+interdigitate

+interdigitation

+interfacial

+interfascicular

+interferential

+interferogram

+interferogram's

+interferograms

+interferometrically

+interfertile

+interfertility

+interfile

+interframe

+interfuse

+interfusion

+intergeneric

+intergradation

+intergradational

+intergrade

+intergrowth

+interhemispheric

+interionic

+interiority

+interjection

+interjectional

+interjectionally

+interjector

+interjectory

+interlacement

+interlaminate

+interlamination

+interlard

+interleaf

+interline

+interlinear

+interlinearly

+interlineation

+interlocal

+interlocution

+interlocutory

+interlope

+interloped

+interloper

+interlopes

+interloping

+interlunar

+interlunary

+intermarry

+intermeddle

+intermeddler

+intermediacy

+intermembrane

+intermetallic

+intermezzo

+intermit

+intermittence

+intermitter

+intermixture

+internality

+internationalism

+interne

+internecine

+internee

+internescine

+interneuron

+interneuronal

+internist

+internment

+internodal

+internode

+internship

+internuclear

+internuncial

+internuncially

+internuncio

+interoceptive

+interoceptor

+interoffice

+interpellate

+interpellation

+interpellator

+interpenetrate

+interpenetration

+interphase

+interplant

+interplead

+interpleader

+interpolator

+interpolatory

+interpretability

+interpretational

+interreligious

+interring

+interrogational

+interrogee

+interrogees

+interscholastic

+intersectoral

+interservice

+intersession

+intersex

+intersexual

+intersexuality

+intersexually

+interspace

+interspecific

+interstadial

+intersterile

+intersterility

+intersubjective

+intersubjectively

+intersubjectivity

+intertestamental

+intertidal

+intertidally

+intertie

+intertill

+intertillage

+intertropical

+intertwinement

+intertwist

+interurban

+intervale

+intervalometer

+intervalometer's

+intervalometers

+interventionism

+intervertebral

+intervertebrally

+interwar

+interweave

+interweaves

+interzonal

+interzone

+intestacy

+intima

+intimidator

+intimidatory

+intinction

+intine

+intitule

+intl

+intnl

+intonational

+intraarterial

+intraarterially

+intracardiac

+intracardial

+intracardially

+intracellular

+intracellularly

+intracranial

+intracranially

+intracutaneous

+intracutaneously

+intradermal

+intradermally

+intrados

+intraepithelial

+intragalactic

+intramolecular

+intramolecularly

+intrans

+intransigeance

+intransigeant

+intransigeantly

+intrant

+intraperitoneal

+intraperitoneally

+intrapersonal

+intrapopulation

+intrapsychic

+intrapsychically

+intraspecies

+intraspecific

+intraspecifically

+intrauterine

+intravascular

+intravital

+intravitally

+intravitam

+intrazonal

+intreat

+intrench

+intrepidity

+intrigant

+intriguant

+intrinsical

+intrinsicalness

+introductorily

+introgressant

+introgression

+introgressive

+introit

+introjection

+intromission

+intromit

+intromittent

+intromitter

+introrse

+introrsely

+introspectional

+introspectionism

+introspectionist

+introspectionistic

+introversive

+introversively

+intrvascularly

+intsv

+intuit

+intuiting

+intuitional

+intuitionism

+intumesce

+intumescence

+intumescent

+intussuscept

+intussusception

+intussusceptive

+inulin

+inundator

+inundatory

+inurement

+inurn

+inutility

+inv

+invaginate

+invaginated

+invaginates

+invaginating

+invagination

+invalidator

+inveiglement

+invenit

+inventorial

+inventorially

+inventress

+invercalt

+invertase

+investable

+investigational

+investiture

+inveteracy

+invictus

+invigorator

+inviible

+invincibility

+invincibly

+inviolableness

+inviolably

+inviolacy

+inviscid

+invitatory

+invocational

+invocatory

+involucral

+involucrate

+involucre

+involucred

+involucrum

+involutional

+involutionary

+invulnerably

+inweave

+iodic

+iodin

+iodoamino

+iodocompounds

+iodoform

+iodophor

+iodoprotein

+iodopsin

+iodothyronines

+iodotyrosines

+iodous

+ione

+ionicity

+ionium

+ionospherically

+iosola

+iotacism

+ipecacuanha

+iproniazid

+ipsilateral

+ipsilaterally

+iraqi

+irascibility

+irascible

+irascibleness

+irascibly

+ireful

+irenaeus

+irenic

+irenically

+irenics

+irid

+iridaceous

+irides

+iridescence

+iridescent

+iridescently

+iridic

+iridosmine

+irina

+ironbound

+ironclad

+ironfisted

+ironhanded

+ironhandedly

+ironhandedness

+ironhearted

+ironist

+ironmaster

+ironmonger

+ironmongery

+ironware

+ironweed

+irradiance

+irradiator

+irradicable

+irradicably

+irrationalism

+irrationalist

+irrationalistic

+irreal

+irreality

+irreclaimable

+irreclaimably

+irreconcilability

+irreconcilably

+irreconciliable

+irrecoverably

+irrecusable

+irrecusably

+irred

+irredenta

+irreducibility

+irreformability

+irreformable

+irrefragability

+irrefragable

+irrefragably

+irrefrangible

+irrefutability

+irrefutably

+irreg

+irregardless

+irrelative

+irrelatively

+irreligion

+irreligionist

+irreligious

+irreligiously

+irremeable

+irremediably

+irremovability

+irremovably

+irrepealability

+irrepealable

+irreplaceability

+irreplaceably

+irrepressibility

+irrepressibly

+irreproachability

+irreproachably

+irresoluble

+irrespirable

+irresponsive

+irresponsiveness

+irretrievability

+irretrievably

+irreversibility

+irrevocability

+irrigational

+irrigationists

+irrigator

+irrigators

+irrotational

+irrotationally

+irrupt

+irrupted

+irrupting

+irruptive

+irruptively

+irrupts

+isentropic

+islandia

+ism

+isoagglutination

+isoagglutinative

+isoagglutinin

+isoagglutinogen

+isoalloxazine

+isoantibody

+isoantigen

+isoantigenic

+isoantigenicity

+isobar

+isobaric

+isobutylene

+isochromatic

+isochron

+isochrone

+isochronism

+isoclinal

+isoclinally

+isoclinic

+isoclinically

+isogram

+isogram's

+isograms

+isolationist

+isolator

+isologue

+isomagnetic

+isomerase

+isomeric

+isomerism

+isomerous

+isometrical

+isometrically

+isometry

+isomorphous

+isoniazid

+isonomy

+isooctane

+isophotal

+isophote

+isopiestic

+isotonically

+isotonicity

+isotopically

+isotopy

+isozyme

+isozymic

+issuable

+issuably

+issueless

+isthmic

+italianate

+itchiness

+itchy

+iterance

+iterant

+itineracy

+itinerancy

+itinerate

+itinerated

+itinerates

+itinerating

+itineration

+itsy

+iud

+iuds

+izaak

+jabber

+jabbered

+jabberer

+jabbering

+jabbers

+jabberwocky

+jabot

+jackal

+jackal's

+jackals

+jackanapes

+jackassery

+jacketted

+jacketting

+jackhammer

+jackscrew

+jacobite

+jacoby

+jacquerie

+jactitation

+jagger

+jaggery

+jaggy

+jai

+jailbait

+jailbird

+jailbreak

+jailor

+jalousie

+jamb

+jambalaya

+jammer

+janis

+janitress

+japanned

+japanner

+japanning

+jape

+japer

+japery

+japes

+japing

+japonica

+jardiniere

+jarful

+jargonistic

+jasmine

+jauntily

+java

+javanese

+jawbreaker

+jawline

+jaybird

+jazzily

+jazzman

+jeanne

+jeepable

+jeeringly

+jell

+jelled

+jelling

+jello

+jells

+jellylike

+jerkily

+jerkin

+jerkwater

+jeroboam

+jessy

+jesuitic

+jesuitical

+jesuitically

+jesuitry

+jetbead

+jetport

+jetsam

+jettied

+jetties

+jettisonable

+jetty

+jettying

+jeunes

+jib

+jibber

+jibbers

+jibbing

+jibboom

+jiff

+jigged

+jigglier

+jiggly

+jimjams

+jingly

+jingo

+jingoes

+jingoish

+jingoism

+jingoist

+jingoistic

+jingoistically

+jink

+jinks

+jinn

+jinni

+jinny

+jitney

+jitneys

+jiujutsu

+jobbed

+jobber

+jobbers

+jobrel

+jocosity

+jocularity

+jocundity

+jodhpur

+jodhpurs

+jogger

+joggers

+jogging

+joinable

+joinder

+joinery

+jointress

+jointure

+jointured

+jointures

+jointuring

+jointworm

+joist

+joists

+jollification

+jollifications

+jolty

+jouncier

+jouncy

+jour

+journalistically

+journeywork

+jow

+jowlier

+jowly

+joyance

+jubilarian

+judgmatic

+judgmatical

+judgmatically

+judoist

+jugful

+jugged

+juggernaut

+juggernaut's

+juggernauted

+juggernauting

+juggernauts

+jugglery

+jugular

+jugulum

+juiceless

+juicily

+jujitsu

+jujutsu

+jukebox

+julienne

+junco

+junctional

+junctor

+jungian

+jungly

+junkyard

+junto

+juntos

+jural

+jurally

+jurassic

+jurat

+jure

+jurel

+juridic

+jurisconsult

+jurisconsults

+juristic

+juristically

+jussive

+jussives

+juste

+justiciability

+justiciar

+justifiability

+justificative

+justificatory

+justment

+jutted

+juttied

+jutties

+jutty

+juttying

+juvenescence

+juvenescent

+juvenilia

+juvenility

+juvenocracy

+juxtapositional

+kaftan

+kaiser

+kale

+kaleidoscope

+kaleidoscoped

+kaleidoscopes

+kaleidoscopic

+kaleidoscopical

+kaleidoscopically

+kaleidoscoping

+kalmia

+kapok

+kaput

+karateist

+karma

+karmic

+karyatid

+katydid

+kava

+kayak

+kayaker

+kayaks

+kayo

+kayoed

+kayoing

+kebab

+kebabs

+keddah

+keegan

+keelboat

+keelhaul

+keelless

+keelson

+keepsake

+keepsakes

+keeshond

+kegful

+kegsful

+kelts

+kerchieves

+kern

+kerne

+kernite

+kerosine

+kerry

+kerygma

+kestrel

+ketch

+ketches

+ketene

+keto

+ketogenesis

+ketogenic

+ketonic

+ketose

+ketosteroid

+ketotic

+kettledrum

+kewaskum

+kewaunee

+keybutton

+keyless

+keyway

+keyways

+khrush

+kibble

+kibbled

+kibbles

+kibbling

+kibbutz

+kibbutznik

+kibe

+kibosh

+kickapoo

+kickshaw

+kickshaws

+kickstand

+kickup

+kickups

+kiddish

+kiddush

+kiddy

+kidskin

+kiel

+kielbasa

+killdeer

+killebrew

+kiln

+kilo

+kilobar

+kilocalorie

+kilocalories

+kilocurie

+kilocycle

+kilocycles

+kilooersted

+kiloparsec

+kilorad

+kilos

+kilt

+kilter

+kindergartner

+kindless

+kindlessly

+kine

+kinematical

+kinematically

+kinescope

+kinescoped

+kinescopes

+kineses

+kinesic

+kinesiology

+kinesis

+kineticist

+kinetin

+kinetochore

+kinetonucleus

+kinetoplast

+kinetoplastic

+kinetoscope

+kinetosome

+kinfolk

+kinfolks

+kingfish

+kingmaker

+kingship

+kingside

+kingwood

+kinkajou

+kinkajou's

+kinnickinnic

+kinsey

+kinsfolk

+kinswoman

+kip

+kipper

+kippered

+kippering

+kippers

+kips

+kirk

+kirkwood

+kirsch

+kismet

+kissable

+kitchenware

+kitchenwares

+kith

+kithe

+kithing

+kitschy

+kittle

+kittled

+kittler

+kittles

+kittling

+kiva

+kivu

+kiwi

+kiwi's

+kiwis

+kiz

+kizzie

+klatch

+klatsch

+klauber

+kleptomania

+kleptomaniac

+kline

+knackery

+knavery

+knavish

+knavishly

+kneadable

+kneehole

+kneeholes

+knickknack

+knifelike

+knish

+knitter

+knitwear

+knobbed

+knobeloch

+knockabout

+knockabouts

+knothole

+knotter

+knotweed

+knout

+knoweth

+knowily

+knowledgeability

+knowledgeably

+knucklebone

+knucklebones

+knucklehead

+knuckleheaded

+koine

+koinonia

+kola

+kolkhoz

+kombu

+konga

+konrad

+kook

+kookaburra

+kookie

+kookier

+kookiness

+kooky

+kooning

+kopeck

+kopek

+kowtow

+kpc

+kraemer

+kraken

+kremlinologist

+kremlinology

+kretchmer

+krummholz

+kudo

+kudu

+kulak

+kultur

+kurdish

+kwashiorkor

+labdanum

+labellate

+labellum

+labia

+labiate

+lability

+labium

+laborious

+laboriously

+laboriousness

+laborsaving

+labradorite

+labyrinthian

+labyrinthine

+laceless

+lacelike

+lacemaker

+lacewing

+lacework

+lacey

+laches

+lachrymal

+lachrymator

+lachrymose

+lachrymosely

+lacier

+laciniate

+laciniated

+laciniation

+lackaday

+laconic

+laconically

+laconics

+laconism

+laconisms

+lacrimal

+lacrimation

+lacrimator

+lactase

+lacteal

+lactic

+lactiferousness

+lactobionamide

+lactobionamides

+lactobionic

+lactobionyl

+lactogenic

+lactoglobulin

+lactone

+lactonic

+lacunal

+lacunar

+lacunaria

+lacunary

+lacunate

+lacustrine

+lacy

+ladanum

+laddie

+lade

+ladybird

+ladybird's

+ladybirds

+ladybug

+ladybug's

+ladybugs

+ladyfern

+ladyfinger

+ladykin

+ladylove

+ladyship

+lage

+lagger

+lagniappe

+lagomorph

+lagomorphic

+lagomorphous

+lagoonal

+laguna

+laic

+laical

+laically

+laicism

+laird

+lairdly

+laitance

+laitances

+lakefront

+lakeshore

+lakewood

+lakh

+laky

+lallygag

+lallygagged

+lam

+lama

+lamasery

+lambast

+lambaste

+lambency

+lambent

+lambently

+lambert

+lambertian

+lambeth

+lambkill

+lambskin

+lamebrain

+lamebrained

+lamella

+lamellae

+lamellar

+lamellarly

+lamellas

+lamellate

+lamellately

+lamellation

+lamelliform

+lametedly

+lamia

+laminal

+laminaria

+laminarian

+laminarin

+laminator

+laminin

+lampoonery

+lamster

+lanai

+lancelet

+lanceolate

+lanceolately

+lancet

+lanceted

+lancinate

+lancinated

+lancinates

+lancinating

+lancination

+lancinations

+landaulet

+landes

+landfall

+landform

+landlocked

+landlordism

+landlubber

+landlubberly

+landmass

+landmasses

+landowning

+landside

+landslip

+landslips

+landsman

+landward

+landwards

+lanesmanship

+langeland

+languishment

+languorous

+languorously

+langur

+lankily

+lanolin

+lanuginous

+lanuginousness

+lanyard

+laodicean

+laparotomy

+lapboard

+lapdog

+lapful

+lapidarian

+lapper

+lappet

+lapstrake

+lapstreak

+lapwing

+larcener

+larcenist

+larcenous

+larcenously

+lardy

+lares

+largehearted

+largess

+larghetto

+largish

+largo

+largos

+larkier

+larkspur

+larky

+larvicidal

+larvicide

+larynges

+laryngitis

+laryngology

+laryngoscope

+laryngoscopic

+lasagna

+lasagne

+lascar

+lase

+lassie

+lassies

+lassitude

+lassitudes

+lassoes

+latchet

+latchkey

+latchstring

+latecomer

+latecomers

+lateen

+lateener

+lateiner

+latened

+latening

+latensification

+latensifications

+latensified

+latensifies

+latensify

+latera

+laterite

+lathery

+latices

+laticiferous

+latish

+latitudinarian

+latitudinarianism

+latten

+latticework

+lattimer

+latus

+laudability

+laudable

+laudableness

+laudation

+laudations

+laudative

+laudatorily

+laughterful

+launderability

+launderette

+launderettes

+laundress

+laundryman

+laundrywoman

+laurate

+laureateship

+lavabo

+lavage

+lavaged

+lavalava

+lavaliere

+lavalike

+lavallade

+lavalliere

+lavation

+lavational

+lavato

+lave

+laveer

+laver

+laverock

+laving

+lawmaker

+lawny

+laxation

+layabout

+layabouts

+layaway

+layerage

+layette

+layover

+layovers

+laypeople

+laywoman

+laywomen

+laze

+lazes

+lazyish

+lea

+leachable

+leadeth

+leadier

+leadless

+leadoff

+leadwork

+leady

+leafage

+leaflike

+leafstalk

+leafstalks

+leakily

+leant

+leapfrogged

+leapfrogging

+learnable

+leary

+leastways

+leastwise

+leasure

+leatherback

+leatherlike

+leatherwork

+lecherous

+lecherously

+lecherousness

+lecithin

+lecithinase

+lectern

+lectern's

+lecterns

+lectin

+lectin's

+lectins

+lection

+lectionary

+lectureship

+lederhosen

+ledgy

+leeboard

+leeds

+leftism

+legalese

+legalism

+legalist

+legalistic

+legalistically

+legateship

+legatine

+legator

+legendarily

+legendry

+legerity

+leges

+legionary

+legionnaire

+legionnaires

+legis

+legislatorial

+legislatorship

+legislatress

+legislatrix

+legist

+legit

+legitimism

+legitimist

+legless

+legman

+legroom

+legwork

+lei

+leith

+lemke

+lemony

+lemur

+lemures

+lengthways

+lenience

+lenis

+lenitive

+lenitively

+lenity

+lense

+lensless

+lenticulate

+lenticulation

+lentissimo

+lento

+leopardess

+leotard

+leotards

+lepidolite

+lepidopterist

+leprechaun

+leprechauns

+leprotic

+leprous

+leprously

+leprousness

+lepton

+lepton's

+leptons

+leptospiral

+les

+lesbianism

+lessee

+letch

+letdown

+letdowns

+lethargic

+lethargically

+letted

+letterpress

+letup

+leu

+leucine

+leucite

+leucitic

+leucoma

+leukemic

+leukemoid

+leukocyte

+leukocytic

+lev

+levanter

+levator

+levatores

+levators

+leveeing

+levelheaded

+levelheadedness

+leven

+leveret

+leviathan

+leviathan's

+levigate

+levigated

+levigates

+levigating

+levigation

+levirate

+leviratic

+levitational

+levorotation

+levorotatory

+levulose

+lewellyn

+lewisite

+lexica

+lexicality

+lexicographer

+lexicographer's

+lexicographers

+lexicography

+lexicostatistic

+lexicostatistics

+ley

+liaise

+liaised

+liaises

+liaising

+liana

+lib

+libationary

+libelist

+liber

+liberace

+liberalist

+liberalistic

+liberationist

+liberationists

+libertarianism

+libertie

+libertinage

+libertinism

+libidinal

+libidinally

+libra

+librae

+librarianship

+librate

+libration

+librational

+libratory

+libriform

+licating

+licenseless

+licenselesses

+licensure

+licentiate

+licentiateship

+lichee

+lichenous

+licht

+lichtenstein

+lichter

+lickerish

+lickerishly

+lickerishness

+lickspittle

+lictor

+lidded

+lido

+lidocaine

+lidos

+lieberman

+lief

+lierne

+lieutenancy

+lieve

+lifeful

+lifeline

+lifelines

+lifemanship

+lifesaver

+lifeway

+lifework

+liftable

+liftman

+ligamentary

+ligamentous

+ligate

+ligated

+ligates

+ligating

+ligation

+ligations

+lighterage

+lightface

+lightfaced

+lightfooted

+lightfootedly

+lightfootedness

+lightful

+lighthanded

+lighthandedness

+lightheaded

+lightish

+lightless

+lightship

+lightsome

+lightsomely

+lightsomeness

+lightyear

+lightyears

+ligneous

+lignification

+lignified

+lignifies

+lignify

+lignifying

+lignin

+lignitic

+lignocellulose

+ligulate

+ligule

+ligure

+likability

+likable

+likableness

+lilliput

+lilliputian

+limba

+limbless

+limbus

+limeade

+limekiln

+limen

+limey

+limier

+liminal

+limitable

+limitary

+limitational

+limitative

+limitrophe

+limmer

+limn

+limner

+limnetic

+limnic

+limning

+limnological

+limnologically

+limnologist

+limnology

+limo

+limo's

+limonene

+limonite

+limonitic

+limos

+limpet

+limpidity

+limpkin

+limpsy

+limulus

+limy

+linac

+linage

+linate

+linated

+lination

+linchpin

+linchpin's

+linchpins

+lindy

+lineality

+lineament

+lineamental

+lineation

+linebacking

+linebreed

+linecaster

+linecasting

+lineolate

+lineolated

+lineprinter

+lineprinter's

+lineprinters

+linerless

+linesman

+linga

+lingoes

+lingonberry

+linguae

+linguine

+linguistical

+linguistician

+lingulate

+linin

+linkboy

+linkman

+linksman

+linkup

+linoleate

+linoleic

+linolenate

+linos

+lintel

+linty

+linum

+lionhearted

+lionlike

+lipide

+lipidic

+lipless

+liplike

+lipolysis

+lipolytic

+lipped

+lippen

+lippier

+lipping

+lippy

+lipread

+lipreading

+liquate

+liquated

+liquates

+liquating

+liquation

+liquations

+liquefactive

+liquefactive's

+liquefactives

+liquefiability

+liquefiable

+liquescent

+liquidator

+liquorice

+lira

+liras

+lire

+lisle

+liss

+lissom

+lissome

+lissomely

+lissomeness

+liste

+listel

+listenable

+listeriosis

+liston

+literalist

+literalistic

+literality

+literarily

+literati

+literatim

+literator

+literatus

+litharge

+lithesome

+lithia

+lithiasis

+lithic

+lithically

+litho

+lithographic

+lithographically

+lithologic

+lithological

+lithologically

+lithophane

+lithophyte

+lithophytic

+lithopone

+lithos

+lithosol

+lithotomy

+lithuanian

+litigable

+litotes

+litterateur

+litterbag

+littermate

+littermate's

+littermates

+littery

+liturgiologist

+liturgiology

+liturgist

+litz

+liveability

+liveable

+livelily

+livelong

+liverish

+liverishness

+liveryman

+lividity

+livlihood

+lixiviate

+lixiviated

+lixiviates

+lixiviating

+lixiviation

+lizzy

+llama

+llama's

+llamas

+llano

+llanos

+lo

+loach

+loaches

+loanable

+loanword

+loanword's

+loanwords

+lobar

+lobate

+lobated

+lobately

+lobation

+lobbing

+lobbyer

+lobbyism

+lobbyist

+lobectomy

+lobelia

+lobeline

+loblolly

+lobo

+lobos

+lobscouse

+lobsterman

+lobstermen

+lobulate

+lobulated

+lobulation

+lobulose

+localism

+localite

+locatable

+loch

+lockable

+lockage

+lockbox

+locket

+lockies

+lockjaw

+lockstep

+lockstitch

+loco

+locoes

+locofoco

+locoism

+locomote

+locomoted

+locomotes

+locomoting

+locular

+loculate

+loculated

+loculation

+locule

+loculed

+loculus

+locution

+locutor

+lode

+loden

+lodestar

+lodgement

+loess

+loftily

+logbook

+loggets

+loggia

+loggie

+loggy

+logia

+logicality

+logistician

+lognormal

+lognormality

+lognormally

+logo

+logogram

+logogram's

+logogrammatic

+logograms

+logograph

+logographic

+logographically

+logogriph

+logomachy

+logorrheic

+logos

+logotype

+logroll

+logroller

+logrolling

+logwood

+logy

+lollipop

+lollop

+lollygag

+lollypop

+londonderry

+lonelily

+longanimity

+longanimous

+longboat

+longboats

+longbow

+longbowman

+longeron

+longevous

+longhair

+longhaired

+longhead

+longheaded

+longheadedness

+longhouse

+longlegs

+longline

+longshoreman

+longshoring

+longsome

+longsomely

+longsomeness

+longspur

+longstreet

+longue

+longwinded

+loo

+loobies

+looby

+looney

+loonier

+looniness

+loony

+loosestrife

+lopper

+loppier

+loppy

+lopseed

+loquat

+loran

+lorans

+lorca

+lordling

+lordosis

+lordotic

+loreal

+lorgnette

+lorgnettes

+lorgnon

+lorgnons

+loricate

+loricated

+loris

+lorn

+lornness

+lory

+los

+losable

+losableness

+losel

+loth

+lotharios

+lotos

+lotted

+lotting

+lotto

+loudmouth

+loudmouthed

+lough

+loup

+loupe

+louping

+lousily

+lout

+loutish

+loutishly

+loutishness

+louts

+loveable

+lovejoy

+lovelily

+lovelock

+lovelocks

+lovemaking

+lovesick

+lovesickness

+lovesome

+lowborn

+lowbred

+lowbrow

+lowermost

+lowery

+lowlihead

+lowlily

+lown

+lox

+loxes

+loxodrome

+loxodromic

+loxodromically

+loxodromics

+loy

+loyola

+lubber

+lubberland

+lubberlanders

+lubberliness

+lubberly

+lubbers

+lube

+lubric

+lubrical

+lubricator

+lubricous

+lubritorium

+lucency

+lucien

+luciferous

+lucubrate

+lucubrated

+lucubrates

+lucubrating

+lucubration

+lucubrations

+lucubrator

+luculent

+luculently

+ludmilla

+lues

+luetic

+luetically

+luggageless

+lugger

+lugubrious

+lugubriously

+lugubriousness

+lukemia

+lum

+lumbago

+lumberjack

+lumberjack's

+lumberjacks

+lumbian

+lumenal

+lumens

+lumina

+luminaire

+luminal

+luminance

+luminesce

+luminesced

+luminescing

+luminiferous

+luminist

+lummus

+lumpily

+luncheonette

+lune

+lunes

+lunette

+lungfish

+lunisolar

+lunitidal

+lunker

+lunkhead

+lunkheaded

+lunt

+lunule

+luny

+lupanar

+lupulin

+lupus

+lurdane

+lusion

+lustihood

+lustra

+lustral

+lustrate

+lustrated

+lustrates

+lustrating

+lustration

+lustrations

+lustrum

+luteal

+lutenist

+luteous

+lutetium

+lutihaw

+lux

+luxate

+luxated

+luxates

+luxating

+luxation

+luxations

+lycanthropic

+lycanthropy

+lycee

+lyceum

+lychee

+lychnis

+lycidas

+lymphadenitis

+lymphatic

+lymphatically

+lymphoblast

+lymphoblastic

+lymphocytic

+lymphocytosis

+lymphoid

+lymphomatoid

+lymphomatosis

+lymphomatous

+lymphopoiesis

+lyndon

+lyonnaise

+lyophile

+lyophilic

+lyophobic

+lyotropic

+lyrate

+lyrated

+lyrately

+lyrebird

+lyrebird's

+lyrebirds

+lyrism

+lyrist

+lysate

+lyse

+lysergic

+lyses

+lysimeter

+lysimeter's

+lysimeters

+lysimetric

+lysin

+lysine

+lysing

+lysis

+lysogen

+lysogenic

+lysogenicity

+lysogeny

+lysolecithin

+lysosomal

+lysosomally

+lysosome

+lysozyme

+lytically

+macadam

+macaque

+macaronic

+macaronically

+macaronies

+macaroon

+macaw

+macaw's

+macaws

+macerate

+macerated

+macerates

+macerating

+maceration

+macerations

+macerator

+macerators

+machete

+machicolate

+machicolation

+machinability

+machinate

+machinated

+machinates

+machinating

+machinator

+machineable

+mackerel

+mackerels

+mackle

+mackled

+mackles

+macklin

+mackling

+macle

+macled

+macrame

+macroaggregate

+macroaggregated

+macrobiotic

+macrobiotics

+macrocephalic

+macrocephalous

+macrocephaly

+macrocosm

+macrocosmic

+macrocosmically

+macrocyte

+macrocytic

+macrocytosis

+macroeconomic

+macroevolution

+macroevolutionary

+macrofossil

+macrogamete

+macroinstruction

+macron

+macronucleus

+macronutrient

+macropathological

+macropathology

+macrophagic

+macrophyte

+macrophytic

+macroscale

+macroscopical

+macrostructural

+macrostructure

+macrostructure's

+maculate

+maculated

+maculates

+maculating

+maculation

+maculations

+macule

+madded

+maddish

+madrigalian

+madrigalist

+madrilene

+madrona

+madrone

+madstone

+madstones

+madwoman

+madwomen

+maelstrom

+maelstrom's

+maelstroms

+maenadic

+maeterlinck

+mafia

+mafioso

+magazinism

+magazinist

+magazinists

+maggotries

+maggotry

+magicked

+magicking

+magill

+magisterium

+magistracy

+magistral

+magistrally

+magistrateship

+magistratical

+magistratically

+magistrature

+magma

+magmatic

+magna

+magnesian

+magnetitic

+magnetodynamo

+magnetoelectric

+magnetoelectrical

+magnetoelectricity

+magnetofluidmechanic

+magnetofluidmechanics

+magnetogasdynamic

+magnetogasdynamics

+magnetogram

+magnetogram's

+magnetograms

+magnetograph

+magnetohydrodynamic

+magnetohydrodynamics

+magnetometer

+magnetometer's

+magnetometers

+magnetometric

+magnetometry

+magnetomotive

+magneton

+magnetooptic

+magnetooptical

+magnetooptics

+magnetoscope

+magnetosphere

+magnetospheric

+magnetostatic

+magnetostriction

+magnetostrictive

+magnetostrictively

+magnetron

+magnetrons

+magnific

+magnifical

+magnifically

+magnifico

+magniloquence

+magniloquent

+magniloquently

+magtape

+magtapes

+maguire

+maguires

+magus

+maharaja

+maharaja's

+maharajah

+maharanee

+maharani

+maharishi

+mahatma

+mahatmaism

+mahler

+mahlstick

+mahout

+maidenhead

+maidenhood

+maidhood

+maidish

+maieutic

+maieutical

+maieutics

+mailability

+mailbag

+mailbags

+mailboat

+mailboats

+maillot

+mailplane

+mailplanes

+mailsack

+mailsacks

+mainmast

+mainsail

+mainsheet

+mainspring

+maintop

+maisonette

+maisonettes

+maitre

+maitres

+maize

+maizer

+maizers

+maizes

+majestical

+majolica

+majordomo

+majordomos

+majorette

+majorettes

+majuscular

+majuscule

+makeable

+makebate

+makefast

+makepeace

+makeshifty

+makeweight

+mako

+makos

+mal

+malachite

+malacologic

+malacological

+malacologist

+malacology

+malacostracan

+maladaptation

+maladminister

+maladministration

+malamud

+malamute

+malapert

+malapertly

+malapertness

+malapportioned

+malapportionment

+malappropriate

+malappropriated

+malappropriates

+malappropriating

+malapropian

+malapropos

+malar

+malarian

+malariated

+malariologist

+malariology

+malarkey

+malate

+malathion

+malaxate

+malaxated

+malaxates

+malaxating

+malconduct

+malconformation

+maldevelopment

+maldistribute

+maldistribution

+maledictory

+malefaction

+malefic

+maleficence

+maleficent

+malemute

+malentendu

+malfeasance

+malgovernment

+malic

+maliferous

+malignance

+malignity

+malinger

+malingered

+malingerer

+malism

+malleability

+mallemuck

+malleus

+mallow

+malmsey

+malodorous

+malodorously

+malodorousness

+malolactic

+malposition

+malpractitioner

+maltase

+maltobionic

+maltose

+maltreatment

+maltster

+malty

+malvasia

+malvasian

+malversation

+malvoisie

+mammalogist

+mammalogy

+mammary

+mammer

+mammies

+mammillar

+mammillary

+mammillate

+mammillated

+mammock

+mammography

+mammon

+mammonism

+mammonist

+mammonite

+mammy

+mana

+manacle

+manacled

+manacles

+manacling

+manageability

+manageably

+managemental

+manageress

+managership

+manchet

+mancipation

+mancipatory

+manciple

+manciples

+mandala

+mandarinate

+mandarinates

+mandarinic

+mandarinism

+mandataries

+mandatary

+mandator

+mandatorial

+mandibular

+mandibulate

+mandola

+mandolinist

+mandolinists

+mandorla

+mandragora

+mandrel

+mandril

+mandrill

+manducate

+manducated

+manducates

+manducating

+manege

+manful

+manfully

+manfulness

+manganate

+manganesian

+manganic

+manganite

+manganous

+mange

+mangel

+mangier

+mangily

+manginess

+mango

+mango's

+mangos

+mangrove

+mangy

+manhandle

+manhandled

+manhandles

+manhandling

+manhunt

+manhunts

+manically

+manicotti

+manicurist

+manifestant

+manifesto

+manifesto's

+manifestoed

+manifestoes

+manifestoing

+manifestos

+manioc

+manipular

+manitowoc

+mankowski

+manless

+manlike

+mannerist

+manneristic

+mannerless

+mannikin

+mannish

+mannishly

+mannishness

+mannitic

+mannitol

+mannopyranosyl

+mannosyl

+manometric

+manometrical

+manometrically

+manometry

+manorialism

+manque

+manrope

+manropes

+mansard

+mansarded

+manse

+manship

+manslayer

+mansuete

+mansuetude

+mantelet

+mantelpiece

+mantelshelf

+mantic

+mantis

+mantises

+mantra

+mantua

+manubrium

+manuduction

+manuductory

+manufactory

+manumission

+manumit

+manumitted

+manumitting

+manurial

+manuscriptal

+manward

+manwards

+manwise

+manyfold

+manzanita

+maplecrest

+mapmaker

+mapmakers

+mapmaking

+mapper

+mappery

+mappist

+mappists

+maquillage

+maquis

+marabou

+maraschino

+marasmic

+marasmus

+maraud

+marauder

+marauding

+marauds

+marbly

+marcelled

+marcelling

+marchesa

+marchese

+marchioness

+marchpane

+marconigram

+marconigram's

+marconigrams

+marcotte

+margarita

+marginate

+marginated

+marginates

+marginating

+margination

+marginations

+mariachi

+marimba

+marish

+marjoram

+markdown

+marketeer

+marketeer's

+marketeering

+marketeers

+marketwise

+markovitz

+marksmen

+markswoman

+markswomen

+markup

+markups

+marl

+marline

+marmoreal

+marmoreally

+marmorean

+marmoset

+marmoset's

+marmosets

+marmot

+marplot

+marque

+marquet

+marquisate

+marquise

+marquisette

+marrowfat

+marrowless

+marrowy

+marse

+marshalcy

+marshalship

+marshier

+marshiness

+marshmallowy

+marshy

+marsupial

+marsupial's

+marsupials

+marsupium

+martensite

+martensitic

+martensitically

+martinet

+martlet

+martyrologies

+martyrologist

+martyrologists

+martyrology

+martyry

+marzipam

+marzipan

+maskable

+masochism

+masochistic

+masochistically

+massbus

+masseter

+masseteric

+masseur

+masseurs

+masseuse

+massicot

+massif

+massifs

+massy

+mastectomies

+mastectomy

+mastership

+mastersinger

+mastersingers

+masterstroke

+masterstrokes

+masterwork

+masthead

+mastic

+masticate

+masticated

+masticates

+masticating

+mastication

+mastications

+masticator

+masticators

+masticatory

+mastitic

+mastodonic

+mastodont

+mastoid

+mastoidectomy

+mastoideus

+mastoiditis

+masturbational

+masturbatory

+matador

+matchboard

+matchboarding

+matchlock

+matchwood

+matelote

+materfamilias

+materialist

+materialistically

+materiality

+matey

+maths

+matinal

+matins

+matriarchate

+matriarchy

+matric

+matricidal

+matricide

+matriculant

+matrilineal

+matrilineally

+matroid

+matronymic

+matt

+matte

+mattei

+mattery

+mattie

+mattock

+matutinal

+matutinally

+matzo

+matzos

+maude

+maudlinism

+maudlinisms

+maugre

+mauricio

+maxi

+maxilla

+maxillae

+maxillary

+maxillas

+maxilliped

+maxillipede

+maximalist

+mayapple

+mayflower

+mayfly

+mayoralty

+mayoress

+maypole

+mayst

+mazy

+mazzard

+mea

+meadowlark

+meadowlark's

+meadowlarks

+meagre

+mealie

+mealymouth

+mealymouthed

+mealymouthedly

+mealymouthedness

+mealymouthednesses

+meandrous

+measurability

+measureless

+meatball

+meatballs

+meath

+meatman

+meatmen

+mech

+mechanician

+mechanistically

+mechanoreceptor

+mecholyl

+mecum

+medallic

+meddlesome

+meddlesomeness

+mediacy

+mediad

+mediae

+medial

+medially

+mediant

+mediational

+mediatorial

+mediatorship

+mediatory

+mediatress

+mediatresses

+mediatrice

+mediatrix

+medicable

+medicably

+medicaid

+medicament

+medicamented

+medicamenting

+medicamentous

+medicaments

+medicare

+medicinable

+medicolegal

+medievalise

+medievalises

+medievalism

+medievalism's

+medievalisms

+medievalistic

+medievalistics

+meditator

+mediumship

+medlar

+medlars

+medulla

+medullary

+medullated

+medusae

+medusoid

+meerschaum

+megabuck

+megacycle

+megagamete

+megagametophyte

+megakaryocyte

+megakaryocytic

+megalith

+megalithic

+megaloblast

+megaloblastic

+megalomaniacal

+megalomaniacally

+megalomanic

+megalopolis

+megalopolistic

+megalopolitan

+megalopolitanism

+megalopteran

+megalopterous

+megaparsec

+megaphone

+megaphonic

+megapolis

+megapolitan

+megarians

+megascopic

+megascopically

+megasporangium

+megaspore

+megasporic

+megasporogenesis

+megasporophyll

+megillah

+megrim

+megrims

+meiosis

+meiotic

+meiotically

+meister

+melancholia

+melancholiac

+melancholic

+melancholically

+melanic

+melanism

+melanist

+melanistic

+melanite

+melanitic

+melanoblast

+melanoblastic

+melanoblastoma

+melanochroic

+melanocyte

+melanogenesis

+melanoid

+melanophore

+melanosis

+melanotic

+melatonin

+melic

+melies

+meliorator

+meliorism

+meliorist

+melioristic

+mell

+melliferous

+mellifluent

+mellifluently

+mellifluous

+mellifluously

+mellifluousness

+mellitin

+mellophone

+melodist

+melodramatically

+melodramatist

+meltability

+meltable

+meltdown

+meltdown's

+meltwater

+meltwaters

+membranal

+membraneless

+membranous

+membranously

+meme

+memorably

+memorialist

+memoriter

+menarcheal

+mencken

+menckenese

+mendable

+mendicancies

+mendicancy

+mendicant

+mendicants

+mendicities

+mendicity

+mendoza

+menhaden

+menhir

+meningeal

+meninges

+meningitic

+meningitis

+meningococcal

+meningococcic

+meninx

+menisci

+meniscus

+meniscuses

+menominee

+menopausal

+menorah

+menorrhagia

+menorrhagic

+mensal

+mensch

+mense

+menseful

+menseless

+menservants

+menstruous

+menstruum

+mensurability

+mensural

+mensurational

+menswear

+mentalist

+mentation

+mentations

+menthol

+mentholated

+mentorship

+mentum

+meow

+meow's

+meowed

+meowing

+meows

+mephitic

+mephitis

+mercantilism

+mercantilist

+mercantilistic

+mercenarily

+mercery

+merchantable

+merchantman

+merchantmen

+mercurate

+mercurated

+mercurates

+mercurating

+mercuration

+mercurations

+mercurous

+merganser

+mergence

+mergences

+meridional

+meridionally

+merino

+meristically

+meriwether

+meroblastic

+meroblastically

+merocrine

+meromorphic

+meromyosin

+merrick

+merrimac

+merrymaker

+merryman

+merrythought

+mescal

+mesdames

+mesdemoiselles

+meseems

+mesenteric

+mesenteron

+meshwork

+meshy

+mesial

+mesially

+mesic

+mesically

+mesmerically

+mesmerism

+mesmerisms

+mesmerist

+mesmerists

+mesne

+mesoblast

+mesoblastic

+mesocarp

+mesoderm

+mesodermal

+mesodermic

+mesomerism

+mesomorph

+mesomorphic

+mesomorphism

+mesomorphy

+mesonephric

+mesonephros

+mesonic

+mesopause

+mesopelagic

+mesophase

+mesophases

+mesosome

+mesosphere

+mesospheric

+mesothoracic

+mesothorax

+mesothorium

+mesotron

+mesotronic

+mesotrophic

+messaline

+messiahship

+messianic

+messianism

+messuage

+messuages

+mestizo

+metabole

+metabolically

+metacarpal

+metacarpus

+metacentric

+metachromatic

+metaethical

+metaethics

+metagalactic

+metagalaxies

+metagalaxy

+metagenesis

+metagenetic

+metagenetically

+metalicities

+metalicity

+metalicity's

+metallically

+metallike

+metallist

+metallists

+metallographer

+metallographic

+metallographically

+metallographist

+metalloidal

+metallurgist

+metalware

+metamathematician

+metamathematics

+metamere

+metameric

+metamerically

+metamerism

+metamorphically

+metanephric

+metanephros

+metaph

+metaphase

+metaphysician

+metaplasia

+metaplasm

+metaplasmic

+metaplastic

+metaprotein

+metapsychological

+metapsychology

+metasomatic

+metasomatically

+metasomatism

+metastability

+metastable

+metastably

+metastasis

+metastatic

+metastatically

+metatarsal

+metatarsally

+metatarsus

+metate

+metathesis

+metathetic

+metathetical

+metathetically

+metathoracic

+metazoa

+metazoal

+metazoan

+metempsychosis

+metencephalic

+metencephalon

+meteorically

+meteoritical

+meteorograph

+meteorographic

+meteoroidal

+meteorol

+meteorologic

+meteorologicaly

+meteorologist

+methacrylate

+methadon

+methadone

+methamphetamine

+methanolic

+metheglin

+methinks

+methionine

+methodic

+methodistic

+methodologist

+methought

+methylal

+methylamine

+methylase

+methylate

+methylated

+methylation

+methylator

+methylcholanthrene

+methylic

+methylnaphthalene

+methylphenidate

+meticulosity

+metier

+metis

+metonym

+metonymic

+metonymical

+metonymically

+metonymy

+metope

+metopon

+metrazol

+metrication

+metrist

+metrological

+metrologically

+metrologist

+metrology

+metronomic

+metronomical

+metronomically

+mewl

+mezuza

+mezuzah

+mezzanine

+mezzanines

+mezzotint

+miasmatic

+miasmic

+micaceous

+micellar

+micelle

+micelle's

+micelles

+micra

+microampere

+microamperes

+microanalyst

+microanalytical

+microanatomical

+microanatomy

+microbarograph

+microbe

+microbe's

+microbeless

+microbes

+microbic

+microbiologic

+microbiological

+microbiologically

+microbiologist

+microbiology

+microbus

+microcalorimetric

+microcephalic

+microcephaly

+microcircuit

+microcircuitry

+microcircuits

+microcirculation

+microcirculatory

+microclimate

+microclimates

+microclimatic

+microclimatological

+microclimatologist

+microclimatology

+microcline

+microclines

+micrococcal

+micrococcus

+microconsumer

+microcontroller

+microcopier

+microcopy

+microcosmic

+microcosmically

+microcrystal

+microcrystalline

+microcrystallinity

+microcyte

+microcytic

+microdensitometer

+microdensitometer's

+microdensitometers

+microdensitometric

+microdensitometry

+microdissection

+microdomain

+microdomains

+microelectrode

+microelectronic

+microelectronically

+microelectronics

+microelectrophoresis

+microelectrophoretic

+microelectrophoretical

+microelectrophoretically

+microelement

+microencapsulate

+microencapsulation

+microenvironment

+microenvironmental

+microevolution

+microevolutionary

+microfarad

+microfarads

+microfauna

+microfaunal

+microfibril

+microfibrillar

+microfiche

+microfiches

+microfilaria

+microfilarial

+microfine

+microflash

+microflora

+microfloral

+microform

+microfossil

+microfungal

+microfungus

+microgamete

+microgametocyte

+micrograph

+micrographer

+micrographers

+microgroove

+microhabitat

+microhardness

+microinch

+microinjection

+microlith

+microlithic

+micromania

+micromanipulation

+micromanipulator

+micromere

+micrometeorite

+micrometeoroid

+micrometeorological

+micrometeorologist

+micrometeorology

+micromethod

+micrometric

+micrometry

+micromicrofarad

+micromicrofarads

+micromicron

+microminiature

+micronuclear

+micronucleate

+micronucleus

+micronutrient

+micronutrients

+microorganic

+micropaleontologic

+micropaleontological

+micropaleontologist

+micropaleontology

+microparasite

+microparasites

+microparasitic

+microphage

+microphonic

+microphonics

+microphotograph

+microphotographer

+microphotographic

+microphotography

+microphotometer

+microphotometer's

+microphotometers

+microphotometric

+microphotometrically

+microphotometry

+microphyll

+microphyllous

+microphysical

+microphysically

+microphysics

+micropipet

+micropipette

+microplankton

+micropore

+microporosity

+microporous

+microprint

+microprobe

+microprogrammable

+microprojection

+microprojector

+micropulsation

+micropump

+micropylar

+micropyle

+microradiograph

+microradiographic

+microradiography

+microreader

+microrelief

+microreproduction

+microscale

+microscopist

+microsection

+microseism

+microseismic

+microseismicity

+microsome

+microsomes

+microspectrophotometer

+microspectrophotometer's

+microspectrophotometers

+microspectrophotometric

+microspectrophotometrical

+microspectrophotometrically

+microspectrophotometry

+microsphere

+microspheric

+microsporangium

+microspore

+microsporic

+microstate

+microstructural

+microstructurally

+microstructure

+microstructures

+microsurgery

+microsurgical

+microtechnic

+microtechnique

+microtome

+microtomes

+microtonal

+microtonality

+microtonally

+microtone

+microtones

+microtubular

+microtubule

+microtubules

+micturate

+micturated

+micturates

+micturating

+micturition

+micturitions

+midafternoon

+midbrain

+midcapacity

+midcourse

+midden

+middens

+middies

+middlebrow

+middlebrowism

+middlebrows

+middorsal

+middy

+midfield

+midfielder

+midget

+midgut

+midline

+midmost

+midplane

+midportion

+midrash

+midrashic

+midrashim

+midrib

+midribbed

+midriff

+midriffs

+midsemester

+midsole

+midsummery

+midtown

+midwatch

+midwatches

+midwifery

+midwing

+midwintry

+midwived

+midwiving

+mig

+mightless

+mignonette

+migraine

+migraines

+migrainous

+migrancy

+migratetic

+migratetics

+migrational

+migrationist

+migrationists

+migrator

+migratorial

+migs

+mikado

+mikhail

+mikoyan

+mila

+milacre

+milady

+milanese

+milch

+mildewcide

+mildewproof

+mildewy

+mildhearted

+mildish

+milepost

+milesian

+milfoil

+milfoils

+milia

+miliaria

+miliarial

+miliarias

+miliary

+milieux

+milinch

+militance

+militances

+militancies

+militancy

+militaristic

+militaristically

+militaryism

+militaryisms

+militiaman

+milium

+milkily

+milkless

+milklike

+milkman

+milkmen

+milksop

+milksopping

+milksoppy

+milkstone

+millable

+millage

+millboard

+millcourse

+milldam

+millenaries

+millenary

+millenia

+millennial

+millerite

+millesimal

+millesimally

+millhouse

+milliammeter

+milliammeter's

+milliammeters

+milliard

+milliary

+millibar

+millibarn

+millicron

+millicurie

+millicycle

+millidarcy

+millieme

+milliemes

+milliequivalent

+millifarad

+milligal

+millihenry

+millihertz

+millihg

+millilambert

+millilux

+millime

+millimetric

+millimicrofarad

+millimicrofarads

+millimicron

+millimicrosecond

+millimolar

+millimolarity

+millimole

+milline

+milliner

+millionairedom

+millionairess

+millionary

+millionfold

+milliphot

+millipoise

+millirad

+milliroentgen

+millman

+millmen

+millowner

+millpond

+millponds

+millrace

+millraces

+millsite

+millstream

+millstreams

+milord

+milquetoast

+milquetoasts

+milt

+milter

+mim

+mimetism

+mimical

+mimicry

+mimosa

+min

+minable

+minaret

+minareted

+minarets

+minatory

+mincy

+mineable

+minestrone

+minesweeping

+mingy

+miniaturist

+miniaturistic

+miniaturists

+minibus

+minibuses

+minicam

+minicamera

+minicar

+minicartridge

+minikin

+minim

+minimalism

+ministrable

+ministrant

+ministration

+minitrack

+minium

+minot

+minous

+minster

+minstrelsy

+mintage

+minuscular

+minutia

+minutial

+minx

+minxes

+miocrystalline

+mioses

+miosis

+miotic

+mirabilite

+miracular

+miraculism

+miraculisms

+miraculist

+miraculists

+mirate

+mirated

+mirates

+mirating

+miration

+mirations

+mirky

+mirrorlike

+mirrory

+mirthful

+mirthfully

+mirthfulness

+mirths

+miry

+misaddress

+misaddressed

+misadjustment

+misadventure

+misadventured

+misadventures

+misadventurous

+misadvise

+misaim

+misalliance

+misally

+misandry

+misanthropically

+misanthropism

+misanthropist

+misanthropists

+misanthropy

+misappreciate

+misappreciation

+misapprehend

+misapprehended

+misapprehending

+misapprehendingly

+misapprehends

+misapprehension

+misapprehensions

+misapprehensive

+misapprehensively

+misapprehensiveness

+misappropriate

+misappropriates

+misappropriation

+misarranged

+misarrangement

+misarray

+misascription

+misassignment

+misattribution

+misbecome

+misbecoming

+misbeget

+misbehadden

+misbeholden

+misbelief

+misbelieve

+misbeliever

+misbelieving

+misbelievingly

+misbeseem

+misbestow

+misbirth

+misc

+miscalculate

+miscalculates

+miscalculating

+miscalculator

+miscall

+miscaller

+miscast

+miscasting

+miscasts

+miscegenational

+miscellanea

+miscellaneity

+miscellanist

+miscellanists

+mischance

+mischiefful

+miscibility

+miscible

+misclassifications

+misclassify

+miscomprehend

+miscomprehension

+misconceit

+misconceive

+misconceived

+misconceiver

+misconceives

+misconceiving

+misconduct

+misconducted

+misconducting

+misconducts

+miscontent

+miscontentment

+miscook

+miscopy

+miscorrect

+miscorrected

+miscounsel

+miscounseled

+miscreance

+miscreances

+miscreate

+miscreation

+miscreative

+miscreator

+misdate

+misdeal

+misdealing

+misdeem

+misdeems

+misdeliver

+misdelivered

+misdelivery

+misdemean

+misdescribe

+misdescription

+misdescriptive

+misdo

+misdoer

+misdoing

+misdoubt

+miseducated

+miseducation

+misemphasis

+misemphasization

+misemphasize

+misemphasized

+misemphasizes

+misemphasizing

+misemploy

+misemployment

+misericorde

+mises

+misesteem

+misestimate

+misestimation

+misfeasance

+misfeasor

+misfeed

+misfile

+misfiled

+misfiles

+misfiling

+misgive

+misgives

+misgovern

+misgovernment

+misguidance

+mishandle

+mishandled

+mishandles

+mishandling

+mishear

+mishmash

+misimpression

+misimprove

+misinformative

+misintelligence

+misinterpretable

+misjoinder

+misknow

+misknowledge

+misknows

+mislabel

+mislay

+mislaying

+mislays

+misleared

+mislike

+mismachine

+mismanagement

+mismarriage

+mismate

+misogamic

+misogamist

+misogamists

+misogamy

+misogynic

+misogynistic

+misologist

+misology

+misoneism

+misorder

+misperception

+misperceptions

+misplay

+mispleading

+mispoint

+mispraise

+misprint

+misprision

+misprisions

+misprize

+misprized

+misprizes

+misprizing

+mispunctuate

+mispunctuation

+misquotation

+misquote

+misquotes

+misreckon

+misrecollect

+misrecollection

+misregister

+misregistration

+misremember

+misreport

+misrepresentative

+misrule

+misruled

+misruler

+misrules

+misruling

+missend

+misshape

+misshapes

+missileer

+missileers

+missileman

+missilemen

+missilery

+missilry

+missionate

+missort

+missout

+misspeak

+misspend

+misspended

+misspender

+misspending

+misspends

+misstrike

+misterm

+mistful

+misthink

+mistily

+mistime

+mistimed

+mistrain

+mistranslate

+mistranslation

+mistreatment

+mistrustful

+mistrustfully

+mistrustfulness

+misusage

+misvalue

+misventure

+miswrite

+miswrites

+miswriting

+mitch

+miterwort

+mitigator

+mitigators

+mitigatory

+mitochondria

+mitochondrion

+mitogenesis

+mitogenetic

+mitogenic

+mitoinhibitory

+mitosis

+mitotic

+mitotically

+mitral

+mitt

+mitted

+mittimus

+mitts

+mitzvah

+mitzvah's

+mitzvahes

+mixable

+mixologist

+mixologists

+mixology

+mizzenmast

+mizzle

+mizzled

+mizzles

+mizzling

+mizzly

+mlea

+moanful

+moanfully

+mobbish

+mobbishly

+mobbishness

+mobbism

+mobocracy

+mobocrat

+mobocratic

+mocha

+mockernut

+moderationist

+moderatism

+moderato

+moderatorship

+modernist

+modicity

+modificative

+modiste

+modulability

+modulatory

+moduli

+mogul

+mohair

+mohm

+moil

+moiler

+moiling

+moilingly

+moistureless

+molality

+molarity

+moldable

+molecularity

+moleskin

+moleskins

+molestation

+molestations

+molluscan

+molluskan

+molotov

+molt

+molter

+molto

+molts

+molucca

+moly

+molybdate

+molybdic

+molybdous

+momental

+momentaneous

+monachal

+monachism

+monadism

+monandrous

+monandry

+monarchal

+monarchial

+monarchical

+monarchically

+monarchism

+monarchist

+monarchistic

+monarchists

+monasterial

+monastical

+monastically

+monatomic

+monde

+mondrian

+monel

+moner

+monestrous

+monet

+monetarily

+moneybags

+moneylender

+moneylending

+moneyless

+moneymake

+moneymaker

+moneywort

+monger

+mongered

+mongering

+mongers

+mongolism

+mongoloid

+mongrel

+mongrelism

+mongrelly

+mongrelness

+monic

+monicker

+monied

+moniker

+monilia

+monish

+monism

+monist

+monistic

+monistical

+monition

+monitions

+monitorial

+monitorially

+monitorship

+monitory

+monitress

+monkeries

+monkery

+monkeyflower

+monkeyshine

+monkhood

+monoacid

+monoacidic

+monoamine

+monochasial

+monochromat

+monochromatically

+monochromaticity

+monochromatism

+monochromic

+monochromist

+monocline

+monocoque

+monocracy

+monocrat

+monocratic

+monocultural

+monoculture

+monocycle

+monocyclic

+monocycly

+monocyte

+monocytic

+monodisperse

+monodist

+monodrama

+monodramatic

+monoecious

+monoeciously

+monoecism

+monoenergetic

+monoester

+monofilament

+monofuel

+monogamic

+monogamist

+monogamists

+monogastric

+monogenean

+monogenesis

+monogenetic

+monogenic

+monogenically

+monogerm

+monogram

+monogram's

+monogrammatic

+monograms

+monographic

+monographical

+monography

+monogynous

+monogyny

+monohybrid

+monoid

+monolayer

+monologuist

+monomania

+monomaniac

+monometallic

+monometer

+monometer's

+monometers

+monomolecular

+monomolecularly

+monomorphemic

+monomorphic

+monomorphism

+monomorphous

+monophonically

+monophony

+monophthong

+monophthongal

+monophyletic

+monophyletism

+monoplane

+monoploid

+monopodial

+monopodially

+monopolist

+monopolistically

+monopropellant

+monopsony

+monopulse

+monorail

+monorail's

+monorails

+monosaccharide

+monosaccharides

+monosomic

+monostat

+monostatic

+monosyllabically

+monosyllabicity

+monosymmetric

+monosymmetry

+monosynaptic

+monosynaptically

+monotheist

+monotheistical

+monotheistically

+monotint

+monotrematous

+monotreme

+monotrichous

+monotype

+monotypic

+monovalent

+monovular

+monoxide

+monozygotic

+monsoonal

+monstrance

+monstrances

+montaigne

+monte

+monticule

+monumentless

+mooch

+moocher

+mooches

+mooching

+moola

+moolah

+moonbeam

+moonbeam's

+moonbeams

+moonbow

+mooncalf

+mooneye

+moonish

+moonishly

+moonless

+moonlet

+moonquake

+moonrise

+moonscape

+moonseed

+moonset

+moonstone

+moonstruck

+moonward

+moony

+moorage

+mopper

+moppet

+morainal

+morainic

+moralism

+moralistically

+morassy

+moray

+mordacious

+mordaciously

+mordacity

+mordancy

+mordent

+morehouse

+morel

+moresque

+morganatic

+morganatically

+morganite

+moribundity

+moron

+moronically

+moronism

+moronity

+morosity

+morph

+morphinic

+morphinism

+morpho

+mort

+mortarboard

+mortem

+mortgagor

+mortgagors

+mortimer

+mortise

+mortising

+mortmain

+mortuaries

+mortuary

+mortuary's

+mosaically

+mosaicism

+mosaicist

+moscone

+mosey

+moseyed

+moseying

+mosquitoey

+mossback

+mossbacked

+mosslike

+mot

+mote

+motet

+mothball

+motherhouse

+motherless

+motherlessness

+mothproof

+mothproofer

+motile

+motility

+motivic

+motivity

+motoneuron

+motorbike

+motorboat

+motorboater

+motorboating

+motorcade

+motorcade's

+motorcades

+motorcyclist

+motordrome

+motoric

+motorically

+motorless

+motortruck

+motorway

+mots

+moulage

+moulin

+moulins

+moult

+mountaintop

+mountaintop's

+mountaintops

+mountainy

+mountebank

+mountebankery

+mousetrap

+mousey

+mousily

+moussaka

+mousse

+mouthier

+mouthlike

+mouthpart

+mouthy

+movability

+movably

+moveless

+movelessly

+movelessness

+moviedom

+moviegoer

+moviemaker

+mown

+moxie

+mozzarella

+mu

+muciferous

+mucilaginous

+mucilaginously

+muckrake

+muckraker

+muckraking

+mucosa

+mucous

+mudded

+muddily

+mudhole

+mudhole's

+mudholes

+mudsill

+mudstone

+mudstones

+muezzin

+mufti

+muftis

+mugged

+mugger

+muggily

+mugho

+mugwump

+muhammad

+mukluk

+muley

+muliebrity

+mullein

+mullet

+mullets

+mullion

+mullite

+multiaperture

+multicavity

+multicellularity

+multichip

+multicollector

+multicompletion

+multicoupler

+multicycle

+multideck

+multielectrode

+multiengine

+multifactorial

+multifactrially

+multifarious

+multifariously

+multifariousness

+multifold

+multiform

+multiformity

+multihued

+multilane

+multilaned

+multilayer

+multilayered

+multilayers

+multilingual

+multilingualism

+multilingualist

+multilingually

+multimeter

+multimeter's

+multimeters

+multinucleate

+multinucleated

+multipactor

+multiparous

+multipartite

+multiphase

+multiphasic

+multiphastic

+multiplicable

+multiplicate

+multiplicates

+multipolar

+multipolarity

+multipronged

+multiracial

+multiracialism

+multisectoral

+multisegment

+multistatic

+multistory

+multivalence

+multivalued

+multivolume

+multivolumed

+mummer

+mummery

+mumming

+mump

+mumper

+mumps

+mundt

+mung

+munificence

+munist

+munroe

+muonic

+muralist

+murderee

+murderess

+muriate

+murkily

+murmurous

+murmurously

+murrain

+murre

+murrey

+murrow

+muscadine

+muscatel

+muscly

+muscularity

+musculoskeletal

+musee

+musette

+musettes

+mushily

+musicale

+musicological

+musicologist

+musketeer

+musketry

+muskie

+muskier

+muskies

+muskiness

+musky

+mussier

+mussily

+mussiness

+mussy

+mustily

+mutably

+mutafacient

+mutagen

+mutagenesis

+mutagenic

+mutagenically

+mutagenicity

+mutandis

+mutase

+mutatis

+muticous

+mutilator

+mutine

+mutined

+mutining

+mutinous

+mutinously

+mutinousness

+muttonchops

+muttony

+mutualism

+mutualist

+mutualistic

+mutuel

+muumuu

+muzzier

+muzzily

+muzziness

+muzzy

+mycobacteria

+mycoplasma

+mycorrhiza

+mycosis

+mycotic

+myel

+myeline

+myeloid

+myocarditis

+myofibril

+myoglobin

+myopically

+myosin

+myosotis

+myotic

+myotome

+myotonia

+myriameter

+myriameter's

+myriameters

+myriapod

+myriopod

+myristate

+myrmecological

+myrrh

+mystagogy

+mythmaker

+mythmaking

+mythologer

+mythologic

+mythologist

+mythomania

+mythomaniac

+mythopoeic

+mythopoetic

+mythopoetical

+mythos

+nacelle

+nacreous

+nagger

+naiad

+naivety

+nakamura

+nakoma

+namable

+nannies

+nanny

+nanook

+napalm

+nape

+napery

+napes

+naphthalene

+naphthalenic

+naphthene

+naphthenic

+naphthol

+napless

+napper

+nappier

+nappies

+nappy

+narc

+narcism

+narcissi

+narcissism

+narcist

+narcolepsy

+narcoleptic

+narcos

+narcotically

+narrational

+narrowminded

+narwal

+narwhal

+narwhal's

+narwhals

+nascence

+nascency

+nastic

+natant

+natation

+natations

+natatorial

+natatorium

+natatory

+nate

+nates

+nationalistically

+nativism

+nativist

+nativistic

+nattily

+naturalistically

+naturam

+naturopath

+naughtily

+nauseant

+nauseous

+nauseously

+nauseousness

+nauseum

+naut

+navaho

+nave

+naves

+navicular

+navigability

+navigably

+navigational

+navigationally

+navona

+navtas

+naw

+nawab

+nazification

+nazifications

+nazified

+nazifies

+nazify

+nazifying

+neath

+nebbish

+nebulosity

+necessitarian

+necessitarianism

+necessitous

+necessitously

+necessitousness

+neckerchief

+necrological

+necrologist

+necrologists

+necrology

+necromantically

+necrophagia

+necrophagous

+necrophagy

+necrophilia

+necrophilic

+necrophilism

+necropolis

+necroses

+nectareous

+nectarine

+needlelike

+needlewoman

+needlewomen

+nefarious

+nefariously

+nefariousness

+negational

+negativist

+negativistic

+negativists

+negaton

+negatron

+neglectful

+neglectfully

+neglectfulness

+negligibility

+negligibly

+negotiability

+negotiator

+negotiators

+negotiatory

+negrophile

+negrophilism

+nematicidal

+nematicide

+nematocyst

+nemeses

+nemophila

+neo

+neoanthropic

+neoclassicism

+neoclassicist

+neocosmic

+neofascism

+neogenesis

+neogenetic

+neoglycolipid

+neoglycolipids

+neoliberalism

+neolith

+neological

+neologistic

+neology

+neonate

+neoorthodox

+neoorthodoxy

+neoplasia

+neoplasm

+neoplastic

+neoplasticism

+neoplasticist

+neoplasticists

+neostigmine

+neotenic

+neoteny

+neoteric

+neotype

+nepenthe

+nepenthean

+nephanalysis

+nepheline

+nephelinic

+nephelinite

+nephelinitic

+nephelite

+nephelometer

+nephelometer's

+nephelometers

+nephelometric

+nephelometry

+nephometer

+nephometer's

+nephometers

+nephoscope

+nephrectomy

+nepotism

+nepotist

+nepotistic

+nepotists

+nereid

+nervation

+nervations

+nervosity

+nescience

+nesciences

+nescient

+nethermost

+netkeeper

+netless

+netlike

+netter

+netty

+neumatic

+neuralgic

+neuritic

+neuroanatomic

+neuroanotomy

+neuroblastoma

+neurochemistry

+neurocirculatory

+neuroendocrine

+neuroepithelial

+neurofibril

+neurofibrillary

+neurogenic

+neurogenically

+neuroglia

+neuroglial

+neuronic

+neuropathic

+neuropathically

+neuropathy

+neurospora

+neurosurgeon

+neurosurgery

+neurosurgical

+neurotically

+neuroticism

+neurotoxic

+neurotoxicity

+neurotoxin

+neurotropic

+neutercane

+neutralistic

+neutronium

+neutrophil

+neutrophile

+neutrophilic

+neutrophilis

+neutrophils

+neve

+nevermore

+nevers

+nevus

+newbury

+newfangled

+newfangledness

+newish

+newsagent

+newsagents

+newsbreak

+newsier

+newsiness

+newsless

+newsmagazine

+newsmonger

+newsprint

+newsroom

+newsy

+niacin

+nib

+nibelungenlied

+nibs

+niccolo

+nickelic

+nickeliferous

+nickelodeon

+nickelous

+nicklaus

+nicknameless

+nicotinamide

+nicotinic

+nidification

+nidifugous

+nietzschean

+nigger

+nightclothes

+nightclubber

+nightglow

+nightie

+nighties

+nightlong

+nightshade

+nightside

+nightstand

+nightstick

+nighttide

+nightwalker

+nighty

+nihilianism

+nihilistically

+nihility

+nijinsky

+nill

+nilmanifold

+nimbostratus

+nimiety

+nimming

+nincompoop

+nincompoopery

+ninebark

+ninepin

+ninepins

+ninetyfold

+ninnies

+ninny

+ninnyhammer

+nipper

+nippers

+nippier

+nippily

+nippiness

+nippy

+nisei

+niseis

+nit

+nite

+nitid

+nitrator

+nitrification

+nitrifications

+nitrify

+nitrile

+nitro

+nitrobenzene

+nitrocellulose

+nitrocellulosic

+nitrofuran

+nitroglycerin

+nitroparaffin

+nitros

+nitrosamine

+nitrosoamine

+nitty

+nitwit

+nitwitted

+nobbier

+nobble

+nobbled

+nobbling

+nobby

+noblewoman

+nocent

+noces

+nociceptive

+nock

+nocking

+noctambulation

+noctambulism

+noctambulist

+nocturn

+nocuous

+nocuously

+nodality

+nodder

+noddies

+noddle

+noddy

+nodi

+nodical

+nodose

+nodosity

+nodulation

+nodus

+noes

+noetic

+nog

+noggin

+nogging

+nohow

+noisome

+noisomely

+noisomeness

+nolo

+noma

+nomad

+nomadic

+nomadism

+nomads

+nomenclator

+nomenclatorial

+nomenclatural

+nomic

+nomina

+nominalism

+nominalist

+nominalistic

+nominator

+nominators

+nomogram

+nomogram's

+nomograms

+nomograph

+nomographer

+nomographic

+nomographically

+nomographies

+nomography

+nomological

+nomology

+nomothetic

+nonage

+nonagenarian

+nonagon

+nonallelic

+nonbank

+nonbook

+noncalcareous

+nonce

+nonchalance

+noncharitable

+noncom

+nonconcurrence

+nonconcurrency

+noncondensing

+nonconducting

+nonconductor

+nonconductors

+nonconfidence

+nonconform

+nonconformable

+nonconformably

+nonconformance

+nonconformer

+nonconforming

+nonconformism

+nonconformity

+noncooperation

+noncooperationist

+noncooperative

+noncooperator

+noncrossing

+noncurrent

+nondeductibility

+nondeductible

+nondefense

+nondefense's

+nondefenses

+nondeforming

+nondegenerate

+nondemocratic

+nondestructive

+nondirectional

+nondirective

+nondisjunction

+nondisjunctional

+nondistinctive

+nondivided

+nondormant

+nondramatic

+nondrying

+noneconomist

+nonelectrolyte

+nonentities

+nonentity

+nonesuch

+noneuclidean

+nonfat

+nonfeasance

+nonfictional

+nonfigurative

+nonflammable

+nonflowering

+nonfragmenting

+nongovernment

+nongovernmental

+nonillion

+nonimpact

+nonimpinging

+noninductive

+nonintersecting

+nonintervention

+noninterventionist

+noninverting

+noninvolvement

+nonjoinder

+nonjuring

+nonjuror

+nonlinguist

+nonliterate

+nonloaded

+nonmatching

+nonmetal

+nonmoral

+nonmultiple

+nonnucleated

+nonobjective

+nonobjectivism

+nonobjectivist

+nonobjectivity

+nonobservance

+nonoccurrence

+nonparallel

+nonparametric

+nonparametrics

+nonpareil

+nonparticipant

+nonparticipating

+nonparticipation

+nonpartisanship

+nonpast

+nonpaternity

+nonpathogenic

+nonpermanent

+nonpersonal

+nonplus

+nonpluses

+nonpolar

+nonporous

+nonpositive

+nonpossession

+nonpossessor

+nonprint

+nonprinting

+nonproducer

+nonproductive

+nonproductively

+nonproductiveness

+nonprofessional

+nonprofessionally

+nonprofitable

+nonprogressive

+nonpros

+nonprossed

+nonprossing

+nonprotein

+nonreactive

+nonreader

+nonrealistic

+nonreclosing

+nonrecording

+nonregulation

+nonreimbursable

+nonrelativistic

+nonreligious

+nonremovable

+nonrenewable

+nonrepresentational

+nonrepresentationalism

+nonrepresentative

+nonresidence

+nonresidency

+nonresistant

+nonrestraint

+nonrestricted

+nonrestrictive

+nonretractable

+nonreturnable

+nonrigid

+nonscheduled

+nonscientific

+nonseasonal

+nonsecretor

+nonsectarian

+nonsegregated

+nonsegregation

+nonsignificant

+nonsignificantly

+nonskid

+nonslip

+nonsocial

+nonspecific

+nonsporting

+nonsupport

+nonsyllabic

+nonsynchronous

+nontemporal

+nontenure

+nonunion

+nonuse

+nonuser

+nonviable

+nonviolence

+nonvolatile

+nonworker

+normotensive

+northeasternmost

+northeastward

+northeastwards

+northwestward

+northwestwards

+nosebag

+nosebag's

+nosebags

+nosegay

+nosepiece

+nosey

+noseying

+nosh

+nosher

+nosily

+nosologic

+nosological

+nosologically

+nosology

+nostrum

+nota

+notability

+notarial

+notarially

+notarius

+notecase

+noteless

+notepaper

+noteworthily

+notional

+notionality

+notionally

+notocord

+nougat

+nouncing

+nous

+novaculite

+novae

+novelette

+novelettish

+novelistic

+novella

+novelle

+novemdecillion

+novena

+novocaine

+nowaday

+noway

+noways

+nowhither

+nowise

+noyes

+nu

+nub

+nubbin

+nubble

+nubbles

+nubbly

+nubility

+nucellar

+nucelli

+nucellus

+nuchal

+nucleant

+nuclease

+nucleator

+nuclein

+nucleocapsid

+nucleolar

+nucleon

+nucleon's

+nucleonic

+nucleonics

+nucleons

+nucleophile

+nucleophilic

+nucleophilically

+nucleophilicity

+nucleoplasm

+nucleoplasmatic

+nucleoplasmic

+nucleoprotein

+nucleoside

+nucleosynthesis

+nucleotidase

+nuclidic

+nudibranch

+nugent

+nullificationist

+nulliparous

+numberable

+numbskull

+numia

+numis

+numismatically

+nummular

+numskull

+nunciation

+nunciature

+nuncupate

+nuncupation

+nuncupative

+nunes

+nunnery

+nuovo

+nuptiality

+nursemaid

+nurserymaid

+nurseryman

+nursling

+nurtural

+nurturant

+nutational

+nuthatch

+nutlike

+nutria

+nutriment

+nutted

+nutting

+nux

+nymphal

+nymphalid

+nymphet

+nymphette

+nympholepsy

+nympholept

+nymphomaniacal

+nystagmic

+nystagmus

+o'er

+oafish

+oafishly

+oafishness

+oarsman

+oarsmanship

+oatcake

+oatcake's

+oatcakes

+obbligato

+obcordate

+obeah

+obeisance

+obi

+objectionably

+objectivism

+objectivist

+objectivistic

+objectless

+objectlessness

+objurgate

+objurgated

+objurgates

+objurgating

+objurgation

+objurgations

+objurgatory

+oblast

+obligator

+obligatorily

+obligee

+obligor

+obligors

+obliquity

+obliterator

+obliviated

+obliviates

+obliviating

+oblongatal

+oblongated

+oblongish

+obloquious

+obloquy

+obnubilate

+obnubilated

+obnubilates

+obnubilating

+obnubilation

+obnubilations

+obovate

+obovoid

+obscurant

+obscurantic

+obscurantism

+obscurantist

+obscuration

+obscurations

+obsessional

+obsessionally

+obsolesce

+obstetric

+obstetrical

+obstetrically

+obstetrician

+obstetrician's

+obstetricians

+obstetrics

+obstreperous

+obstreperously

+obstreperousness

+obstructionism

+obstructionistic

+obstructor

+obstruent

+obtainability

+obtainment

+obtect

+obtected

+obtest

+obtestation

+obtrusion

+obtund

+obturate

+obturated

+obturates

+obturating

+obturation

+obturator

+obvert

+occas

+occiput

+occludent

+occlusal

+occultation

+occultations

+occultism

+occultist

+occurrent

+oceana

+oceanarium

+oceanfront

+oceangoing

+oceanographer

+oceanographer's

+oceanographers

+oceanographical

+oceanographically

+oceanologic

+oceanological

+oceanologically

+oceanologist

+oceanology

+ocellar

+ocellate

+ocellated

+ocellation

+ocelli

+ocellus

+och

+ochlocracy

+ochlocrat

+ochlocratic

+ochlocratical

+oconomowoc

+ocotillo

+octadecyl

+octahedra

+octahedral

+octahedrally

+octameter

+octameter's

+octameters

+octandrious

+octant

+octant's

+octants

+octodecillion

+octodecimo

+octoploid

+octoploidy

+octopod

+octopodan

+octopodous

+octosyllabic

+octosyllable

+octroi

+oculomotor

+odalisque

+oddball

+oddball's

+oddballs

+oddment

+odea

+odeum

+odic

+odilo

+odograph

+odontologst

+odontology

+odorant

+odoriferous

+odoriferously

+odoriferousness

+oedipal

+oeillade

+oenology

+oenomel

+oersted

+oeuvre

+oeuvres

+offcast

+officialese

+officialism

+officiant

+officiary

+offish

+offishly

+offishness

+offprint

+offprints

+offsaddle

+offscour

+offscouring

+offscreen

+offside

+ofttimes

+ogeographically

+ogle

+ogler

+ogles

+ogling

+ogre

+ogreish

+ogress

+ohmage

+ohmically

+ohs

+oilcan

+oilily

+oilskin

+oilstone

+oink

+okamoto

+okapi

+okra

+olasticism

+oldfangled

+oldie

+oldish

+oleaginous

+oleaginously

+oleaginousness

+oleaster

+oleate

+olefin

+oleg

+oleophilic

+oleophobic

+olfaction

+olfactions

+olfactive

+olfactology

+olfactometer

+olfactometer's

+olfactometers

+olfactorily

+olfactory

+oligarch

+oligarchical

+oligochaete

+oligoclase

+oligomer

+oligomer's

+oligomers

+oligosaccharide

+oligosaccharide's

+oligosaccharides

+olivine

+olympiad

+om

+ombudsman

+ombudsman's

+ombudsperson

+omelette

+omental

+omentum

+omer

+omissible

+ommatidial

+ommission

+omnidirectional

+omnifarious

+omnifariously

+omnifariousness

+omnificence

+omnificences

+omnificent

+omnify

+omnipotency

+omnipresence

+omnirange

+omniscience

+omnisciency

+omnist

+omnivorous

+omnivorously

+omnivorousness

+onanistic

+oncogene

+oncogene's

+oncogenes

+oncogenic

+onefold

+oneiric

+oneirocritic

+oneirocritical

+oneirocritically

+oneiromancy

+onionskin

+onium

+onload

+onlooking

+onomastic

+onomastics

+onomatology

+onomatopoeia

+onomatopoeia's

+onomatopoeic

+onsetting

+onshore

+onside

+onstage

+ontically

+ontogenesis

+ontogenetic

+ontogenetically

+ontologist

+oocyte

+oomph

+oozier

+oozy

+op

+opalescence

+opalescences

+opaline

+openability

+openable

+openendedness

+openhanded

+openhandedly

+openhandedness

+openhearted

+openheartedly

+openheartedness

+openmouthed

+openmouthedly

+openmouthedness

+openwork

+operability

+operably

+operatically

+operationalism

+operationalist

+operationalistic

+operationism

+operationist

+opercular

+operculate

+operculated

+operculum

+operettist

+operon

+ophidian

+ophiology

+ophiophagous

+ophite

+ophitic

+ophthalmologic

+ophthalmologically

+ophthalmology

+ophthalmoscope

+ophthalmoscopic

+ophthalmoscopical

+ophthalmoscopy

+opine

+opined

+opines

+oping

+opining

+opinionate

+opinionative

+opinionatively

+opinionativeness

+opportunist

+opposability

+opposeless

+oppositional

+opprobrious

+opprobriously

+opprobriousness

+oppugn

+oppugner

+ops

+opsonic

+opsonin

+optative

+optatively

+optician

+optima

+optimistical

+optimo

+optoacoustic

+optoisolate

+optokinetic

+optometrical

+opulence

+opuntia

+opuscule

+opusculum

+ora

+orach

+orache

+oracular

+oracularity

+oracularly

+orality

+orangeade

+orangeroot

+orangery

+orangewood

+orangey

+orangish

+orangoutan

+orangy

+oratio

+oratoric

+orbicular

+orbicularity

+orbicularly

+orbiculate

+orbiculately

+orca

+orca's

+orcas

+orch

+orchardist

+orchardman

+orchesis

+orchestrational

+orchestrator

+orchestre

+orchis

+ordainment

+orderless

+ordinand

+ordines

+ordure

+organdie

+organelle

+organicism

+organicist

+organismal

+organismically

+orgasmic

+orgastic

+orgiastically

+orgulous

+orientable

+orientalism

+orientalist

+orientational

+orientationally

+orienteering

+orificial

+oriflamme

+origami

+origanum

+orismological

+orismology

+orison

+orney

+ornith

+ornithic

+ornithine

+ornithology

+ornithology's

+orogenic

+orogeny

+orographical

+orographically

+orotund

+orotundity

+ort

+orthant

+orthicon

+ortho

+orthocephalic

+orthocephalous

+orthocephaly

+orthochromatic

+orthoclase

+orthoclastic

+orthodontia

+orthoepic

+orthoepical

+orthoepically

+orthoepist

+orthoepy

+orthogenesis

+orthogenetic

+orthogenetically

+orthogenic

+orthognathism

+orthognathous

+orthognathy

+orthograde

+orthographical

+orthographically

+orthopsychiatric

+orthopsychiatrist

+orthopsychiatry

+orthopteran

+orthopterist

+orthopteroid

+orthopteron

+orthorhombic

+orthoscope

+orthoscopes

+orthoscopic

+orthotic

+orthotics

+orthotist

+orthotropic

+orthotropically

+orthotropism

+orthotropous

+ortolan

+orts

+oryx

+oryxes

+orzae

+oscillational

+oscillogram

+oscillogram's

+oscillograms

+oscillograph

+oscillographic

+oscillographically

+oscillography

+oscilloscopic

+oscilloscopically

+oscine

+osculate

+osculated

+osculates

+osculating

+osculation

+osculations

+osculatory

+osculum

+osier

+osmatic

+osmeterium

+osmic

+osmiridium

+osmolal

+osmolality

+osmolar

+osmolarity

+osmometer

+osmometer's

+osmometers

+osmometric

+osmometry

+osmoregulation

+osmoregulatory

+osmose

+osmosed

+osmosing

+osmotically

+osmous

+osmunda

+oso

+osram

+osric

+ossicle

+ossicular

+ossiculate

+ossiculated

+ossificatory

+ossifrage

+ossuary

+osteitis

+ostensive

+ostensively

+ostensorium

+ostentation

+ostentations

+osteoarthritic

+osteoarthritis

+osteoblast

+osteoblastic

+osteoclast

+osteoclastic

+osteocyte

+osteoid

+osteological

+osteologically

+osteologist

+osteoma

+osteopathically

+osteophyte

+osteophytic

+osteoplastic

+osteoplasty

+ostracod

+otherguess

+otherwhere

+otherwhile

+otherwhiles

+otiose

+ouabain

+ouan

+oubliette

+ough

+oui

+outbalance

+outbid

+outbound

+outbrave

+outbreed

+outbreeding

+outbuilding

+outby

+outbye

+outcaste

+outcrop

+outcross

+outdazzle

+outdistance

+outdoorsman

+outdoorsmanship

+outdoorsy

+outdraw

+outercoat

+outfall

+outfight

+outfighting

+outfitter

+outfitting

+outflank

+outflanker

+outfoot

+outgas

+outgeneral

+outgiving

+outgo

+outgoes

+outguess

+outgun

+outhaul

+outlier

+outmatch

+outmode

+outmoding

+outmost

+outpace

+outpaced

+outplay

+outpoint

+outport

+outporter

+outpull

+outputted

+outrace

+outrance

+outrange

+outrank

+outride

+outrider

+outrival

+outscore

+outsell

+outsert

+outshine

+outshoot

+outshout

+outsight

+outsit

+outsize

+outskirt

+outsleep

+outsmell

+outsoar

+outsole

+outspeak

+outspeed

+outspend

+outspent

+outspin

+outstand

+outstare

+outstart

+outstay

+outstretch

+outtake

+outtalk

+outthink

+outturn

+outwear

+outwork

+ouvre

+ouzel

+ovarial

+ovarian

+ovariectomy

+ovariole

+ovariotomy

+ovaritis

+ovenbird

+ovenbirds

+overabundant

+overact

+overaction

+overactivity

+overarm

+overawe

+overbalance

+overbear

+overbearance

+overbid

+overbite

+overblew

+overblow

+overblowing

+overblows

+overbought

+overbuild

+overbuy

+overcall

+overcalled

+overcalling

+overcalls

+overcapacity

+overcareful

+overcarefully

+overcautious

+overcharge

+overcompensate

+overcompensation

+overcompensatory

+overconfidence

+overcurrent

+overcurrents

+overdetermination

+overdetermined

+overdevelop

+overdevelopment

+overdo

+overdominance

+overdominant

+overdress

+overdrive

+overemphasization

+overemphasization's

+overemphasizations

+overet

+overexcite

+overexcitement

+overexposure

+overfastidious

+overfed

+overfish

+overfleshed

+overflight

+overflown

+overfly

+overgarment

+overglaze

+overgraze

+overgrow

+overgrowth

+overily

+overindulge

+overindulgence

+overindulgent

+overissue

+overissued

+overissues

+overissuing

+overleap

+overlearn

+overlie

+overlong

+overlord

+overlordship

+overman

+overmaster

+overmatch

+overmuch

+overoptimism

+overoptimist

+overoptimistic

+overoptimistically

+overpass

+overpay

+overpersuade

+overpersuasion

+overplay

+overplus

+overpopulate

+overpraise

+overprize

+overproduce

+overproduced

+overproduces

+overproducing

+overpronounce

+overproof

+overproportion

+overprotect

+overrate

+overreact

+overreaction

+overrefine

+overrefinement

+overrepresent

+overripe

+oversanguine

+oversea

+overseen

+oversell

+overselling

+oversells

+oversensitive

+oversensitiveness

+oversexed

+overshoe

+overskirt

+overslaugh

+oversleep

+overslip

+oversold

+oversoul

+overspeculate

+overspeculation

+overspeed

+overspend

+overspender

+overspending

+overspends

+overspread

+oversteepen

+oversteer

+overstep

+oversteps

+overstock

+overstory

+overstrain

+overstrew

+overstride

+overstrung

+overstuff

+overstuffed

+overstuffing

+overstuffs

+oversubscribe

+oversubscribes

+oversubscribing

+oversubscription

+oversubtle

+oversubtlety

+overtax

+overtaxation

+overthrust

+overtop

+overtrade

+overtrain

+overtrick

+overtrump

+overvalue

+overvoltage

+overvoltages

+overwatch

+overwear

+overweary

+overween

+overweening

+overweigh

+overwind

+overwinter

+overword

+overwrought

+ovicidal

+ovicide

+oviduct

+oviductal

+ovine

+oviparous

+oviparously

+oviparousness

+oviposit

+oviposition

+ovipositional

+ovipositor

+ovoid

+ovoidal

+ovonic

+ovotestis

+ovoviviparous

+ovoviviparously

+ovoviviparousness

+ovular

+ovulate

+ovulated

+ovulates

+ovulating

+ovulation

+ovulations

+ovule

+ow

+owerless

+owlet

+oxacillin

+oxalacetate

+oxalacetic

+oxalis

+oxaloacetate

+oxazine

+oxblood

+oxbow

+oxeye

+oxheart

+oxidase

+oxidasic

+oxidic

+oxonian

+oxtail

+oxygenator

+oxygenic

+oxygenicity

+oxygenless

+oxyhemoglobin

+oxyhydrogen

+oxymoron

+oxyphil

+oxyphile

+oxyphilic

+oxysome

+oxysulfide

+oystchers

+oysterman

+oystermen

+oz

+ozagen

+ozagenians

+ozocerite

+ozokerite

+ozonic

+ozonide

+ozoniferous

+ozonosphere

+ozonous

+ozzie

+pacem

+pacemaking

+pacesetter

+pachyderm

+pachydermal

+pachydermatous

+pachydermatously

+pachysandra

+pachytene

+pacifiable

+pacifically

+pacificator

+pacificators

+pacificatory

+pacificist

+pacifistically

+packability

+packable

+packboard

+packhorse

+packinghouse

+packman

+packsack

+packsaddle

+packthread

+packwood

+paddleboard

+padrone

+paella

+paeon

+paestum

+paganini

+paganish

+pageboy

+paginal

+pailful

+painfuller

+painfullest

+paisley

+paix

+paladin

+palaeoanthropic

+palaeontology

+palaeontology's

+palaestra

+palanquin

+palasts

+palatably

+palatial

+palatially

+palatialness

+palatinate

+palaver

+palavered

+palavering

+palazzo

+palazzos

+paleface

+paleoanthropology

+paleoanthropology's

+paleoecologic

+paleoecological

+paleoecologist

+paleoecology

+paleogeographic

+paleogeographical

+paleogeographically

+paleogeography

+paleographer

+paleographic

+paleographical

+paleographically

+paleography

+paleolith

+paleoliths

+paleologist

+paleologists

+paleomagnetics

+paleontologic

+paleontological

+paleontologist

+paleontology

+paleozoological

+paleozoology

+palingenesis

+palingenetic

+palinode

+palish

+palladia

+pallbearer

+pallette

+pallial

+palliasse

+palliator

+pallium

+pallor

+pallor's

+pallors

+palmar

+palmary

+palmate

+palmated

+palmately

+palmation

+palmier

+palmistry

+palmitate

+palmlike

+palmy

+palomino

+palp

+palpability

+palpal

+palpate

+palpated

+palpates

+palpating

+palpation

+palpations

+palpebral

+palpi

+palpitant

+palpitate

+palpitated

+palpitates

+palpitating

+palter

+paltered

+palterer

+paltering

+paludal

+paludism

+palynologic

+palynological

+palynologically

+palynologist

+palynology

+pampa

+pampas

+pamphleteer

+pamphleteers

+panacean

+panache

+panatela

+panchromatic

+pancratium

+pandect

+pandects

+pandied

+pandit

+panegyric

+panegyrical

+panegyrically

+panegyrist

+panetela

+panetella

+panful

+pangenesis

+pangenetic

+pangolin

+panhandle

+panhandled

+panhandler

+panhandles

+panhandling

+panhuman

+panicking

+panicle

+pannier

+panoramically

+panpipe

+panpipes

+pantalets

+pantalettes

+pantaloon

+pantaloons

+pantas

+pantheistic

+pantheistical

+pantheistically

+pantie

+pantile

+pantiled

+pantisocracies

+pantisocracy

+pantisocratic

+pantisocratical

+pantisocratist

+pantograph

+pantographic

+pantomimic

+pantomimist

+pantothenate

+pantothenic

+pantropic

+pantryman

+pantrymen

+pantsuit

+pantywaist

+panza

+panzer

+papacy

+papaw

+paperbound

+paperboy

+paperboys

+paperhanger

+paperhanging

+papermaker

+papermakers

+papermaking

+papiers

+papilla

+papillae

+papillate

+papillated

+papilloma

+papillomatous

+papillon

+papillose

+papillote

+papist

+papistry

+pappose

+para

+parabiosis

+parabiotic

+parabiotically

+parabolically

+parachutic

+parachutist

+paradigmatical

+paradisaic

+paradisaical

+paradisaically

+paradisal

+paradisiac

+paradisiacal

+paradisiacally

+paraffinic

+paragenesis

+paragenetic

+paragenetically

+paraginase

+paragonite

+paragraphic

+paralinguistic

+parallactic

+paralogism

+paralytic

+paramagnetically

+paramagnetism

+paramecium

+paramedic

+parament

+parametrical

+paramnesia

+paramountcy

+paramour

+paranormality

+paranymph

+paraoxon

+paraph

+paraphrasable

+paraphrastic

+paraphrastically

+paraphysis

+paraplegia

+parapodial

+parapodium

+paraquat

+pararosaniline

+parasang

+paraselene

+paraselenic

+parasexual

+parasexuality

+parasitical

+parasitically

+parasiticidal

+parasiticide

+parasitism

+parasympathomimetic

+parasynthesis

+parasynthetic

+paratactic

+paratactical

+paratactically

+parataxis

+parathion

+parathyroid

+parathyroidectomy

+paratyphoid

+paravane

+paraxial

+parbuckle

+parbuckled

+parbuckling

+parcenary

+parcener

+pard

+pardner

+pardners

+paregoric

+parella

+parenchyma

+parenchymal

+parenteral

+parenterally

+parfait

+parian

+paries

+parietal

+parietes

+parioli

+parisina

+parisology

+parka

+parka's

+parkas

+parkinsonism

+parlante

+parle

+parling

+parlous

+parlously

+parmigiana

+parmigiano

+parodic

+parodist

+parodistic

+parol

+paronomasia

+paronomastic

+paronym

+paronymous

+parotid

+parotitis

+parous

+paroxysm

+paroxysmal

+paroxytone

+parquetry

+parrakeet

+parricidal

+parricide

+parrillo

+parring

+parris

+partan

+parterre

+parthenocarpic

+parthenocarpically

+parthenocarpy

+parthenogenesis

+parthenogenetic

+parthenogenetically

+parti

+partible

+participator

+particularism

+particularist

+partisanship

+partite

+partitionist

+partitive

+partitively

+partizan

+parturient

+parturition

+partway

+parure

+parve

+parvenue

+parvis

+parvise

+paschal

+pasha

+passably

+passarine

+passavant

+passbook

+passbook's

+passbooks

+passel

+passementerie

+passerine

+passible

+passim

+passional

+passionless

+passivate

+passivated

+passivates

+passivating

+passivation

+passivations

+passivism

+passivist

+passivists

+passkey

+pastelist

+pastellist

+pastern

+pasternak

+pasterns

+pastil

+pastilles

+pastlle

+pastorale

+pastoralism

+pastoralist

+pastorate

+pastorium

+pastorship

+pastrami

+pasturage

+pastureland

+patagonians

+patchboard

+patchily

+patchouli

+patchouly

+pate

+patella

+patellae

+patellar

+patellas

+patelliform

+patency

+patentability

+patentor

+paterfamilias

+paternalist

+pathbreaking

+pathetical

+pathetically

+pathfinder

+pathfinding

+pathogenetic

+pathogenically

+pathogenicity

+pathognomonic

+pathol

+pathometer

+pathometer's

+pathometers

+pathomorphologic

+pathomorphological

+pathomorphology

+pathophysiologic

+pathophysiological

+pathophysiology

+patible

+patil

+patinae

+patine

+patined

+patining

+patisseries

+patois

+patresfamilias

+patriarchate

+patriciate

+patriciates

+patricidal

+patricide

+patrilineage

+patrilineal

+patriotically

+patristical

+patroller

+patronal

+patronne

+patronymic

+patroon

+patten

+pattie

+patulous

+patulously

+patulousness

+paulownia

+pauperism

+pavanne

+pavese

+pavid

+pawl

+pawnbroker

+pawnbroker's

+pawnbrokers

+pawnbroking

+pawnor

+pawpaw

+pax

+paxam

+paxton

+payee

+paygrade

+paygrades

+payola

+payor

+peaceably

+peacekeeper

+peacekeeping

+peacemake

+peacemaker

+peachier

+peachy

+peacockish

+peafowl

+peahen

+pealike

+pearlescence

+pearlescent

+pearlite

+pearlitic

+pearlstone

+peascod

+peasecod

+peashooter

+peaty

+pebbly

+peccable

+peccadillo

+peccancy

+peccant

+peccantly

+peccavi

+pecky

+pectate

+pectic

+pectin

+pectinaceous

+pectinate

+pectinated

+pectination

+pectines

+pectoralis

+peculator

+pecuniarily

+pedagog

+pedalfer

+pedalferic

+pedantically

+peddlery

+peden

+pederast

+pederastic

+pederasts

+pederasty

+pedestrianism

+pediatrist

+pedicab

+pedicel

+pedicellate

+pedicle

+pedicled

+pediculate

+pediculosis

+pediculous

+pedicure

+pedicurist

+pedimental

+pedipalp

+pedlar

+pedlary

+pedocal

+pedocalic

+pedogenesis

+pedogenetic

+pedogenic

+pedologic

+pedological

+pedologist

+pedology

+pedometer

+pedometer's

+pedometers

+pedophile

+pedophilia

+pedophiliac

+pedophilic

+pee

+peekaboo

+peelable

+peeress

+peeter

+peewee

+peignoir

+pekoe

+pelage

+pelagic

+pellagrin

+pellagrous

+pelletal

+pellitory

+pellucid

+pellucidity

+pellucidly

+pellucidness

+peloria

+peloric

+pelorus

+pelota

+pelotas

+peltate

+peltately

+peltries

+peltry

+pemberton

+pemican

+penates

+pendency

+pendent

+pendentive

+pendently

+pendleton

+pendular

+pendulous

+pendulously

+pendulousness

+penetrability

+penetrable

+penetrableness

+penetrably

+penetralia

+penetrance

+penetrances

+penetrant

+penetrants

+penetrometer

+penetrometer's

+penetrometers

+pengally

+penholder

+penicillate

+penicillately

+penicillation

+penicillium

+penile

+peninsular

+penis

+penises

+penitence

+penitences

+penitency

+penlight

+penmanship

+penna

+pennaceous

+pennae

+pennate

+pennis

+pennyroyal

+penological

+penologist

+penology

+pensile

+pensionable

+pensionary

+pensionless

+pentacle

+pentacles

+pentad

+pentadactyl

+pentadactylism

+pentagram

+pentagram's

+pentagrams

+pentagraph

+pentahedral

+pentahedron

+pentamerous

+pentameter

+pentane

+pentangle

+pentangles

+pentapeptide

+pentaploid

+pentaploidy

+pentaquin

+pentaquine

+pentarchy

+pentathlete

+pentathlon

+pentatonic

+pentavalent

+pentazocine

+pentobarbital

+pentobarbitone

+pentode

+pentodes

+pentomic

+pentosan

+penuche

+penult

+penultima

+penumbra

+penumbral

+peon

+peonage

+peones

+peoplehood

+peopleless

+pepperminty

+peppertree

+pepsico

+pepsin

+pepsinogen

+peptic

+peptone

+peradventure

+perambulate

+perambulated

+perambulates

+perambulating

+perambulation

+perambulations

+perambulator

+perambulatory

+percale

+percaline

+perceptibility

+perceptional

+perceptivity

+perchlorate

+percipience

+percipient

+percoidean

+percptibly

+percuss

+percussionist

+perdurability

+perdurable

+perdurably

+pere

+peregrinate

+peregrinated

+peregrinates

+peregrinating

+peregrination

+peregrinations

+peregrine

+peremptorily

+perennate

+perennated

+perennates

+perennating

+perennation

+perennations

+perfecta

+perfectivity

+perfecto

+perfervid

+perfoliate

+perfoliation

+perforator

+performable

+performative

+performatory

+perfuse

+perfused

+perfusing

+perfusive

+pergola

+pericardial

+pericarditis

+pericardium

+pericarp

+perichondral

+perichondrial

+perichondrium

+pericranial

+pericranium

+pericycle

+pericyclic

+pericynthion

+periderm

+peridermal

+peridermic

+peridia

+peridium

+peridot

+peridotic

+peridotite

+peridotitic

+perigean

+perigee

+perigee's

+perigynous

+perigyny

+perihelial

+perikaryal

+perikaryon

+perilune

+perilymph

+perimorph

+perimysium

+perinatal

+perineum

+periodontics

+periodontist

+perioneum

+periotic

+peripatecically

+peripatetically

+peripateticism

+peripatus

+peripety

+peripherad

+periphrasis

+periphrastically

+periphytic

+periphyton

+periplast

+periscopic

+perishability

+peritectic

+peritonitis

+peritrichous

+peritrichously

+perjurious

+perjuriously

+perkily

+perlite

+perlitic

+perlocutionary

+perm

+permafrost

+permeability

+permeably

+permeance

+permease

+permissable

+permitter

+permittivity

+permutational

+peroneal

+peroral

+perorally

+perorate

+peroration

+perorational

+peroxidase

+peroxidic

+peroxisomal

+peroxisome

+perpend

+perpendicularity

+perpetuator

+perseverant

+perseveration

+perseverations

+persistency

+persnickety

+personalism

+personalist

+personalistic

+personate

+personated

+personates

+personating

+personation

+personative

+personator

+personhood

+perspicacity

+perspiratory

+persuasible

+pertinacity

+pertinency

+perturbable

+perturbational

+perturbative

+perversity

+pervious

+perviousness

+peso

+pesos

+pessary

+pessimal

+pessimistically

+pessimum

+peste

+pestiferous

+pestiferously

+pestiferousness

+petallike

+petaloid

+petalous

+petard

+petasos

+petasus

+petiolate

+petiolated

+petiole

+petioled

+petiolule

+petit

+petitionary

+petrarchan

+petrel

+petrifaction

+petrochemistry

+petrogenesis

+petrogenetic

+petrographer

+petrographic

+petrographical

+petrographically

+petrography

+petrolatum

+petrologic

+petrological

+petrologically

+petrologist

+petronel

+petrosal

+petrous

+pettibone

+pettifog

+pettifogger

+pettifoggery

+pettily

+petulancy

+pewaukee

+pewee

+ph

+phaeton

+phage

+phagocytosis

+phalanges

+phalanstery

+phalarope

+phalli

+phallic

+phallically

+phallicism

+phallus

+phalluses

+phanerogam

+phanerogamic

+phanerogamous

+phantasm

+phantasma

+phantasmagoria

+phantasmagoric

+phantasmal

+phantasmic

+phantomlike

+pharaoh

+pharaonic

+pharisaic

+pharisaical

+pharisaically

+pharisaicalness

+pharisaism

+pharisee

+pharmacodynamic

+pharmacodynamically

+pharmacodynamics

+pharmacogenetic

+pharmacogenetics

+pharmacognostic

+pharmacognostical

+pharmacognosy

+pharmacokinetic

+pharmacokinetics

+pharmacologic

+pharmacologist

+pharmacopoeia

+pharnges

+pharos

+pharyngitis

+phasic

+phasmid

+phd

+phenetics

+phenetidine

+phenetole

+phenobarbital

+phenobarbitone

+phenocain

+phenocopy

+phenocryst

+phenolate

+phenological

+phenologically

+phenology

+phenomenalism

+phenomenalist

+phenomenalistic

+phenomenalistically

+phenomenologist

+phenothiazine

+phenotypic

+phenotypical

+phenotypically

+phenoxide

+phentolamine

+phenylalanine

+phenylene

+phenylephrine

+phenylic

+pheromone

+pheromone's

+pheromones

+phial

+philanthropical

+philanthropically

+philatelic

+philatelically

+philatelist

+philately

+philco

+philippe

+philippians

+philogyny

+philol

+philologist

+philoprogenitive

+philoprogenitiveness

+philter

+philtre

+phlebitis

+phlebotomy

+phlegmatic

+phlegmatically

+phlegmy

+phloem

+phlogistic

+phlogiston

+phobia

+phon

+phonate

+phonated

+phonates

+phonating

+phonation

+phonematic

+phonemically

+phonetical

+phonetician

+phoney

+phoneys

+phonically

+phonily

+phonocardiogram

+phonocardiogram's

+phonocardiograms

+phonocardiograph

+phonocardiographic

+phonocardiography

+phonogram

+phonogram's

+phonogramic

+phonogramically

+phonogrammic

+phonogrammically

+phonograms

+phonographic

+phonographically

+phonography

+phonolite

+phonolitic

+phonologial

+phonologist

+phonon

+phonons

+phonoreception

+phonoreceptor

+phonorecord

+phonos

+phosgene

+phosphatic

+phosphatide

+phosphatidic

+phosphatidyl

+phosphene

+phosphite

+phosphocreatine

+phospholipid

+phospholipids

+phosphore

+phosphorescence

+phosphoreted

+phosphoretted

+phosphorism

+phosphorite

+phosphoritic

+phosphorolysis

+phosphorolytic

+phosphorous

+phosphoryl

+phosphorylase

+phosphorylate

+phosphorylation

+phosphorylative

+photic

+photically

+photoautotrophic

+photoautotrophically

+photobiologic

+photobiological

+photobiologist

+photobiology

+photobiotic

+photocathode

+photocathodes

+photocell

+photochemist

+photochemistry

+photochromic

+photochromism

+photocoagulation

+photocompose

+photocomposer

+photocomposition

+photoconductive

+photoconductivity

+photocurrent

+photodecomposition

+photodetector

+photodiode

+photodiodes

+photodisintegrate

+photodisintegration

+photodissociation

+photodissociative

+photodrama

+photoduplicate

+photoduplication

+photodynamic

+photodynamically

+photodynamics

+photoelectric

+photoelectrically

+photoelectron

+photoemission

+photoemissive

+photoengrave

+photoengraver

+photoengraving

+photoflash

+photoflood

+photofluorogram

+photofluorogram's

+photofluorograms

+photofluorographic

+photofluorography

+photogene

+photogenically

+photogeologic

+photogeological

+photogeology

+photogram

+photogram's

+photogrammetric

+photogrammetrist

+photogrammetry

+photograms

+photogravure

+photoheliograph

+photoinduced

+photoinduction

+photoinductive

+photojournalism

+photojournalist

+photojournalist's

+photojournalistic

+photojournalists

+photokinesis

+photokinetic

+photolithograph

+photolithographer

+photolithographic

+photolithographically

+photolithography

+photolytically

+photomap

+photomechanical

+photomechanically

+photometer

+photometer's

+photometers

+photometrically

+photomicrgraphical

+photomicrogram

+photomicrogram's

+photomicrograms

+photomicrographic

+photomicroscope

+photomicroscopic

+photomontage

+photomorphogenesis

+photomorphogenic

+photomultiplier

+photomural

+photonegative

+photonic

+photonuclear

+photooxidation

+photooxidative

+photoperiod

+photoperiodic

+photoperiodically

+photoperiodism

+photophilic

+photophilous

+photophily

+photophobia

+photophobic

+photophore

+photopia

+photoplay

+photopositive

+photoprint

+photoproduct

+photoproduction

+photoreaction

+photoreception

+photoreceptive

+photoreceptor

+photoreconnaissance

+photorecord

+photorecorder

+photoreduction

+photoresistance

+photorespiration

+photosensitivity

+photoset

+photosetter

+photosphere

+photospheric

+photostat

+photostatic

+photosynthesis

+photosynthetic

+photosynthetically

+phototactic

+phototactically

+phototaxis

+phototelegraphy

+phototropic

+phototropically

+phototropism

+phototube

+phototypesetter

+phototypesetting

+phototypographic

+phototypography

+photovoltaic

+phrasally

+phrasemaker

+phrasemonger

+phrasemongering

+phraseogram

+phraseogram's

+phraseograms

+phraseograph

+phraseological

+phraseologically

+phraseologist

+phratries

+phratry

+phreatic

+phreatophyte

+phreatophytic

+phrenetic

+phrenic

+phrenological

+phrenologically

+phrenologist

+phrenology

+phrensy

+phthalate

+phycologist

+phycology

+phycomycete

+phycomycetes

+phylactery

+phylae

+phylar

+phyle

+phylesis

+phyletic

+phyllary

+phylloclade

+phyllode

+phyllodium

+phylloid

+phyllome

+phyllomic

+phyllophagous

+phyllopod

+phylogenetic

+physiatrics

+physiatrist

+physicalism

+physicalist

+physicalistic

+physicality

+physicked

+physicking

+physicochemically

+physiocratic

+physiognomic

+physiognomical

+physiognomically

+physiographer

+physiographic

+physiographical

+physiography

+physiol

+physiopathologic

+physiopathological

+physiopathology

+physostigmine

+phytane

+phytoalexin

+phytochemical

+phytochemically

+phytochemist

+phytochemistry

+phytochrome

+phytoflagellate

+phytogenic

+phytogeographic

+phytogeographical

+phytogeographically

+phytogeography

+phytography

+phytological

+phytologically

+phytology

+phyton

+phytonic

+phytopathogen

+phytopathogenic

+phytopathologic

+phytopathological

+phytopathology

+phytophagous

+phytophagy

+phytoplanktonic

+phytosociological

+phytosociologically

+phytosociologist

+phytosociology

+phytosterol

+phytotoxic

+phytotoxicity

+pial

+pianistically

+pianoforte

+pianoforte's

+pianofortes

+pias

+piassava

+piazze

+pibroch

+pic

+picador

+picadores

+picaninny

+picara

+picaresque

+picaro

+picaroon

+picayunish

+piccalilli

+piccoloist

+pice

+piceous

+pickaback

+pickaninny

+pickaroon

+pickax

+pickeer

+picketboat

+picklock

+pickpocket

+pickproof

+pickthank

+picnicky

+picnometer

+picnometer's

+picnometers

+picoline

+picon

+picosecond

+picoseconds

+pictograph

+pictographic

+pictography

+pictorialism

+picturegoer

+piebald

+piecework

+pieceworker

+piecrust

+piefort

+pieing

+pieta

+pietism

+pietist

+pietistic

+pietistical

+pietistically

+pietro

+piezoelectrically

+piezometer

+piezometer's

+piezometers

+piezometric

+piezometry

+piffle

+piffled

+piffles

+piffling

+pigboat

+pigeonberry

+pigeonfoot

+pigeonhearted

+pigeonwing

+pigged

+piggeries

+piggery

+piggyback

+piggybacked

+piggybacking

+pigheaded

+pigheadedness

+piglet

+piglets

+pigmentary

+pigmy

+pigstick

+pigsticker

+pigsticking

+pikeman

+pikestaff

+pilaf

+pilaff

+pilaster

+pilchard

+pilea

+pileate

+pileated

+pilei

+pileum

+pileup

+pileus

+pilewort

+pilgarlic

+pillbox

+pillboxes

+pillion

+pillions

+pillowcase

+pillowcases

+piloerection

+pilotage

+pilotages

+pilothouse

+pilotless

+pilsener

+pilsner

+pilular

+pilule

+pilus

+pinar

+pinaster

+pinata

+pinbone

+pincer

+pincer's

+pincerlike

+pincers

+pinchbeck

+pinchcock

+pindling

+pineal

+pinecone

+pinedrops

+pinene

+pinery

+pinesap

+pineta

+pinetum

+pinewood

+piney

+pinfold

+pingo

+pinkeye

+pinko

+pinkoes

+pinkos

+pinkroot

+pinky

+pinna

+pinnace

+pinnae

+pinnal

+pinnas

+pinnate

+pinnately

+pinner

+pinniped

+pinniped's

+pinnipeds

+pinnula

+pinnular

+pinnulate

+pinnulated

+pinnule

+pinprick

+pinpricks

+pinscher

+pinsetter

+pinspotter

+pinstripe

+pinta

+pintle

+pintoes

+pinup

+pinxter

+pionic

+pipage

+pipal

+pipeage

+pipefish

+pipeful

+pipeless

+pipelike

+piperazine

+piperidine

+piperine

+piperonal

+pipestone

+pipgras

+pipit

+pipkin

+pippin

+pipping

+pipsissewa

+piquancy

+piquet

+piranha

+piraro

+piratical

+piratically

+pirogue

+piroplasm

+piroplasma

+piroplasmata

+piscicultural

+pisciculture

+pisciculturist

+piscina

+piscine

+piscivorous

+pisiform

+pismire

+pisolite

+pisolitic

+pissoir

+pistillate

+pistoleer

+pita

+pitchman

+pitchout

+pitchy

+pithead

+pithily

+pitiably

+pivotable

+pivotman

+pixie

+pixieish

+pixilated

+pixilates

+pixilation

+pizazz

+pizz

+pizzazz

+pizzeria

+placability

+placable

+placably

+placatory

+placebo

+placeholder

+placeman

+placemat

+placemat's

+placemats

+placency

+placent

+placentation

+placentations

+placentia

+placidity

+placket

+plagal

+plage

+plagiaristic

+plagiary

+plagioclase

+plaguesome

+plaguey

+plaguily

+plaguy

+plaice

+plainclothesman

+plainsman

+plainspoken

+plainspokenness

+plaint

+plaintext

+plaintful

+plainview

+plaister

+planarian

+planation

+planchet

+planetoidal

+planetological

+planetologist

+planetology

+plangency

+plangent

+plangently

+planimeter

+planimeter's

+planimeters

+planimetric

+planish

+planisher

+planisphere

+planispheric

+planktonic

+planless

+planlessly

+planlessness

+planograph

+planographic

+planography

+planosol

+plantable

+plantar

+plantlike

+planula

+planular

+planuloid

+plasmagel

+plasmagene

+plasmagenic

+plasmalemma

+plasmapheresis

+plasmasol

+plasmatic

+plasmid

+plasmid's

+plasmids

+plasmin

+plasminogen

+plasmodesm

+plasmodium

+plasmogamy

+plasmolysis

+plasmolytic

+plasmolytically

+plasmon

+plasodesma

+plasterboard

+plasterwork

+plastery

+plastid

+plastidial

+plastisol

+plastisols

+plastogene

+plastral

+plastron

+plat

+plateaux

+plateful

+platelike

+platemaker

+platemaking

+plateresque

+platies

+platina

+platinic

+platinous

+platipi

+platipi's

+platitudinal

+platitudinarian

+platonically

+platterful

+platting

+platypus

+platypus's

+platypuses

+plauded

+plauding

+plaudit

+plause

+plausive

+playa

+playability

+playact

+playbill

+playbills

+playbook

+playgirl

+playgoer

+playgoers

+playland

+playmaker

+playpen

+playpen's

+playpens

+playsuit

+pleadable

+pleasantry

+pleasurability

+pleasurably

+pleasureless

+pleatless

+plebe

+plebeianism

+plebes

+plebian

+plebiscitary

+plebs

+plectrum

+plectrum's

+plectrums

+pledgee

+pledget

+pledgor

+plenipotent

+plenish

+plenitudinous

+plentitude

+plethoric

+pleurae

+pleuritic

+pleurodont

+plex

+plexiform

+plexiglass

+plexus

+pliability

+pliably

+plimsoll

+plinth

+plodder

+plosion

+plotless

+plotlessness

+plottage

+plottier

+plotty

+plowmen

+plowmen's

+pluckily

+plugboard

+plugboard's

+plugboards

+plugger

+plumbaginous

+plumbago

+plumbate

+plumbeous

+plumbic

+plumbiferous

+plumbism

+plumbous

+plumelet

+plumier

+plumlike

+plummier

+plummy

+plumose

+plumosely

+plumpish

+plumulate

+plumule

+plumulose

+plumy

+plunderable

+plunderage

+plunderous

+pluperfect

+pluralistically

+pluriaxial

+pluripotent

+plussage

+plusses

+plutocracy

+plutocrat

+plutocratic

+plutocratically

+pluton

+plutonian

+plutonic

+pluvial

+plyscore

+pneumatically

+pneumaticity

+pneumatology

+pneumatolysis

+pneumatolytic

+pneumatometer

+pneumatometer's

+pneumatometers

+pneumatophore

+pneumatophoric

+pneumectomy

+pneumococcus

+pneumonic

+pocahontas

+pockmark

+pocky

+poco

+podagra

+podagral

+podded

+podding

+podgier

+podgy

+podiatric

+podiatrist

+podiatry

+podite

+poditic

+poetaster

+poetess

+poeticism

+pogromist

+poi

+poikilotherm

+poikilothermic

+poikilothermism

+poilu

+poinciana

+pointe

+pointillism

+pointillist

+pointilliste

+pointillistic

+pointwise

+poirot

+poitrine

+pokey

+pokeys

+pokier

+pokily

+pokiness

+poky

+polarimetric

+polariscopic

+polariton

+polarographic

+polarographically

+polaron

+polder

+poleax

+poleless

+polemicist

+polemist

+polemonium

+polestar

+poleward

+policewoman

+policewoman's

+policewomen

+policyholder

+policyholders

+poliomyelitic

+poliomyelitis

+poliovirus

+politesse

+politick

+politicker

+polity

+polkadot

+polkadots

+pollee

+pollenate

+pollenated

+pollenates

+pollenating

+pollenation

+pollenosis

+pollex

+pollical

+pollices

+pollinate

+pollinated

+pollinates

+pollinating

+pollination

+pollinator

+pollinic

+polliniferous

+pollinium

+polloi

+pollster

+pollywog

+pollywog's

+pollywogs

+poloist

+poltergeist

+poltroon

+poltroonery

+poltroonish

+poltroonishly

+polyandrous

+polyandry

+polyanka

+polyantha

+polyanthus

+polybasite

+polycarbonate

+polycarpellary

+polycarpic

+polycarpous

+polycarpy

+polycentrism

+polychaete

+polychaetous

+polychasium

+polychotomous

+polychotomy

+polychromatic

+polychrome

+polychromy

+polycistronic

+polyclinic

+polycondensation

+polycot

+polycotyl

+polycotyledon

+polycotyledonous

+polycrystal

+polycyclic

+polycythemia

+polycythemic

+polydactyl

+polydactylous

+polydactyly

+polydipsi

+polygala

+polygamic

+polygamical

+polygamically

+polygamist

+polygene

+polygenesis

+polygenesist

+polygenetic

+polygenetically

+polygenic

+polyglandular

+polyglot

+polyglotism

+polyglottism

+polygonum

+polygram

+polygram's

+polygrams

+polygraph

+polygraphic

+polygynoecial

+polygyny

+polyhedrosis

+polyhistor

+polyhistoric

+polyhydroxy

+polymath

+polymathic

+polymathy

+polymerically

+polymerism

+polymorphically

+polymorphism

+polymorphonuclear

+polymorphous

+polymorphously

+polymyxin

+polyneuritis

+polynuclear

+polynucleotide

+polynya

+polyonymous

+polyp

+polypary

+polypeptide

+polypeptidic

+polypetalous

+polyphagia

+polyphagous

+polyphagy

+polyphase

+polyphasic

+polyphenol

+polyphenolic

+polyphone

+polyphonically

+polyphonous

+polyphonously

+polyphyletic

+polyphyletically

+polyphyleticism

+polypide

+polyploid

+polyploidy

+polypnea

+polypneic

+polypody

+polypoid

+polypous

+polyptych

+polyrhythm

+polyrhythmic

+polyrhythmically

+polyribonucleotide

+polyribosomal

+polyribosome

+polysaccharide

+polysaccharides

+polysaprobic

+polysemous

+polysemy

+polysepalous

+polysilicon

+polysiloxanes

+polysome

+polysomic

+polysorbate

+polystichous

+polysulfide

+polysyllabic

+polysyllabically

+polysyllable

+polysynaptic

+polysynaptically

+polysyndeton

+polytene

+polyteny

+polytheism

+polytheist

+polytheistic

+polytheistical

+polythene

+polytocous

+polytonality

+polytope

+polytrophic

+polytype

+polytypic

+polytypism

+polytypy

+polyurethane

+polyuria

+polyvalence

+polyvalent

+polyvinyl

+polywater

+polyzoan

+polyzoarium

+polyzoic

+pomace

+pomaceous

+pomade

+pomaded

+pomades

+pomander

+pomatum

+pome

+pomelo

+pomerania

+pomeranian

+pomiferous

+pommel

+pomological

+pomologically

+pomologist

+pomology

+pompey

+pompon

+pon

+ponderable

+ponderosa

+ponderosa's

+ponderosas

+pong

+pont

+pontific

+pontificaly

+pontificator

+pontifices

+pontine

+pontius

+ponton

+pontonier

+pontoon

+ponytail

+pood

+poolroom

+poop

+poorhouse

+poorish

+popery

+popgun

+popinjay

+popish

+popishly

+popliteal

+popover

+poppa

+poppet

+popple

+poppycock

+poppyhead

+populaire

+populaires

+populism

+populist

+populistic

+porcelainlike

+porcelaneous

+porcellaneous

+poriferal

+poriferan

+porkies

+porky

+pornographically

+porphyria

+porphyrin

+porphyritic

+porphyroid

+porphyropsin

+porphyry

+porrect

+porringer

+portance

+portative

+portcullis

+porterage

+porthole

+portico

+portiere

+portionless

+portraitist

+portress

+portulaca

+posable

+posada

+posey

+posies

+positivistic

+positivity

+positronium

+posseman

+possemen

+possessory

+posset

+possets

+postaxial

+postaxially

+postbag

+postbags

+postbellum

+postbox

+postboxes

+postboy

+postboys

+postbreeding

+postclassic

+postclassical

+postcolonial

+postdental

+postdiluvian

+postdoctorate

+postembryonal

+postembryonic

+postemergence

+posteriad

+posteriority

+postern

+postexilic

+postface

+postform

+postglacial

+posthaste

+posthole

+posthypnotic

+postiche

+postilion

+postillion

+postmastership

+postmenopausal

+postmillenarian

+postmillenarianism

+postmillennial

+postmillennialism

+postmillennialist

+postmistress

+postmodern

+postmultiply

+postnasal

+postnatal

+postnatally

+postnuptial

+postnuptially

+postorbital

+postpaid

+postpituitary

+postponable

+postposition

+postpositional

+postpositionally

+postpositive

+postpositively

+postprandial

+postprandially

+postprocess

+postprocessor

+postprocessors

+postschool

+postsynaptic

+postsynaptically

+posttension

+posttraumatic

+postulancy

+postulant

+postulational

+postulator

+postural

+posy

+potability

+potassic

+potation

+potboy

+poteen

+potemkin

+potence

+potentiate

+potentiation

+potentiator

+potentiometric

+potful

+pothead

+potheen

+pother

+pothered

+pothering

+pothook

+pothouse

+pothunter

+pothunting

+potpie

+potsdam

+potsherd

+potshot

+potshotting

+potstone

+pottage

+pottawatomie

+potteringly

+pottier

+potties

+pottle

+potto

+pottos

+potty

+pouchier

+pouchy

+pouf

+pouff

+pouffed

+poulard

+poularde

+poult

+poulterer

+poultryman

+poundage

+poundal

+pourable

+pourboire

+pourparler

+pourpoint

+poussette

+poussetted

+poussetting

+poussin

+poussins

+pouty

+powderman

+powdermen

+powerboat

+powerhouse

+powerhouse's

+powerhouses

+powwow

+poxvirus

+poza

+ppm

+practicum

+praecox

+praedial

+pragmatical

+pragmaticism

+pragmaticist

+pragmatistic

+praiseworthily

+praline

+prandial

+prankish

+prankishly

+prankishness

+prankster

+pranksters

+prase

+pratfall

+pratincole

+pratique

+prawn

+prawner

+prawns

+praxeological

+praxeology

+pre

+preachier

+preachifies

+preachify

+preachily

+preachiness

+preachment

+preachy

+preadapt

+preadaptation

+preadapted

+preadaptive

+preadolescence

+preadolescent

+preamplifier

+preamplifiers

+prearrange

+prearrangement

+preatomic

+preaxial

+preaxially

+prebend

+prebendal

+prebendary

+prebind

+prebiologic

+prebiological

+prebiotic

+precancel

+precancerous

+precast

+precautious

+precedency

+preceeded

+preceeding

+precensor

+precentor

+precentorial

+precentorship

+preceptor

+preceptorial

+preceptorship

+preceptory

+preceptress

+precessional

+preciosity

+precipitance

+precipitancy

+precipitant

+precipitantly

+precipitantness

+precipitator

+precipitin

+precipitinogen

+precipitinogenic

+precisian

+precisianism

+precisionist

+preclinical

+preclusion

+preclusive

+preclusively

+precoat

+precoating

+precocial

+precognition

+precognitive

+precombustion

+precompact

+precompose

+precomputation

+precomputed

+preconceptual

+preconcert

+preconcerted

+preconcertedly

+preconcertedness

+preconsonantal

+precook

+precritical

+precursory

+predaceous

+predaceousness

+predacious

+predacity

+predatorily

+predawn

+predecease

+predefense

+predefense's

+predefenses

+predesignate

+predesignation

+predestinarian

+predestinarianism

+predestinate

+predestination

+predestinator

+predestine

+predetermination

+predicable

+predicatable

+predicatory

+predigest

+predigestion

+predominancy

+preemergence

+preemergent

+preemie

+preemphasization

+preemphasization's

+preemphasize

+preemphasized

+preemphasizer

+preemphasizers

+preemphasizes

+preemphasizing

+preexchange

+preexchanged

+preexist

+preexistence

+prefatorial

+prefatorially

+prefatorily

+prefectural

+preferability

+preferrer

+prefigurative

+prefiguratively

+prefigurativeness

+prefigure

+prefigured

+prefigurement

+prefigures

+prefiguring

+prefixal

+prefixally

+prefocus

+prefocused

+prefocuses

+prefocusing

+preform

+preformation

+preformed

+preforms

+prefrontal

+pregnability

+pregnable

+pregnenolone

+preheat

+preheated

+preheater

+prehensile

+prehensility

+prehension

+prehistorian

+prehistorical

+prehistorically

+prehistory

+prehominid

+preignition

+preinduction

+prejudicious

+prejudiciously

+prelature

+prelection

+prelibation

+prelicense

+prelicensed

+prelicenser

+prelicenses

+prelicensing

+preliminarily

+prelusion

+prelusive

+prelusively

+prelusory

+premalignant

+preman

+premed

+premedial

+premedian

+premedical

+premedieval

+premedieval's

+premedievalism

+premedievalism's

+premedievalisms

+premedievals

+premeditator

+premeiotic

+premenstrual

+premenstrually

+premership

+premie

+premillenarian

+premillenarianism

+premillennial

+premillennialism

+premillennialist

+premillennially

+premiss

+premolar

+premonish

+premonitorily

+premorse

+premune

+premunition

+prename

+prenatal

+prenatally

+prenominate

+prenomination

+prenotion

+preoccupancy

+preoperative

+preoperatively

+preorbital

+preordain

+preordained

+preordaining

+preordains

+preordination

+preoviposition

+preovulatory

+prepackage

+preparator

+preparatorily

+prepausal

+prepay

+prepense

+prepensely

+preplan

+preponderancy

+prepositive

+prepositively

+prepossess

+prepossessing

+prepossessingly

+prepossessingness

+prepossession

+prepotency

+prepotent

+prepotently

+preppie

+preprandial

+preprocess

+preprocessed

+preprocesses

+preprofessional

+prepuberal

+prepuberally

+prepubertal

+prepubertally

+prepuberty

+prepubescence

+prepuce

+prepunch

+prepupal

+preputial

+prerealization

+prerealization's

+prerealizations

+prerealize

+prerealizes

+prerecord

+presageful

+presanctified

+presbyope

+presbyopia

+presbyopic

+presbyter

+presbyterate

+presbyterial

+presbyterially

+presbytery

+prescient

+prescientific

+presciently

+prescind

+prescore

+prese

+preselection

+presell

+presentability

+presentably

+presentative

+presentee

+presentient

+presentiment

+presentimental

+presentment

+preservable

+preservationist

+presettable

+presetting

+preshrunk

+presidentship

+presidial

+presidiary

+presidio

+presidium

+presignify

+presley

+presoak

+pressboard

+pressmark

+pressor

+pressroom

+pressrun

+presswork

+prest

+prester

+presternum

+prestigeful

+prestissimo

+prestress

+prestressed

+presumptive

+presumptively

+presynaptic

+presynaptically

+pretax

+preteen

+pretensionless

+preterit

+preterite

+preterition

+preteritive

+preterminal

+pretermission

+pretermit

+preternatural

+preternaturally

+preternaturalness

+pretreat

+pretreatment

+prettification

+prettify

+prettyish

+pretubercular

+pretuberculous

+pretzel

+prevaricate

+prevaricated

+prevaricates

+prevaricating

+prevarication

+prevaricator

+prevenient

+preveniently

+preventability

+preventative

+preventible

+preverbal

+previsional

+previsionary

+prevocalic

+prevocational

+prevue

+prexy

+priapic

+pricey

+pricier

+pricket

+prickier

+pricky

+pricy

+prideful

+pridefully

+pridefulness

+priesthood

+prieur

+priggery

+priggism

+prima

+primality

+primateship

+primatial

+primatological

+primatologist

+primatology

+primero

+primipara

+primiparity

+primiparous

+primitivist

+primitivistic

+primitivity

+primmer

+primmest

+primming

+primo

+primogenitor

+primogeniture

+primos

+primrdium

+primula

+primus

+princedom

+princekin

+princelet

+princeling

+princeship

+princesse

+principalship

+principial

+principium

+princox

+prink

+prinker

+printability

+printemps

+printery

+printless

+priorate

+prioress

+prioresses

+priorship

+pripet

+prise

+prisere

+prismatically

+prismatoid

+prismatoidal

+prismoid

+prismoidal

+prissily

+pristane

+prithee

+privatdocent

+privatdozent

+privatism

+privet

+privily

+privity

+prix

+prizefight

+prizefighter

+prizefighting

+prizewinner

+proa

+proach

+proaching

+proactive

+probabilism

+proband

+probang

+probational

+probationally

+probationary

+probatory

+probenecid

+probit

+probosces

+proboscidean

+proboscidian

+proboscis

+procambial

+procambium

+procaryote

+procaryotic

+procathedral

+procephalic

+procercoid

+processability

+processable

+processibility

+processible

+proclimax

+proclitic

+proconsul

+proconsular

+proconsulate

+proconsulship

+procreant

+procreator

+procryptic

+proctodaeum

+proctologic

+proctological

+proctologist

+proctology

+proctorial

+proctorship

+procumbent

+procurable

+procurance

+procuration

+procurator

+procuratorial

+procuress

+prodder

+prodigality

+prodromal

+prodromata

+prodrome

+prodromes

+prodromic

+productional

+proemial

+proenzyme

+proestrus

+profanation

+profanatory

+professeur

+professorate

+professoriat

+professoriate

+profili

+profitless

+profitted

+profitting

+profligacy

+profluent

+prog

+progamete

+progestational

+progesterone

+progestin

+progestogen

+progging

+proglottid

+proglottidean

+proglottis

+prognathic

+prognathism

+prognathous

+prognostic

+prograde

+programmatic

+programmatically

+progressional

+progressionist

+progressist

+progressivist

+progressivistic

+prohibitionist

+projectable

+projectional

+projet

+projets

+prokaryote

+prokaryotic

+prolactin

+prolamin

+prolamine

+prolan

+prolapse

+prolapsed

+prolapsing

+prole

+proleptic

+proletarian

+proliferous

+proliferously

+prolificacy

+prolificity

+proline

+prolocutor

+prolotherapy

+prolusion

+prolusions

+prolusory

+prom

+promazine

+promisee

+promisor

+promissory

+promotability

+promotable

+promptbook

+promptbooks

+promulgator

+pronatalism

+pronatalist

+pronate

+pronated

+pronating

+pronation

+pronator

+pronephric

+pronephros

+pronghorn

+pronghorns

+pronominal

+pronominally

+pronuclear

+pronucleus

+pronunciamento

+pronunciational

+prooflike

+proofread

+proofroom

+propaedeutic

+propagable

+propagandism

+propagandistically

+propagational

+propagator

+propagule

+proparoxytone

+propellent

+propellor

+propend

+propense

+properdin

+propertyless

+prophage

+prophase

+prophasic

+prophetess

+prophetical

+prophylactic

+prophylactically

+prophylaxis

+propine

+propined

+propining

+propionibacteria

+propitiable

+propitiator

+propitiatory

+proplastid

+propman

+propolis

+propone

+proponed

+proponing

+proportionable

+proportionably

+propos

+propositus

+propranolol

+proprietress

+proprioceptor

+proptosis

+propulsive

+propyl

+prorogate

+prorogation

+prorogue

+prorogued

+proroguing

+prosaically

+prosaism

+prosaist

+prosateur

+prosciutto

+proscriptive

+proscriptively

+prosector

+prosectorial

+prosecutable

+proselyte

+proselytism

+proseminar

+prosencephalic

+prosencephalon

+prosenchyma

+prosenchymas

+prosenchymata

+prosenchymatous

+prosier

+prosily

+prosiness

+prosit

+proso

+prosobranch

+prosodical

+prosodically

+prosodist

+prosoma

+prosomal

+prosopographical

+prosopography

+prosopopoeia

+prossed

+prosser

+prost

+prostaglandin

+prostatectomy

+prostatic

+prostatism

+prostatitis

+prosthesis

+prosthetically

+prosthodontics

+prosthodontist

+prostitutor

+prostomial

+prostomium

+prosy

+protamine

+protasis

+protatic

+protea

+protectant

+protectionism

+protectoral

+protectorship

+protectory

+protectress

+proteid

+proteide

+proteinaceous

+proteinase

+proteinate

+proteinuria

+proteinuric

+protend

+protensive

+protensively

+proteoclastic

+proteose

+proteranthous

+proteranthy

+protestor

+proteus

+prothalamion

+prothalamium

+prothallial

+prothallium

+prothallus

+prothesis

+prothetelic

+prothetely

+prothetic

+prothonotarial

+prothonotary

+prothoracic

+prothorax

+prothrombin

+protist

+protistan

+protitch

+protium

+proto

+protoderm

+protodermal

+protogalaxy

+protogeometric

+protohistorian

+protohistoric

+protohistory

+protohuman

+protolanguage

+protolithic

+protomartyr

+protonate

+protonated

+protonation

+protonema

+protonemal

+protonematal

+protonic

+protonotary

+protonymph

+protonymphal

+protopathic

+protophloem

+protophyta

+protoplanet

+protoplast

+protoplastic

+protoporphyrin

+protostar

+protostele

+protostelic

+prototroph

+prototrophic

+prototrophy

+prototypal

+protoxylem

+protozoal

+protozoic

+protozoological

+protozoologist

+protozoology

+protozoon

+protractile

+protraction

+protractor

+protreptic

+protrusible

+protuberatly

+proudful

+proudhearted

+provascular

+provement

+provender

+provenience

+provincialist

+provinciality

+proviral

+provirus

+provisionary

+provisons

+provisory

+provitamin

+provolone

+proxemic

+proxemics

+proximo

+proxmire

+prude

+prude's

+prudery

+prudes

+prudish

+prudishly

+prudishness

+pruinose

+prurience

+pruriency

+pruriginous

+prurigo

+pruritic

+pruritus

+prussiate

+prussic

+prutot

+pryer

+psalmbook

+psalmody

+psalter

+psalterium

+psaltery

+psaltry

+psephological

+psephologist

+psephology

+pseud

+pseudepigraph

+pseudepigraphon

+pseudepigraphy

+pseudoallele

+pseudoallelic

+pseudoallelism

+pseudoclassic

+pseudoclassicism

+pseudoenergy

+pseudomedieval

+pseudomedieval's

+pseudomedievals

+pseudonymity

+pseudonymous

+pseudonymously

+pseudonymousness

+pseudopotential

+pseudoscience

+pseudoscientific

+pseudoscientist

+pseudoscorpion

+pseudosophisticated

+pseudosophistication

+pseudotuberculosis

+psychedelia

+psychedelically

+psychiatrically

+psychoanalytical

+psychoanalytically

+psychobiographical

+psychobiography

+psychobiologic

+psychobiological

+psychobiologist

+psychochemical

+psychodrama

+psychodramatic

+psychodynamic

+psychodynamically

+psychodynamics

+psychogenesis

+psychogenetic

+psychogenic

+psychogenically

+psychognosis

+psychognosy

+psychograph

+psychokinesis

+psychokinetic

+psycholinguist

+psychologic

+psychologism

+psychometrically

+psychomotor

+psychoneurosis

+psychoneurotic

+psychopathically

+psychopathologic

+psychopathological

+psychopathologically

+psychopathologist

+psychopathology

+psychopathy

+psychopharmaceutical

+psychopharmacologic

+psychopharmacological

+psychopharmacologist

+psychopharmacology

+psychophysicist

+psychophysiologic

+psychophysiological

+psychophysiologically

+psychophysiologist

+psychopomp

+psychosexual

+psychosexuality

+psychosexually

+psychosomatically

+psychosurgery

+psychosurgical

+psychotherapeutically

+psychotherapist

+psychotically

+psychotogen

+psychotogenic

+psychotomimetic

+psychotomimetically

+psychotropic

+psychrometer

+psychrometer's

+psychrometers

+psychrometric

+psychrometry

+psychrophilic

+psyllium

+pterodactyl

+pterodactyl's

+pterodactyls

+ptolemaists

+ptomaine

+puberal

+pubertal

+puberulent

+pubes

+pubescence

+pubic

+pubis

+publican

+publicans

+publicist

+publick

+publique

+publishable

+puccoon

+puce

+pucka

+puckery

+pud

+puddingstone

+pudency

+pudendal

+pudendum

+puerperal

+puerperium

+pug

+pugaree

+puggaree

+pugging

+pugilism

+pugilist

+pugilistic

+pugmark

+pugnacious

+pugnaciously

+pugnaciousness

+pugnacity

+puisne

+puissance

+pukka

+pul

+pulchritude

+pulchritudinous

+pule

+puler

+puli

+pulicide

+pulik

+puling

+pulis

+pullback

+pullet

+pullout

+pullulate

+pullulation

+pulmonate

+pulmonic

+pulmotor

+pulpal

+pulpally

+pulpiness

+pulpwood

+pulpy

+pulque

+pulsant

+pulsator

+pulsatory

+pulsimeter

+pulsimeter's

+pulsimeters

+pulsometer

+pulsometer's

+pulsometers

+pulverulent

+pulvillus

+pulvinus

+pumiceous

+pumicite

+pumpernickel

+pumpkinseed

+pumpkinseeds

+puna

+punchball

+punchballs

+punchboard

+puncheon

+punchier

+punchinello

+punchless

+punchy

+punctate

+punctation

+punctilio

+punctilious

+punctiliously

+punctiliousness

+punctuator

+pung

+punily

+punishability

+punition

+punkah

+punkie

+punkin

+punnier

+punning

+punny

+punties

+punty

+pupae

+puparia

+puparial

+puparium

+pupfish

+pupilage

+pupilar

+pupillage

+pupillary

+pupiparous

+puppetry

+pupping

+purblind

+purblindly

+purblindness

+purdah

+purdew

+pureblood

+purebred

+puree

+puree's

+pureed

+pureeing

+purees

+purfle

+purfled

+purfling

+purgatorial

+purificator

+purificatory

+purifing

+purine

+puristic

+puritanism

+purl

+purled

+purler

+purlers

+purlieu

+purlin

+purling

+puromycin

+purplish

+purply

+purpura

+purpure

+purpuric

+purselike

+pursewarden

+pursier

+pursiness

+purslane

+pursuance

+pursuivant

+pursy

+purtenance

+purulence

+purulent

+purveyance

+purvis

+pushball

+pushcart

+pushchair

+pushchairs

+pushful

+pushfulness

+pushily

+pushout

+pushover

+pushover's

+pushovers

+pushpin

+pushpin's

+pushpins

+pusillanimity

+pusillanimous

+pusillanimously

+pussyfoot

+pussyfooter

+pussyfooting

+pussytoes

+pustulant

+pustular

+pustulate

+pustulated

+pustulation

+pustule

+pustules

+putains

+putas

+putdown

+putdown's

+putdowns

+putout

+putrefaction

+putrefactive

+putrescence

+putrescent

+putrescible

+putrescine

+putridity

+putsch

+putschist

+puttana

+puttee

+puttees

+puttyroot

+puzzleheaded

+puzzleheadedness

+pycnidium

+pycnogonid

+pycnometer

+pycnometer's

+pycnometers

+pyelitis

+pyelonephritic

+pyelonephritis

+pyemia

+pyemic

+pygidial

+pygidium

+pygmaean

+pygmean

+pygmoid

+pygmyish

+pygmyism

+pyknic

+pylon

+pylons

+pylori

+pyloric

+pylorus

+pyocanea

+pyoderma

+pyodermic

+pyogenic

+pyracanth

+pyracantha

+pyralid

+pyralidid

+pyramidical

+pyran

+pyranoid

+pyranose

+pyranoside

+pyrargyrite

+pyrene

+pyrenoid

+pyrethrin

+pyrethroid

+pyrethrum

+pyretic

+pyrexia

+pyrexial

+pyrexic

+pyrheliometer

+pyrheliometer's

+pyrheliometers

+pyrheliometric

+pyric

+pyridoxal

+pyridoxamine

+pyridoxin

+pyridoxine

+pyriform

+pyrimethamine

+pyrimidine

+pyrimidines

+pyrite

+pyrites

+pyritic

+pyrocatechol

+pyrocellulose

+pyrochemical

+pyrochemically

+pyroclastic

+pyroelectric

+pyroelectricity

+pyrogallol

+pyrogen

+pyrogenic

+pyrogenicity

+pyrogenous

+pyrola

+pyroligneous

+pyrolusite

+pyrolytic

+pyrolytically

+pyromancy

+pyromania

+pyromaniac

+pyromaniac's

+pyromaniacal

+pyromaniacs

+pyrometallurgical

+pyrometallurgy

+pyrometric

+pyrometrically

+pyromorphite

+pyronine

+pyroninophilic

+pyrope

+pyrophoric

+pyrophosphatic

+pyrophyllte

+pyrosis

+pyrotechnical

+pyrotechnically

+pyrotechnist

+pyroxenic

+pyroxenitic

+pyroxenoid

+pyroxylin

+pyrrhic

+pyrrhotite

+pyrrhuloxia

+pyrrol

+pyrrole

+pyrrolic

+pyruvate

+pyschiatrist

+pythoness

+pythonic

+pythonine

+pyuria

+pyx

+pyxides

+pyxidium

+pyxie

+pyxis

+qua

+quackish

+quadded

+quadding

+quadrantal

+quadraphonic

+quadraphonics

+quadraphony

+quadrat

+quadrate

+quadrated

+quadrates

+quadrating

+quadrennium

+quadricentennial

+quadricipital

+quadrifid

+quadripuntal

+quadrisect

+quadrisected

+quadrisecting

+quadrisects

+quadrisyllabic

+quadrivalent

+quadrivial

+quadroon

+quadroons

+quadrumvir

+quadrumvirate

+quadruped

+quadrupedal

+quadrupeds

+quadruplet

+quadruplets

+quadruplicity

+quadruply

+quadrupolar

+quadrupole

+quaestor

+quag

+quai

+quaich

+qualmish

+qualmishly

+qualmishness

+qualmy

+quant

+quantal

+quantasome

+quantic

+quantifiably

+quantificational

+quantificationally

+quantifys

+quantitate

+quantitated

+quantitates

+quantitating

+quantitation

+quantitations

+quarantinable

+quark

+quarks

+quartan

+quarterage

+quarterdeck

+quarterdecks

+quarterfinal

+quarterfinalist

+quartern

+quarternary

+quarterstaff

+quartette

+quartic

+quartics

+quarto

+quartos

+quartziferous

+quartzitic

+quartzose

+quasimodo

+quasiparticle

+quatercentenary

+quaternion

+quaternity

+quatrefoil

+quattrocento

+quattuordecillion

+quavery

+quayage

+quayside

+quean

+queasily

+queazy

+queenship

+queerish

+quenchable

+quenchless

+querilla

+querist

+quern

+querns

+questionary

+questionless

+questor

+quetzal

+quetzales

+quib

+quibs

+quickset

+quid

+quid's

+quiddity

+quids

+quiescence

+quietism

+quietist

+quietus

+quiff

+quiffed

+quiffs

+quillwort

+quince

+quinces

+quincuncial

+quincuncially

+quincunx

+quincunxes

+quincunxial

+quindecillion

+quinidine

+quiniela

+quinoa

+quinoid

+quinoidine

+quinoline

+quinquennium

+quinquevalent

+quinquivalent

+quintain

+quintal

+quintessence

+quintette

+quintic

+quintuple

+quintupled

+quintuples

+quintuplet

+quintuplet's

+quintuplets

+quintuplicate

+quintuplicated

+quintuplicates

+quintuplicating

+quintupling

+quintus

+quipped

+quipster

+quirkily

+quirkiness

+quirky

+quisling

+quislingism

+quitch

+quitclaim

+quitrent

+quittance

+quitted

+quittor

+quixotical

+quixotically

+quixotry

+quizmaster

+quizzer

+quizzicality

+quod

+quodlibet

+quoin

+quoit

+quoits

+quondam

+quot

+quotable

+quotidian

+rRNA

+rabbet

+rabbeted

+rabbeting

+rabbets

+rabbinate

+rabbinic

+rabbinism

+rabbitry

+rabbity

+rabblement

+rabic

+rabidity

+racecourse

+racecourses

+racemate

+racemic

+racemose

+rachet

+rachides

+rachiodont

+rachis

+rachises

+rachitic

+rachitis

+racialism

+racialist

+racialistic

+racily

+racine

+rackle

+racon

+raconteur

+racoon

+rad

+radarscope

+radarscopes

+raddle

+raddled

+raddles

+raddling

+radiale

+radiancy

+radiational

+radiationless

+radic

+radicand

+radicate

+radicle

+radicular

+radioautograph

+radioautographic

+radioautography

+radiobiologic

+radiobiological

+radiobiologically

+radiobiologist

+radiobiology

+radiobroadcast

+radiobroadcaster

+radiobroadcasting

+radiocast

+radiocaster

+radiochemist

+radiochlorine

+radioecological

+radioecologist

+radioecology

+radioelement

+radiogenic

+radiogram

+radiogram's

+radiograms

+radiograph

+radiographically

+radioimmunoassay

+radioisotope

+radioisotopic

+radioisotopically

+radiolarian

+radiolocation

+radiologist

+radiolucency

+radiolucent

+radiolysis

+radiolytic

+radiometeorograph

+radiometrically

+radiomimetic

+radionuclide

+radiopaque

+radiophone

+radiophoto

+radiophotograph

+radioscopic

+radioscopy

+radiosensitive

+radiosensitivity

+radiosonde

+radiostrontium

+radiosymmetrical

+radiotelegraph

+radiotelegraphic

+radiotelegraphy

+radiotelephone

+radiotelephony

+radiotherapist

+radiothorium

+radiotracer

+radome

+rads

+radula

+radular

+raff

+raffia

+raffinose

+raftsman

+raga

+ragamuffin

+ragbag

+raggedy

+raggle

+ragi

+raglan

+ragman

+ragpicker

+ragtag

+ragtime

+rah

+rainmaker

+rainmaking

+rainproof

+rainspout

+rainsquall

+rainwash

+rainwear

+raj

+raja

+rale

+rallye

+rallyist

+rallymaster

+ramate

+rambunctious

+rambunctiously

+rambunctiousness

+ramekin

+ramentum

+ramequin

+rami

+ramie

+ramiform

+ramillies

+ramirez

+rammer

+ramose

+ramosely

+ramous

+rampageous

+rampageously

+rampageousness

+rampancy

+rampion

+ramshackle

+ramus

+ranchman

+ranian

+rantry

+ranunculus

+rapacity

+rapine

+rapist

+rappee

+rappen

+rapporteur

+rapscallion

+raptor

+raptorial

+rapunzel

+rarebit

+rarefaction

+rarefactional

+rarefactive

+rarify

+rasa

+rascality

+rasing

+rasorial

+raspy

+rasure

+rata

+ratably

+ratafia

+rataplan

+ratch

+ratel

+ratemeter

+ratemeter's

+ratemeters

+ratepayer

+ratepayers

+rathe

+rathskeller

+raticide

+ratificationist

+ratiocinator

+rationalistically

+ratlike

+ratline

+raton

+ratoon

+rattan

+ratted

+ratteen

+ratter

+ratting

+rattlebrain

+rattlebrained

+rattletrap

+rattly

+rattrap

+raunchier

+raunchily

+raunchiness

+raunchy

+ravagement

+ravel

+ravelment

+ravels

+ravioli

+ravishment

+rawinsonde

+rawlings

+rawlins

+rayless

+raylessness

+rayon

+razeed

+razeeing

+razorbill

+razz

+razzmatazz

+reabsorb

+reabsorption

+reacquaint

+reacquire

+reacquisition

+reactance

+reactances

+reactional

+reactionally

+reactionaryism

+reaggregate

+reaggregation

+realpolitik

+reapportion

+rearhorse

+rearm

+rearmament

+rearming

+rearmost

+rearward

+rearwardly

+rearwards

+reasonability

+reasonless

+reasonlessly

+reassembly

+reave

+reaver

+reaving

+reb

+rebarbative

+rebarbatively

+reboant

+rebs

+rebus

+rebuttable

+rebutter

+recalcitrance

+recalcitrancy

+recalescence

+recallability

+recantation

+recap

+recatory

+receivership

+recension

+receptaculum

+recessional

+recessionary

+recharge

+rechargeable

+recharger

+recharging

+recheat

+recidivism

+recidivist

+recidivistic

+reciprocator

+recision

+recitalist

+recitativo

+reck

+reclinate

+reclosable

+recoin

+recombinant

+recommit

+recommitment

+recompence

+recompose

+reconcilability

+reconcilable

+reconcilableness

+reconcilement

+reconfirm

+reconfirmation

+reconstitute

+reconstitution

+reconstructionism

+reconstructionist

+reconstructor

+recontaminate

+reconversion

+reconvert

+reconverted

+reconvey

+reconveyance

+recordable

+recordation

+recordist

+recoupable

+recoupment

+recreant

+recreatable

+recreationist

+recriminatory

+recrudesce

+recrudescence

+recrudescent

+rectal

+rectally

+rectangularity

+recti

+rectifiability

+rectifiable

+recting

+rection

+rectitudinous

+rective

+recto

+rectorate

+rectorial

+rectorship

+rectos

+rectrices

+rectrix

+rectus

+recumbency

+recusancy

+redaction

+redactional

+redargue

+redbone

+redcap

+redded

+reddy

+rede

+redear

+redecorate

+redecorator

+redeemable

+redemptional

+redemptory

+redeploy

+redeployed

+redeployment

+redescribe

+redescription

+redetermine

+redetermined

+redetermining

+redhook

+redhorse

+redia

+rediae

+redial

+redias

+redintegrate

+redintegration

+redintegrative

+rediscount

+rediscountable

+redistributory

+redistrict

+redivivus

+redleg

+redolence

+redolent

+redolently

+redondo

+redoubt

+redoubtably

+redout

+redox

+redpoll

+redroot

+redshank

+redshift

+redshifted

+redshifting

+redshifts

+redshirt

+redskin

+redstart

+redtop

+reductant

+reductase

+reductio

+reductional

+reductionist

+reductionistic

+reduplicate

+reduplication

+reduplicative

+reduplicatively

+reduviid

+redwing

+ree

+reedbuck

+reedify

+reeducate

+reeducative

+reeky

+reelable

+reembroider

+reemphasization

+reemphasization's

+reemploy

+reemployment

+reenforce

+reenlist

+reenlisted

+reenlistment

+reentrance

+reest

+reestablishment

+ref

+reface

+refacing

+refect

+refection

+referable

+refinish

+refinisher

+refinishes

+refinishing

+refit

+reflation

+reflationary

+reflectional

+reflectometer

+reflectometer's

+reflectometers

+reflectometry

+reflexion

+reflexology

+reflorescence

+reflorescent

+reflow

+refluence

+reforest

+reforge

+reformate

+reformational

+refractile

+refractivities

+refractivity

+refractometric

+refractometry

+refractor

+refractorily

+refrainment

+refrangibility

+refrangible

+refrangibleness

+refrigerant

+refringent

+reft

+refugeeism

+refugium

+refulgence

+refulgent

+refundability

+refundable

+refurbishment

+refutably

+regality

+regardant

+regardful

+regardfully

+regardfulness

+regelation

+regenerable

+regeneracy

+regenerator

+regental

+regicidal

+regicide

+regimental

+regimentally

+regimentals

+regionalist

+regionalistic

+regisseur

+regius

+reglet

+regna

+regnal

+regnant

+regnum

+regolith

+regorge

+regorged

+regorging

+regosol

+regrant

+regreet

+regressor

+regretless

+regretter

+regrid

+regridded

+regridding

+regrow

+regurgitate

+regurgitated

+regurgitates

+regurgitating

+regurgitation

+regurgitative

+rehabilitant

+rehabilitationist

+rehabilitator

+rehear

+rehouse

+rehousing

+rehydratable

+rehydrate

+rehydration

+reichsmark

+reification

+reified

+reify

+reifying

+reimpression

+reincarnationist

+reinfection

+reinforceable

+reinhard

+reinhardt

+reinless

+reinsman

+reinsurance

+reinsure

+reinsurer

+reintegrate

+reintegration

+reintegrative

+reinvestment

+reinvigorate

+reinvigorator

+reiterator

+reive

+reiver

+reiving

+rejectee

+rejuvenate

+rejuvenated

+rejuvenates

+rejuvenating

+rejuvenation

+rejuvenator

+rejuvenescence

+rejuvenescent

+relatable

+relator

+relaxant

+relaxin

+releasability

+releasably

+relection

+reliction

+relievable

+relievo

+religionist

+religiose

+reline

+relinquishment

+reliquary

+relique

+reliquiae

+relishable

+relocatee

+relucent

+reluctancy

+reluctate

+reluctated

+reluctation

+reluctivity

+relume

+relumed

+relumine

+reluming

+remaines

+reman

+remanence

+remanent

+remanufacture

+remanufacturer

+remap

+remarque

+remediably

+remedially

+remediate

+remediation

+remediless

+remedilessly

+rememberability

+rememberable

+remigial

+remindful

+reminiscential

+remint

+remise

+remised

+remising

+remissible

+remissibly

+remitment

+remittable

+remittal

+remittent

+remittently

+remitter

+remonstrance

+remonstrant

+remonstrantly

+remonstrator

+remount

+removability

+removably

+remunerator

+remuneratory

+remus

+renascence

+renderable

+renegade

+renegades

+renege

+reneged

+reneger

+reneges

+reneging

+renewability

+renewably

+reniform

+renig

+renigged

+renigging

+renin

+renitency

+renitent

+rennet

+rennin

+renographic

+renography

+renominate

+renominating

+renomination

+renouncement

+renovator

+rentability

+rentable

+rente

+rentier

+renunciatory

+reoccupy

+reoccur

+reoccurrence

+rep

+repack

+repacker

+repacking

+repairability

+repand

+reparative

+repass

+repassage

+repatriate

+repatriated

+repatriates

+repatriating

+repatriation

+repealable

+repellant

+repellency

+repeller

+repercussive

+repetend

+repetitional

+replant

+repleviable

+replevied

+replevies

+replevin

+reportable

+reposal

+reposeful

+reposefully

+reposefulness

+reposit

+reposited

+repositing

+repossess

+repossession

+repower

+reprehend

+reprehensibility

+reprehensibly

+reprehension

+reprehensive

+representationalism

+representationalist

+repressibility

+repressible

+repressionist

+repressor

+reprieval

+repristinate

+repristination

+repro

+reproachable

+reproachful

+reproachfully

+reproachfulness

+reprobance

+reprobatory

+reprocess

+reprocessable

+reprocesses

+repros

+repudiationist

+repudiator

+repugn

+repugnancy

+reputability

+req

+requestioner

+requestor

+requiescat

+requin

+requital

+reradiate

+reradiation

+reredos

+reremouse

+rereward

+resail

+rescale

+rescindment

+rescission

+rescissory

+rescript

+researchist

+resect

+resectability

+resectable

+resection

+reseed

+resend

+resending

+reserpine

+reservist

+reservists

+resettable

+reship

+reshipment

+reshipper

+reshuffle

+residua

+resile

+resiled

+resiliency

+resiling

+resinate

+resinify

+resinoid

+resinous

+resiny

+resistable

+resistibility

+resistless

+resistlessly

+resistlessness

+resitting

+resojet

+resole

+resolvent

+resorb

+resorcinol

+resorption

+resorptive

+respell

+respirable

+respirational

+respirometer

+respirometer's

+respirometers

+respirometric

+respirometry

+resplendence

+resplendency

+responsory

+responsum

+ressentiment

+resses

+restage

+restartable

+restauranteur

+restitute

+restorable

+restoral

+restrainable

+restrictionism

+restrictionist

+restrike

+resultful

+resultfulness

+resultless

+resupinate

+resupination

+resupine

+resurgam

+resurge

+resurging

+resurrectional

+resurrectionist

+resuscitator

+resuscitators

+resvering

+ret

+retable

+retake

+retardate

+retentivity

+retenue

+retia

+retiarius

+reticency

+reticule

+reticulocyte

+reticulocytic

+reticulose

+retiform

+retinacular

+retinaculum

+retinae

+retinene

+retinitis

+retinol

+retinopathy

+retinoscopy

+retinospora

+retinula

+retinular

+retirant

+retool

+retortion

+retot

+retouch

+retoucher

+retractile

+retractility

+retrainable

+retrainee

+retral

+retrally

+retread

+retreaded

+retreading

+retreatant

+retrench

+retrial

+retributive

+retributively

+retributory

+retrievability

+retroaction

+retroactivity

+retrocede

+retrocession

+retrofire

+retrofitted

+retrogradation

+retrogress

+retrogression

+retrolental

+retrolingual

+retropack

+retroperitoneal

+retroperitoneally

+retroreflection

+retroreflective

+retroreflector

+retrorse

+retrorsely

+retroserrate

+retroversion

+rets

+retsina

+retted

+retting

+returnee

+returnee's

+returnees

+retuse

+reunification

+reunify

+reunionist

+reunionistic

+rev

+revalidate

+revalidating

+revaluate

+revalue

+revanche

+revanchist

+revealable

+revealment

+revegetate

+revegetation

+revehent

+reveille

+reveilles

+revelator

+revenant

+rever

+reverb

+reverberant

+reverberantly

+reverberatory

+reverential

+reverentially

+revers

+reversibly

+reversional

+reversionary

+revertible

+revery

+revest

+revetment

+revetted

+revictual

+revilement

+revisal

+revisionism

+revisor

+revisory

+revivable

+revivalist

+revivalistic

+revivalists

+revivification

+revivify

+reviviscence

+reviviscent

+revokable

+revoluable

+revolute

+revolutionarily

+revolutionibus

+revolutionist

+revolvable

+revs

+revulsed

+revulsive

+rew

+rewake

+rewaken

+rewardable

+rexroth

+rey

+reynard

+rezone

+rhabdom

+rhabdomancy

+rhabdome

+rhabdomere

+rhadamanthine

+rhamnaceous

+rhamnose

+rhamnus

+rhaphe

+rhapsodical

+rhapsodically

+rhapsodist

+rhatany

+rhebok

+rheims

+rheinholdt

+rheological

+rheologically

+rheologist

+rheometer

+rheometer's

+rheometers

+rheophile

+rheophilic

+rheostatic

+rhesus

+rhet

+rhetor

+rheumatically

+rheumatiz

+rheumatoid

+rheumatologist

+rheumatology

+rheumy

+rhinal

+rhinelander

+rhinencephalic

+rhinencephalon

+rhinitis

+rhinocerotic

+rhinolaryngology

+rhinopharyngitis

+rhinoscopy

+rhinosporidium

+rhinovirus

+rhizanthous

+rhizobium

+rhizocarpic

+rhizocarpous

+rhizocephalan

+rhizocephalid

+rhizoctonia

+rhizogenesis

+rhizogenetic

+rhizogenic

+rhizoid

+rhizoidal

+rhizomatous

+rhizome

+rhizomic

+rhizomorphous

+rhizoplane

+rhizopod

+rhizopodal

+rhizopodous

+rhizopus

+rhizosphere

+rhizotomy

+rhodamine

+rhodochrosite

+rhodomontade

+rhodoplast

+rhodopsin

+rhodora

+rhomb

+rhombencephalon

+rhombi

+rhombohedral

+rhombohedron

+rhomboid

+rhomboidal

+rhomboideus

+rhombs

+rhonchi

+rhonchus

+rhumb

+rhumba

+rhumbs

+rhus

+rhuses

+rhymester

+rhyolite

+rhyolitic

+rhythmicity

+rhythmist

+rhytidome

+ri

+rial

+rialto

+riant

+riantly

+riata

+ribaldry

+riband

+ribas

+ribband

+ribber

+ribbonlike

+ribby

+ribgrass

+riblet

+ribonuclease

+ribonucleoprotein

+ribonucleoside

+ribonucleotide

+ribose

+ricci

+ricebird

+ricercar

+richert

+richey

+richland

+richment

+rici

+ricin

+ricinus

+rickards

+rickenbaugh

+rickettsia

+rickey

+rickeys

+rickrack

+ricksha

+ricotta

+rictal

+rictus

+ridded

+ridder

+rideable

+riderless

+ridgeling

+ridgling

+ridgy

+ridotto

+ridpath

+riegger

+riel

+rien

+rier

+rife

+rifely

+riff

+riffle

+riffled

+riffler

+riffles

+riffling

+riffraff

+rification

+rifice

+rificer

+riflebird

+riflery

+riflescope

+rifying

+rigadoon

+rigatoni

+rigaudon

+rightism

+rigidification

+rigidify

+rigorism

+rigorism's

+rigorisms

+rigorist

+rigorist's

+rigoristic

+rigoristics

+rigorists

+rile

+riling

+rilke

+rille

+rillet

+rilly

+rimbaud

+rimier

+rimland

+rimose

+rimous

+rimrock

+rimy

+rin

+rinascimento

+rinderpest

+ringbark

+ringbolt

+ringbolts

+ringbone

+ringboned

+ringdove

+ringel

+ringent

+ringleader

+ringleaders

+ringlike

+ringmaster

+ringmasters

+ringneck

+ringolade

+ringstraked

+ringtail

+ringtaw

+ringtoss

+ringworm

+ringworms

+ripieno

+ripoff

+ripoff's

+ripoffs

+riposte

+ripper

+riprap

+ripsaw

+ripsnorter

+ripsnorting

+riptide

+risibility

+risorgimento

+risotto

+rit

+ritard

+ritualism

+ritualist

+ritualistic

+ritualistically

+ritzier

+ritziness

+ritzy

+rivalrous

+riverbed

+riverview

+riverward

+riverwards

+riverweed

+riyal

+roadability

+roadless

+roadrunner

+roadrunners

+roadstead

+roadwork

+roadworks

+roadworthiness

+roadworthy

+roan

+robalo

+roband

+robbie

+roble

+robustious

+robustiously

+robustiousness

+roc

+rocambole

+rochet

+rockabilly

+rockaway

+rockaways

+rocketeer

+rocketry

+rockettes

+rockfish

+rocklike

+rockling

+rockoon

+rockrose

+rockshaft

+rockskipper

+rococo

+rodenticide

+rodeph

+rodless

+rodlike

+roemer

+roentgenogram

+roentgenogram's

+roentgenograms

+roentgenograph

+roentgenographic

+roentgenographically

+roentgenography

+roentgenologic

+roentgenological

+roentgenologically

+roentgenologist

+roentgenology

+roentgenoscope

+roentgenoscopic

+roentgenoscopy

+roentgenotherapy

+roff

+rogation

+rogueing

+roguery

+roi

+roic

+roily

+roister

+roistered

+roisterer

+roistering

+roisterous

+rolamite

+rollick

+rollie

+rollout

+rollover

+rolnick

+romaine

+romanticist

+romanza

+romaunt

+romulo

+rondeau

+rondeaux

+rondel

+rondelet

+rondelle

+rondure

+ronnel

+ronyon

+roofhouse

+roofless

+rooflike

+roofline

+rooftree

+rookery

+rooky

+roomette

+rooney

+roorback

+roos

+roose

+rootage

+roothold

+rootlet

+rootlike

+rootstalk

+rootstock

+rooty

+ropean

+ropedancer

+ropedancing

+ropery

+ropewalk

+ropewalker

+ropeway

+ropework

+ropier

+ropiness

+ropy

+roque

+roquelaure

+rorqual

+rosabelle

+rosaceous

+rosaniline

+rosarian

+rosebay

+rosefish

+roselike

+rosella

+rosemaling

+roseola

+roseolar

+rosery

+roset

+rosewater

+rosewood

+rosie

+rosily

+rosin

+rosined

+rosining

+rosinous

+rosinweed

+roslev

+rossi

+rossoff

+rostagno

+rostagnos

+rostellar

+rostellate

+rostellum

+rostra

+rostral

+rostrate

+rosulate

+roswell

+rota

+rotaed

+rotameter

+rotameter's

+rotameters

+rotatable

+rotatory

+rote

+rotenone

+rotgut

+rothko

+rotifer

+rotisserie

+rotonda

+rotorcraft

+rotos

+rotted

+rottenstone

+rotter

+rottosei

+rottweiler

+roturier

+rou

+rouen

+roughage

+roughcast

+roughhouse

+roughhoused

+roughhousing

+roughleg

+roughrider

+roughriders

+roulade

+rouleau

+rouleaux

+roundel

+roundelay

+roundish

+roundlet

+roundsman

+roundwood

+roup

+rous

+rouseabout

+rousement

+roust

+rouster

+routeman

+routeway

+routh

+roux

+roven

+rowdily

+rowdyish

+rowdyism

+rowlock

+roxy

+royalism

+royaux

+royster

+rozella

+rozelle

+rozzer

+rpt

+rubasse

+rubato

+rubberlike

+rubberneck

+rubbernecker

+rubbishy

+rubblework

+rubefacient

+rubellite

+rubeola

+rubeolar

+rubicundity

+rubiginous

+rubious

+rubrical

+rubrically

+rubricate

+rubrication

+rubricator

+rubus

+rubythroat

+rucellai

+ruche

+ruching

+ruck

+rucksack

+ruction

+rudbeckia

+rudd

+rudderpost

+rudderstock

+ruddily

+ruddle

+ruddled

+ruddleman

+ruddling

+ruddock

+ruderal

+rudesbies

+rudesby

+rudimental

+rudimentarily

+rufescent

+ruff

+ruffe

+ruffed

+ruffianism

+ruffly

+rufous

+ruga

+rugae

+rugal

+rugate

+rugby

+rugger

+ruggiero

+rugose

+rugosely

+rugosity

+rugulose

+ruh

+ruidoso

+ruinate

+ruleless

+rulership

+rumba

+rumbly

+rumbustious

+rumdum

+rumina

+ruminal

+ruminate

+rumination

+ruminative

+ruminatively

+ruminator

+rummel

+rummer

+rummest

+rumrunner

+runagate

+runaround

+runback

+runcinate

+rundle

+rundlet

+runless

+runlet

+runnel

+runnels

+runneth

+runny

+runout

+runouts

+runover

+runtm

+rupiah

+rupiahs

+rupicoline

+rupicolous

+ruppert

+ruralist

+rurban

+rushall

+rushee

+rushlight

+rushy

+russetting

+russification

+russify

+russula

+rustical

+rustically

+rusticator

+rusticity

+rustily

+ruthenic

+ruthenious

+rutilant

+rutile

+ruttish

+ruttishly

+ruttishness

+ryegrass

+saba

+sabadilla

+sabbat

+sabbatic

+sabin

+sabol

+sabot

+saboteur

+saboteurs

+sabra

+sac

+sacahuiste

+sacaton

+saccade

+saccadic

+saccate

+saccharase

+saccharate

+saccharide

+saccharides

+saccharification

+saccharify

+saccharimeter

+saccharimeter's

+saccharimeters

+saccharimetry

+saccharin

+saccharine

+saccharinity

+saccharoidal

+saccharometer

+saccharometer's

+saccharometers

+saccharomyces

+saccharose

+saccular

+sacculate

+sacculated

+sacculates

+sacculation

+saccule

+sacculus

+sacerdotal

+sacerdotalism

+sacerdotalist

+sacerdotally

+sachem

+sachemic

+sachems

+sachet

+sacheted

+sacheverell

+sackbut

+sackcloth

+sackful

+saclike

+sacque

+sacra

+sacramental

+sacramentalism

+sacramentalist

+sacramentally

+sacrarium

+sacre

+sacrestia

+sacrilegiousnes

+sacring

+sacristan

+sacristy

+sacroiliac

+sacrosanctity

+sacrum

+saddhu

+saddlebow

+saddlecloth

+saddleless

+saddlery

+saddletree

+sadomasochism

+sadomasochist

+sadomasochistic

+safecracker

+safecracking

+safelight

+safetyman

+safflower

+safranin

+safranine

+safrole

+sagami

+saggar

+sagger

+sagittal

+sagittally

+sagittate

+sago

+sagos

+saguaro

+sahib

+sailable

+sailboard

+sailcloth

+sailon

+sailplane

+sailplaner

+sain

+sainfoin

+saintdom

+saintlike

+saintsbury

+saintship

+saith

+saithe

+saki

+sako

+salability

+salamandrine

+salariat

+saleable

+saledo

+saleratus

+saleroom

+salesclerk

+salesroom

+saleswoman

+salic

+salicin

+salicylate

+salida

+salientian

+salimeter

+salimeter's

+salimeters

+salinity

+salinometer

+salinometer's

+salinometers

+sallet

+sallowish

+salmagundi

+salmi

+salmonberries

+salmonberry

+salmonella

+salmonellosis

+salmonid

+salmonoid

+salometer

+salometer's

+salometers

+saloonkeep

+saltarello

+saltation

+saltatorial

+saltatory

+saltbox

+saltbush

+saltcellar

+saltern

+saltily

+saltine

+saltire

+saltless

+saltlike

+saltonstall

+saltshaker

+saltworks

+saltwort

+salubrity

+saluki

+salutarily

+salutaris

+salutational

+salutatorian

+salutatory

+salutiferous

+salutory

+salvable

+salvageability

+salvational

+salvationism

+salvationist

+salverform

+salvific

+salvoes

+salvor

+samar

+samara

+samarium

+samarskite

+samba

+sambar

+sambur

+samisen

+samite

+samlet

+samp

+sampan

+samphire

+samurai

+samurai's

+samurais

+sanatarium

+sanative

+sanbenito

+sancta

+sanctimony

+sanctum

+sandarac

+sandbagger

+sandbank

+sandbar

+sandbox

+sandbur

+sandglass

+sandhog

+sandling

+sandlot

+sandlotter

+sandpapery

+sandsoap

+sandstorm

+sandstorms

+sandworm

+sandworms

+sangaree

+sangfroid

+sanguinaria

+sanguinarily

+sanguineum

+sanguinity

+sanguinolent

+sanicle

+sanious

+sanipractor

+sanitaire

+sanitarian

+sanitarily

+sanitorium

+sannyasi

+sans

+sansei

+sanseis

+sanserif

+sansevieria

+sanskritic

+sansom

+sansome

+sant

+santolina

+santonica

+santonin

+santour

+saphead

+sapheaded

+saphenous

+sapid

+sapidity

+sapience

+sapiens

+sapient

+sapiently

+sapio

+sapless

+saplessness

+sapodilla

+sapogenin

+saponaceous

+saponaceousness

+saponifiable

+saponification

+saponifier

+saponify

+saponin

+saponins

+saponite

+sapor

+saporous

+sapota

+sapper

+sapphic

+sapphirine

+sapphism

+sapremia

+sapremic

+saprobe

+saprobic

+saprobically

+saprogenic

+saprogenicity

+saprolite

+sapropelic

+saprophagous

+saprophyte

+saprophytic

+saprophytically

+saprozoic

+sapsago

+saraband

+sarabande

+sarape

+sarasate

+sarcenet

+sarcoid

+sarcoidosis

+sarcolemma

+sarcolemmal

+sarcomatosis

+sarcomatous

+sarcomere

+sarcomeric

+sarcophagic

+sarcophagous

+sarcophagus

+sarcophagy

+sarcoplasm

+sarcoplasma

+sarcoplasmatic

+sarcoplasmic

+sarcosomal

+sarcosome

+sardonically

+sardonicism

+sardonyx

+sargasso

+sargassum

+sarge

+sarmi

+sarod

+sarode

+sarodist

+sarong

+sarong's

+sarongs

+sarpsis

+sarsaparilla

+sarsenet

+sarsparilla

+sarti

+sartorial

+sartorially

+sashimi

+saskatoon

+sass

+sassier

+sasswood

+sassy

+satang

+satangs

+satanically

+satchelful

+sateen

+satem

+sati

+satiety

+satinet

+satinwood

+satiny

+satori

+saturable

+saturant

+saturator

+saturnali

+saturnalian

+saturnalianly

+saturniid

+satyriasis

+satyric

+satyrid

+saucebox

+saucerlike

+sauch

+sauerbraten

+sauger

+saurel

+saurian

+sauries

+sauropod

+savable

+savagism

+savanna

+savanna's

+savannas

+savant

+savants

+savate

+saveable

+sawbelly

+sawbones

+sawboneses

+sawbuck

+sawfish

+sawfly

+sawlike

+sawtimber

+saxhorn

+saxifrage

+saxophonic

+saxton

+sayable

+scabbier

+scabbing

+scabble

+scabbled

+scabbles

+scabbling

+scabby

+scabies

+scabietic

+scabiosa

+scabious

+scad

+scad's

+scads

+scag

+scagliola

+scalade

+scalado

+scalage

+scalare

+scalariform

+scalariformly

+scalation

+scalawag

+scaleless

+scalelike

+scalene

+scalepan

+scallion

+scallopini

+scallywag

+scallywags

+scalogram

+scalogram's

+scalograms

+scammed

+scamming

+scammony

+scampi

+scampini

+scampish

+scandalmonger

+scandent

+scannable

+scansion

+scantling

+scape

+scapegoatism

+scapegrace

+scaphoid

+scapin

+scaping

+scapolite

+scapose

+scarab

+scarabaeid

+scaramouch

+scaramouche

+scarecrowish

+scarehead

+scaremonger

+scarey

+scarfpin

+scarfskin

+scarious

+scarlatinal

+scarless

+scarp

+scarped

+scarper

+scarpered

+scarpering

+scarpers

+scarph

+scarping

+scarps

+scarring

+scarry

+scatback

+scathe

+scathed

+scatheless

+scathes

+scatological

+scatology

+scatted

+scatteration

+scattershot

+scattier

+scatty

+scaup

+scauper

+scaups

+scc

+scena

+scenarist

+scenical

+scenically

+scenographic

+scenographically

+scenography

+scentless

+sceptibly

+schelling

+schematism

+scherzi

+scherzo

+schismatic

+schismatical

+schismatically

+schismatist

+schistose

+schistosity

+schistosomal

+schistosome

+schistosomiasis

+schistous

+schizo

+schizocarp

+schizogonic

+schizogonous

+schizogony

+schizomycete

+schizomycetous

+schizont

+schizophrene

+schizophrenically

+schizophyte

+schizophytic

+schizos

+schizothymic

+schlemiel

+schlepp

+schlieren

+schlieric

+schlock

+schmaltz

+schmaltzy

+schmalz

+schnauzer

+schnitzel

+scholastica

+scholasticate

+scholasticism

+scholiast

+scholiastic

+scholium

+schoolbag

+schoolchild

+schoolfellow

+schoolman

+schoolmistress

+schooltime

+schopenhauer

+schorlaceous

+schuman

+schwada

+sciaenoid

+sciatic

+sciential

+scientifique

+scientism

+scientologist

+scientology

+scilicet

+scilla

+scintigraphic

+scintigraphy

+scintilla

+scintillant

+scintillantly

+scintillator

+scintillometer

+scintillometer's

+scintillometers

+sciolism

+sciolist

+sciolistic

+sciomancy

+sciomantic

+scirocco

+scirrhi

+scirrhous

+scirrhus

+scissile

+scission

+scissortail

+sclerose

+sclerosed

+sclerotial

+sclerotin

+sclerotium

+scofflaw

+scofflaw's

+scofflaws

+scolecite

+scolex

+scolices

+scoliosis

+scoliotic

+scollop

+scolopendra

+scombroid

+sconce

+scone

+scoopful

+scopic

+scopolamine

+scopula

+scopulate

+scorbutic

+scorbutically

+scorekeeper

+scoria

+scoriaceous

+scorpaenid

+scorpioid

+scotchgard

+scotchman

+scoter

+scotoma

+scotomatous

+scotopic

+scottie

+scouse

+scouser

+scoutcraft

+scoutmaster

+scrabbly

+scrag

+scraggier

+scragging

+scraggy

+scrannel

+scrapie

+scrapper

+scrappier

+scrappiness

+scrapple

+scrappy

+scrawly

+screak

+screaky

+scree

+screenable

+screenful

+screvane

+screwbean

+screwier

+screwiness

+screwlike

+screwworm

+screwy

+scrieve

+scrimpy

+scrimshaw

+scrip

+scriptal

+scription

+scriptorium

+scriptwriter

+scriptwriter's

+scriptwriters

+scrod

+scrofula

+scrofulous

+scrollwork

+scrota

+scrotal

+scrotum

+scrotum's

+scrotums

+scrouge

+scrouging

+scrubbier

+scrubby

+scrubland

+scrubwoman

+scruff

+scruffier

+scruffiness

+scruffy

+scrum

+scrummage

+scrunch

+scrutator

+scrutin

+scrutineer

+scud

+scudded

+scudding

+scuds

+scull

+sculled

+sculler

+sculleries

+scullery

+sculling

+scullion

+scullions

+sculls

+sculpin

+sculpsit

+sculptress

+sculpturesque

+sculpturesquely

+scumble

+scumbled

+scumbles

+scumbling

+scumming

+scummy

+scunner

+scup

+scupper

+scuppered

+scuppering

+scuppernong

+scuppers

+scups

+scurf

+scurfy

+scurril

+scurrile

+scurrility

+scurvily

+scuttlebutt

+scutum

+seabag

+seabeach

+seabed

+seabed's

+seabird

+seaboot

+seaborne

+seacraft

+seadog

+seadrome

+seafloor

+seafowl

+seafront

+seagirt

+seagoing

+sealery

+sealskin

+seamanlike

+seamark

+seamlike

+seamount

+seamster

+seaplane

+seaquarium

+searchable

+searchless

+seascape

+sease

+seashell

+seashell's

+seashells

+seasick

+seasickness

+seastrand

+seatmate

+seatmate's

+seatmates

+seawall

+seaware

+seawater

+seawater's

+seaworthiness

+seaworthy

+sebaceous

+sebum

+sec

+secateur

+secateurs

+secco

+secessionism

+seclusive

+seclusively

+seclusiveness

+secobarbital

+secondo

+secretaryship

+secretin

+secretionary

+secretor

+secretory

+sectarianism

+sectary

+sectile

+sectility

+sectionalism

+sectorial

+secularistic

+secund

+securement

+seder

+sedgwick

+sedgy

+sedilia

+sedimentologic

+sedimentological

+sedimentologically

+sedimentologist

+sedimentology

+seducement

+seductress

+sedulity

+sedulous

+sedulousness

+sedum

+seeable

+seedcake

+seedcakes

+seedily

+seedlike

+seedpod

+seedsman

+seedtime

+seel

+seeley

+seepy

+seeress

+seerey

+segetal

+segmentary

+segno

+segnos

+segue

+segue's

+segued

+segueing

+segues

+seguidilla

+segur

+segura

+sei

+seicento

+seiche

+seigneur

+seigneurial

+seigneury

+seignior

+seigniorage

+seigniory

+seignorage

+seignorial

+seignory

+seine

+seiner

+seining

+seisin

+seisins

+seism

+seismicity

+seismogram

+seismogram's

+seismograms

+seismographic

+seismologist

+seismometric

+seismometry

+selachian

+selaginella

+selden

+selectee

+selectman

+selectmen

+selenic

+selenide

+seleniferous

+selenious

+selenocentric

+selenographer

+selenographic

+selenographist

+selenography

+selenological

+selenologist

+selenologist's

+selenologists

+selenology

+selenosis

+selfadjoint

+selfdom

+selfhood

+sellable

+selle

+selvage

+selvaged

+selvedge

+selvedged

+semasiological

+semasiologist

+semasiology

+sematic

+semblable

+semblably

+semeiology

+sement

+semestral

+semestrial

+semiabstract

+semiabstraction

+semiaquatic

+semiarboreal

+semiaridity

+semiautomatically

+semiautonomous

+semibasement

+semibreve

+semicentenary

+semicentennial

+semicircle

+semicircles

+semiclassic

+semiclassical

+semicolonial

+semicolonialism

+semicolony

+semicommercial

+semiconducting

+semiconscious

+semiconsciously

+semiconsciousness

+semiconservative

+semiconservatively

+semicrystalline

+semicylindrical

+semidarkness

+semidesert

+semidetached

+semidiameter

+semidiurnal

+semidivine

+semidocumentary

+semidome

+semidomed

+semidomestic

+semidomesticated

+semidomestication

+semidominant

+semidouble

+semidry

+semiellipse

+semielliptic

+semielliptical

+semiempirical

+semierect

+semievergreen

+semifinal

+semifinalist

+semifinished

+semifitted

+semiflexible

+semifluid

+semiformal

+semifossil

+semigloss

+semigovernmental

+semigroup

+semilegendary

+semilethal

+semiliquid

+semiliterate

+semilog

+semilunar

+semilustrous

+semimanufactures

+semimetal

+semimetallic

+semimicro

+semimoist

+semimonastic

+semimonthly

+semimystical

+seminarist

+seminiferous

+semiofficial

+semiofficially

+semiological

+semiology

+semiopaque

+semiosis

+semiotic

+semiotical

+semiotician

+semiotics

+semipalmated

+semiparasitic

+semipermeability

+semipermeable

+semiphore

+semipolitical

+semiporcelain

+semipostal

+semiprecious

+semiprivate

+semipro

+semiquaver

+semiramis

+semireligious

+semiretired

+semiretirement

+semirigid

+semisacred

+semisedentary

+semishrub

+semishrubby

+semiskilled

+semisoft

+semisolid

+semisweet

+semisynthetic

+semiterrestrial

+semitonal

+semitonally

+semitone

+semitonic

+semitonically

+semitrailer

+semitranslucent

+semitransparent

+semitropic

+semitropics

+semivowel

+semiweekly

+semiworks

+semiyearly

+semmes

+semolina

+semper

+sempervivum

+sempiternal

+sempiternally

+sempiternity

+semple

+semplice

+sempre

+sempstress

+semra

+sen

+senarii

+senarius

+senary

+senatorian

+senatorship

+sendable

+senecio

+senectitude

+senega

+senesac

+senescence

+senescent

+seneschal

+sengi

+senhor

+senhora

+senhores

+senhorita

+senilis

+senility

+senioritatis

+seniti

+senna

+sennet

+sennight

+sennit

+sens

+sensa

+sensationalist

+sensationalistic

+senseful

+sensibilia

+sensillum

+sensitometer

+sensitometer's

+sensitometers

+sensitometric

+sensitometry

+sensorial

+sensorially

+sensorimotor

+sensorineural

+sensorium

+sensualism

+sensualist

+sensualistic

+sensum

+sensuosity

+sententia

+sententious

+sententiously

+sententiousness

+senti

+sentience

+sentimentalism

+sentimentalist

+sepal

+separably

+separationist

+separatism

+separatist

+separatistic

+sepiolite

+sepses

+sepsis

+septa

+septal

+septenarius

+septendecillion

+septentrion

+septentrional

+septicemia

+septicemic

+septicidal

+septifragal

+sepuchral

+sepulture

+sequacious

+sequaciously

+sequacity

+sequela

+sequelae

+sequency

+sequent

+sequestrate

+sequestrum

+sequinned

+sequitur

+ser

+sera

+serac

+serafin

+seraglio

+serai

+seral

+seraphic

+seraphically

+seraphs

+serbantian

+serbian

+sere

+serfage

+sergeancy

+sergeanty

+serialism

+serialist

+seriate

+seriately

+seriatim

+sericeous

+sericin

+sericultural

+sericulture

+sericulturist

+serieuses

+serif

+serigraph

+serigrapher

+serigraphy

+serin

+serine

+seriocomic

+seriocomically

+serjeants

+serjeanty

+sermonic

+serodiagnosis

+serodiagnostic

+serologic

+serologist

+seropurulent

+serosa

+serosal

+serotinal

+serotinous

+serotonin

+serotype

+serous

+serow

+serpiginous

+serpiginously

+serra

+serranid

+serranoid

+serrate

+serrated

+serrates

+serrating

+serration

+serratus

+serried

+serriedly

+serriedness

+serry

+serrying

+serting

+sertive

+sertularian

+serval

+servanda

+servation

+servatius

+serviceably

+serviceberry

+servility

+servomotor

+servosystem

+servosystems

+sesamoid

+sesquicarbonate

+sesquicentenary

+sesquicentennial

+sesquipedalian

+sessed

+sesshu

+sessile

+sessility

+sessional

+sesterce

+sestertium

+sestet

+sestina

+seta

+setaceous

+setaceously

+setae

+setal

+setline

+setnm

+seto

+setoff

+setom

+setose

+setout

+setpoint

+setpoints

+settee

+settees

+settlor

+setz

+setzb

+setzm

+seurat

+sevec

+sevenths

+seventyfold

+severability

+severable

+severna

+sevigli

+sewickley

+sexagenarian

+sexagesimal

+sexdecillion

+sexily

+sexless

+sexlessly

+sexlessness

+sexology

+sexpot

+sext

+sextant

+sextic

+sexto

+sextodecimo

+sextos

+sextuor

+sextuplicate

+sey

+sforzando

+shacklebone

+shad

+shadberry

+shadblow

+shadbush

+shaddock

+shadeless

+shadflower

+shadoof

+shadowbox

+shadowgraph

+shadowily

+shadowless

+shadowlike

+shagbark

+shaggily

+shaggymane

+shagreen

+shahdom

+shahn

+shaitan

+shakeout

+shako

+shakoes

+shakya

+shalloon

+shallop

+shallot

+shalt

+shaman

+shamanism

+shamanist

+shamanistic

+shamefaced

+shamefacedness

+shamefast

+shammer

+shammes

+shamming

+shammosim

+shammy

+shamus

+shan

+shandies

+shandrydan

+shandy

+shandygaff

+shanghaied

+shanghaier

+shankpiece

+shansi

+shantey

+shantyman

+shantytown

+shapable

+shapeable

+shapen

+shard

+shareability

+shareable

+sharkskin

+sharpie

+sharpies

+sharpy

+shashlick

+shashlik

+shatilov

+shaveling

+shavetail

+shavie

+shawano

+shawm

+shawomet

+shay

+shayne

+shayol

+shays

+sheaflike

+sheahe

+shearn

+shearwater

+sheatfish

+sheathbill

+shebang

+shebeen

+sheboygan

+shedded

+shedder

+sheen

+sheeny

+sheepfold

+sheepherder

+sheepherding

+sheepish

+sheepishly

+sheepishness

+sheepshank

+sheepshead

+sheepshearer

+sheepshearing

+sheeran

+sheetfed

+sheetlike

+sheikdom

+sheikh

+sheikhdom

+shekel

+shelagh

+shelfful

+shelflike

+shellac

+shellacked

+shellacking

+shellback

+shellback's

+shellbacks

+shellcracker

+shellfire

+shellfish

+shellproof

+shellwork

+shelly

+shelterbelt

+shelterless

+sheltie

+shelties

+shelty

+shend

+shending

+shensi

+shep

+shepherdess

+sher

+sherbert

+sherd

+sherif

+sheriffdom

+sherris

+shevelling

+shew

+shewe

+shews

+shh

+shiel

+shieling

+shietz

+shiflett

+shiftable

+shigella

+shih

+shikar

+shikari

+shikarred

+shikarring

+shiksa

+shikse

+shilingi

+shillalah

+shillelagh

+shillong

+shimmery

+shindies

+shindy

+shingly

+shinleaf

+shinleafs

+shinnery

+shinney

+shinnied

+shinning

+shinny

+shinnying

+shinplaster

+shinsplints

+shipborne

+shipfitter

+shiplap

+shipload

+shipmaster

+shipowner

+shipside

+shipway

+shipworm

+shipwright

+shirr

+shirring

+shirtwaist

+shirtwaister

+shirty

+shish

+shitepoke

+shiv

+shivaree

+shlemiehl

+shlock

+sho

+shoat

+shockproof

+shoddily

+shoebill

+shoeblack

+shoepac

+shoepack

+shogun

+shogunate

+sholom

+shoon

+shoplift

+shoplifter

+shoplifters

+shoplifting

+shoppe

+shoptalk

+shoran

+shorebird

+shorebird's

+shorebirds

+shorefront

+shoreside

+shoreward

+shorewards

+shortbread

+shortcake

+shortchange

+shortchanger

+shorthorn

+shortie

+shorties

+shortliffe

+shorty

+shotbush

+shotline

+shotlines

+shotten

+shouldst

+shoup

+shovelful

+shovelhead

+shovelman

+shovelnose

+shovelsful

+showbread

+showery

+showily

+showstopper

+shrievalty

+shrieve

+shrike

+shrimpy

+shrive

+shrived

+shriven

+shroff

+shrubbier

+shrubby

+shtetel

+shtetl

+shtetlach

+shtg

+shtick

+shuiski

+shul

+shulde

+shunner

+shunpike

+shunpiker

+shunpiking

+shush

+shute

+shutterbug

+shutterless

+shuz

+shyer

+shyes

+shyest

+shylockian

+shyster

+si

+sialagogue

+siamang

+sib

+sibe

+sibilate

+sibilation

+sibly

+sibyl

+sibylic

+sibylla

+sibyllic

+sibylline

+sibyls

+siccative

+siccing

+siciliana

+sickbed

+sickbed's

+sickbeds

+sicklebill

+sicklemia

+sicklewort

+sicklily

+sid

+siddo

+siddur

+siddurim

+sideburned

+sidedress

+sidehill

+sidekick

+sidekicks

+sideling

+sidency

+sident

+sidepiece

+siderite

+sideritic

+siderolite

+sideslip

+sideslips

+sidespin

+sidesplitting

+sidestepped

+sidestepper

+sidestroke

+sideswipe

+sideward

+sidewards

+sie

+sieben

+siebern

+siecle

+siecles

+siepi

+sierran

+sieux

+sig

+sightless

+sightlessness

+sigmoid

+sigmoidal

+sigmoidally

+signalman

+signalmen

+signalment

+signatory

+signifiable

+significancy

+significative

+significatively

+significativeness

+significs

+signior

+signiories

+signiory

+signori

+signories

+signorina

+signorino

+signory

+sike

+siking

+silane

+sild

+silds

+silenus

+silesia

+silex

+siliceous

+silicic

+silicicolous

+silicification

+silicify

+silicious

+silicle

+silicosis

+silicothermic

+silicotic

+silique

+silkaline

+silke

+silkoline

+silkweed

+sillabub

+sillily

+sillimanite

+silone

+siloxane

+siltstone

+siltstones

+siluroid

+silva

+silvan

+silvas

+silverfish

+silvern

+silverside

+silversides

+silverweed

+silvical

+silvicolous

+silvics

+silvicultural

+silviculturally

+silviculture

+silviculturist

+simazine

+simba

+simca

+simian

+simmel

+simms

+simnel

+simoleon

+simony

+simoom

+simoon

+simp

+simpatico

+simper

+simpered

+simperer

+simpering

+simpers

+simplices

+simplicial

+simplicially

+simplifiction

+simplism

+simplistically

+simulacre

+simulacrum

+simular

+sinan

+sinapism

+sincipita

+sincipital

+sinciput

+sind

+sinecure

+sinfonia

+sinfonietta

+singeing

+singleminded

+singlestick

+singletree

+singsong

+singsongy

+singspiel

+sinh

+siniboia

+sinistrorse

+sinistrous

+sinkable

+sinkage

+sinoatrial

+sinological

+sinologist

+sinologue

+sinology

+sinopia

+sinsyne

+sinterability

+sinton

+sinuate

+sinuately

+sinuatrial

+sinuosity

+sinusitis

+sion

+sipper

+sippet

+siree

+sirenian

+sirloin

+sirocco

+sirra

+sirrah

+sirree

+sirupy

+sirvente

+sirventes

+siskin

+sissies

+sissified

+sissy

+sisterhood

+sistrum

+sith

+sitosterol

+siva

+sivas

+sixmo

+sixmos

+sixpenny

+sixteenmo

+sixths

+sixtyfold

+sizably

+sizar

+sizova

+skag

+skagen

+skald

+skaldic

+skateboard

+skateboard's

+skateboarder

+skateboarding

+skateboards

+skedaddle

+skedaddled

+skedaddler

+skedaddles

+skedaddling

+skeg

+skeigh

+skein

+skein's

+skeins

+skeleta

+skellum

+skelp

+skelping

+skelpit

+skelter

+skeltered

+skeltering

+skene

+skep

+skepsis

+skerries

+skers

+skery

+skewback

+skewbald

+skiable

+skiagram

+skiagram's

+skiagrams

+skiagraph

+skiagraphy

+skiascope

+skiascopy

+skidder

+skiddier

+skiddoo

+skiddy

+skidoo

+skiffle

+skilful

+skilfully

+skilless

+skimobile

+skimpily

+skinflint

+skinflint's

+skinflints

+skinful

+skinhead

+skink

+skinker

+skint

+skintight

+skipjack

+skirl

+skirr

+skitter

+skittery

+skittish

+skittishly

+skittishness

+skive

+skiver

+skiving

+skivvies

+skivvy

+skiway

+skiwear

+skoal

+skulduggery

+skyborne

+skycap

+skydiving

+skyey

+skylounge

+skyphoi

+skyphos

+skyros

+skysail

+skywrite

+skywriter

+skywriting

+slabber

+slabbered

+slabbering

+slabbing

+slangily

+slanginess

+slangy

+slantways

+slantwise

+slapdash

+slaphappy

+slapjack

+slatelike

+slather

+slathered

+slathering

+slathers

+slattern

+slatternliness

+slatternly

+slaty

+slaughterous

+slaughterously

+slaveholder

+slaveholders

+slaveholding

+slavey

+slaveys

+slavocracy

+sleazily

+sledded

+sledder

+sleekit

+sleeplessess

+sleeplike

+sleepyhead

+sleeveless

+sleevelet

+slesinger

+sleuth

+sleuthhound

+slidden

+slideway

+slily

+slimily

+slimmest

+slimming

+slimpsy

+slimsy

+slinkier

+slinkily

+slinkiness

+slinky

+slipcase

+slipcover

+slipform

+slipknot

+slipover

+slippier

+slippy

+slipshod

+slipslop

+slipsole

+slipstick

+slipup

+slithery

+slitless

+slivovitz

+slobber

+slobbered

+slobberer

+slobbering

+slobbers

+slobbery

+slobbish

+slogger

+slopwork

+slopworker

+slotback

+slotting

+slouchier

+slouchily

+slouchiness

+slouchy

+sloughy

+slowish

+slowpoke

+slub

+slubber

+slubbered

+slubbering

+slubbing

+sludgier

+sludgy

+slue

+sluff

+slugabed

+slugfest

+sluggard

+sluggardly

+sluggardness

+sluiceway

+sluicy

+sluing

+slumberous

+slumbery

+slumbrous

+slumgullion

+slumlord

+slummer

+slummier

+slummy

+slungshot

+slushier

+slushiness

+slushy

+slut

+sluttish

+sluttishly

+sluttishness

+slyboots

+slyer

+slyest

+smartie

+smarties

+smartweed

+smarty

+smashup

+smatter

+smatterer

+smearcase

+smeary

+smectic

+smegma

+smeltery

+smidgen

+smidgeon

+smileless

+smilelessly

+smirch

+smirky

+smithery

+smithsonite

+smoggier

+smoggy

+smogless

+smokeable

+smokechaser

+smokeless

+smokelike

+smokeproof

+smokey

+smokily

+smolt

+smoochy

+smoothbore

+smoothie

+smoothies

+smooths

+smoothy

+smorgasbord

+smothery

+smoulder

+smsa

+smsa's

+smsas

+smudgily

+smugger

+smuggest

+smutch

+smutchy

+smutted

+smuttily

+smutting

+snaffle

+snaffled

+snaffling

+snaggletooth

+snaggletoothed

+snaggy

+snaillike

+snakebite

+snakebite's

+snakebites

+snakemouth

+snakeskin

+snakestrike

+snakeweed

+snakily

+snaky

+snappe

+snapshoot

+snapshooter

+snark

+snarks

+snarly

+snash

+snatchy

+snath

+snathe

+sndmsg

+snead

+sneap

+sneck

+sneed

+sneesh

+sneezeweed

+sneezewort

+sneezy

+snell

+snelling

+snick

+snickersnee

+snickery

+sniffily

+sniffiness

+sniffish

+sniffishly

+sniffishness

+sniffy

+snigger

+sniggered

+sniggerer

+sniggering

+sniggle

+sniggled

+sniggling

+sniperscope

+snippety

+snit

+snitch

+snitcher

+snobbism

+snobby

+snodgrass

+snollygoster

+snood

+snooperscope

+snoopily

+snoot

+snootier

+snootily

+snootiness

+snooty

+snooze

+snoozer

+snoozes

+snoozing

+snoozle

+snoozled

+snoozles

+snoozling

+snopes

+snot

+snoutish

+snouty

+snowbound

+snowbrush

+snowcap

+snowcapped

+snowdrift

+snowdrop

+snowfield

+snowless

+snowmaker

+snowmaking

+snowmelt

+snowpack

+snowplow

+snowscape

+snowshed

+snowshoeing

+snowslide

+snowsuit

+snubber

+snubbiness

+snubby

+snuffbox

+snuffy

+snugger

+snuggery

+snuggest

+soakage

+soapbark

+soapbox

+soapboxes

+soapily

+soapless

+soapmaking

+soapwort

+soba

+sobe

+sobersided

+sobersides

+sobf

+sobibor

+socage

+socager

+socal

+soccage

+sochi

+sociableness

+socialistically

+socialite

+socinianism

+sociolinguistic

+sociolinguistics

+sociologic

+sociopath

+sociopathic

+sociopolitical

+sociosexual

+sociosexuality

+sockdolager

+sockdologer

+sockeye

+socle

+socola

+soconoco

+sodalist

+sodalite

+sodality

+sodbuster

+sodded

+sodic

+sodomite

+soeren

+soever

+soffit

+softback

+softbound

+softcover

+softhead

+softheaded

+softheadedly

+softheadedness

+softhearted

+softheartedly

+softheartedness

+softie

+softies

+softish

+softy

+soggily

+sohn

+soign

+soignee

+soilborne

+soilge

+soilless

+soilure

+soir

+soke

+sokeman

+sokol

+sokolev

+sokolov

+sokolsky

+sola

+solacement

+solanaceous

+solanin

+solanine

+solanum

+solarium

+solate

+solated

+solating

+solatium

+soldan

+solderability

+soldi

+soldiership

+solecistic

+solemnify

+solenoidal

+soleplate

+soleprint

+solesmes

+solfatara

+solicitant

+solicitorship

+solidago

+solidarism

+solidarist

+solidaristic

+solidus

+solifluction

+soliloquist

+solipsist

+solipsistic

+solitarily

+soliton

+solitudinarian

+solitudinem

+solleret

+soln

+solonets

+solonetz

+solonetzic

+solstitial

+solubleness

+solubly

+solus

+solute

+solvability

+solvate

+solvated

+solvation

+solventless

+solvolysis

+solvolytic

+somatically

+somatogenic

+somatological

+somatology

+somatoplasm

+somatoplastic

+somatopleure

+somatopleuric

+somatosensory

+somatotrophin

+somatotropin

+somatotype

+somatotypic

+somatotypically

+sombre

+sombrero

+sombrous

+somebodies

+somedeal

+someway

+someways

+somewhen

+somewhither

+somite

+somitic

+somnambulant

+somnambular

+somnambulate

+somnambulation

+somnambulator

+somnambulism

+somnambulist

+somnambulistic

+somnambulistically

+somnifacient

+somniferous

+somniferously

+somnolency

+sonambula

+sonance

+sonant

+sonarman

+sonatina

+sonde

+sone

+songau

+songbird

+songfest

+songless

+songlessly

+songsmith

+songster

+songtress

+songwriter

+songwriting

+sonically

+sonicate

+sonicated

+sonication

+sonicator

+sonicators

+sonless

+sonneteer

+sonnobuoy

+sonogram

+sonogram's

+sonograms

+sonorant

+sonovox

+sonship

+sonsie

+sonsy

+soomed

+soothfast

+sootier

+sootily

+sootiness

+sooty

+sophistic

+sophistical

+sophistically

+sophy

+sopite

+sopited

+sopiting

+sopor

+soporiferous

+soporiferousness

+soppier

+soppy

+sopranino

+sopsaisana

+sora

+sorb

+sorbability

+sorbable

+sorbate

+sorbed

+sorbent

+sorceress

+sorcerous

+sordino

+sorehead

+soreheaded

+sorgo

+sori

+soricine

+sorites

+sororal

+sororate

+sorption

+sorptive

+sorrentine

+sorrentino

+sorrily

+sortable

+sortilege

+sortition

+sorus

+sostenuto

+sot

+soteriological

+soteriology

+sotol

+sottish

+sottishly

+sottishness

+sotun

+sou

+soubise

+soubrette

+souchong

+sough

+soukhouma

+soule

+soulless

+soullessly

+soullessness

+soundable

+soundboard

+soundless

+soundlessly

+soupier

+soupspoon

+soupy

+sourberry

+sourceless

+sourish

+sourpuss

+soursop

+sourwood

+sousaphone

+souse

+sousing

+sout

+soutache

+soutane

+souter

+southeasternmost

+southeastward

+southeastwards

+souths

+southwesternmost

+southwestward

+southwestwards

+sovietism

+sovkhoz

+sovkhozes

+sovran

+sovranty

+sowbug

+sowbug's

+sowbugs

+soxhlet

+spa

+spaceband

+spaceflight

+spaceless

+spaceman

+spaceport

+spacetime

+spacewalker

+spacewalking

+spacial

+spackle

+spackled

+spackling

+spacs

+spacward

+spada

+spadeful

+spadework

+spadices

+spadille

+spadix

+spaeing

+spahi

+spahn

+spake

+spalding

+spall

+spallable

+spallation

+spalled

+spalling

+spandrel

+spandril

+spang

+spanworm

+spareable

+spareribs

+sparge

+sparger

+sparging

+sparkily

+sparkish

+sparkplug

+sparred

+sparrowgrass

+sparsity

+spartan

+sparteine

+spas

+spasmodic

+spasmodical

+spasmodically

+spasmolytic

+spasmolytically

+spastically

+spasticity

+spathe

+spathic

+spathulate

+spatiotemporal

+spatiotemporally

+spatlum

+spatted

+spatting

+spatulate

+spavin

+speakeasy

+spean

+spearfish

+spearman

+specialism

+specialisms

+specialistic

+speciate

+speciation

+speciational

+speciosity

+specsartine

+spect

+spectate

+spectated

+spectating

+spectatress

+spector

+spectrality

+spectrofluorimeter

+spectrofluorimeter's

+spectrofluorimeters

+spectrofluorometer

+spectrofluorometer's

+spectrofluorometers

+spectrofluorometric

+spectrofluorometry

+spectrographic

+spectroheliogram

+spectroheliogram's

+spectroheliograms

+spectroheliograph

+spectroheliography

+spectrohelioscope

+spectrophotometrical

+spectrophotometrically

+spectroscopical

+spectroscopist

+speculum

+speechify

+speedball

+speedlight

+speedster

+speedway

+speedwell

+speel

+speir

+speiss

+speleogenesis

+speleogenetic

+spellbind

+spellbinder

+spelldown

+spelt

+spelter

+spelunker

+spelunking

+spendable

+spendthrift

+spenglerian

+spermaceti

+spermagonium

+spermary

+spermatheca

+spermathecal

+spermatial

+spermatic

+spermatid

+spermatium

+spermatocidal

+spermatocide

+spermatocyte

+spermatogenesis

+spermatogenetic

+spermatogenic

+spermatogonial

+spermatogonium

+spermatophore

+spermatophytic

+spermatozoa

+spermatozoal

+spermatozoan

+spermatozoid

+spermatozoon

+spermicidal

+spermicide

+spermidine

+spermiogenesis

+spermophile

+sperrylite

+spessartite

+sphagnous

+sphagnum

+sphalerite

+sphene

+sphenodon

+sphenodont

+sphenoid

+sphenoidal

+sphenopsid

+spheral

+sphericity

+spherometer

+spherometer's

+spherometers

+spheroplast

+spherulite

+spherulitic

+sphery

+sphincter

+sphincteral

+sphinges

+sphingid

+sphingosine

+sphygmograph

+sphygmographic

+sphygmography

+sphygmomanometer

+sphygmomanometer's

+sphygmomanometers

+sphygmomanometric

+sphygmomanometrically

+sphygmomanometry

+spicae

+spicate

+spiccato

+spiceberry

+spicery

+spicily

+spicula

+spicular

+spiculate

+spiculation

+spicule

+spiculiferous

+spiculum

+spiderweb

+spiegeleisen

+spiel

+spieler

+spiffier

+spiffy

+spikelet

+spikelike

+spikenard

+spile

+spiled

+spiles

+spiling

+spillable

+spillage

+spillage's

+spillages

+spillikin

+spillikins

+spillway

+spilosite

+spilth

+spinco

+spindly

+spindrift

+spinel

+spinelle

+spinescent

+spinet

+spinifex

+spinless

+spinneret

+spinnerette

+spinney

+spinneys

+spinodal

+spinoff

+spinor

+spinosely

+spinosity

+spinous

+spinout

+spinrad

+spinse

+spinsterhood

+spinsterish

+spinthariscope

+spinule

+spinulose

+spiracle

+spiracular

+spiraea

+spirant

+spirea

+spireme

+spirillum

+spiritism

+spiritist

+spiritistic

+spiritless

+spiritlessly

+spiritlessness

+spiritoso

+spiritous

+spiritualism

+spiritualist

+spiritualistic

+spiritualty

+spirituel

+spirituelle

+spirituous

+spirograph

+spirographic

+spirography

+spirogyra

+spirometer

+spirometer's

+spirometers

+spirometric

+spirometry

+spirt

+spirula

+spiry

+spital

+spitball

+spitted

+spitter

+spittoon

+spittoons

+splashboard

+splashdown

+splashdowns

+splashily

+splatter

+splayfoot

+splayfooted

+spleenful

+spleenwort

+spleeny

+splendent

+splendiferous

+splendiferously

+splendiferousness

+splendorous

+splendrous

+splenectomy

+splenetically

+splenic

+splenius

+splenomegaly

+splent

+spleuchan

+splore

+spluttery

+spodumene

+spoilable

+spoilsman

+spoilsport

+spoilt

+spokeshave

+spokespeople

+spokesperson

+spokesperson's

+spokeswoman

+spoliate

+spoliation

+spoliator

+spondaic

+spondee

+spondylitis

+sponson

+sponsorial

+spontoon

+spookily

+spookish

+spoondrift

+spooney

+spoonier

+spoonsful

+spoony

+spoor

+sporangial

+sporangiophore

+sporangium

+sporicidal

+sporicide

+sporiferous

+sporocarp

+sporocyst

+sporocystic

+sporogenesis

+sporogenic

+sporogenous

+sporogonic

+sporogonium

+sporogonos

+sporogony

+sporophore

+sporophyll

+sporophyte

+sporophytic

+sporopollenin

+sporotrichosis

+sporozoan

+sporozoite

+sportful

+sportfully

+sportfulness

+sportily

+sportsmanlike

+sportswoman

+sportswriting

+sporulate

+sporulation

+sporulative

+spottable

+spottily

+sprat

+spreadability

+spreadable

+sprent

+sprier

+spriest

+sprigging

+sprightful

+sprightfully

+sprightfulness

+sprigtail

+springal

+springald

+springbok

+springboks

+springe

+springily

+springtail

+springtails

+springtide

+springwood

+sprit

+spritsail

+sprucier

+sprucy

+spry

+spryer

+spryest

+spryly

+spryness

+spss

+spudded

+spudding

+spumone

+spumous

+spumy

+spunkie

+spunkier

+spunkily

+spunkiness

+spunky

+spurrey

+spurreys

+spurrier

+spurry

+spurtle

+sputa

+sputum

+spuyten

+squab

+squabs

+squadded

+squadding

+squalene

+squallier

+squally

+squama

+squamae

+squamate

+squamation

+squamosal

+squamose

+squamulose

+squaresville

+squarish

+squarishly

+squarishness

+squark

+squashberry

+squashily

+squattest

+squattier

+squatty

+squawbush

+squawroot

+squeegeeing

+squeezability

+squeezable

+squelchy

+squib

+squibs

+squidded

+squidding

+squiffed

+squiffy

+squiggle

+squiggled

+squiggles

+squiggling

+squiggly

+squilgee

+squill

+squilla

+squillae

+squills

+squinch

+squinnied

+squinny

+squinnying

+squinty

+squirarchy

+squirearchy

+squirish

+squoosh

+stabat

+stabber

+stabile

+stablemate

+stablish

+stablishment

+staddle

+stade

+stadia

+stadtholder

+stadtholderate

+stadtholdership

+stagecraft

+stagehand

+stagestruck

+stagey

+staggerbush

+staggery

+stagging

+staggy

+staghound

+stagily

+stagnancy

+stainability

+stainable

+stakeholder

+stakeout

+stalactitic

+stalagmite

+stalagmite's

+stalagmites

+stalagmitic

+stalkless

+stalky

+stallard

+stalworth

+staminal

+staminodium

+staminody

+stammel

+standardbred

+standaway

+standbys

+standee

+standeth

+standoffish

+standoffishly

+standoffishness

+standout

+standpat

+standpatter

+standpattism

+standpipe

+stang

+stanite

+stannard

+stannaries

+stannary

+stanzaic

+stapedectomy

+stapedes

+stapedial

+stapelia

+stapes

+staph

+staphylinid

+staphylococcal

+staphylococcic

+starbird

+starchily

+stardust

+starets

+starless

+starlike

+starlit

+starre

+starveling

+stases

+statable

+statant

+stateable

+statecraft

+statedly

+statehouse

+stateside

+statical

+statice

+stational

+stationarily

+statism

+statist

+stato

+statoblast

+statocyst

+statolatry

+statolith

+stator

+stators

+statoscope

+statutable

+statz

+staurolite

+staurolitic

+stavesacre

+stavropoulos

+steamroll

+steamroller

+steapsin

+stearate

+stearic

+stearin

+stearine

+steatite

+steatitic

+steatolysis

+steatopygia

+steatopygic

+steelhead

+steelie

+steelwork

+steelworker

+steelworks

+steelyard

+steenbok

+steeplechase

+steeplechaser

+steeplejack

+steerable

+steerage

+steerageway

+steersman

+steeve

+steeving

+steffens

+stegosaur

+stegosaurus

+steichen

+steinbecks

+stela

+stelae

+stelar

+stele

+stellate

+stelliform

+stellify

+stemless

+stemma

+stemmata

+stemmer

+stemmier

+stemmy

+stemson

+stemware

+stenchful

+stenchy

+steno

+stenobathic

+stenograph

+stenographic

+stenographically

+stenohaline

+stenophagous

+stenos

+stenosed

+stenosis

+stenotherm

+stenothermal

+stenothermy

+stenotic

+stenotopic

+stenotypist

+stenotypy

+stentor

+stentorian

+stentorophonic

+stephan

+stephanotis

+stepladder

+steplike

+stepparent

+steprelation

+steradian

+stercoraceous

+stere

+stereobate

+stereochemical

+stereochemically

+stereochemistry

+stereogram

+stereogram's

+stereograms

+stereograph

+stereographic

+stereographically

+stereoisomer

+stereoisomeric

+stereoisomerism

+stereoisomers

+stereological

+stereologically

+stereology

+stereometric

+stereomicroscope

+stereomicroscopic

+stereomicroscopically

+stereophonically

+stereophony

+stereophotographic

+stereophotography

+stereopsis

+stereopticon

+stereoregular

+stereoregularity

+stereoscope

+stereoscopic

+stereoscopically

+stereospecific

+stereospecifically

+stereospecificity

+stereotape

+stereotaxic

+stereotaxically

+stereotropism

+stereotypy

+steric

+sterically

+sterics

+sterigma

+sterilant

+sterios

+sterlet

+sterna

+sternforemost

+sternite

+sternmost

+sternocostal

+sternpost

+sternson

+sternutation

+sternutator

+sternutatory

+sternward

+sternwards

+sternway

+steroidal

+steroidogenesis

+steroidogenic

+sterol

+stertor

+stertorous

+stertorously

+stet

+stethoscopic

+stethoscopically

+stetted

+stettin

+stetting

+stevie

+stewpan

+stibine

+stibnite

+stichomythia

+stichomythic

+stichomythy

+stickball

+stickful

+stickhandler

+stickit

+stickseed

+sticktight

+stickum

+stickup

+stickweed

+stickwork

+sticle

+sticy

+stidger

+stiffish

+stigmal

+stigmasterol

+stigmatic

+stigmatically

+stigmatism

+stigmatist

+stilbene

+stilbestrol

+stilbite

+stillman

+stillroom

+stillwater

+stillwell

+stilly

+stime

+stimulator

+stimulators

+stingaree

+stingily

+stingless

+stingray

+stingray's

+stingrays

+stinkard

+stinkbug

+stinkbug's

+stinkbugs

+stinkhorn

+stinkpotters

+stinkstone

+stinkweed

+stinkwood

+stion

+stioning

+stipe

+stiped

+stipel

+stipellate

+stipendiary

+stipes

+stipitate

+stipites

+stipular

+stipulator

+stipulatory

+stipule

+stipuled

+stirabout

+stirk

+stirp

+stirpes

+stirps

+stitchery

+stithies

+stithy

+stoat

+stoat's

+stoats

+stockbreeder

+stockbrokerage

+stockbroking

+stockcar

+stockily

+stockinet

+stockinette

+stockish

+stockist

+stockkeeper

+stockman

+stockpot

+stockproof

+stocktaking

+stockyard

+stockynges

+stodge

+stodgily

+stodging

+stogie

+stogies

+stogy

+stoical

+stoically

+stoichiometrically

+stokehold

+stokehole

+stokesia

+stolidity

+stoll

+stollen

+stollens

+stolon

+stolonate

+stoloniferous

+stoloniferously

+stolzenbach

+stoma

+stomachache

+stomachic

+stomachically

+stomachy

+stomal

+stomas

+stomata

+stomatal

+stomate

+stomatitis

+stomatologic

+stomatological

+stomatologist

+stomatology

+stomatopod

+stomodaeal

+stomodaeum

+stomodeal

+stomodeum

+stonecrop

+stonecutting

+stonemasonry

+stonework

+stoneworker

+stoney

+stonyhearted

+stonyheartedness

+stoolie

+stoopball

+stopband

+stope

+stopes

+stoplight

+stoplights

+stopple

+stoppled

+stoppling

+storable

+storax

+storefront

+storefront's

+storefronts

+storeria

+storeship

+storewide

+storksbill

+stormily

+storybook

+storybooks

+storytelling

+storywriter

+stouthearted

+stoutheartedly

+stoutheartedness

+stoutish

+stovepipe

+stovepipes

+stowaway

+stowaway's

+stowaways

+stowe

+stowey

+strabismic

+strabismus

+strafaci

+stragglier

+straggly

+straightbred

+straightedge

+straightish

+straightjacket

+straightlaced

+strainometer

+strainometer's

+strainometers

+straitjacket

+straitlaced

+straitlacedly

+straitlacedness

+strake

+stram

+stramash

+stramonium

+stranahan

+strandline

+stranglehold

+strangury

+straphang

+straphanger

+strapless

+strappado

+strapper

+strategical

+strath

+strathspey

+strathspeys

+strati

+straticulate

+stratiform

+stratocracy

+stratocumulus

+stratus

+stravage

+stravinsky

+strawboard

+strawman

+streakier

+streakiness

+streaky

+streambed

+streamlet

+streamside

+streek

+streetwalker

+streetwalking

+strengthless

+strengthlessness

+strenuosity

+strep

+streptobacillus

+streptococcal

+streptococcic

+streptokinase

+streptolysin

+streptomyces

+streptomycete

+streptothricin

+stressless

+stresslessness

+stressor

+stretchability

+stretta

+stretti

+stretto

+strettos

+strewment

+stria

+striae

+strick

+strickle

+strickled

+strickling

+stridden

+stridence

+stridor

+stridulate

+stridulation

+stridulatory

+stridulous

+stridulously

+strifeless

+strigil

+strigose

+strikebound

+strikeless

+strikeout

+strikeover

+stringboard

+stringcourse

+stringency

+stringendo

+stringhalt

+stringhalted

+stringless

+stringpiece

+stripeless

+stripfilm

+stripier

+stripling

+strippable

+stript

+stripy

+strobila

+strobilar

+strobilation

+strobile

+strobilus

+stroboscope

+stroboscopically

+strobotron

+stroma

+stromal

+stromata

+stromatal

+stromatic

+stromatolite

+stromatolitic

+stromeyerite

+strongbox

+strongheart

+strongish

+strontia

+strontianite

+strontic

+strophanthin

+strophic

+strophoid

+stroud

+strouding

+strow

+strowing

+structuralism

+structureless

+structurelessness

+strudel

+struma

+strumae

+strumas

+strummer

+strumose

+strumpet

+strunt

+struthious

+strychninism

+stubblefield

+stubblefields

+stubbly

+stuccoes

+stuccowork

+studbook

+studbooks

+studding

+studentship

+studentships

+studhorse

+stuffily

+stuffless

+stull

+stum

+stumblebum

+stumer

+stumming

+stunner

+stunsail

+stupa

+stupe

+stupefacient

+stupefaction

+stuporous

+sturch

+sturdily

+sturley

+sturt

+stye

+styes

+stying

+styka

+stylebook

+styleless

+stylelessness

+stylet

+styliform

+stylite

+stylitic

+stylobate

+stylograph

+stylographic

+stylographical

+stylographically

+stylography

+styloid

+stylolite

+stylopodium

+stymieing

+styptic

+styrax

+suability

+suably

+suasion

+suasive

+suasively

+suasiveness

+subacid

+subacidly

+subacidness

+subacute

+subacutely

+subadar

+subadult

+subaerial

+subaerially

+subagency

+subagent

+subahdar

+subalpine

+subalternate

+subalternately

+subalternation

+subantarctic

+subapical

+subaquatic

+subaqueous

+subarctic

+subarea

+subatmospheric

+subaudible

+subaudition

+subaverage

+subbase

+subbasement

+subcabinet

+subcapsular

+subcelestial

+subcellular

+subcentral

+subcentrally

+subchaser

+subchloride

+subclavian

+subclimax

+subclinical

+subclinically

+subcollegiate

+subcommunity

+subcompact

+subcontinental

+subcontractor

+subcontraoctave

+subcontrariety

+subcontrary

+subcool

+subcordate

+subcortex

+subcortical

+subcritical

+subcrustal

+subcultural

+subcutaneous

+subcutaneously

+subdeacon

+subdeb

+subdebutante

+subdepot

+subdiaconate

+subdividable

+subdominance

+subdominant

+subedit

+subeditor

+subeditorial

+subemployed

+subemployment

+subentries

+subentry

+subepidermal

+subepidermally

+suberect

+subfamilies

+subfamily

+subfix

+subfossil

+subfreezing

+subgenus

+subglacial

+subglacially

+subglottal

+subgrade

+subgrammar

+subgross

+subhead

+subheading

+subhuman

+subhumanity

+subi

+subic

+subinfeud

+subinfeudate

+subinfeudation

+subinfeudatory

+subirrigate

+subirrigation

+subito

+subj

+subjacency

+subjacent

+subjacently

+subjectivism

+subjectivistic

+subjectless

+subjoin

+subjugator

+subjunction

+subjunctive

+subkingdom

+sublate

+sublated

+sublating

+sublation

+sublet

+sublethal

+sublethally

+sublevel

+sublicense

+sublicensed

+sublicenser

+sublicenses

+sublicensing

+sublieutenant

+sublimable

+sublimity

+sublingual

+subliterature

+sublittoral

+sublunar

+subluxation

+submandibular

+submarginal

+submarginally

+submaxilla

+submaxillary

+submediant

+submergence

+submergible

+submerse

+submersed

+submersing

+submersion

+submicrogram

+submicrogram's

+submicrograms

+submicron

+submicroscopic

+submicroscopically

+subminiature

+submiss

+submitochondrial

+submitter

+submitters

+submontane

+submucosa

+submucosal

+submucosally

+submucous

+submultiple

+subnormality

+suboceanic

+subopposite

+suboptimum

+suborbicular

+suborbital

+suborder

+suborn

+subornation

+suborned

+suborner

+suborning

+suborns

+subovate

+suboxide

+suboxides

+subpar

+subparallel

+subphylum

+subplot

+subplots

+subpolar

+subpotency

+subpotent

+subprincipal

+subprofessional

+subreption

+subreptitious

+subreptitiously

+subring

+subrogate

+subsaline

+subsatellite

+subsaturated

+subsaturation

+subsectio

+subserve

+subserviency

+subshrub

+subshrubby

+subsidence

+subsidiarily

+subsonic

+subsonically

+subspecific

+substage

+substanceless

+substandard

+substantiality

+substantival

+substantivally

+substation

+substations

+substituent

+substituents

+substitutional

+substitutionally

+substratosphere

+substratospheric

+substructural

+subsumption

+subteen

+subtemperate

+subtenancy

+subtenant

+subtend

+subterminal

+subterraneous

+subtetanic

+subthreshold

+subtile

+subtilely

+subtileness

+subtiler

+subtilest

+subtilis

+subtilisin

+subtilty

+subtonic

+subtotal

+subtropic

+subtropical

+subtropics

+subulate

+subvention

+subventionary

+subversionary

+subviral

+subvocal

+subvocally

+succedaneous

+succedaneum

+succedent

+successional

+successionally

+succinate

+succinyl

+succinylcholine

+succory

+succotash

+succuba

+succubi

+succulence

+succulent

+succulently

+suchlike

+sucrase

+sucre

+sucrose

+suctional

+suctorial

+suctorian

+sudanic

+sudatorium

+sudatory

+sudoriferous

+sudorific

+sudsier

+sudsless

+sudsy

+suede

+suet

+suey

+suff

+sufferable

+sufferableness

+sufferably

+suffixation

+suffragan

+suffragist

+suffragists

+sugarcane

+sugarcoat

+sugarhouse

+sugarloaf

+sugarplum

+sugary

+suint

+sukarno

+sukiyaki

+sulamite

+sulamith

+sulcate

+sulci

+sulcus

+sulfa

+sulfadiazine

+sulfanilamide

+sulfatase

+sulfatide

+sulfatides

+sulfhydryl

+sulfinyl

+sulfitic

+sulfonate

+sulfonation

+sulfone

+sulfonic

+sulfonium

+sulfonmethane

+sulfonyl

+sulfonylurea

+sulfoxide

+sulfureous

+sulfureously

+sulfureousness

+sulfuret

+sulfuryl

+sullage

+sulphurou

+sulphurous

+sultanate

+sultaness

+sultrily

+sulzberger

+sumach

+summa

+summability

+summable

+summae

+summated

+summates

+summating

+summational

+summerhouse

+summersault

+summerwood

+summery

+sumptuary

+sunay

+sunbath

+sunbathe

+sunbather

+sunbird

+sunbow

+sunburst

+sunbursts

+sundae

+sundaes

+sundew

+sundrops

+sunfast

+sunlamp

+sunless

+sunn

+sunna

+sunnily

+sunroof

+sunscald

+sunscreen

+sunscreen's

+sunscreening

+sunscreens

+sunstroke

+sunstruck

+sunsuit

+suntanning

+sunup

+sunward

+sunwards

+sunwise

+superable

+superableness

+superably

+superabound

+superabundance

+superabundant

+superabundantly

+superadd

+superaddition

+superagency

+superaltern

+superannuate

+superannuated

+superannuation

+superblock

+supercalender

+supercargo

+supercharge

+supercharger

+superciliary

+supercity

+superconduct

+superconducting

+superconductive

+superconductivity

+superconductor

+superconductors

+supercool

+superdominant

+superelevate

+superelevation

+supereminence

+supereminent

+supereminently

+superempirical

+superencipher

+superencipherment

+supererogation

+supererogatory

+superfamily

+superfecundation

+superfetation

+superficies

+superfine

+superfix

+superfluid

+superfluidity

+supergalaxy

+supergene

+supergiant

+superheat

+superheater

+superheats

+superheterodyne

+superhighway

+superhumanity

+superieure

+superimposable

+superimposition

+superincumbent

+superincumbently

+superindividual

+superinduce

+superinduction

+superinfection

+superintendence

+superintendency

+superjacent

+superjet

+superliner

+superluminal

+superlunar

+superman

+supernal

+supernally

+supernaturalist

+supernaturalistic

+supernormality

+supernovae

+supernumerary

+superorder

+superordinate

+superorganism

+superovulation

+superparasitism

+superpatriot

+superpatriotic

+superpatriotism

+superphosphate

+superphysical

+superpower

+superpowered

+superpowers

+supersaturate

+supersaturated

+supersaturation

+superscribe

+superscription

+supersedeas

+supersedure

+supersensible

+supersensory

+superserviceable

+supersession

+supersessive

+supersonically

+superstar

+superstratum

+supersubstantial

+supersubtle

+supersubtlety

+supersystem

+supertanker

+supertax

+supertonic

+supervenience

+supervenient

+supervention

+supervisee

+supinate

+supination

+supinator

+suppl

+supplantation

+supplejack

+suppletion

+suppletive

+suppletory

+suppliance

+suppliant

+suppliantly

+supplicant

+supplicant's

+supplicantly

+supplicants

+supplicatory

+supportability

+supportableness

+supportably

+supposably

+supposal

+suppositional

+suppositionally

+suppositious

+supposititious

+supposititiously

+supposititiousness

+suppositive

+suppositively

+suppositories

+suppository

+suppressant

+suppressibility

+suppurate

+suppuration

+suppurative

+supr

+supraglottal

+supralaryngeal

+supraliminal

+supraliminally

+supramolecular

+supranationalist

+supranationality

+supraorbital

+supraprotest

+suprarational

+suprarenal

+supravital

+supravitally

+supremum

+surah

+surbase

+surbased

+surcingle

+surcliffe

+surcoat

+surcoats

+surefire

+surefooted

+surefootedly

+surefootedness

+suretyship

+surfable

+surfboard

+surfboarder

+surfboards

+surfboat

+surfboats

+surficial

+surfperch

+surg

+surjection

+surjective

+surlily

+surmountable

+surmullet

+surpassable

+surplice

+surplusage

+surprint

+surprisal

+surra

+surrealistic

+surrealistically

+surrebutter

+surrejoinder

+surroyal

+surtout

+surveil

+survivable

+survivance

+susceptance

+susceptive

+susceptiveness

+susceptivity

+suspenseful

+suspensoid

+suspensory

+suspiration

+suspire

+suspired

+suspiring

+susquehanna

+sustentacular

+sustentation

+sustentative

+sustention

+susurrant

+susurration

+susurrous

+susurrus

+sutra

+suttee

+sutural

+suturally

+suzerain

+suzerainty

+swabber

+swabbie

+swadesh

+swage

+swagging

+swagman

+swainish

+swainishness

+swale

+swallowable

+swallowtail

+swallowwort

+swang

+swanherd

+swankily

+swannery

+swanning

+swansdown

+swanskin

+swartz

+swashbuckle

+swashbuckler

+swashbuckling

+swayback

+swaybacked

+swearword

+sweatbox

+sweatily

+sweatpants

+sweatshop

+sweatshop's

+sweatsocks

+sweazey

+sweepback

+sweepier

+sweepy

+sweetbread

+sweetbread's

+sweetbreads

+sweetbrier

+sweetmeat

+sweetshop

+sweetsop

+swellhead

+swellheaded

+swellheadedness

+swelter

+sweltered

+swidden

+swigger

+swill

+swiller

+swimmable

+swimmeret

+swimmier

+swimmily

+swimminess

+swimmy

+swinburne

+swineherd

+swingably

+swinge

+swingeing

+swingletree

+swishingly

+switchable

+switchback

+switchback's

+switchbacks

+switcheroo

+switchgrass

+switchyard

+swith

+swither

+swivet

+swoosh

+swop

+swordfight

+swordfight's

+swordfights

+swordlike

+swordsman

+swordsmanship

+swot

+swots

+swotted

+swotting

+sybarite

+sybaritically

+sybert

+sycamine

+syce

+sycee

+syconium

+sycophancy

+sycophantish

+sycophantishly

+sycophantism

+sycosis

+syenite

+syenitic

+syllabarium

+syllabary

+syllabically

+syllabicate

+syllabication

+syllabub

+syllepsis

+sylleptic

+syllogist

+syllogistically

+sylph

+sylphid

+sylphlike

+sylvanite

+sylvatic

+sylviculture

+sylvie

+sylvine

+sylvite

+sym

+symbiontic

+symbiote

+symbiotically

+symbolist

+symbolistic

+symbology

+symington

+symmetallism

+symonds

+sympathin

+sympatholytic

+sympathomimetic

+sympatric

+sympatrically

+sympatry

+sympetalous

+sympetaly

+symphonically

+symphonious

+symphoniously

+symphonist

+symphyseal

+symphysial

+symphysis

+symplectic

+sympodial

+sympodially

+symposiarch

+symposiast

+symptomatically

+symptomatologic

+symptomatological

+symptomatologically

+symptomless

+synaeresis

+synaesthesis

+synagog

+synagogal

+synalepha

+synaloepha

+synapsis

+synaptically

+synaptosomal

+synaptosome

+synarthrodial

+synarthrodially

+synarthrosis

+sync

+syncarpous

+syncarpy

+synch

+synching

+synchro

+synchroflash

+synchromesh

+synchronal

+synchroneity

+synchronic

+synchronical

+synchronically

+synchronistic

+synchros

+synchroscope

+syncing

+synclinal

+syncline

+syncopal

+syncopator

+syncope

+syncretic

+syncretism

+syncretist

+syncretistic

+syncytial

+syncytium

+syndactylism

+syndactyly

+syndesis

+syndesmosis

+syndesmotic

+syndetic

+syndetically

+syndical

+syndicalism

+syndicalist

+syndicator

+syne

+synecdoche

+synecdochic

+synecdochical

+synecdochically

+synecologic

+synecological

+synecologically

+synecology

+synectic

+synectically

+synectics

+synephrine

+syneresis

+synergetic

+synergic

+synergically

+synergid

+synergist

+synergistically

+synesis

+syngamy

+syngeneic

+synizesis

+synkaryon

+synodal

+synodic

+synodical

+synonymic

+synonymical

+synonymist

+synonymity

+synoptical

+synoptically

+synostosis

+synovial

+synovitis

+synsepalous

+synthesist

+synthetase

+synthetical

+synthetically

+syntonic

+syntonically

+syphilis

+syphilologist

+syphilology

+syren

+syringa

+syringomyelia

+syringomyelic

+syrinx

+syrinxes

+syrphid

+sysgt

+syst

+systaltic

+systat

+systematical

+systematism

+systematist

+systemically

+systemless

+systemwide

+systole

+systolic

+syzygial

+syzygy

+tabac

+tabanid

+tabard

+tabbed

+tabellen

+tabernacular

+tabes

+tabetic

+tabla

+tablature

+tableaux

+tableful

+tablespoonsful

+tableware

+tabloid

+tabor

+tabored

+taborer

+taborers

+taborin

+taboring

+taborins

+tabors

+tabu

+tace

+tacet

+tach

+tachinid

+tachism

+tachist

+tachiste

+tachistoscope

+tachistoscopic

+tachistosopically

+tachs

+tachycardia

+tachygraphic

+tachygraphical

+tachygraphy

+tachylite

+tachymeter

+tachymeter's

+tachymeters

+tachyon

+tachyon's

+tachyons

+taciturn

+taciturnity

+tackboard

+tackier

+tackies

+tackifier

+tackify

+tackily

+tacky

+tacloban

+taconite

+tactician

+tactility

+taction

+tactless

+tactlessly

+tad

+tadpole

+taeniacide

+taeniasis

+tagalong

+tagboard

+tagine

+tagines

+taiga

+tailboard

+tailbone

+tailcoat

+tailcoated

+taille

+tailless

+taillight

+taillight's

+taillights

+taillike

+tailorbird

+tailoress

+tailpiece

+tailrace

+tailspin

+tailspin's

+tailspins

+tailwater

+tailwind

+tailwind's

+tailwinds

+taintless

+taipan

+taiwanese

+takedown

+takeout

+talc

+talcose

+talcum

+talebearer

+talebearing

+talentless

+talesman

+taleysim

+tali

+talipes

+talipot

+talisman

+talismanically

+talkathon

+talladega

+tallage

+tallahatchie

+tallahoosa

+tallboy

+tallchief

+talleyrand

+tallish

+tallith

+tallithim

+tallowy

+tallyman

+talmudic

+talmudical

+talus

+tam

+tamandua

+tamarau

+tamarin

+tamarisk

+tambala

+tambour

+tambourer

+tamburitza

+tameable

+tameless

+tampala

+tamperproof

+tampion

+tanager

+tanbark

+tance

+tangelo

+tangere

+tangibility

+tanglement

+tangram

+tanh

+tanka

+tankage

+tankful

+tannage

+tannate

+tannenbaum

+tannest

+tannic

+tannish

+tansies

+tansy

+tantalate

+tantalic

+tantalite

+tantara

+tantivy

+tantra

+tantric

+tapa

+tapeline

+tapeta

+tapetum

+taphole

+tapioca

+tapis

+tapley

+tappa

+taproom

+taprooms

+tapster

+tapsters

+tara

+taraday

+tarantara

+tarantism

+taras

+taraxacum

+tarboosh

+tarbush

+tardigrade

+tardo

+tare

+targe

+targo

+tarheelia

+tarlatan

+tarmac

+tarmacadam

+tarn

+tarnishable

+taro

+tarok

+taros

+tarot

+tarpaper

+tarragon

+tarrant

+tarre

+tarriance

+tarsal

+tarsi

+tarsier

+tarsus

+tartan

+tartarughe

+tartish

+tartishly

+tartlet

+tartlets

+tartrate

+tartrated

+tartrates

+tartuffe

+taruffi

+taskmistress

+taskwork

+tasse

+tassel

+tassel's

+tasso

+tastemaker

+tastily

+tat

+tatami

+tate

+tatian

+tatler

+tatras

+tatted

+tatterdemalion

+tattersall

+tattooist

+taui

+taupe

+taurine

+taurocholate

+taurocholic

+taurog

+taussig

+tautog

+tautologous

+tautologously

+tautomer

+tautomeric

+tautomerism

+tautonym

+tautonymic

+tautonymous

+tautonymy

+taverna

+taw

+tawdrily

+tawes

+tawie

+tawpie

+taws

+tawse

+taxa

+taxability

+taxeme

+taxemic

+taxidermic

+taxidermist

+taxidermist's

+taxidermists

+taxidermy

+taxies

+taximan

+taximeter

+taximeter's

+taximeters

+taxon

+taxonomist

+taxonomist's

+taxonomists

+taxons

+taxus

+taxying

+tazza

+tchaikovsky

+teachability

+teachably

+teachership

+teacupful

+teak

+teak's

+teaks

+teapoy

+teardown

+teargas

+tearier

+tearily

+tearjerker

+tearle

+tearless

+tearlessly

+tearlessnss

+tearoom

+tearooms

+tearstain

+tearstained

+teary

+teaspoonsful

+teatime

+teatro

+teazel

+teazle

+teazled

+technetronic

+technic

+technics

+technion

+technocracy

+technocrat

+technocratic

+technol

+technologic

+technostructure

+techy

+tecta

+tectal

+tectonism

+tectum

+tecum

+ted

+tedded

+tedding

+teds

+teenie

+teenier

+teentsier

+teentsy

+teeny

+teenybopper

+teepee

+teeter

+teeterboard

+teetotal

+teetotalism

+teetotalist

+teetotum

+tegmen

+tegmental

+tegmentum

+tegument

+tegumental

+tegumentary

+teiid

+tektitic

+tel

+telamon

+telamones

+telangiectasia

+telangiectasis

+telangiectatic

+tele

+telecamera

+telecast

+telecaster

+telecourse

+teledu

+telefacsimile

+telefilm

+teleg

+telegony

+telegraphese

+telegraphically

+telegraphist

+telekinetic

+telekinetically

+teleman

+telemann

+telemark

+telemetrically

+telencephalic

+telencephalon

+teleologic

+teleologist

+teleost

+teleostean

+teleostome

+telephonically

+telephonist

+telephonists

+telephoto

+telephotographic

+teleplay

+teleran

+telescopically

+telesis

+telethermoscope

+telethon

+teletypesetting

+teletypewrite

+teletypewriter

+teletypist

+teleutospore

+teleutosporic

+teleview

+televiewer

+televisionally

+televisionary

+televisual

+telia

+telial

+telic

+telically

+teliospore

+teliosporic

+telium

+telli

+tellurian

+telluric

+telluride

+tellurite

+tellurometer

+tellurometer's

+tellurometers

+tellurous

+telly

+telocentric

+teloic

+telome

+telophase

+telos

+telotaxis

+telpher

+telson

+temblor

+temerarious

+temerariously

+temerariousness

+tempeh

+tempera

+temperable

+tempi

+templeman

+templet

+temporality

+temptable

+tempura

+tenability

+tenably

+tenace

+tenaculum

+tenantable

+tenantless

+tenantry

+tench

+tenches

+tenda

+tendance

+tendencious

+tendentious

+tendentiously

+tendentiousness

+tenderhearted

+tenderheartedly

+tenderheartedness

+tenderometer

+tenderometer's

+tenderometers

+tendinous

+tendresse

+tendril

+tendrilous

+tendrils

+tenebrific

+tenebrionid

+tenebrious

+tenebrism

+tenebrist

+tenementary

+tenenbaum

+tenesmus

+tenex

+tenia

+teniacide

+teniasis

+tennist

+tenosynovitis

+tenour

+tenpenny

+tenpin

+tenpins

+tenpounder

+tenrec

+tensility

+tensimeter

+tensimeter's

+tensimeters

+tensiometer

+tensiometer's

+tensiometers

+tensiometric

+tensiometry

+tensity

+tensometer

+tensometer's

+tensometers

+tentacular

+tentage

+tenterhook

+tenterhooks

+tentie

+tentless

+tentmaker

+tenty

+tenuis

+tenuity

+tenurial

+tenurially

+tenuto

+teocalli

+teonanacatl

+teosinte

+tepa

+tepee

+tephra

+tepidity

+ter

+terai

+teraph

+teraphim

+teratogen

+teratogenesis

+teratogenicity

+teratologic

+teratological

+teratologist

+teratoma

+teratomatous

+terce

+tercentenary

+tercentennial

+tercept

+tercet

+terebene

+terebic

+terebinth

+terebinthine

+tered

+teredines

+teredo

+terephthalate

+terest

+terete

+terga

+tergal

+tergite

+tergiversate

+tergiversation

+tergiversator

+tergum

+teriyaki

+termagant

+termagantly

+terminably

+terminational

+termined

+termining

+terminism

+termitarium

+termless

+termtime

+ternate

+ternately

+terneplate

+terpene

+terpeneless

+terpenic

+terpenoid

+terpineol

+terpolymer

+terr

+terrae

+terram

+terrane

+terraqueous

+terrarium

+terrazzo

+terrene

+terreplein

+terret

+terricolous

+terrifically

+terrigenous

+territorialism

+territorialist

+territoriality

+terrorless

+tertre

+tervalent

+tery

+tessera

+tessie

+tessitura

+testa

+testacean

+testaceous

+testacy

+testae

+testatrix

+testcross

+testis

+teston

+testoon

+testosterone

+testudo

+tetanal

+tetanic

+tetanically

+tetany

+tetartohedral

+tetched

+tetchier

+tetchy

+tete

+teter

+teth

+tetherball

+tetra

+tetrabasic

+tetrabasicity

+tetracaine

+tetrachord

+tetracid

+tetrad

+tetradecyl

+tetradic

+tetradrachm

+tetradymite

+tetradynamous

+tetraethyl

+tetraethyllead

+tetragonolobus

+tetragrammaton

+tetrahedrite

+tetrahydrate

+tetrahydrated

+tetrahydrocannabinol

+tetrahydrofuran

+tetrahydroxy

+tetrahymena

+tetralogy

+tetramer

+tetramer's

+tetrameric

+tetramerous

+tetramers

+tetrameter

+tetramethyl

+tetramethyllead

+tetraploid

+tetraploidy

+tetrapod

+tetrapyrrole

+tetrarch

+tetrarchic

+tetrarchy

+tetraspore

+tetrasporic

+tetratomic

+tetrazolium

+tetrode

+tetrodes

+tetrodotoxin

+tetrxide

+tetryl

+tetter

+tewfik

+textbookish

+textuary

+thalamencephalon

+thalamic

+thalamically

+thalamus

+thalassemia

+thalassemic

+thalassic

+thalassocracy

+thalassocrat

+thaler

+thalidomide

+thalli

+thallic

+thalloid

+thallophytic

+thallous

+thallus

+thalluses

+thames

+thane

+thaneship

+thankworthy

+thar

+thaumaturge

+thaumaturgic

+thaumaturgist

+thaumaturgy

+theast

+theat

+theatricalism

+theatricality

+theca

+thecae

+thecal

+thecate

+thecodont

+thee

+theelin

+theelol

+theist

+theist's

+theistical

+theistically

+theists

+thematically

+thenar

+thenceforward

+thenceforwards

+theobromine

+theocentric

+theocentricity

+theocentrism

+theocrat

+theocratic

+theocratical

+theocratically

+theodicy

+theodolite

+theodolitic

+theodosius

+theogonic

+theogony

+theol

+theolog

+theologic

+theologue

+theonomous

+theonomously

+theonomy

+theophanic

+theophany

+theophylline

+theorematic

+theosophical

+theosophically

+theosophist

+theosophy

+therapeusis

+therapeutically

+therapeutist

+therapsid

+thereabout

+thereat

+thereinafter

+thereinto

+thereunto

+therewithal

+theriac

+theriaca

+theriacal

+theriomorphic

+therm

+thermae

+thermalization

+thermalize

+thermalized

+thermalizes

+thermalizing

+thermic

+thermically

+thermion

+thermite

+thermite's

+thermochemical

+thermochemist

+thermochemistry

+thermocline

+thermocoagulation

+thermoduric

+thermodynamical

+thermodynamicist

+thermoelectron

+thermoelement

+thermoform

+thermoformable

+thermogram

+thermogram's

+thermograms

+thermograph

+thermographic

+thermographically

+thermography

+thermohaline

+thermojunction

+thermolabile

+thermolability

+thermoluminescence

+thermoluminescent

+thermolysis

+thermolytic

+thermomagnetic

+thermomagnetically

+thermometrically

+thermoperiodicity

+thermoperiodism

+thermophile

+thermophilic

+thermophilous

+thermoplasticity

+thermopylae

+thermoreceptor

+thermoregulation

+thermoregulator

+thermoregulatory

+thermoremanence

+thermoremanent

+thermoscope

+thermoset

+thermosphere

+thermospheric

+thermostability

+thermostatically

+thermotactic

+thermotaxis

+thermotropic

+thermotropism

+theroelectricity

+thesaural

+thetic

+thetically

+theurgic

+theurgical

+theurgist

+theurgy

+thew

+thiabendazole

+thiaminase

+thiamine

+thiazide

+thiazine

+thiazole

+thickety

+thickhead

+thickheaded

+thickset

+thievery

+thievish

+thievishly

+thievishness

+thighbone

+thigmotaxis

+thigmotropism

+thill

+thills

+thimbleberry

+thimbleful

+thimbleful's

+thimblerig

+thimblerigger

+thimblesful

+thimbleweed

+thimerosal

+thinclad

+thingamabob

+thingumajig

+thingummy

+thiocarbamide

+thiocyanic

+thioguanine

+thiol

+thiolic

+thionate

+thionic

+thiopental

+thiophene

+thiophosphate

+thiosulfate

+thiosulfuric

+thiotepa

+thiouracid

+thiourea

+thir

+thiram

+thirdhand

+thirl

+thirstily

+thirtyfold

+thistly

+thitherto

+thitherward

+thixotropic

+thixotropy

+tho

+thod

+tholdy

+thole

+tholed

+tholeiite

+tholeiitic

+tholepin

+tholer

+tholes

+tholing

+thoraces

+thoracic

+thoracically

+thoracotomy

+thorax

+thoraxes

+thoria

+thorianite

+thoric

+thorite

+thornback

+thornbush

+thornless

+thornlike

+thoroughpin

+thoroughwort

+thoth

+thoughtway

+thousandfold

+thraldom

+thralldom

+thrasonical

+thrasonically

+thraw

+thrawart

+thrawn

+thrawnly

+threadfin

+threadiness

+threadless

+threadlike

+thready

+threepence

+threepences

+threepenny

+thremmatology

+threnode

+threnodic

+threnodist

+threnody

+threonine

+thriftily

+thriftless

+thriftlessly

+thriftlessness

+thrips

+thriven

+thro

+throatily

+throatlatch

+throbber

+throe

+thrombin

+thrombocyte

+thrombocytic

+thrombocytopenia

+thrombocytopenic

+thromboembolic

+thromboembolism

+thrombokinase

+thrombophlebitis

+thromboplastic

+thromboplastically

+thromboplastin

+thrombosed

+thrombospondin

+thrombotic

+throneberry

+throstle

+throttleable

+throttlehold

+throughither

+throughother

+throughway

+throve

+throwaway

+throwster

+thrustful

+thrustfulness

+thrustor

+thudded

+thumbhole

+thumbprint

+thumbprint's

+thumbprints

+thumbscrew

+thunderbird

+thundercloud

+thundercloud's

+thunderclouds

+thunderflower

+thunderhead

+thunderpeal

+thundershower

+thundershower's

+thundershowers

+thunderstone

+thunderstrike

+thunderstroke

+thurber

+thurible

+thurifer

+thurl

+thwartwise

+thwump

+thylacine

+thylakoid

+thyme

+thyme's

+thymectomy

+thymes

+thymey

+thymic

+thymidine

+thymine

+thymocyte

+thymol

+thymus

+thymy

+thyrglobulin

+thyrocalcitonin

+thyroidectomy

+thyroiditis

+thyrotoxicosis

+thyroxin

+thyrse

+thyrsi

+thyrsus

+thysanopteran

+thysanuran

+ti

+tial

+tiality

+tian

+tiara

+tiated

+tibial

+tiburon

+tical

+ticism

+tickicide

+ticklebrush

+tickseed

+ticktack

+ticktacktoe

+ticktock

+ticonderoga

+tictac

+tiddledywinks

+tiddlywinks

+tideless

+tidemark

+tideway

+tieback

+tieck

+tieing

+tieless

+tiemannite

+tien

+tiepin

+tierce

+tiercel

+tigerish

+tigerishly

+tigerishness

+tigerlike

+tightfisted

+tightrope

+tightwad

+tightwad's

+tightwads

+tightwire

+tiglon

+tigon

+tijuana

+tike

+tiki

+til

+tilapia

+tilefish

+tillandsia

+tillerman

+tillich

+tillie

+tilly

+tiltable

+tiltmeter

+tiltmeter's

+tiltmeters

+tiltyard

+timbal

+timbale

+timberhead

+timberline

+timberman

+timberwork

+timbral

+timbrel

+timbrelled

+timekeeper

+timekeeping

+timeous

+timeously

+timepleaser

+timesaving

+timeserver

+timeservers

+timeserving

+timework

+timeworker

+timmy

+timocracy

+timocratic

+timocratical

+timorous

+timorously

+timorousness

+timpani

+timpanist

+tinamou

+tinc

+tincal

+tinct

+tinctorial

+tinctorially

+tinderbox

+tinea

+tineal

+tineau

+tinful

+ting

+tingeing

+tingen

+tingly

+tinhorn

+tinkly

+tinman

+tinnitus

+tinstone

+tintinnabulary

+tintinnabulation

+tintless

+tintoretto

+tinwork

+tinworks

+tipcart

+tipi

+tippecanoe

+tippet

+tipsily

+tipstaff

+tipstaves

+tipster

+tipstock

+tirewoman

+tisane

+tissuey

+titaness

+titania

+titanically

+titaniferous

+titanism

+titanous

+titbit

+tithable

+tithonia

+titi

+titivate

+titivation

+titlark

+titleholder

+titleholders

+titlist

+titmice

+tito

+titrant

+titratable

+titrator

+titrimetric

+titrimetrically

+tittie

+tittivate

+tittle

+tittup

+toadstool

+toastmaster

+toastmaster's

+toastmasters

+toastmistress

+tobacconist

+tobacconist's

+tobacconists

+tobies

+toboggan

+toboggan's

+tobogganer

+tobogganing

+tobogganist

+toboggans

+tocher

+tocopherol

+tocsin

+tod

+toddies

+toddy

+toddy's

+todies

+tody

+toehold

+toehold's

+toeholds

+toeing

+toeless

+toepiece

+toeplate

+toff

+toffies

+toffy

+toft

+toga

+togaed

+toggery

+togue

+toile

+toiletry

+toilette

+toilful

+toilfully

+toilworn

+toke

+tokenism

+tokonoma

+tola

+toland

+tolbooth

+tolbutamide

+tole

+tolerator

+tolidine

+toling

+tollbooth

+tollbooth's

+tollbooths

+tolley

+tollman

+tollway

+tolu

+toluate

+toluic

+toluidine

+toluol

+tolyl

+tolylene

+tombac

+tombigbee

+tombless

+tombolo

+tomboy

+tomboyish

+tomboyishness

+tomcat

+tomcod

+tomentose

+tomentum

+tomfoolery

+tommyrot

+tomogram

+tomogram's

+tomograms

+tompion

+tomtit

+tonality

+tondi

+tondo

+toneme

+tonemic

+tonetic

+tonetically

+tonetics

+tonette

+tonga

+tongueless

+tonguelike

+tonically

+tonicity

+tonio

+tonn

+tonne

+tonneau

+tonneaus

+tonner

+tonnes

+tonometer

+tonometer's

+tonometers

+tonometric

+tonometry

+tonoplast

+tonsillar

+tonsillectomy

+tonsorial

+tonsure

+tonsured

+tonsuring

+tontine

+tonus

+toolbox

+toolboxes

+toolhead

+toolholder

+toolhouse

+toolroom

+toolshed

+toom

+toomey

+toon

+toothache

+toothache's

+toothaches

+toothless

+toothlike

+tooths

+toothsome

+toothsomely

+toothsomeness

+toothwort

+topcross

+topdressing

+tope

+topee

+topes

+topflight

+topful

+topfull

+topheavy

+tophi

+tophus

+topi

+topiary

+topicality

+topkick

+topknot

+topless

+toploftical

+toploftily

+toploftiness

+toplofty

+topmast

+topminnow

+topograph

+topographer

+topoi

+topologise

+topologist

+toponym

+toponymic

+toponymical

+toponymy

+topos

+topper

+topsail

+topstitch

+topwork

+toque

+tor

+torchbearer

+torchlight

+torchon

+torchwood

+toreador

+torero

+toreutic

+toreutics

+tormentil

+tormentor

+tornadic

+tornillo

+torpidity

+torquate

+torr

+torrens

+torrential

+torrentially

+torridity

+torsade

+torsi

+torte

+tortes

+torticollis

+tortilla

+tortious

+tortiously

+tortoni

+tortricid

+tortrix

+tortuosity

+torturous

+torturously

+torula

+tosh

+tosspot

+totalism

+totaquina

+totaquine

+totemically

+totemism

+totemist

+totemistic

+totemite

+tother

+totipotency

+totipotent

+toto

+tottery

+totting

+toucan

+touchback

+touchhole

+touchline

+touchmark

+touchwood

+toughie

+toughies

+toughy

+toulouse

+toupee

+touraco

+tourbillion

+tourbillon

+touristic

+touristically

+tourmaline

+tournedos

+tourney

+tourneyed

+tourneying

+tourneys

+tourniquet

+tourniquets

+touse

+tousing

+tovarich

+tovarish

+towage

+towerlike

+towhee

+towie

+towline

+towmond

+townee

+townies

+townlet

+townley

+townsfolk

+townspeople

+townswoman

+townwear

+towny

+towpath

+towrope

+towsley

+toxaphene

+toxemia

+toxemic

+toxicant

+toxicogenic

+toxicologic

+toxicological

+toxicologically

+toxicologist

+toxicology

+toxicosis

+toxigenic

+toxigenicity

+toxoid

+toxophilite

+toxophilites

+toxophily

+toxoplasma

+toxoplasmic

+toxoplasmosis

+toylike

+toynbee

+toyon

+trabeate

+trabeated

+trabeation

+trabecula

+trabecular

+trabeculate

+traceability

+traceably

+tracheae

+tracheal

+tracheary

+tracheate

+tracheated

+tracheid

+tracheidal

+tracheitis

+tracheobronchial

+tracheolar

+tracheole

+tracheophyte

+tracheotomy

+trachoma

+trachomatous

+trachyte

+trachytic

+tracklayer

+tracklaying

+trackman

+trackside

+trackwalker

+tractableness

+tractably

+tractarians

+tractate

+tractional

+tradable

+tradeable

+tradescantia

+tradespeople

+tradevman

+traditionary

+traditionless

+tradtionalist

+traduce

+traduced

+traducement

+traducer

+traducing

+trafficable

+tragacanth

+tragedienne

+tragi

+tragical

+tragicomedy

+tragicomical

+tragopan

+tragus

+trailblazer

+trailblazer's

+trailblazers

+trailblazing

+trailbreaker

+trailerable

+trailerist

+trailerite

+trailership

+trailhead

+trailhead's

+trailheads

+trailless

+trainability

+trainable

+trainband

+trainbearer

+traineeship

+trainferry

+trainful

+trainload

+trainload's

+trainloads

+trainsick

+traitoress

+traitress

+traject

+trajection

+tral

+tramcar

+tramline

+tramming

+tramontane

+trampoline

+trampoliner

+trampolining

+trampolinist

+tramroad

+trancelike

+trangam

+transactinide

+transactional

+transactor

+transamination

+transaxle

+transcendency

+transcendentalist

+transcriptional

+transcriptionally

+transcutaneous

+transduced

+transducing

+transductional

+transection

+transeptal

+transferase

+transferential

+transfiguration

+transfigure

+transfixion

+transformant

+transformants

+transformationalist

+transformative

+transfusible

+transfusional

+transglottal

+tranship

+transhumance

+transhumant

+transilluminate

+transillumination

+transilluminator

+transitio

+transitorily

+translatory

+translocate

+translocation

+transmarine

+transmembrane

+transmigrate

+transmigration

+transmigrator

+transmigratory

+transmissibility

+transmissive

+transmissivity

+transmissometer

+transmissometer's

+transmissometers

+transmontane

+transmountain

+transmutable

+transmutative

+transnational

+transnatural

+transonic

+transparence

+transpersonal

+transpicuous

+transpierce

+transplacental

+transplacentally

+transplantability

+transpolar

+transponder

+transpontine

+transportational

+transpositional

+transsexual

+transsexualism

+transshape

+transthoracic

+transthoracically

+transubstantial

+transubstantiate

+transubstantiation

+transudate

+transudation

+transude

+transuded

+transuding

+transuranic

+transuranium

+transvaluate

+transvaluation

+transvalue

+transvestism

+transylvania

+trapeze

+trapezist

+trapezius

+trapezohedron

+trapnest

+traprock

+trapshooter

+trapshooting

+trapunto

+trashman

+trass

+trattoria

+traumata

+traumatically

+traumatism

+trave

+travois

+travoises

+trawlerman

+trayal

+trayful

+treacle

+treacly

+treadless

+treadwell

+treasonably

+treasurable

+treasurership

+treatability

+treatable

+trebly

+trebuchet

+trebucket

+trecento

+tred

+tredecillion

+treece

+treehopper

+treeing

+treeless

+treenail

+trehalase

+trehalose

+treillage

+trekker

+trelliswork

+trematode

+tremolant

+tremolite

+tremolitic

+tremolo

+tremulant

+trenail

+trenchancy

+trendily

+trepan

+trepanation

+trepang

+trepanned

+trepanning

+trepans

+trephination

+trephine

+trephined

+trephining

+trepid

+trepidant

+treponema

+treponemal

+treponematosis

+treponematous

+treponeme

+tressel

+trestletree

+trestlework

+trews

+trey

+treys

+tri

+triacetate

+triacid

+triadically

+triage

+trialogue

+triangularity

+triarchy

+triaxial

+triaxiality

+triazine

+triazines

+trib

+tribalism

+tribasic

+triboelectric

+triboelectricity

+tribological

+tribologist

+tribology

+triboluminescence

+triboluminescent

+tribophysics

+tribrach

+tribrachic

+tribromide

+tribunate

+tribuneship

+tricarboxylic

+tricarpellary

+tricarpellate

+trice

+triceps

+tricepses

+triceratops

+trichiasis

+trichina

+trichinal

+trichinosis

+trichinous

+trichite

+trichlorfon

+trichloride

+trichocyst

+trichocystic

+trichogyne

+trichoid

+trichome

+trichomic

+trichomonacidal

+trichomonacide

+trichomonad

+trichomonadal

+trichomonal

+trichomoniasis

+trichopteran

+trichotomous

+trichotomously

+trichromat

+trichromatism

+trichrome

+trichuriasis

+tricing

+trickily

+trickish

+trickishly

+trickishness

+tricksier

+tricksiness

+tricksy

+triclad

+triclinic

+triclinium

+tricolette

+tricorn

+tricorne

+tricornered

+tricot

+tricotine

+tricotyledonous

+trictrac

+tricuspid

+tricycle

+tricycles

+tricyclic

+tridimensional

+tridimensionality

+triduum

+triene

+triennium

+trierarch

+trierarchy

+triethyl

+trifacial

+trifid

+trifluralin

+trifocal

+trifoliate

+trifoliolate

+trifolium

+triforium

+triform

+trifurcate

+trifurcation

+trigeminal

+triggerfish

+triggerman

+trigging

+triglyceride

+triglycerides

+triglyph

+triglyphic

+triglyphical

+trigon

+trigonometrical

+trigonometrically

+trigonous

+trigraph

+trigraphic

+trihybrid

+trihydroxy

+triiodothyronine

+trijet

+trilateral

+trilaterality

+trilaterally

+trilbies

+trilby

+trilinear

+trilingual

+trilingually

+triliteral

+triliteralism

+trillium

+trilobate

+trilobation

+trilobed

+trilocular

+triloculate

+trimaran

+trimble

+trimeric

+trimerous

+trimestral

+trimestrial

+trimeter

+trimetrogon

+trimonthly

+trimorph

+trimorphic

+trimorphism

+trimorphous

+trimotor

+trinal

+trinary

+trindle

+trindled

+trindling

+trine

+trinitrotoluene

+trinketry

+trinkums

+trinocular

+trinomial

+trinucleotide

+triol

+triolet

+triose

+tripack

+triphammer

+triphammer's

+triphammers

+triphenylmethane

+triphibian

+triphibious

+triphosphate

+triphthong

+triphthongal

+tripinnate

+tripinnately

+triplane

+tripletail

+triplicity

+triplite

+triploblastic

+triploid

+triploidy

+tripodal

+tripos

+tripper

+trippet

+triptane

+triquetrous

+triradiate

+trireme

+tris

+trisaccharide

+trisect

+trisection

+trisector

+triskele

+triskelion

+trismus

+trisoctahedron

+trisome

+trisomic

+trisomy

+triste

+tristearin

+tristeza

+tristful

+tristfully

+tristfulness

+tristimulus

+trisubstituted

+trisulfide

+trisyllabic

+trisyllabicall

+trit

+tritheism

+tritheist

+tritheistic

+tritheistical

+trithing

+tritiated

+triticale

+tritoma

+tritone

+triturable

+triturate

+trituration

+triturator

+triumvir

+triumviral

+triumvirate

+trivalve

+trivet

+triweekly

+trochaic

+trochal

+trochanter

+trochanteral

+trochanteric

+trochar

+troche

+trochee

+trochilus

+trochlea

+trochlear

+trochoid

+trochoidal

+trochophore

+troglodytic

+trogon

+trograd

+troilite

+trolleybus

+trollied

+trollies

+trolly

+trombidiasis

+trommel

+tromp

+trona

+trone

+troostite

+trop

+tropaeolum

+trope

+tropez

+trophallaxis

+trophically

+trophoblast

+trophoblastic

+trophozoite

+tropidoclonion

+tropistic

+tropologic

+tropological

+tropologically

+tropology

+tropomyosin

+tropopause

+tropophilous

+troposphere

+tropotaxis

+troth

+trothplight

+trotline

+trotsky

+trotskyism

+troubadour

+troubadour's

+troubadours

+troubleshot

+troublous

+troublously

+troublousness

+troupial

+trousseau

+trousseaus

+trousseaux

+troutier

+trouty

+trove

+trover

+trow

+truantry

+truckage

+truckee

+truckle

+truckled

+truckler

+truckline

+truckling

+truckload

+truckload's

+truckloads

+truckman

+truckmaster

+truculency

+trueborn

+truehearted

+trueheartedness

+trueing

+truelove

+truepenny

+truffle

+truffle's

+truffled

+truffles

+truistic

+trujillo

+trull

+trumpetlike

+trumpetweed

+truncheon

+truncheons

+trunkfish

+trunkful

+trunnel

+trunnion

+trunnions

+trustability

+trustable

+trustbuster

+trusteeing

+trustless

+trustworthily

+tryout

+trypanosome

+trypanosomiasis

+tryparsamide

+trypsinogen

+tryptamine

+tryptic

+tryptophan

+tryptophane

+trysail

+tryst

+trytophan

+tryworks

+tset

+tsetse

+tsetses

+tsunamic

+tsunematsu

+tubal

+tubbable

+tubbed

+tubber

+tubbier

+tubbing

+tubby

+tubeless

+tubelike

+tubercle

+tubercled

+tubercular

+tubercularly

+tuberculate

+tuberculated

+tuberculation

+tuberculin

+tuberculoid

+tuberculous

+tuberculously

+tuberose

+tuberosity

+tuberous

+tubful

+tubifex

+tubifexes

+tubificid

+tubocurarine

+tubularity

+tubulous

+tuchun

+tuckahoe

+tucket

+tuebor

+tuel

+tufa

+tufaceous

+tuff

+tuffaceous

+tuffet

+tufty

+tugboat

+tugger

+tui

+tuille

+tuitional

+tularemic

+tulation

+tulatory

+tule

+tulipwood

+tullibee

+tumblebug

+tumbledown

+tumblerful

+tumbleweed

+tumbrel

+tumbril

+tumefaciens

+tumefaction

+tumefactive

+tumescence

+tumescent

+tumidity

+tumoral

+tumorigenic

+tumorigenicity

+tumorlike

+tumorlike's

+tumorlikes

+tumorous

+tump

+tumpline

+tumultuary

+tumulus

+tunability

+tunably

+tundish

+tuneable

+tuneless

+tunesmith

+tungstic

+tungstite

+tunica

+tunicae

+tunicate

+tunicated

+tunicle

+tunnellike

+tunny

+tup

+tuppence

+tupping

+tuque

+tural

+turbanned

+turbellarian

+turbid

+turbidimeter

+turbidimeter's

+turbidimeters

+turbidimetric

+turbidimetrically

+turbidimetry

+turbidite

+turbidity

+turbidly

+turbidness

+turbinal

+turbit

+turbjet

+turbo

+turbocar

+turbocharge

+turbocharger

+turboelectric

+turboprop

+turbos

+turboshaft

+turbosupercharged

+turbosupercharger

+turbot

+turbots

+turbulency

+turd

+ture

+tured

+tureen

+turfman

+turfski

+turfskiing

+turfy

+turgescence

+turgescent

+turgidity

+turgor

+turion

+turmeric

+turnbuckle

+turncoat

+turndown

+turnery

+turnsole

+turnspit

+turnstile

+turnup

+turnverein

+turpentinic

+turpentinous

+turps

+turquois

+turtledove

+turtlehead

+turves

+tusche

+tush

+tusklike

+tussah

+tussive

+tussock

+tussocks

+tussocky

+tussore

+tutee

+tutees

+tutelar

+tutelary

+tutorage

+tutoress

+tutorship

+tutoyer

+tutti

+tux

+tuyere

+twae

+twangy

+tween

+tweet

+tweeter

+twelvefold

+twelvemonth

+twentyfold

+twerp

+twiggy

+twilit

+twinberry

+twinborn

+twinflower

+twingeing

+twinkly

+twinship

+twiny

+twirp

+twitchily

+twitted

+twittery

+twixt

+twofer

+twohandedness

+twopence

+twopences

+twopenny

+tyke

+tyke's

+tykes

+tymbal

+tympan

+tympani

+tympani's

+tympanic

+tympanis

+tympanites

+tympanitic

+tympanum

+tympanum's

+tympany

+typal

+typeable

+typecase

+typecast

+typefounder

+typefounding

+typefoundry

+typeout

+typey

+typhlosole

+typic

+typier

+typograph

+typologist

+typy

+tyramine

+tyrannosaur

+tyrannosaurus

+tyrannous

+tyrannously

+tyro

+tyrocidin

+tyrocidine

+tyros

+tyrosinase

+tyrothricin

+tzaddik

+tzaddikim

+tzar

+tzigane

+tzimmes

+tzitzis

+udall

+udder

+uglification

+uglify

+uglily

+ukulele

+ulama

+ulcerogenic

+ulcerous

+uldered

+ulema

+ulexite

+ullage

+ulna

+ulna's

+ulnar

+ulotrichous

+ulotrichy

+ultima

+ultimacy

+ultimo

+ultimogeniture

+ultrabasic

+ultracentrifugal

+ultrafashionable

+ultrafiche

+ultrafilter

+ultrafiltration

+ultrahigh

+ultraism

+ultraist

+ultraistic

+ultramafic

+ultramicro

+ultramicroscope

+ultramicroscopes

+ultramicrotome

+ultramicrotomes

+ultramicrotomy

+ultramodernist

+ultramontane

+ultramontanism

+ultranationalism

+ultranationalist

+ultrapure

+ultrapurely

+ultrasecret

+ultrasonicate

+ultrasonicated

+ultrasonicates

+ultrasonicating

+ultrastructural

+ultrastructurally

+ululant

+ululate

+ululation

+ulva

+umbel

+umbellate

+umbellifer

+umbelliferous

+umbilicate

+umbilicated

+umbilication

+umbonate

+umbones

+umbos

+umbrae

+umbrageous

+umbrageously

+umbrageousness

+umbral

+umlaut

+ump

+umpirage

+umpteen

+umpteenth

+un

+unaccountability

+unadapted

+unageing

+unalterability

+unamazed

+unamusing

+unanchor

+unanswerably

+unapologetic

+unappealable

+unappreciation

+unapproachably

+unarm

+unassailability

+unassailably

+unassertive

+unassuageable

+unattach

+unaverage

+unballasted

+unbandage

+unbar

+unbeautiful

+unbecome

+unbeknown

+unbelief

+unbeliever

+unbeseeming

+unbiblical

+unbid

+unbitted

+unblenched

+unblessed

+unbolt

+unbosom

+unbox

+unbrace

+unbraid

+unbridle

+unbroke

+unbuckle

+unbudgeable

+unbudgeably

+unbuild

+unbundle

+unburden

+uncage

+uncalculated

+uncalculatingly

+uncandid

+uncannily

+uncelebrated

+unchain

+unchallengeable

+unchancy

+unchangealeness

+uncharge

+unchaste

+unchastely

+unchasteness

+unchivalrous

+unchoke

+uncial

+uncially

+unciform

+uncil

+uncinaria

+uncinariasis

+uncinate

+uncinus

+uncircumcision

+unclamp

+unclasp

+unclassical

+unclench

+unclimbable

+unclimbableness

+unclinch

+uncloak

+unclog

+unclose

+unclothe

+unclutter

+uncock

+uncoffin

+uncoffined

+uncoil

+uncommercial

+uncompassionate

+uncompetitive

+uncompetitiveness

+uncomplicated

+uncompromisable

+unconformable

+unconformably

+uncongenial

+unconquerably

+unconscionability

+unconscionably

+unconstraint

+uncork

+uncorseted

+uncouple

+uncoupler

+uncross

+uncrown

+uncrumple

+unctuous

+unctuously

+unctuousness

+uncurl

+uncus

+uncut

+undauntable

+undebatably

+undecagon

+undeceive

+undecillion

+underact

+underactivity

+underage

+underbid

+underbidder

+underbody

+underbred

+underbrim

+undercarriage

+undercharge

+underclass

+undercoat

+undercoating

+undercook

+undercool

+underdo

+underdrawers

+underdress

+underdressed

+undereducation

+underexpose

+underexposure

+underfeed

+undergarment

+undergird

+underglaze

+underhand

+underinsurance

+underlaid

+underlayment

+underlet

+underlip

+undermanned

+undermost

+undernourished

+undernourishment

+undernutrition

+underpants

+underpart

+underpass

+underpasses

+underpin

+underplot

+underplots

+underpowered

+underproduction

+underproductive

+underproof

+underreport

+underripe

+underrun

+undersaturated

+undersecretariat

+undersell

+undersexed

+undershorts

+undershrub

+undersigned

+underskirt

+underslung

+undersong

+underspin

+understaffed

+understeer

+understory

+understrapper

+understrength

+undersupply

+undersurface

+undertenant

+undertone

+undertrick

+underused

+undervaluation

+undervalue

+undervaluing

+underwaist

+underweight

+underwing

+underwool

+undetectability

+undine

+undiplomatically

+undock

+undogmatic

+undouble

+undramatic

+undrape

+undraw

+undrunk

+undulant

+undulatory

+une

+unequivocably

+unexceptionable

+unexceptionableness

+unexceptionably

+unexceptional

+unexpressive

+unfancy

+unfasten

+unfeeling

+unfeelingly

+unfeelingness

+unfetter

+unfix

+unfixable

+unflappability

+unflappable

+unforgettability

+unforgiveable

+unforgiveably

+unfreeze

+unfriended

+unfrock

+unfussy

+ungenerosity

+ungenerous

+ungird

+unglue

+ungovernable

+ungrudging

+ungual

+unguard

+unguent

+ungulate

+unhair

+unhandiness

+unhandsome

+unhandy

+unharness

+unhitch

+unhitches

+unhitching

+unhood

+unhorse

+unhorsed

+unialgal

+uniaxial

+uniaxially

+unibuss

+unicameral

+unicamerally

+unicellular

+unicellularity

+unicycle

+unicyclist

+unifactorial

+unifiable

+unifoliate

+unifoliolate

+uniformitarian

+uniformitarianism

+unijugate

+unilinear

+unilingual

+unillusioned

+unilocular

+uninformative

+unintelligence

+uninucleate

+uninvaginated

+unionism

+unionist

+unionists

+uniparental

+uniparentally

+uniparous

+uniplanar

+uniplex

+unipolarity

+uniramous

+unisex

+unisexual

+unisexuality

+unisexually

+unitage

+unital

+unitarily

+unitarity

+universalist

+univocal

+univocally

+unkenned

+unkennel

+unlace

+unlade

+unlash

+unlatch

+unlay

+unlimber

+unlimbered

+unlimbering

+unlive

+unloose

+unloosen

+unman

+unmate

+unmating

+unmeaning

+unmeet

+unmemorable

+unmemorably

+unmitigatd

+unmoor

+unmoral

+unmorality

+unmuffle

+unmuzzle

+unmyelinated

+unnail

+uno

+unopenable

+unpackage

+unpackaging

+unpalatable

+unpeg

+unpeople

+unperfect

+unperson

+unpick

+unpile

+unpin

+unplug

+unpolitical

+unpregnant

+unprofessed

+unpronounced

+unquote

+unreel

+unreeve

+unregenerate

+unreserve

+unrestraint

+unriddle

+unrig

+unrip

+unrobe

+unroof

+unroot

+unrotate

+unround

+unrounded

+unsaddle

+unsafety

+unsaturate

+unsay

+unsayable

+unseal

+unsealing

+unseam

+unsearchable

+unsearchably

+unsel

+unselective

+unserviceable

+unset

+unsettle

+unsettlement

+unsew

+unsex

+unshackle

+unshapen

+unshell

+unshift

+unship

+unshockability

+unshockable

+unshped

+unsight

+unsighted

+unsling

+unslinged

+unslinging

+unsnarl

+unspeak

+unspeakably

+unsphere

+unsportsmanlike

+unstate

+unstep

+unstick

+unstop

+unstoppably

+unstrap

+unstring

+unstudied

+unsubstantial

+unsubstantiality

+unsuccess

+unswathe

+unswear

+unsymmetrical

+untangle

+untenability

+unter

+untether

+unthaw

+unthink

+unthinkability

+unthought

+unthread

+unthrone

+untimeous

+untouchability

+untraceability

+untread

+untruss

+untuck

+untune

+untwine

+untwist

+unutterable

+unvocal

+unvoice

+unwarrantably

+unweave

+unweeting

+unweetingly

+unweight

+unwell

+unwieldily

+unwinnable

+unwisdom

+unwish

+unwished

+unworthily

+unwreathe

+unyoke

+unzio

+unzip

+upas

+upbuild

+upbuilder

+upcast

+upchuck

+updo

+updos

+upgrowth

+upheave

+upheaver

+uphoster

+upmanship

+upmost

+upperpart

+upping

+uppish

+uppishly

+uppishness

+uppity

+uppityness

+uprear

+uprush

+upsetter

+upshift

+upspring

+upstage

+upstaged

+upstages

+upstaging

+upstart

+upstroke

+upsweep

+upswept

+upthrow

+upthrust

+uptight

+uptightness

+uptilt

+upwell

+uracil

+uraei

+uraemia

+uraeus

+uralite

+uralitic

+uranic

+uranide

+uraninite

+uranographic

+uranographical

+uranography

+uranological

+uranology

+uranometry

+uranous

+urate

+uratic

+urbanist

+urbanistic

+urbanistically

+urbanity

+urbanologist

+urbanology

+urbiculture

+urceolate

+ure

+urease

+uredinial

+uredinium

+urediospore

+uredium

+uredostage

+ureide

+uremic

+ureotelic

+ureotelism

+ureter

+ureteral

+ureteric

+urethan

+urethral

+urethritis

+urethroscope

+uric

+uricosuric

+uricotelic

+uricotelism

+uridine

+urinalysis

+urinogenital

+urinometer

+urinometer's

+urinometers

+urinous

+urochord

+urochordal

+urochordate

+urochrome

+urodele

+urogenital

+urokinase

+urol

+urolith

+urolithiasis

+urologic

+urological

+urologist

+urology

+uropod

+uropygial

+uropygium

+urostyle

+ursine

+urticaria

+urticarial

+urticate

+urtication

+urus

+urushiol

+usableness

+usance

+useably

+usernames

+useway

+usherette

+usnea

+usrio

+usufruct

+usufructuary

+ute

+uteca

+utep

+uterus

+uteruses

+utilitarianism

+utiny

+utopism

+utopist

+utopistic

+utricle

+utricular

+utricularia

+utriculus

+utterable

+uttium

+uvarovite

+uvea

+uveal

+uveitis

+uvula

+uvular

+uvularly

+uxorial

+uxoricide

+uxorious

+uxoriously

+uxoriousness

+vacationist

+vacationless

+vaccinal

+vaccinate

+vaccinated

+vaccinates

+vaccinator

+vaccinators

+vacua

+vacuolar

+vagabondage

+vagabondish

+vagabondism

+vagally

+vagarious

+vagariously

+vagile

+vagility

+vagotomy

+vagotonic

+vagotropic

+vagrancy

+vainglory

+valediction

+valerian

+valetudinarian

+valetudinarianism

+valetudinary

+valiance

+valiancy

+valine

+valise

+valises

+valle

+vallecular

+valorous

+valorously

+valuational

+valuationally

+valvular

+vamoose

+vamoosed

+vamooses

+vamoosing

+vampirism

+vampish

+vandalistic

+vanderburgh

+vandyked

+vanguardism

+vanguardist

+vanillic

+vanillin

+vanquishable

+vanquishment

+vanward

+vapid

+vapidity

+vapidly

+vapidness

+vaporous

+vaporously

+vaporousness

+vaquero

+variac

+variational

+variationally

+varices

+varicose

+varicosed

+varicosity

+variegator

+varietal

+varietally

+variform

+variocoupler

+varioloid

+variolous

+variometer

+variometer's

+variometers

+variorum

+varisized

+varix

+varlet

+varletry

+varnishy

+varsity

+varus

+varve

+varved

+vasal

+vascularity

+vasculature

+vasculum

+vaselike

+vasiform

+vasoactive

+vasoactivity

+vasoconstriction

+vasoconstrictive

+vasoconstrictor

+vasodilatation

+vasodilation

+vasodilator

+vasomotor

+vasopressin

+vasopressor

+vasospasm

+vasospastic

+vasotocin

+vassalage

+vastitude

+vastity

+vasty

+vatic

+vaticinal

+vaticinate

+vaticination

+vaticinator

+vatted

+vatting

+vaudevillian

+vaulty

+vauntful

+vauntingly

+vaunty

+vaward

+vealy

+vectograph

+vectographic

+vectorcardiogram

+vectorcardiogram's

+vectorcardiograms

+vectorcardiographic

+vectorcardiography

+vee

+veep

+veeries

+veery

+vegetably

+vegetal

+vegetarianism

+vegetational

+vegetationally

+vegete

+vegetive

+veinal

+veinlet

+veiny

+velamen

+velamentous

+velamina

+velarium

+veld

+velitation

+velleity

+veloce

+velocimeter

+velocimeter's

+velocimeters

+velocipede

+velodrome

+velopment

+velure

+velutinous

+velveteen

+venae

+venality

+venatic

+venation

+venational

+vendable

+vendace

+vendaces

+vendee

+vendibility

+vendibly

+vendition

+vendue

+veneeal

+venenate

+venenation

+venerability

+venerably

+venerator

+venereological

+venereologist

+venereology

+venerology

+venery

+venesection

+venetian

+venge

+venging

+venin

+venipuncture

+venire

+venireman

+venisection

+venography

+ventage

+ventail

+ventilatory

+ventless

+ventricose

+ventricular

+ventriculus

+ventriloquial

+ventriloquially

+ventriloquism

+ventriloquist

+ventriloquist's

+ventriloquistic

+ventriloquists

+ventriloquy

+ventrolateral

+ventrolaterally

+ventromedial

+ventura

+venturous

+venturously

+venturousness

+venule

+veratrine

+veratrum

+verbalism

+verbalist

+verbalistic

+verbena

+verbenas

+verbicide

+verbid

+verbify

+verbigeration

+verbile

+verdancy

+verderor

+verdigris

+verdin

+verdurous

+verdurousness

+vergil

+veridic

+veridicality

+verisimilar

+verisimilarly

+verisimilitudinous

+verism

+verismo

+verist

+veristic

+veritably

+verjuice

+vermeil

+vermian

+vermicelli

+vermicide

+vermicular

+vermiculate

+vermiculated

+vermiculation

+vermiform

+vermifuge

+vermillion

+verminosis

+verminous

+verminously

+vern

+vernacle

+vernacularism

+vernation

+vernicle

+vernissage

+versal

+verseman

+verset

+versicle

+versicular

+versification

+versifier

+versify

+versine

+versional

+verso

+versos

+verticality

+verticil

+verticillte

+vertiginous

+vertiginously

+vesical

+vesicant

+vesicate

+vesication

+vesicularity

+vesiculate

+vesiculation

+vesperal

+vespertinal

+vespertine

+vespiary

+vespid

+vespine

+vesta

+vestee

+vestiary

+vestibular

+vestlike

+vestment

+vestmental

+vestryman

+vesuvian

+vesuvianite

+vetchling

+vetted

+vexillary

+vexillologic

+vexillological

+vexillologist

+vexillology

+vexillum

+viand

+viands

+viaticum

+vibist

+vibraharp

+vibraharpist

+vibrance

+vibraphone

+vibraphonist

+vibratile

+vibratility

+vibrational

+vibrationless

+vibrator

+vibratory

+vibrion

+vibriosis

+vibrissa

+vibrissae

+viburnum

+vic

+vicarage

+vicarate

+vicarial

+vicariate

+vicarship

+vicegerency

+vicegerent

+vicennial

+viceregal

+viceregally

+vicereine

+viceroyalty

+viceroyship

+vichyssoise

+vicinage

+vicinal

+vicissitudinous

+vickers

+victress

+vicuna

+vidal

+vide

+videophone

+vidette

+vidicon

+viduity

+viewfinder

+viewfinder's

+viewfinders

+viewy

+vigesimal

+vigintillion

+vignettist

+vigorish

+vigorist

+vigorist's

+vigorists

+vigoroso

+vilipend

+villadom

+villagery

+villainess

+villanella

+villanelle

+villatic

+villein

+villenage

+villi

+villiform

+villosity

+villus

+vim

+vimen

+vinaceous

+vinaigrette

+vinal

+vinblastine

+vinca

+vincible

+vincristine

+vinculum

+vindicable

+vindicator

+vindicators

+vindicatory

+vineal

+vinedresser

+vinedressers

+vinegarish

+vinegarroon

+vinegary

+vinery

+vineyardist

+vinic

+viniculture

+vinier

+viniferous

+vinification

+vino

+vinosity

+vinous

+vinously

+viny

+vinylic

+vinylidene

+viol

+violability

+violable

+violableness

+violably

+violaceous

+violaceously

+violist

+viomycin

+viosterol

+viperine

+viperish

+viperous

+viperously

+viraginous

+virago

+virelay

+viremia

+viremic

+vireo

+vires

+virescence

+virescent

+virga

+virgate

+virginium

+virgulate

+viricidal

+viricide

+virid

+viridescent

+viridian

+viridity

+virilism

+virion

+virologic

+virological

+virologically

+virologist

+virology

+viroses

+virosis

+virtuality

+virtueless

+virtuosa

+virtuosic

+virucidal

+virucide

+virulency

+viruliferous

+virustatic

+viscacha

+viscerogenic

+visceromotor

+viscidity

+viscometric

+viscometry

+viscose

+viscosimeter

+viscosimeter's

+viscosimeters

+viscosimetric

+viscountcy

+viscountess

+viscounty

+viscus

+visional

+visionally

+visionless

+visitable

+visitant

+visitational

+visitatorial

+visorless

+vitalism

+vitalist

+vitalistic

+vitamer

+vitameric

+vitellin

+vitelline

+vitellogenesis

+vitellus

+vitiator

+viticultural

+viticulture

+viticulturist

+vitiligo

+vitiosity

+vitite

+vitrifiable

+vitrine

+vittae

+vittate

+vittles

+vituperate

+vituperation

+vituperator

+vituperatory

+vitus

+vivarium

+viverrid

+vivific

+viviparity

+viviparous

+viviparously

+viviparousness

+vivisect

+vivisection

+vivisectional

+vivisectionally

+vivisectionist

+vivisector

+vixenish

+vixenishly

+vixenishness

+vizard

+vizierate

+vizierial

+viziership

+vizor

+vms

+vocabular

+vocalically

+vocality

+vocationalism

+vocationalist

+vociferant

+vociferate

+vociferation

+vociferator

+voguish

+voguishness

+voicedness

+voiceful

+voicefulness

+voiceprint

+voidable

+voidableness

+voidance

+voile

+volant

+volante

+volcanically

+volcanicity

+volcanoes

+volcanologic

+volcanological

+volcanologist

+volcanology

+vole

+voles

+volitive

+volkslied

+volkslieder

+volplane

+volplaned

+volplaning

+voltameter

+voltameter's

+voltameters

+voltametric

+volubility

+volubly

+volumeter

+volumeter's

+volumeters

+voluminosity

+voluntarism

+voluntarist

+voluntaristic

+voluntaryism

+voluntaryist

+volunteerism

+voluptuary

+volute

+voluted

+volutin

+volution

+volva

+volvement

+volvox

+vomerine

+vomitory

+vomiturition

+vomitus

+von

+voodooism

+voodooist

+voodooistic

+vored

+vortical

+vortically

+vorticella

+vorticism

+vorticist

+vorticose

+vortiginous

+votaress

+votarist

+voteless

+votress

+vouchee

+vouchsafement

+voussoir

+voyageur

+voyageurs

+voyeur

+voyeurism

+voyeuristic

+voyeuristically

+voyeurs

+vroom

+vs

+vulcanian

+vulcanicity

+vulcanologist

+vulcanology

+vulgarian

+vulgarism

+vulgarity

+vulgate

+vulgus

+vulnerably

+vulnerary

+vulterine

+vulturine

+vulturous

+vulva

+vulvae

+vulval

+vulvar

+vulviform

+vulvitis

+wackily

+wadable

+wadder

+waddie

+waddied

+waddies

+wadding

+waddy

+waddying

+wadeable

+wadi

+waftage

+wafture

+wageless

+wageworker

+wagger

+waggery

+waggly

+wagoneer

+wagoneer's

+wagoneers

+wagonette

+wagonette's

+wagonettes

+wagonload

+wagonload's

+wagonloads

+wah

+wahine

+wahoo

+wahoos

+waif

+wailful

+wailfully

+wain

+wained

+wainscotting

+waistband

+wakeless

+wakerobin

+walkabout

+walkaway

+walkingstick

+walkout

+wallaroo

+wallenstein

+walleye

+walleyed

+wallflower

+wamble

+wambled

+wambling

+wampum

+wanderlust

+waney

+wanier

+wanner

+wannest

+wanning

+wansee

+wansley

+wany

+warbonnet

+wardenship

+wardership

+wardress

+wardship

+warehousemen

+wareroom

+warlock

+warlord

+warlordism

+warlords

+warpage

+warpath

+warplane

+warplane's

+warplanes

+warrantable

+warrantableness

+warrantably

+warrantee

+warrantees

+warrantless

+warrantor

+warrantors

+washability

+washable

+washcloth

+washerman

+washerwoman

+washhouse

+washoe

+washrag

+washroom

+washrooms

+washstand

+washstands

+washtub

+washtubs

+washwoman

+wasplike

+wassail

+wassailer

+wast

+wastage

+wastages

+wastepaper

+watchcase

+watcheye

+watchtower

+watchworks

+waterborne

+watercraft

+watercress

+waterflood

+waterfowl

+waterfowl's

+waterfowler

+waterhole

+waterhole's

+waterholes

+waterily

+waterish

+waterishness

+waterless

+waterlessly

+waterlessness

+waterlog

+waterlogged

+watermanship

+watermark

+waterpower

+waterscape

+waterweed

+waterwheel

+waterworks

+waterworn

+wattmeter

+wattmeter's

+wattmeters

+waught

+waukesha

+waunona

+waupaca

+waupun

+wausau

+wauwatosa

+waveland

+waveless

+wavelessly

+wavelet

+wavelets

+wavelike

+wavery

+wavily

+waxlike

+waxwing

+waxwing's

+waxwings

+waybill

+wayfarer

+wayfaring

+waygoing

+waylay

+wayless

+wayworn

+weakhearted

+weakish

+weakling

+weal

+wealthily

+weanling

+wearability

+weariful

+wearifully

+wearifulness

+weariless

+wearilessly

+weatherability

+weatherboard

+weatherboarding

+weatherglass

+weatherman

+weatherstripping

+weatherworn

+weathery

+webbed

+webber

+webby

+webfoot

+weblike

+wedder

+wedgy

+weedless

+weeknight

+weeknights

+weepy

+weet

+weever

+weevil

+weevilly

+weevily

+weft

+wefts

+weider

+weidman

+weighable

+weightily

+weightless

+weightlessly

+weimaraner

+weiner

+weir

+weirdie

+weirdies

+weldable

+weldment

+weldor

+weldwood

+welfarism

+welfarist

+welkin

+wellaway

+wellborn

+wellhead

+wellington

+wellman

+wellwisher

+wellwisher's

+wellwishers

+welmers

+weltschmerz

+wen

+wend

+wert

+weskit

+westernmost

+wetback

+wettable

+wettish

+wff

+whacky

+whaleback

+whaleboat

+whalebone

+whalebone's

+whalebones

+whang

+whangee

+whap

+wharfage

+wharfinger

+wharfmaster

+whats

+wheal

+wheatear

+wheatland

+wheaton

+wheelbarrow

+wheelbarrow's

+wheelhorse

+wheelless

+wheelman

+wheelock

+wheelsman

+wheelwork

+wheelwright

+wheen

+wheezily

+whelm

+whenas

+whencesoever

+whensoever

+whereat

+wherefrom

+whereinto

+whereness

+wheres

+wheresomever

+wherethrough

+whereto

+whereunto

+wherewithal

+wherries

+wherry

+whetstone

+whetter

+whichsoever

+whicker

+whickered

+whickering

+whidding

+whiffletree

+whigmaleerie

+whilom

+whilst

+whimsicality

+whiney

+whinstone

+whipcord

+whiplike

+whippersnapper

+whippier

+whippletree

+whippoorwill

+whippy

+whipstitch

+whipstock

+whirlybird

+whirried

+whirry

+whirrying

+whish

+whisht

+whiskery

+whispery

+whist

+whitebait

+whitebeard

+whitecap

+whitefish

+whiteleaf

+whiteley

+whiteout

+whitesmith

+whitethroat

+whitewall

+whitewater

+whitewing

+whithersoever

+whitherward

+whitish

+whity

+whizbang

+whizz

+whizzbang

+whizzer

+whomp

+whoopee

+whoopla

+whopper

+whoredom

+whorehouse

+whoremaster

+whoremonger

+whoreson

+whorish

+whort

+whortle

+whosesoever

+whoso

+whump

+whup

+whys

+wickerwork

+wickiup

+widemouthed

+widgeon

+widgeons

+widish

+widowerhood

+widthways

+wieland

+wieldy

+wienerwurst

+wienie

+wifehood

+wifeless

+wifelike

+wigan

+wigeon

+wigeons

+wigged

+wight

+wiglet

+wigwag

+wilco

+wildcatted

+wildcatting

+wildebeest

+wildebeest's

+wilderment

+wildflower

+wildflower's

+wildflowers

+wildfowl

+wildfowler

+wildfowling

+wildish

+wildling

+wildwood

+willable

+willemite

+willet

+willies

+williwaw

+willowlike

+willowware

+willpower

+willy

+willying

+wilmette

+wimble

+wimbled

+wimbles

+wimbling

+wimple

+wimpled

+wimpling

+winchell

+windage

+windblown

+windburn

+windburned

+windflaw

+windily

+windjammer

+windlass

+windlassed

+windlasses

+windlassing

+windlassly

+windpipe

+windproof

+windscreen

+windsurf

+windsurfed

+windsurfing

+windsurfs

+windswept

+windway

+wineglass

+winegrower

+winehead

+winepress

+wineshop

+winey

+wingbeat

+wingbeat's

+wingbeats

+wingding

+wingless

+winglessness

+winglet

+winglike

+wingover

+wingspread

+wingspread's

+wingspreads

+wingy

+winism

+winnable

+winnebago

+winned

+winooski

+winsett

+wintergreen

+winterkill

+wintertide

+wintery

+wintle

+wintrily

+winze

+wirable

+wiredraw

+wiredrawer

+wiredrawn

+wirehair

+wirehaired

+wirelike

+wiretapper

+wireway

+wirework

+wireworks

+wireworm

+wirily

+wisent

+wisewoman

+wisha

+wispish

+wistaria

+wisteria

+witchery

+witchlike

+witchy

+withdrawable

+withe

+witherite

+witherspoon

+withies

+withindoors

+withoutdoors

+withy

+witless

+witling

+witted

+witticism

+wittily

+wiz

+wizardry

+wolfhound

+wolflike

+wolverine

+wolverine's

+wolverines

+wolverton

+womanish

+womanishly

+womanishness

+womankind

+womanless

+womanlike

+womanpower

+wombat

+wombat's

+wombats

+womenfolk

+womenfolks

+womenkind

+wonderwork

+wonky

+wonning

+wonton

+woodberry

+woodcraft

+woodcutter

+woodcutting

+woodenhead

+woodenheaded

+woodenware

+woodlore

+woodnote

+woodpile

+woodsman

+woodsy

+woolie

+woolpack

+woolsack

+woolshed

+woolskin

+woops

+woozier

+woozily

+wooziness

+woozy

+wordage

+wordages

+wordbook

+wordless

+wordlessness

+wordmonger

+wordplay

+workability

+workbasket

+workboat

+workbox

+workfolk

+workfolks

+workforce

+workforce's

+workforces

+workhouse

+workless

+worklessness

+workpeople

+workroom

+workrooms

+workweek

+workwoman

+worldling

+wormhole

+wormlike

+worriment

+worrywart

+worshipless

+wort

+worthful

+worthily

+wotted

+wouldst

+woundless

+woundwort

+wowser

+wrack

+wracked

+wracks

+wraiths

+wrapup

+wrasse

+wrathy

+wreathy

+wriggly

+wristlet

+wristlock

+wristy

+writeup

+writeup's

+writeups

+writhen

+wrongheaded

+wrongheadedly

+wrongheadedness

+wunderkind

+wysiwyg

+xanthate

+xanthene

+xanthic

+xanthin

+xanthine

+xenia

+xenomania

+xenophile

+xenophilous

+xenophobe

+xenophobic

+xerarch

+xeric

+xerically

+xerographic

+xerographically

+xerophile

+xerophilous

+xerophily

+xylophonist

+xylose

+xylotomic

+xylotomical

+xylotomous

+xylotomy

+yack

+yacking

+yah

+yak

+yakking

+yalies

+yam

+yamen

+yardarm

+yardbird

+yardman

+yardmaster

+yare

+yarely

+yarmelke

+ycleped

+yclept

+ye

+yearling

+yearlong

+yeastily

+yellerish

+yep

+yester

+yeuk

+yew

+yoghurt

+yoghurt's

+yogic

+yogin

+yoknapatawpha

+yolky

+yond

+youngling

+yuba

+yuletide

+yuri

+zabaglione

+zagged

+zanier

+zanies

+zanily

+zaniness

+zany

+zazen

+zealotry

+zeffirelli

+zenithal

+zeolite

+zeolitic

+zephyr

+zeppelin

+ziggy

+zillion

+zincate

+zincic

+zinfandel

+zingier

+zingy

+zinnia

+zippier

+zippy

+zirconia

+zirconic

+zither

+zitherist

+zithers

+zizith

+zoantharian

+zoarial

+zoarium

+zobrist

+zombi

+zombiism

+zonate

+zonated

+zonation

+zonked

+zoogenic

+zoogenous

+zoogeographer

+zoogeographic

+zoogeography

+zooks

+zoologic

+zoomorphic

+zoonosis

+zoonotic

+zooparasite

+zooparasitic

+zoophagous

+zoophilic

+zoophilous

+zoophyte

+zoophytic

+zooplankton

+zoosporal

+zoospore

+zoosterol

+zootechnics

+zori

+zucchini

+zwitterion

+zwitterionic

+zwitterions

+zygote

+zygote's

+zygotes

diff --git a/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.3 b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.3
new file mode 100644
index 0000000..4ecbceb
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/main/resources/org/apache/tapestry/test/english.3
@@ -0,0 +1,19708 @@
+AAU

+AKA

+APS

+Aachen

+Aalborg

+Aalesund

+Aargau

+Aaronic

+Abba

+Abbado

+Abbevillian

+Abbeydale

+Abelard

+Abele

+Abelmosk

+Abernethy

+Aberystwyth

+Abravanel

+Abraxas

+Absalom

+Abu

+Abyssinian

+Acarus

+Accrington

+Aceldama

+Achaemenid

+Achates

+Achernar

+Achitophel

+Acis

+Actinia

+Actium

+Adamite

+Adar

+Addams

+Addington

+Adenauer

+Adige

+Adonai

+Adonic

+Adullamite

+Advowson

+Aedes

+Aegeus

+Aegina

+Aegisthus

+Aeolic

+Aeolipile

+Aeolis

+Aepyornis

+Aeschines

+Aesculapian

+Aesculapius

+Aesir

+Aetolia

+Affenpinscher

+Africanism

+Africanist

+Afrikander

+Afrikanerdom

+Agama

+Agapanthus

+Ageratum

+Agincourt

+Aglaia

+Agostini

+Agra

+Agrapha

+Agrippa

+Aguascalientes

+Ahasuerus

+Ahmednagar

+Ahriman

+Ahvenanmaa

+Ahwaz

+Aidan

+Aidin

+Aileen

+Akan

+Akhmatova

+Akkad

+Akkadian

+Akmolinsk

+Aktyubinsk

+Alamein

+Alaric

+Albi

+Albigenses

+Albinoni

+Albion

+Alboin

+Albury

+Alcman

+Alcock

+Alcoran

+Alcyone

+Aldermaston

+Alderney

+Aldine

+Aldus

+Aleksandropol

+Aleksandrovsk

+Alemanni

+Alemannic

+Aleppo

+Alexandrian

+Alexius

+Algerine

+Algonkian

+Alkoran

+Allahabad

+Allenby

+Allende

+Allhallowtide

+Almeida

+Almohade

+Almoravide

+Alsatia

+Altaic

+Altamira

+Altrincham

+Amaryllis

+Amati

+Amboina

+Ambrosian

+Ameling

+Americanist

+Amerigo

+Amerindian

+Amersfoort

+Ameslan

+Amfortas

+Amish

+Ammonites

+Amoy

+Ampelopsis

+Amphitrite

+Amphitryon

+Amritsar

+Amundsen

+Amytal

+Anabaena

+Anabas

+Anableps

+Anacreontic

+Anam

+Ananias

+Anchises

+Ancona

+Andaman

+Andhra

+Angara

+Angarsk

+Angelus

+Angevin

+Angkor

+Anglesey

+Anglian

+Anglicist

+Anglomania

+Anglophone

+Anguilla

+Anjou

+Annam

+Annamese

+Annapurna

+Anopheles

+Anouilh

+Ansermet

+Antarctic

+Anthurium

+Antigonus

+Antigua

+Anubis

+Anzac

+Aphis

+Apis

+Apollyon

+Apus

+Arabist

+Arafat

+Araiza

+Aramaic

+Araucanian

+Araucaria

+Arawakan

+Arbela

+Arcadic

+Archaeopteryx

+Archaeornis

+Archean

+Archilochian

+Arctic

+Arctogaea

+Areca

+Areopagus

+Ares

+Arethusa

+Argerich

+Argyrol

+Arian

+Ariel

+Aristides

+Aristippus

+Arius

+Arkhangelsk

+Arkhipova

+Arlberg

+Arminian

+Arrau

+Arroyo

+Arthurian

+Asarum

+Ascanius

+Ascensiontide

+Aschaffenburg

+Ascham

+Asclepiadean

+Asclepius

+Ashanti

+Ashford

+Ashkenazi

+Ashkenazy

+Ashkhabad

+Ashmore

+Ashton

+Ashur

+Asimov

+Aspasia

+Assamese

+Assisi

+Astilbe

+Aten

+Athanasian

+Atherton

+Atlantean

+Atlantov

+Attenborough

+Attila

+Aubergine

+Aubervilliers

+Aubrietia

+Aubusson

+Auger

+Augsburg

+Augustinian

+Aurignacian

+Aussie

+Auster

+Austerlitz

+Australasia

+Australiana

+Australianism

+Australoid

+Australorp

+Austrasia

+Austronesia

+Austronesian

+Autoharp

+Avar

+Averroism

+Avestan

+Axminster

+Aymara

+Ayrshire

+Azerbaijani

+Azilian

+Azotobacter

+Azov

+Azrael

+BBC

+BCPL

+BNF

+Baal

+Baalbek

+Baaskap

+Bab

+Babi

+Babism

+Bacchae

+Bacharach

+Bacquier

+Bactrian

+Baedeker

+Baganda

+Bagdad

+Bahai

+Bahaism

+Bahrain

+Bairam

+Baker

+Bala

+Balaam

+Balakirev

+Balaklava

+Balaton

+Balearic

+Balkis

+Balmacaan

+Balmoral

+Balt

+Balthazar

+Baltsa

+Baluchi

+Baluchistan

+Bambara

+Bamberg

+Banda

+Banff

+Bank

+Bannockburn

+Bantoid

+Bantustan

+Banville

+Barabbas

+Barathea

+Barbarossa

+Barbary

+Barber

+Barbirolli

+Barbuda

+Barcoo

+Bardolatry

+Barenboim

+Bari

+Barmecide

+Barotse

+Barsac

+Bart

+Bartoletti

+Bashkir

+Basilian

+Basingstoke

+Baskerville

+Bassas

+Bastianini

+Basutoland

+Bataan

+Bathonian

+Battenburg

+Battle

+Baudo

+Bauhinia

+Bax

+Bayard

+Beaconsfield

+Beaufort

+Beaune

+Bebington

+Bechuana

+Bechuanaland

+Beckenham

+Beckford

+Beckmann

+Bedfordshire

+Bedlington

+Beghard

+Beguin

+Behrens

+Belgae

+Belgravia

+Belial

+Belisarius

+Belisha

+Belleek

+Bellerophon

+Bellingshausen

+Bellmouth

+Bellona

+Belmondo

+Belorussia

+Belostok

+Belsen

+Beltane

+Bemba

+Benackova

+Benedictus

+Benedikt

+Beni

+Benin

+Benison

+Benne

+Bennet

+Berber

+Berberis

+Berbie

+Berchtesgaden

+Berdichev

+Berdyayev

+Berenson

+Berezina

+Berezniki

+Berg

+Bergama

+Bergamo

+Berganza

+Berger

+Bergonzi

+Bergsonism

+Berkeleian

+Berkeleianism

+Bernese

+Bessarabia

+Bethany

+Bethmann

+Betta

+Beulah

+Beveridge

+Bewick

+Bice

+Biedermeier

+Bielefeld

+Bihari

+Biisk

+Bilharzia

+Billingham

+Billingsgate

+Billiton

+Bim

+Birkenhead

+Bishop

+Blachut

+Blackbeard

+Blagoveshchensk

+Blanzat

+Blavatsky

+Blech

+Blegen

+Bley

+Blindheim

+Blini

+Bliss

+Blomstedt

+Bloomsbury

+Boanerges

+Boatwright

+Boche

+Bodoni

+Bogas

+Bohm

+Boildieu

+Boito

+Bokhara

+Bolshie

+Bolson

+Boltonia

+Bonapartism

+Bonynge

+Bordelaise

+Borghese

+Borodin

+Boronia

+Bosky

+Bosnia

+Bougainville

+Boughton

+Boulez

+Boult

+Bournemouth

+Bouvet

+Bozcaada

+Braata

+Brachiosaurus

+Bragi

+Brahman

+Brahmana

+Brahmani

+Brahmanism

+Brahmin

+Brahui

+Brailler

+Braillers

+Braillewriters

+Brantford

+Breconshire

+Bremerhaven

+Brendel

+Brentano

+Brentwood

+Brescia

+Breslau

+Bresson

+Bretagne

+Bretton

+Breuer

+Breughel

+Briareus

+Bridgeford

+Bridgeman

+Bright

+Brigid

+Britannia

+Briticism

+Britishism

+Brixton

+Brno

+Broadbrim

+Bromberg

+Brown

+Bruch

+Brule

+Brummagem

+Brunei

+Brunelle

+Bruson

+Brutus

+Bryansk

+Brython

+Brythonic

+Bubo

+Bucephalus

+Buchmanism

+Buckingham

+Buckinghamshire

+Buddleia

+Buenaventura

+Bueno

+Bulgar

+Bumbledom

+Buna

+Bundaberg

+Bundoora

+Bundu

+Burberry

+Burgos

+Burgoyne

+Burkina

+Burseraceous

+Bushire

+Bute

+Buttermere

+Butterworth

+Bydgoszcz

+Byelorussian

+Byelostok

+CATV

+CB

+CCNY

+CEQ

+CGS

+CO

+Caballe

+Cabinda

+Caddoan

+Cadmean

+Cadmus

+Caelian

+Caelum

+Caernarvonshire

+Caerphilly

+Caesarean

+Caesarism

+Cahokia

+Caicos

+Calabar

+Caladium

+Calciferous

+Caledonia

+Caledonian

+Caliban

+Calicut

+Callas

+Calliopsis

+Calvados

+Calvinism

+Calydonian

+Cambridgeshire

+Camelopardus

+Camenae

+Cana

+Canaanite

+Canaanitic

+Canadianism

+Candace

+Candiot

+Candlemas

+Canicula

+Canopic

+Canossa

+Cantabrian

+Canuck

+Capablanca

+Cape

+Capernaum

+Capetian

+Capone

+Cappuccilli

+Capri

+Capricornus

+Capsian

+Caravaggio

+Carbonari

+Cardiganshire

+Caribbee

+Carlist

+Carlovingian

+Carman

+Carmarthenshire

+Carmel

+Carmelite

+Carpathian

+Carreras

+Carrick

+Carteri

+Carthaginian

+Carthusian

+Cartier

+Caslon

+Caspar

+Casparian

+Caspian

+Cassegrainian

+Cassia

+Castalia

+Castilian

+Castilla

+Castleford

+Castlereagh

+Casuarina

+Catalan

+Cathay

+Cattleya

+Caucasoid

+Cavell

+Cavesson

+Cavetto

+Cavour

+Cawdrey

+Cawley

+Cawnpore

+Caxton

+Cayes

+Cayman

+Cayuse

+Ceanothus

+Cecrops

+Ceiba

+Celadon

+Celaeno

+Celeste

+Celtiberian

+Centaurus

+Central

+Cepheid

+Ceratodus

+Cercis

+Cerenkov

+Ceres

+Cete

+Chaco

+Chadderton

+Chailly

+Chalcis

+Chaldean

+Chaldee

+Cham

+Chamaeleon

+Chambertin

+Charlottenburg

+Charlottetown

+Charlton

+Charmeuse

+Charpentier

+Chartism

+Chasidim

+Chatterton

+Chaucerian

+Chechen

+Cheek

+Chellean

+Chelmsford

+Cheltenham

+Chelyabinsk

+Chelyuskin

+Chengchow

+Chengteh

+Chengtu

+Cheongsam

+Cheops

+Cherbourg

+Cheremiss

+Cheremkhovo

+Cherenkov

+Chernovtsy

+Chernozem

+Chertsey

+Cherubini

+Chessel

+Chesterfieldian

+Chetnik

+Cheval

+Chian

+Chibchan

+Chickasaw

+Chihuahua

+Childermas

+Chilean

+Chiltern

+Chilton

+China

+Chinee

+Chinookan

+Chionodoxa

+Chiron

+Chita

+Chkalov

+Chlorella

+Chloromycetin

+Chocho

+Choco

+Chrissie

+Christadelphian

+Christchurch

+Christhood

+Christmastide

+Christoff

+Christology

+Christophe

+Chukchi

+Chung

+Churrigueresque

+Chuvash

+Ciccolini

+Cicely

+Cid

+Cilician

+Cimbri

+Cimmerian

+Cinchona

+Cincinnatus

+Cinemascope

+Cineraria

+Cipango

+Circassian

+Circinus

+Cisalpine

+Cistercian

+Cistus

+City

+Clacton

+Clapham

+Clapton

+Clarabella

+Clarenceux

+Clarkia

+Claudel

+Claudius

+Clausewitz

+Claytonia

+Clematis

+Clementine

+Clemmons

+Cleome

+Cleopatra

+Cleve

+Clevenger

+Cliburn

+Clintonia

+Clipperton

+Clostridium

+Cluj

+Cluytens

+Clydesdale

+Coast

+Coatbridge

+Cobbett

+Cobham

+Cochin

+Cockaigne

+Cocos

+Cointreau

+Colchicum

+Colchis

+Colima

+Colleen

+Collier

+Collinsia

+Colloq

+Colobus

+Cologne

+Colossian

+Coltrane

+Columba

+Colwyn

+Comanchean

+Comintern

+Command

+Comoros

+Compositae

+Comptometer

+Comus

+Conferva

+Congreve

+Coniston

+Conium

+Convolvulus

+Cook

+Copland

+Coprosma

+Copt

+Coptic

+Coquille

+Coral

+Corantijn

+Cordelier

+Cordovan

+Coreopsis

+Corriedale

+Cortes

+Corvallis

+Corybant

+Corydalis

+Corydon

+Costa

+Costermansville

+Cotinga

+Cotrubas

+Couperin

+Courland

+Cousteau

+Cowell

+Cowichan

+Craal

+Cranfield

+Cressida

+Creston

+Cretic

+Crichton

+Crinum

+Croat

+Crockford

+Crompton

+Cronin

+Crookes

+Crookesmoor

+Crossley

+Crownland

+Cryptomeria

+Cuberli

+Culex

+Cumbrian

+Cundick

+Curculio

+Curcuma

+Curtana

+Curvet

+Cuscus

+Cushitic

+Cuthbert

+Cymric

+Cypripedium

+Cyrano

+Cyrenaic

+Cytherea

+Czechoslovak

+Czernowitz

+Czerny

+DMF

+DPP

+DWT

+Dagenham

+Dagestan

+Dago

+Daltonism

+Damara

+Damaraland

+Damascene

+Damien

+Damson

+Danaides

+Danegeld

+Danelaw

+Danio

+Danton

+Daphnis

+Dapsang

+Darby

+Dard

+Dardan

+Dardic

+Darien

+Darjeeling

+Darry

+Dartford

+Dartmoor

+Davidovich

+Deauville

+Deb

+Decembrist

+Deepfreeze

+Delian

+Delibes

+Delius

+Deller

+Delorme

+Delos

+Delsarte

+Demogorgon

+Demosthenes

+Denbighshire

+Dene

+Denis

+Dentalium

+Depraz

+Dernesch

+Derris

+Deuteronomist

+Deuteronomistic

+Deuteronomy

+Deutschland

+Deutzia

+Devereux

+Devonian

+Diablo

+Diamond

+Dictaphone

+Dictograph

+Didache

+Dieskau

+Dimitrovo

+Dinaric

+Dinesen

+Dingaan

+Dinka

+Dinnington

+Dinoceras

+Dione

+Dionysia

+Dionysiac

+Dioscuri

+Diplodocus

+Dirham

+Ditzel

+Djibouti

+Dneprodzerzhinsk

+Dnepropetrovsk

+Dniester

+Docetism

+Dodgson

+Dodona

+Doese

+Dohnanyi

+Dol

+Dolichosaurus

+Dominica

+Domitian

+Donar

+Donath

+Donatist

+Doncaster

+Donegal

+Donetsk

+Dongola

+Donizetti

+Dopper

+Dor

+Dorati

+Dorian

+Dorking

+Dormoy

+Doronicum

+Dowland

+Dowson

+Dracaena

+Draconic

+Drakensberg

+Drayton

+Dressen

+Dronfield

+Druse

+Duala

+Dubonnet

+Duisburg

+Dukas

+Dulcinea

+Dumbarton

+Dunbarton

+Dunker

+Dupre

+Duralumin

+Durban

+Durkheim

+Duroc

+Durufle

+Dutoit

+Duyker

+Dvandva

+Dvina

+Dvinsk

+Dvorsky

+Dyak

+Dyonisian

+Dzaudzhikau

+Dzerzhinsk

+Dzhambul

+Dziggetai

+Dzongka

+Dzungaria

+ECAD

+Eaglestone

+Eaglewood

+Eastbourne

+Eastertide

+Eastleigh

+Ebert

+Ecclesiastes

+Ecclesiasticus

+Echeveria

+Edda

+Eddington

+Edo

+Edomite

+Edwardine

+Efik

+Egbert

+Egeria

+Egham

+Egmont

+Ehrenburg

+Eichendorff

+Eiffel

+Eijkman

+Eikon

+Eilat

+Eindhoven

+Einkorn

+Eisenach

+Eisenstadt

+Eisenstein

+Eisteddfod

+Ekaterinburg

+Ekaterinodar

+Ekaterinoslav

+Elamite

+Elbert

+Eleatic

+Eleusinian

+Elfland

+Elgar

+Elia

+Elias

+Elisabethville

+Elisavetgrad

+Elisavetpol

+Ellesmere

+Ellice

+Ellington

+Elohim

+Elohist

+Elsass

+Elvira

+Emirates

+Emmenthal

+Emmet

+Emmy

+Empson

+Endamoeba

+Endrich

+Endymion

+Enesco

+Engel

+Englishism

+Englishry

+Entamoeba

+Eozoic

+Ephedra

+Ephemera

+Ephraimite

+Epigoni

+Episcopalism

+Equatorial

+Equisetum

+Erastianism

+Erechtheum

+Erechtheus

+Erenburg

+Erica

+Ericson

+Erin

+Eritrea

+Ermanaric

+Ermler

+Erse

+Erymanthian

+Escallonia

+Escherichia

+Escorial

+Esdras

+Eskilstuna

+Esperanto

+Esquiline

+Essene

+Estonian

+Eth

+Ethelbert

+Ethelred

+Ethiopian

+Eton

+Eucharis

+Euonymus

+Eupatorium

+Euphrosyne

+Euroclydon

+Eurocommunism

+Eurocrat

+Eurodollar

+Euromarket

+Eurovision

+Eurus

+Euryale

+Eurystheus

+Eustachian

+Euxine

+Everton

+Evertor

+Evesham

+Evonymus

+Ewing

+Excalibur

+Exmoor

+Exon

+FPS

+Fabianism

+Fabrikoid

+Factice

+Faisal

+Faizabad

+Falange

+Faliscan

+Falkirk

+Falkner

+Falla

+Falstaffian

+Fanti

+Fareham

+Farnborough

+Farnese

+Farnesol

+Farnham

+Faroe

+Faroes

+Farouk

+Farquhar

+Farrago

+Farthingale

+Fartlek

+Faruk

+Fassbaender

+Fassbinder

+Fathometer

+Fatimid

+Fatshan

+Faubourg

+Faure

+Fayal

+Fedoseyev

+Feigin

+Feisal

+Feme

+Fenian

+Fenice

+Fenrir

+Fergus

+Fernandi

+Ferrara

+Fescennine

+Feuchtwanger

+Feuerbach

+Feuilleton

+Fezzan

+Fianna

+Finnic

+Finsen

+Finsteraarhorn

+Firbank

+Flamig

+Flaminian

+Fleetwood

+Flensburg

+Fletcher

+Fletcherism

+Flintshire

+Flugelhorn

+Flysch

+Foism

+Foison

+Fokine

+Fokker

+Foochow

+Fornax

+Forrester

+Forsythia

+Fouquet

+Fourierism

+Fournet

+Fournier

+Francescatti

+Franck

+Franconia

+Franconian

+Francophile

+Francophobe

+Francophone

+Franglais

+Frankenstein

+Frankish

+Frauenfeld

+Fraunhofer

+Frazer

+Frazil

+Freccia

+Freda

+Fredericia

+Frederiksberg

+Fredrikstad

+Freesia

+Freiburg

+Frenchy

+Freni

+Frescobaldi

+Freytag

+Fribourg

+Fricandeau

+Friesian

+Frigg

+Frijol

+Frisch

+Frisco

+Friuli

+Friulian

+Frizette

+Frobisher

+Froment

+Ft

+Fuegian

+Fulham

+Futuna

+Fyzabad

+Gadarene

+Gael

+Gaeltacht

+Gagarin

+Gaia

+Gainsborough

+Galago

+Galenic

+Galenical

+Galenism

+Galibi

+Galician

+Galla

+Gallic

+Gallican

+Gallicanism

+Gallicism

+Galton

+Galwegian

+Gambeson

+Gambetta

+Gambier

+Gamboge

+Ganda

+Gandhiism

+Ganga

+Garamond

+Gargantua

+Garrya

+Garth

+Gascon

+Gaspar

+Gates

+Gatha

+Gaucho

+Gaulish

+Gaullism

+Gaullist

+Gaultheria

+Gaza

+Gedda

+Gehenna

+Geisel

+Geissler

+Gelderland

+Gelsemium

+Gelsenkirchen

+Gemara

+Gencer

+Gendron

+Genevan

+Genf

+Genfersee

+Genghis

+Genoese

+Genova

+Gentoo

+Geordie

+Georgette

+Germanism

+Germanophile

+Germanophobe

+Gethsemane

+Geum

+Gharial

+Gharry

+Ghaut

+Ghazi

+Ghazzah

+Gheber

+Gherao

+Ghiaurov

+Ghiberti

+Ghibli

+Ghillie

+Ghirlandaio

+Ghitalla

+Giacometti

+Gibeonite

+Gielgud

+Gierek

+Giessen

+Gigout

+Gilbertian

+Gileadite

+Gilels

+Gillingham

+Gippsland

+Gippy

+Giraud

+Giraudoux

+Gisborne

+Giscard

+Giulini

+Giulio

+Glagolitic

+Glazunov

+Glengarry

+Glickman

+Glinka

+Globigerina

+Glorioso

+Gloucestershire

+Gloxinia

+Gluck

+Gobbi

+Gobelin

+Godesberg

+Godetia

+Godiva

+Godolphin

+Godspeed

+Godthaab

+Godunov

+Goebbels

+Goidel

+Golconda

+Goldmark

+Golgi

+Golgotha

+Gomberg

+Gond

+Gondi

+Gondwanaland

+Gongorism

+Goop

+Gorcock

+Gorgonzola

+Gorki

+Gorlovka

+Goshen

+Gosplan

+Goth

+Gotha

+Gothenburg

+Gotland

+Goucher

+Gounod

+Goya

+Graafian

+Graben

+Gracchus

+Graeae

+Graffman

+Graian

+Granth

+Grecism

+Green

+Greenham

+Gregorian

+Greisen

+Grenada

+Grenadines

+Gretna

+Grieg

+Grierson

+Griffe

+Griffiths

+Griffon

+Grig

+Grigioni

+Grignard

+Grikwa

+Grindelia

+Griqua

+Griqualand

+Grison

+Grolier

+Grundheber

+Grus

+Guadeloupe

+Guarani

+Guernica

+Guernsey

+Guerrero

+Guevara

+Guido

+Guildford

+Guillaume

+Guillou

+Guinea

+Guinness

+Gurmukhi

+Gurzenich

+Gypsophila

+Habsburg

+Haddington

+Hadith

+Haematoxylon

+Hagegard

+Hagiographa

+Haida

+Hainan

+Haitink

+Hakea

+Hallamshire

+Halle

+Hallowmas

+Hallstatt

+Halpern

+Hamite

+Hamitic

+Handley

+Hansard

+Hanseatic

+Hanuman

+Hanyang

+Hardenberg

+Hardy

+Hargreaves

+Haringey

+Harl

+Harlow

+Harmsworth

+Harper

+Harrild

+Harrovian

+Hathor

+Hauptmann

+Haversian

+Hawick

+Heard

+Heaviside

+Hebraism

+Hebraist

+Hebron

+Heifetz

+Helgoland

+Helianthus

+Heligoland

+Heliogabalus

+Helios

+Helladic

+Hellas

+Helldiver

+Helleborine

+Hellenism

+Hellenist

+Hellenistic

+Helvetia

+Helvetian

+Helvetic

+Helvetii

+Hemmings

+Henie

+Henryson

+Henslowe

+Henze

+Hephaestus

+Heptateuch

+Heraclid

+Herat

+Hercynian

+Herefordshire

+Herero

+Hermaphroditus

+Hertford

+Hertfordshire

+Hertzian

+Herzegovina

+Herzl

+Herzog

+Hesione

+Hesperia

+Hesperian

+Hesperides

+Hesychast

+Het

+Heteroousian

+Hexateuch

+Heynis

+Heysham

+Hezekiah

+Hialeah

+Hibernicism

+Hickox

+Hideyoshi

+Hieland

+Hilary

+Hildesheim

+Himyarite

+Himyaritic

+Hinayana

+Hindemith

+Hindenburg

+Hippeastrum

+Hippocrene

+Hippolytus

+Hippomenes

+Hirudin

+Hispania

+Hispanicism

+Hispaniola

+Hittite

+Hobbism

+Hochheimer

+Hocktide

+Hodgson

+Hoene

+Hofmann

+Hohenzollern

+Hollandia

+Holliday

+Holliger

+Hom

+Homoiousian

+Hong

+Honiton

+Horatian

+Horatius

+Horenstein

+Horne

+Hortense

+Hosta

+Houdan

+Houstonia

+Howland

+Hoya

+Huddersfield

+Huddleston

+Hudibrastic

+Huguenot

+Humperdinck

+Hunnish

+Huntingdonshire

+Hussite

+Huybrechts

+Hyacinthus

+Hydrastis

+Hydroski

+Hydrus

+Hygeia

+Hynninen

+Hyoscyamus

+Hypnos

+Hyson

+ISSN

+Iapetus

+Ibo

+Ibrahim

+Icaria

+Icarian

+Iceni

+Ichthyornis

+Ido

+Idomeneus

+Ignatius

+Igorot

+Iguanodon

+Ijssel

+Ijsselmeer

+Ilford

+Ilkeston

+Illyrian

+Imai

+Immanuel

+Immelmann

+Immingham

+Impatiens

+Inbal

+Ind

+Indiaman

+Indic

+Indologist

+Indris

+Ingush

+Inkerman

+Innuit

+Inselberg

+Intelsat

+Interisland

+Invar

+Ionesco

+Ionia

+Ionian

+Ipomoea

+Ireton

+Irishism

+Irkutsk

+Irons

+Iroquoian

+Isbn

+Iscariot

+Ishmael

+Ishmaelite

+Ishtar

+Isidore

+Iskander

+Iskenderun

+Islington

+Ismaili

+Isocheim

+Italia

+Ivanovo

+Ivanovsky

+Ives

+Ivory

+Ixia

+Ixion

+Ixtaccihuatl

+Izhevsk

+Iztaccihuatl

+JCL

+Jabalpur

+Jabir

+Jabiru

+Jaborandi

+Jacaranda

+Jacobin

+Jacquard

+Jadotville

+Jaga

+Jahvist

+Jain

+Jainism

+Jamesian

+Janacek

+Janiculum

+Janigro

+Janowitz

+Jansenism

+Jap

+Japheth

+Japhetic

+Jarvi

+Jarvis

+Jat

+Jehovist

+Jemmy

+Jena

+Jenghis

+Jenner

+Jephthah

+Jeremiad

+Jersey

+Jervis

+Jespersen

+Jesselton

+Jesu

+Jethro

+Jetton

+Jewess

+Jewry

+Jezebel

+Jezreel

+Joab

+Jocasta

+Jochum

+Jodo

+Johnsonian

+Joinville

+Jolson

+Jonah

+Jonson

+Jotunheim

+Juantorena

+Jubbulpore

+Judaea

+Judah

+Judaic

+Juilliard

+Juliana

+Jumada

+Juneberry

+Junius

+Junoesque

+Jylland

+KWIC

+KWOC

+Kaaba

+Kabaka

+Kabyle

+Kaffir

+Kaffraria

+Kafir

+Kaiserslautern

+Kalahari

+Kalevala

+Kalmuck

+Kamu

+Kanaka

+Kanarese

+Kanawa

+Kandinsky

+Kanji

+Kapfenberg

+Karaite

+Karajan

+Karakul

+Karczykowski

+Karelian

+Karloff

+Karlovy

+Karlsbad

+Karlsruhe

+Karnak

+Karpov

+Karri

+Karst

+Kasha

+Kashmiri

+Kaspszyk

+Katrine

+Keeling

+Keewatin

+Keighley

+Keijo

+Kelson

+Kempff

+Kennelly

+Kennington

+Kentish

+Kerenski

+Kermanshah

+Kertesz

+Keswick

+Keynesianism

+Khabarovsk

+Khachaturian

+Khaddar

+Khakass

+Khakis

+Khalid

+Khalif

+Khalkha

+Khalkidiki

+Khama

+Khamsin

+Khanate

+Khanga

+Khania

+Kharif

+Kharkov

+Khat

+Khayal

+Khedive

+Khelat

+Kherson

+Khieu

+Khingan

+Khirbet

+Khiva

+Khoikhoi

+Khoisan

+Khojent

+Khotan

+Khufu

+Khulna

+Khuskhus

+Khyber

+Kiaat

+Kiang

+Kiangsi

+Kiangsu

+Kiaochow

+Kibitka

+Kiblah

+Kidderminster

+Kielce

+Kier

+Kierkegaard

+Kieselguhr

+Kif

+Kikoi

+Kikumon

+Kilauea

+Kildare

+Kilderkin

+Kilkenny

+Killarney

+Killick

+Killiecrankie

+Killifish

+Killikinick

+Kilmarnock

+King

+Kingdom

+Kingman

+Kinnock

+Kinross

+Kinshasa

+Kirchhoff

+Kirghiz

+Kiribati

+Kirigami

+Kirin

+Kirkby

+Kirkcaldy

+Kirkcudbright

+Kirkman

+Kirkuk

+Kirkwall

+Kirman

+Kirmess

+Kirovabad

+Kirovograd

+Kirshbaum

+Kiruna

+Kirundi

+Kisangani

+Kish

+Kishinev

+Kishke

+Kismayu

+Kissel

+Kissin

+Kissinger

+Kist

+Kistna

+Kisumu

+Kitts

+Kizil

+Klagenfurt

+Klangfarbe

+Klansman

+Klausenburg

+Klee

+Kleiber

+Kleist

+Klemperer

+Klimt

+Klipspringer

+Klondike

+Kneller

+Knesset

+Knighthead

+Kniplova

+Knobkerrie

+Knussen

+Koblenz

+Kodaly

+Koestler

+Koheleth

+Kohima

+Kohl

+Kohn

+Kohoutek

+Kokand

+Kokanee

+Kokobeh

+Kokoschka

+Kolhapur

+Kolinsky

+Kollo

+Kollwitz

+Kolmar

+Kolmogorov

+Kolo

+Kolomna

+Kolyma

+Komati

+Komatik

+Komi

+Kommunarsk

+Kommunizma

+Komodo

+Komsomol

+Komsomolsk

+Konakry

+Kondo

+Kondrashin

+Konstanz

+Kootenay

+Kopeisk

+Kopje

+Koppa

+Korbut

+Korchnoi

+Kordofan

+Kordofanian

+Korma

+Korngold

+Korsakov

+Kortrijk

+Koruna

+Korzybski

+Kos

+Kosciusko

+Kossuth

+Kostroma

+Kosygin

+Kota

+Kotabaru

+Koulibiaca

+Koumis

+Kovno

+Kovrov

+Koweit

+Kowhai

+Kozhikode

+Kra

+Kraal

+Kragujevac

+Krait

+Krakau

+Kramatorsk

+Krameria

+Kranj

+Krans

+Krasnodar

+Krasnoyarsk

+Krefeld

+Kreisky

+Kreisler

+Kremenchug

+Kremer

+Krems

+Kreplach

+Kreutzer

+Kriegspiel

+Kriemhild

+Krimmer

+Krio

+Krips

+Kriss

+Kristiansand

+Kristianstad

+Krivoy

+Kromesky

+Krone

+Kronig

+Kronos

+Kroon

+Kropotkin

+Krugersdorp

+Kruller

+Krummhorn

+Krupp

+Kruysen

+Krym

+Kshatriya

+Kuala

+Kuban

+Kubelik

+Kublai

+Kubrick

+Kuch

+Kuchen

+Kuching

+Kueh

+Kuenlun

+Kufic

+Kuibyshev

+Kukri

+Kuku

+Kula

+Kulturkampf

+Kulun

+Kum

+Kumamoto

+Kumasi

+Kumbaloi

+Kung

+Kungur

+Kunming

+Kunzite

+Kuomintang

+Kuopio

+Kura

+Kurgan

+Kuril

+Kurland

+Kurosawa

+Kuroshio

+Kurrajong

+Kursaal

+Kursk

+Kurzeme

+Kuskokwim

+Kutaisi

+Kutch

+Kutuzov

+Kuznetsk

+Kwa

+Kwacha

+Kwajalein

+Kwakiutl

+Kwangchow

+Kwangchowan

+Kwangju

+Kwangtung

+Kwantung

+Kwanza

+Kwara

+Kwazulu

+Kweichow

+Kweilin

+Kweisui

+Kweiyang

+Kwela

+Kynewulf

+Kyongsong

+Kyprianou

+Kyrie

+Kyushu

+LPG

+La

+Laager

+Laaland

+Laburnum

+Lacedaemonian

+Lactobacillus

+Ladin

+Ladino

+Lagting

+Lahnda

+Lahti

+Laibach

+Lakeland

+Lakes

+Laksa

+Lakshadweep

+Lalo

+Lamaism

+Lamarckian

+Lamarckism

+Lamington

+Lammas

+Lammastide

+Lancastrian

+Landau

+Langland

+Langobard

+Langobardic

+Langridge

+Langton

+Langtry

+Lantana

+Lapith

+Laplacian

+Lapland

+Lapp

+Lar

+Laski

+Lassen

+Latakia

+Latimeria

+Latina

+Latinism

+Latinist

+Latino

+Latona

+Latour

+Latvian

+Laudian

+Laughton

+Launce

+Launceston

+Lawless

+Lawrentian

+Lazar

+Leacock

+Leaf

+Leah

+Leamington

+Leatherette

+Leda

+Lefkowitz

+Leibnitz

+Leicester

+Leicestershire

+Leichhardt

+Leiden

+Leif

+Leinsdorf

+Leinster

+Leishmania

+Leitner

+Lemberg

+Lemmens

+Leninabad

+Leninakan

+Leno

+Lenya

+Leoncavallo

+Leonidas

+Leopardi

+Lepanto

+Lepidosiren

+Leptocephalus

+Lepton

+Lepus

+Lermontov

+Lerwick

+Lethbridge

+Leto

+Lett

+Lettish

+Leucippus

+Levant

+Levantine

+Leverhulme

+Leverkusen

+Levite

+Levitical

+Levko

+Lewisham

+Leyte

+Lhasa

+Liadov

+Liao

+Liaoning

+Liaotung

+Liaoyang

+Lias

+Lichfield

+Liebfraumilch

+Lilith

+Limbourg

+Limburg

+Limburger

+Limpopo

+Lincolnshire

+Linnaean

+Linsang

+Lipetsk

+Lippizaner

+Liriodendron

+Listerism

+Liszt

+Liv

+Ljubljana

+Llandaff

+Llandudno

+Llanelli

+Llangollen

+Llewellyn

+Lleyn

+Lobachevsky

+Locarno

+Loewe

+Lolland

+Lollard

+Lombrosian

+Longbenton

+Longford

+Longobard

+Lonicera

+Lorengar

+Loretta

+Lota

+Loughborough

+Louisburg

+Luba

+Lucan

+Lucania

+Lucina

+Lucknow

+Luddite

+Ludendorff

+Ludwigsburg

+Ludwigshafen

+Luffa

+Luganda

+Lugansk

+Luluabourg

+Luo

+Lupercalia

+Lur

+Lusatian

+Lusitania

+Lutetia

+Luton

+Lutoslawski

+Lutyens

+Luxemburg

+Luxon

+Lvov

+Lycian

+Lydian

+Lyme

+Lymington

+Lyonnais

+Lyonnesse

+Lysander

+Lysenkoism

+Lysimachus

+Lytham

+Lythraceous

+Lyublin

+MFD

+MIRV

+MKS

+MKSA

+MSC

+MVS

+MVT

+Ma

+Maag

+Maar

+Maarianhamina

+Maas

+Maastricht

+Maazel

+Mab

+MacKerras

+Macao

+Macaskill

+Macau

+Maccabean

+Maccabees

+Macclesfield

+Macdonnell

+Mackay

+Mackerras

+Maclean

+Macleod

+Macmahon

+Macneice

+Macpherson

+Macready

+Maddalena

+Maecenas

+Magdalen

+Magdalenian

+Magdeburg

+Magellan

+Maghreb

+Maglemosian

+Magnificat

+Magyar

+Mahdi

+Mahican

+Mahomet

+Mahonia

+Mahound

+Maia

+Maintenon

+Maitland

+Majlis

+Malacca

+Malaya

+Malinowski

+Malison

+Malpighian

+Mam

+Mameluke

+Manchu

+Mancunian

+Mandaean

+Mandalay

+Mande

+Mandeville

+Mandingo

+Manichaeism

+Mannerheim

+Mannheim

+Mantler

+Manuguerra

+Manx

+Manxman

+Marabout

+Maracaibo

+Maratha

+Marathi

+Marburg

+Marchland

+Marciano

+Marcionism

+Marconi

+Marengo

+Marenzio

+Margaux

+Margay

+Marge

+Mariana

+Mariehamn

+Marienbad

+Marinduque

+Marinetti

+Mariolatry

+Mariology

+Marist

+Mariupol

+Marius

+Marivaux

+Markevitch

+Markhor

+Markka

+Markova

+Marley

+Marlow

+Maronite

+Marquesan

+Marrakech

+Marrakesh

+Marriner

+Marsala

+Marseillaise

+Marseille

+Marshalsea

+Marston

+Martin

+Martinmas

+Martinon

+Marton

+Masai

+Mascagni

+Masefield

+Massawa

+Massenet

+Matabele

+Matabeleland

+Mathis

+Matorin

+Mattila

+Mauceri

+Maud

+Maugham

+Mauricio

+Maurist

+Mauser

+Mavourneen

+Mawson

+Maxim

+Mayakovski

+Mayan

+Mayen

+Mayotte

+Mazdaism

+Mbujimayi

+McNair

+Mccarthyism

+Mccartney

+Mccormack

+Mccullers

+Mcdiarmid

+Mcgonagall

+Mcluhan

+Mclure

+Mcmunn

+Mcmurdo

+Mcnaughten

+Mcqueen

+Meade

+Meccano

+Mechem

+Mechlin

+Mecklenburg

+Mede

+Medina

+Megaera

+Mehta

+Meissen

+Melaleuca

+Melanochroi

+Melchite

+Melchizedek

+Meleager

+Melitopol

+Melton

+Melungeon

+Memnon

+Memphian

+Mendeleyev

+Mendelism

+Menelik

+Mengelberg

+Menshevik

+Menton

+Mercian

+Mercouri

+Mercurian

+Mercurochrome

+Merionethshire

+Merovingian

+Merseburg

+Mersey

+Merseyside

+Merton

+Mesembryanthemum

+Mesple

+Messapian

+Metol

+Metternich

+Mexicali

+Meyerbeer

+Meyerhof

+Micah

+Michaelmas

+Micmac

+Microscopium

+Middelburg

+Middlesbrough

+Middlewood

+Midway

+Milashkina

+Milford

+Milhaud

+Milnes

+Milstein

+Mina

+Mindel

+Ming

+Mingrelian

+Minkowski

+Minorca

+Minorite

+Minton

+Minya

+Miquelon

+Miserere

+Mishima

+Mishnah

+Mithraism

+Mithras

+Mitropolous

+Mitropoulos

+Mittelland

+Mitterrand

+Mixtec

+Mizoguchi

+Mlle

+Mme

+Mnemosyne

+Modiolus

+Modred

+Mogilev

+Mohave

+Mohican

+Mohock

+Mojave

+Moldau

+Moldavian

+Moldavite

+Molech

+Moll

+Mollet

+Molokai

+Mommsen

+Momus

+Moncton

+Mondale

+Mondial

+Monegasque

+Mongo

+Mongol

+Mongolic

+Monmouthshire

+Monophysite

+Monteux

+Montezuma

+Montgomeryshire

+Montserrat

+Moorcock

+Moorland

+Moradabad

+Mordvin

+Mordvinian

+Moreton

+Morisco

+Moro

+Morocco

+Morpheus

+Moselle

+Mossi

+Mosul

+Mountbatten

+Mountie

+Moussorgsky

+Mousterian

+Mozambique

+Mozarab

+Mridang

+Muharram

+Mulciber

+Munch

+Munda

+Murdabad

+Murdoch

+Murillo

+Murmansk

+Musca

+Muskhogean

+Mussulman

+Muti

+Mwalimu

+Mweru

+Mycobacterium

+Myrica

+Myrmidon

+NCAR

+NGK

+NTP

+Naafi

+Nabataean

+Nabokov

+Nabonidus

+Nadia

+Naga

+Nagaland

+Nagana

+Nagano

+Nagari

+Nagpur

+Nagyszeben

+Nahuatl

+Nahum

+Nama

+Namaqualand

+Namibia

+Nana

+Nansen

+Napier

+Napierian

+Napoli

+Napravnik

+Narayanganj

+Narraganset

+Nathanael

+Nauru

+Navassa

+Nayarit

+Nazarite

+Nearctic

+Neblett

+Nederland

+Negress

+Negritic

+Negrito

+Negrophil

+Negrophobe

+Negus

+Nehemiah

+Nejd

+Nekrasov

+Nelly

+Nelson

+Nembutal

+Nemean

+Nemesia

+Neocene

+Neogaea

+Neogene

+Neotropical

+Neozoic

+Neptunian

+Nereis

+Neri

+Nestorianism

+Neubrandenburg

+Neville

+Nevis

+Nevski

+New

+Newburg

+Newcombe

+Newcomen

+Newfie

+Newgate

+Newham

+Newhaven

+Newmarket

+Newtonabbey

+Newtown

+Ngaio

+Ngaliema

+Ngoma

+Nguni

+Ngwee

+Nha

+Nicaea

+Nice

+Nicene

+Nicias

+Nicobar

+Nicol

+Nicola

+Nicolai

+Nicolesco

+Nicolson

+Nicotiana

+Niedersachsen

+Niersteiner

+Nietszche

+Niflheim

+Nijmegen

+Nikaria

+Nike

+Nikolainkaupunki

+Nikolayev

+Nilotic

+Nimitz

+Nimrod

+Nimwegen

+Ningpo

+Ninon

+Nipissing

+Nisei

+Nishapur

+Nissen

+Niue

+Nizam

+Noachian

+Noble

+Noctiluca

+Noguchi

+Noordholland

+Nordkyn

+Norland

+Normanton

+Norn

+Norseman

+Northallerton

+Northamptonshire

+Northcliffe

+Northcountryman

+Northman

+Northmen

+Northumbria

+Northumbrian

+Northumbrians

+Northwich

+Nostoc

+Notogaea

+Notornis

+Nototherium

+Notour

+Nottinghamshire

+Notus

+Novgorod

+Novokuznetsk

+Nuba

+Nucci

+Nuffield

+Nullstellensatz

+Nuneaton

+Nupe

+Nuremberg

+Nyanja

+Nyasaland

+Nynorsk

+Nyoro

+OSHA

+Oahu

+Oakham

+Oakville

+Oaxaca

+Obadiah

+Oberammergau

+Oberhausen

+Oberland

+Oberon

+Obraztsova

+Ochman

+Ockham

+Ocrea

+Octans

+Octavian

+Octobrist

+Odelsting

+Odontoglossum

+Ogham

+Oglethorpe

+Ogpu

+Ogygian

+Oidium

+Oireachtas

+Oistrakh

+Okayama

+Okeechobee

+Okefenokee

+Okhotsk

+Okie

+Olcott

+Oldcastle

+Oldham

+Oliveira

+Olynthus

+Ommiad

+Omsk

+Ophiuchus

+Oporto

+Oppens

+Orangeism

+Orangeman

+Oratorian

+Orcadian

+Ordovician

+Orenburg

+Orff

+Oriya

+Orleanist

+Ormandy

+Ormazd

+Ornithorhynchus

+Orphean

+Orphism

+Orpington

+Orsk

+Orvieto

+Osage

+Oscan

+Oshawa

+Oshogbo

+Osijek

+Osmanli

+Osnaburg

+Osset

+Ossetic

+Ossian

+Ostrogoth

+Ostyak

+Othin

+Ottley

+Ouija

+Ovambo

+Overijssel

+Oxbridge

+Oxfordshire

+Ozawa

+PABA

+PCB

+PCBS

+POBox

+PUC

+PWT

+Paal

+Pachisi

+Pachouli

+Pacific

+Paddywhack

+Paderewski

+Padus

+Pahari

+Pahlavi

+Paignton

+Paiute

+Palacio

+Palaearctic

+Palaeocene

+Palaeozoic

+Palau

+Palenque

+Pali

+Pallas

+Palmerston

+Panama

+Panathenaea

+Pandarus

+Pandean

+Panhellenic

+Panhellenism

+Panjabi

+Pantagruel

+Paphian

+Papiamento

+Papuan

+Paracel

+Paracelsus

+Parma

+Parnassian

+Parnassus

+Parsee

+Parthenopaeus

+Parthenope

+Parthenos

+Parthian

+Pasch

+Pashto

+Passamaquoddy

+Passiontide

+Pasteurism

+Pathan

+Patmos

+Pauk

+Paulinus

+Pavarotti

+Pavo

+Pawnee

+Pears

+Pecksniffian

+Pehlevi

+Pekin

+Pekingese

+Pelagian

+Pelagianism

+Pelasgian

+Peleus

+Pelew

+Pelias

+Pelmanism

+Peloponnesian

+Pelops

+Pembrokeshire

+Pentland

+Pentstemon

+Penutian

+Pepys

+Pequot

+Perceval

+Percheron

+Peritricha

+Perlman

+Persicaria

+Persis

+Persson

+Pesach

+Peterborough

+Peterlee

+Peterloo

+Peterman

+Petermann

+Petersham

+Petra

+Petrie

+Petrine

+Petronius

+Petropavlovsk

+Petrosian

+Petrov

+Petrovsk

+Petrozavodsk

+Peyer

+Pfalz

+Pforzheim

+Phaeacian

+Phaedrus

+Philadelphus

+Philippeville

+Philippic

+Philistia

+Philistinism

+Philoctetes

+Philomela

+Phlegethon

+Phoenician

+Phragmites

+Phrygian

+Phylloxera

+Pianola

+Piavko

+Picard

+Pickwickian

+Pictish

+Pierian

+Pierides

+Pierrot

+Pietermaritzburg

+Pieterson

+Pilsen

+Pilsudski

+Piltdown

+Pindaric

+Pinkerton

+Pinkster

+Pinsk

+Pisanello

+Pisano

+Piscis

+Pitcairn

+Pithecanthropus

+Pitta

+Plasson

+Plasticine

+Platonical

+Plattdeutsch

+Platte

+Platteland

+Plautus

+Podolsk

+Pogonia

+Pogorelich

+Polack

+Polanski

+Polje

+Pollack

+Pollini

+Pollyanna

+Polska

+Polycarp

+Pondo

+Pondoland

+Pons

+Pontic

+Popov

+Popp

+Porson

+Posen

+Positif

+Poulenc

+Powhatan

+Praesepe

+Praetorian

+Prakrit

+Pressburg

+Pretre

+Preussen

+Previn

+Prey

+Priapus

+Price

+Principe

+Priscian

+Procne

+Prokopyevsk

+Proterozoic

+Protophyta

+Provincetown

+Prunella

+Prussianism

+Pskov

+Psoralea

+Ptolemaist

+Puppis

+Purbeck

+Puseyism

+Pyrrhus

+Pythagoreanism

+Pythia

+Pythian

+Quadragesima

+Quassia

+Queenborough

+Queenstown

+Quimper

+Quinquagesima

+Quirites

+Quivar

+RI

+RTT

+Rabelais

+Rabelaisian

+Rabi

+Rabia

+Rackham

+Radetzky

+Radnorshire

+Rafflesia

+Raia

+Raimondi

+Rajput

+Rama

+Rambouillet

+Rameses

+Rampal

+Randova

+Ranki

+Rapallo

+Raphia

+Rastafarian

+Rattle

+Rauwolfia

+Ravel

+Rea

+Rebozo

+Recklinghausen

+Redbridge

+Redemptorist

+Redgrave

+Regensburg

+Rehoboam

+Reichsrat

+Reiner

+Remblai

+Reme

+Remex

+Renardy

+Renfrew

+Rensselaerite

+Resnik

+Respighi

+Reunion

+Rhadamanthus

+Rhaetian

+Rhaetic

+Rheinland

+Rhemish

+Rhodesian

+Rhodesoid

+Rhodian

+Rhodope

+Ricci

+Ricciarelli

+Riesling

+Rigsdaler

+Rijeka

+Rijksdaaler

+Rijn

+Rijswijk

+Riksdag

+Rimini

+Rimsky

+Ripuarian

+Riss

+Rivera

+Roanoke

+Robeson

+Robespierre

+Robson

+Rochberg

+Rochdale

+Rochelle

+Rockhampton

+Rockingham

+Rodin

+Rodrigo

+Rodzinski

+Roethke

+Rojak

+Rolf

+Rollo

+Roma

+Romagna

+Romaic

+Romains

+Romaji

+Romanes

+Romanic

+Romanies

+Romanism

+Romanist

+Romanov

+Romansch

+Romany

+Romberg

+Romero

+Romeros

+Romish

+Rommel

+Romney

+Roncesvalles

+Ronin

+Ronsard

+Rosalind

+Rosicrucian

+Rossini

+Rostov

+Rostropovich

+Rotherham

+Rothermere

+Rothesay

+Rotterdam

+Rouault

+Roubaix

+Roussillon

+Routemarch

+Rowan

+Rowbotham

+Rowicki

+Rowlandson

+Roxburgh

+Royden

+Rozhdestvensky

+Rubenstein

+Rubicon

+Rudesheimer

+Ruhr

+Rumpelstiltskin

+Rundstedt

+Rupert

+Rurik

+Ruritania

+Ruskin

+Russky

+Russophile

+Russophobe

+Ruthenian

+Rutherfordium

+Rutter

+Rybinsk

+Ryswick

+Ryukyu

+Ryurik

+Rzewski

+SNCC

+SNOBOL

+STOL

+Saadi

+Saar

+Saarinen

+Saarland

+Sabaean

+Sabaoth

+Sabbatarian

+Sabellian

+Sackville

+Sacramentarian

+Sadducee

+Saens

+Safar

+Safi

+Sahaptin

+Saharan

+Saint

+Saintpaulia

+Saiva

+Sakai

+Sakharov

+Sakyamuni

+Salford

+Salian

+Salicornia

+Sallinen

+Salminen

+Salol

+Salonen

+Salpa

+Salpiglossis

+Salvia

+Salzburg

+Samarkand

+Sambo

+Samian

+Samnite

+Samoyed

+Sanctus

+Sandhurst

+Sandringham

+Sandwich

+Sanforized

+Sanger

+Sangh

+Sangraal

+Sanjak

+Sankhya

+Santee

+Sao

+Sarajevo

+Sarangi

+Saransk

+Saratov

+Sard

+Sardinian

+Sardis

+Sardius

+Sardou

+Sargodha

+Sargon

+Sark

+Sarkis

+Sarracenia

+Sarsen

+Saschowa

+Sassanid

+Sassenach

+Satie

+Satsuma

+Saturnian

+Sauerbaum

+Sawney

+Saxe

+Scandian

+Schaerbeek

+Schaffhausen

+Schein

+Schenck

+Schiedam

+Schiff

+Schippers

+Schleiermacher

+Schlesien

+Schleswig

+Schliemann

+Schnecken

+Schnitzler

+Schwarz

+Schwarzkopf

+Sci

+Scimone

+Scleroderma

+Scofield

+Scopus

+Scorpius

+Scotism

+Scotswoman

+Scotticism

+Scotto

+Scriabin

+Scythian

+Seabee

+Sealyham

+Searle

+Seaton

+Sebastopol

+Secunderabad

+Sedgemoor

+Seebeck

+Seeger

+Seeland

+Seidlitz

+Seifert

+Selene

+Seleucid

+Selig

+Seljuk

+Semipalatinsk

+Semitics

+Senechal

+Senlac

+Sephardi

+Septembrist

+Septuagint

+Serapis

+Serb

+Serkin

+Sevastopol

+Severnaya

+Severus

+Sexagesima

+Shaban

+Shabuoth

+Shackleton

+Shaka

+Shakta

+Shakti

+Shang

+Shankar

+Shankaracharya

+Sharia

+Shavian

+Shaw

+Shawwal

+Shchedrin

+Shcheglovsk

+Shcherbakov

+Shechem

+Shekinah

+Shemite

+Shemitic

+Sheol

+Sherpa

+Sherrington

+Shetland

+Shiah

+Shiism

+Shimonoseki

+Shiraz

+Shluh

+Shoa

+Sholokhov

+Shona

+Shoshonean

+Shostakovich

+Shrewsbury

+Shropshire

+Shrovetide

+Shulamite

+Sibelius

+Sicanian

+Siddhartha

+Sierra

+Sihanouk

+Sika

+Silures

+Silurian

+Silvanus

+Simarouba

+Simbirsk

+Simeon

+Simferopol

+Sinaloa

+Sindhi

+Singhalese

+Sinhalese

+Sinicism

+Sinitic

+Sinopoli

+Sintow

+Siouan

+Siracusa

+Sisley

+Sitka

+Sivaism

+Sivan

+Siwash

+Sixtus

+Skelton

+Skijoring

+Skikda

+Skimmia

+Skipton

+Skokiaan

+Skolly

+Skrowaczewski

+Skua

+Slatkin

+Slavism

+Slavkov

+Slavonia

+Slavophile

+Slavophiles

+Slesvig

+Slovak

+Slovene

+Smeaton

+Smetana

+Smilax

+Smirnov

+Smolensk

+Smollett

+Sobranje

+Socinian

+Soderblom

+Soderstrom

+Sodom

+Soffel

+Sogdian

+Solenodon

+Solti

+Solutrean

+Solzhenitsyn

+Somaliland

+Sondheim

+Songhai

+Sorbian

+Sorbonne

+Sordello

+Sothic

+Sothis

+Sotho

+Souphanourong

+Souslik

+Sousse

+Souterrain

+Southdown

+Southern

+Southport

+Southron

+Southwark

+Sovetsk

+Soviet

+Soweto

+Soyinka

+Soyuz

+Spaak

+Spartacus

+Spassky

+Speenhamland

+Spenborough

+Spence

+Spengler

+Spenser

+Spenserian

+Spinoza

+Spinozism

+Spitsbergen

+Spivakov

+Spratly

+Springhaas

+Srbija

+Stade

+Stagirite

+Stakhanovism

+Stalinabad

+Stalingrad

+Stalinism

+Stalinogrod

+Stalinsk

+Stanislavsky

+Stanleyville

+Starker

+Stavanger

+Stavropol

+Steber

+Stefansson

+Stegodon

+Stegomyia

+Stegosaurus

+Steier

+Steiermark

+Stein

+Steinbeck

+Steinitz

+Stellite

+Stern

+Stijl

+Stillson

+Stillsons

+Stilton

+Stilwell

+Stockhausen

+Stockport

+Stockwood

+Stokowski

+Stokys

+Storting

+Stourbridge

+Stradivari

+Stradivarius

+Strafford

+Stralsund

+Stranraer

+Stratas

+Strathclyde

+Straus

+Stravaig

+Streisand

+Strelitzia

+Stretford

+Streusel

+Stroheim

+Strophanthus

+Strymon

+Stu

+Stylops

+Sudetenland

+Sudra

+Sufi

+Sufism

+Sultanabad

+Sulu

+Sumba

+Sumbawa

+Summers

+Sumo

+Sunderland

+Sunni

+Sunnite

+Suomi

+Surinam

+Suriname

+Susanna

+Susian

+Susu

+Sutcliffe

+Suvorov

+Suwannee

+Svalbard

+Sverdlovsk

+Svetlanov

+Swabia

+Swadeshi

+Swanee

+Swatow

+Swazi

+Swedenborg

+Swedenborgianism

+Sweeny

+Swithin

+Sylvan

+Symons

+Syriac

+Syrtis

+Szabadka

+Szczecin

+Szechwan

+Szeged

+Szell

+Szerying

+Szeryng

+Szewinska

+Szombathely

+Szymanowski

+TKO

+TP

+TWP

+Tabasco

+Tabriz

+Tacamahac

+Tacchino

+Tachina

+Tadzhiki

+Tagalog

+Tai

+Taichung

+Tainan

+Taino

+Taiping

+Taisho

+Tajik

+Talaing

+Talmudist

+Talvela

+Tambov

+Tamerlane

+Tamworth

+Tanagra

+Tanjungpriok

+Tannenberg

+Tardenoisian

+Targum

+Tarkington

+Tarnopol

+Tarpeia

+Tarpeian

+Tarquin

+Tartarean

+Tartaric

+Tartarus

+Tasmanian

+Tatar

+Tatary

+Tatum

+Taunton

+Tay

+Taymyr

+Tayra

+Tayside

+Tbilisi

+Tchad

+Te

+Teal

+Tear

+Tebaldi

+Technicolor

+Technion

+Tel

+Telegu

+Telescopium

+Telford

+Telstar

+Telugu

+Tema

+Temne

+Tempe

+Templar

+Tenebrae

+Tenerife

+Tennstedt

+Tenzi

+Terence

+Teresina

+Tereus

+Ternopol

+Terrani

+Tethys

+Teton

+Teucer

+Teucrian

+Teuton

+Teutonism

+Tewkesbury

+Thanatos

+Thebaid

+Themis

+Theodora

+Theodoric

+Theophilus

+Thermit

+Thersites

+Thetford

+Thomism

+Thorndike

+Thorvaldsen

+Thucydides

+Thuja

+Thurgau

+Thuringia

+Thuringian

+Thurn

+Thyestes

+Tiberius

+Tilburg

+Tilbury

+Tilsit

+Timor

+Timoshenko

+Timour

+Tintagel

+Tippett

+Tirol

+Tiruchirapalli

+Tirunelveli

+Tisa

+Tishab

+Tisiphone

+Titanesque

+Titanomachy

+Titograd

+Titoism

+Tivoli

+Tjirebon

+Tlaxcala

+Tlemcen

+Tlingit

+Tmesis

+Tobey

+Tobolsk

+Tobruk

+Tocharian

+Tocqueville

+Togliatti

+Togoland

+Tojo

+Tokay

+Tokelau

+Tokharian

+Tokoloshe

+Tokugawa

+Tolan

+Tolbert

+Tolima

+Tolkien

+Toller

+Tolly

+Toltec

+Toluca

+Tome

+Tomowa

+Tomsk

+Tonbridge

+Tonga

+Tonka

+Tonkin

+Tophet

+Torricellian

+Torsk

+Tourel

+Townsville

+Tractarianism

+Transcaucasia

+Transylvanian

+Trappist

+Treblinka

+Trent

+Trevino

+Treviso

+Tridentine

+Trinil

+Tripitaka

+Triticum

+Tromelin

+Trondheim

+Trowbridge

+Troyanos

+Truffaut

+Truro

+Tuamotu

+Tuareg

+Tucana

+Tucker

+Tuckwell

+Tunbridge

+Tungus

+Tungusic

+Tupi

+Turanian

+Turco

+Turkey

+Turki

+Turkic

+Turkism

+Turkmen

+Turkoman

+Turks

+Tuvalu

+Twelfthtide

+Twi

+Twickenham

+Tyche

+Tynwald

+Tyrannosaurus

+Tyrian

+Tyrol

+Tyrolienne

+Tyrone

+Tyrr

+Tyrrhenian

+UHF

+Ubangi

+Ubiquitarian

+Ude

+Ugrian

+Ugric

+Uhland

+Uhuru

+Uigur

+Uinta

+Uitlander

+Ujamaa

+Ujiji

+Ujjain

+Ujung

+Ukase

+Ukiyoe

+Ulbricht

+Ullswater

+Ulm

+Ulsterman

+Ulyanovsk

+Umbrian

+Umbriel

+Unalaska

+Uniat

+Union

+United

+Ural

+Uralic

+Uranian

+Uredo

+Uriah

+Uriel

+Urmston

+Urnfield

+Ustinov

+Uxbridge

+Uzbek

+VAC

+VAG

+VDU

+VLF

+VTOL

+Vaal

+Vaasa

+Vaishnava

+Valencia

+Valenciennes

+Valentinian

+Valjakka

+Vanda

+Vandyke

+Vanir

+Vanuatu

+Varady

+Varangian

+Varga

+Varuna

+Vaseline

+Vaticanism

+Veasy

+Veblen

+Vedalia

+Vedanta

+Vedda

+Veddoid

+Vedernikov

+Vedic

+Velsen

+Venda

+Veneti

+Venetia

+Venetic

+Venezia

+Venizelos

+Venora

+Venusberg

+Veracruz

+Vernoleninsk

+Veronal

+Veronese

+Verrett

+Vertumnus

+Vierne

+Vietcong

+Vietminh

+Vihuela

+Viipuri

+Vijayawada

+Vilayet

+Villach

+Villahermosa

+Villainage

+Villanovan

+Villars

+Villeneuve

+Villeurbanne

+Villiers

+Villon

+Vilnius

+Viminal

+Vincennes

+Vindhya

+Vineland

+Vinland

+Virchow

+Visakhapatnam

+Visayan

+Visby

+Visconti

+Viseu

+Vishakhapatnam

+Vishinsky

+Vitebsk

+Vizagapatam

+Vizcacha

+Vizsla

+Vlaardingen

+Vlach

+Vladikavkaz

+Vlaminck

+Vlei

+Vlissingen

+Vltava

+Voetsek

+Voetstoots

+Vogelweide

+Vogul

+Volans

+Volapuk

+Volga

+Volgograd

+Volsci

+Volscian

+Von

+Vorarlberg

+Voronezh

+Voroshilov

+Voroshilovgrad

+Voroshilovsk

+Vortumnus

+Votyak

+Vouvray

+Vries

+Vuelta

+Vulcanite

+Vulpecula

+Vyatka

+Vyshinsky

+Vyvyan

+WAAC

+WAAF

+Waart

+Waddenzee

+Waddington

+Wahhabi

+Waikato

+Waikiki

+Wajda

+Wakashan

+Wakayama

+Wakerife

+Waksman

+Walach

+Walachia

+Walbrzych

+Walcheren

+Waldemar

+Waldenburg

+Waldgrave

+Waldheim

+Waley

+Wallachia

+Walloon

+Wallsend

+Walpurgis

+Walsall

+Walsingham

+Walther

+Walvis

+Wand

+Wandsworth

+Wapentake

+Wappenshaw

+Waragi

+Warangal

+Warbeck

+Ward

+Warfarin

+Warhol

+Warison

+Warley

+Warren

+Warrington

+Wartburg

+Warwickshire

+Wasatch

+Waterford

+Watford

+Watling

+Watteau

+Wattenscheid

+Watts

+Watusi

+Waugh

+Wayland

+Webern

+Wedgwood

+Weigela

+Weikert

+Weikl

+Weill

+Weimar

+Weismannism

+Weisshorn

+Weizmann

+Wellingborough

+Wellingtonia

+Welsbach

+Welshman

+Welwitschia

+Wembley

+Wenceslaus

+Wendish

+Wenkel

+Wensleydale

+Westernism

+Westfalen

+Westmeath

+Westmorland

+Wetterhorn

+Wexford

+Weymouth

+Whikehart

+White

+Whiteboy

+Whitechapel

+Whitefield

+Whitlam

+Whitley

+Whitlow

+Whitsun

+Whitsuntide

+Whittington

+Wickersley

+Wickliffe

+Wicklow

+Widor

+Wiesbaden

+Wigner

+Wigtown

+Wijngaarden

+Wilberforce

+Willcocks

+Wilton

+Wimbledon

+Wimshurst

+Winceyette

+Winchesters

+Winckelmann

+Wiseman

+Wittenberg

+Witwatersrand

+Wixell

+Wobbegong

+Wodehouse

+Woden

+Woking

+Wokingham

+Wolds

+Wolffian

+Wolfram

+Wolfsburg

+Wollongong

+Wolof

+Wolverhampton

+Woodsia

+Woomera

+Wotton

+Woulfe

+Wraac

+Wrexham

+Wunderlich

+Wycliffite

+Wykeham

+Xeres

+Xmas

+Yablonovy

+Yahoo

+Yahweh

+Yakut

+Yakutsk

+Yalu

+Yangtze

+Yankeeism

+Yarborough

+Yarkand

+Yaroslavl

+Yashmak

+Yekaterinburg

+Yekaterinodar

+Yekaterinoslav

+Yelisavetgrad

+Yelisavetpol

+Yelizaveta

+Yenisei

+Yerba

+Yerkes

+Yevtushenko

+Yid

+Yorke

+Yorkist

+Yorkists

+Yoruba

+Yoshihito

+Youngberry

+Younker

+Ypres

+Yquem

+Yresko

+Ysaye

+Yser

+Yseult

+Yssel

+Yuga

+Yukawa

+Yuman

+Yurev

+Yurlov

+Yuzovka

+Zaandam

+Zabrze

+Zacatecas

+Zaccaria

+Zacharias

+Zaibatsu

+Zakai

+Zakuski

+Zambezi

+Zamboanga

+Zamenhof

+Zamia

+Zanasi

+Zanthoxylum

+Zapotec

+Zeebrugge

+Zeeland

+Zeeman

+Zemstvo

+Zend

+Zenobia

+Zepperitz

+Zermatt

+Zetland

+Zhdanov

+Zhitomir

+Zhivkov

+Zho

+Zhukov

+Zimbabwe

+Zindabad

+Zinman

+Zinovievsk

+Zinzendorf

+Zoa

+Zoroastrianism

+Zouave

+Zoysia

+Zuider

+Zuidholland

+Zukerman

+Zwilich

+aardwolf

+abac

+abaca

+abactinal

+abadan

+abaddon

+abakan

+abamp

+abampere

+abator

+abbasid

+abbatial

+abbess

+abcoulomb

+abdias

+abdominous

+abednego

+abeokuta

+aberdare

+abfarad

+abhenry

+abib

+abietic

+abilene

+abingdon

+abirritant

+abirritate

+abkhaz

+ablactation

+ablator

+abohm

+aboideau

+aborticide

+aboukir

+aboulia

+abranchiate

+abri

+abruzzi

+abseil

+absinthism

+absonant

+absorbefacient

+absorptivity

+absquatulate

+abstergent

+abukir

+abulia

+abvolt

+abwatt

+aby

+abydos

+abysm

+acajou

+acanthaceous

+acanthine

+acanthoid

+acanthous

+acariasis

+acarid

+acaroid

+acarology

+acarpous

+acas

+acaudal

+accad

+accentor

+accidie

+accipitrine

+accommodatory

+accouplement

+accrescent

+accutron

+acerate

+acerose

+acescent

+acetabulum

+acetanilide

+acetometer

+acetophenetidin

+acetum

+acetylcholine

+acetylide

+acetylsalicylic

+achaea

+achelous

+achene

+acheron

+acheulian

+achlamydeous

+achlorhydria

+achondrite

+achondroplasia

+achromatin

+achromatous

+achromic

+acicula

+aciculate

+aciculum

+acidometer

+acidophil

+acidophilus

+acidosis

+acierate

+acinaciform

+aciniform

+ackee

+acl

+aclinic

+acnode

+acol

+aconcagua

+aconite

+acotyledon

+acouchi

+acridine

+acriflavine

+acrilan

+acrocarpous

+acrodrome

+acrogen

+acrolein

+acrolith

+acromegaly

+acromion

+acrospire

+acroter

+acrylamide

+acrylonitrile

+acrylyl

+acta

+actin

+actinal

+actinidin

+actiniform

+actinochemistry

+actinoid

+actinomere

+actinomorphic

+actinomycete

+actinomycin

+actinomycosis

+actinon

+actinopod

+actinotherapy

+actinouranium

+actinozoan

+actomyosin

+aculeus

+acutance

+acyclical

+adactylous

+adamawa

+adamsite

+adana

+adaptably

+addax

+ademption

+adenectomy

+adenitis

+adenocarcinoma

+adenohypophysis

+adenoidectomy

+adenovirus

+adhibit

+adiaphorism

+adiaphorous

+adiathermancy

+adipocere

+adit

+adivasi

+admass

+admetus

+adminicle

+adnate

+adnominal

+adnoun

+adowa

+adrastus

+adscription

+adsorbtion

+adsuki

+adularia

+adumbral

+aduwa

+adventitia

+adversarial

+adygei

+adynamia

+adytum

+adzhar

+adzuki

+aeciospore

+aecium

+aedile

+aegospotami

+aegrotat

+aeneous

+aestheticism

+afebrile

+affettuoso

+afflatus

+affreightment

+aforemention

+aforetime

+afrit

+afrormosia

+afterbody

+afterbrain

+afterburning

+afterheat

+afterpains

+aftersensation

+aftershaft

+aga

+agadir

+agalloch

+agamogenesis

+agaric

+agartala

+agateware

+agegroup

+aggro

+agha

+agiotage

+agist

+aglet

+agley

+aglimmer

+agma

+agminate

+agnail

+agni

+agnus

+agora

+agraffe

+agram

+agranulocytosis

+agraphia

+agrestal

+agrestic

+agrigento

+agrippina

+agrose

+agrostology

+agrypnotic

+agueweed

+agulhas

+ahab

+ahimsa

+ahithophel

+ahura

+aiglet

+aiguille

+aiguillette

+aikido

+aikona

+ailurophile

+ailurophobe

+ain

+aintab

+airboat

+airbrick

+aircraftman

+airdrie

+aire

+airforce

+airgun

+airt

+aisha

+aisne

+ait

+aitchbone

+ajaccio

+ajmer

+akbar

+akela

+akene

+akhara

+akhenaten

+akihito

+akkerman

+aksum

+akure

+akvavit

+alagez

+alagoas

+alamode

+alanbrooke

+alanine

+alannah

+alap

+alar

+albacete

+albata

+albemarle

+alberti

+albertite

+albertus

+albescent

+albinus

+albite

+albuminate

+albuminuria

+albumose

+alburnum

+alcaeus

+alcahest

+alcaide

+alcalde

+alcan

+alcatraz

+alcheringa

+alcidine

+alcmene

+alcoholicity

+alcuin

+aldabra

+aldan

+aldershot

+aldis

+aldol

+aldosterone

+aldoxime

+alecost

+alecto

+alegar

+alekhine

+alembicated

+alessandria

+alethic

+aleurone

+alevin

+alexandretta

+alexipharmic

+alfieri

+alfilaria

+alforja

+algarroba

+algebraical

+algeciras

+alginic

+algoid

+algolagnia

+algology

+algometer

+algor

+algorism

+alible

+alicante

+aligarh

+aliped

+alit

+aliunde

+alkalic

+alkane

+alkene

+alkmaar

+alky

+alkyd

+alkylation

+alkyne

+allanite

+allantoid

+allantois

+allargando

+alleppey

+allethrin

+allhallows

+alloa

+allodial

+allodium

+allonym

+alloplasm

+allotts

+allyou

+almada

+almelo

+almemar

+almonry

+almucantar

+almuce

+alodium

+alopecia

+alost

+alow

+alpenhorn

+alpes

+alphatically

+alpheus

+alphonsus

+alphorn

+alphosis

+alsace

+alsike

+alt

+altdorf

+altdorfer

+alternant

+althing

+althorn

+altiplano

+altissimo

+altogther

+altona

+altostratus

+aludel

+alula

+aluminiferous

+aluminothermy

+alumroot

+alvey

+alvine

+amadavat

+amadou

+amagasaki

+amalekite

+amalthea

+amaranthaceous

+amaranthine

+amarelle

+amaryllidaceous

+amatol

+amaut

+amazonas

+ambala

+ambary

+amberjack

+amberoid

+amblygonite

+amblyopia

+ambo

+amboceptor

+amboise

+amboyna

+ambroid

+ambry

+amdahl

+ameba

+ameer

+amenhotep

+amesace

+amhara

+amharic

+amianthus

+amice

+amicus

+amidol

+amidship

+amin

+aminophenol

+aminopyridine

+aminopyrine

+amir

+ammendment

+ammendments

+ammine

+ammocoete

+ammon

+ammonal

+ammonate

+ammonic

+amoebaean

+amon

+amontillado

+amoroso

+amowt

+amphiarthrosis

+amphiaster

+amphibiotic

+amphiblastula

+amphibrach

+amphichroic

+amphicoelous

+amphictyon

+amphictyony

+amphidiploid

+amphigory

+amphimacer

+amphimixis

+amphiprostyle

+amphiprotic

+amphisbaena

+amphistylar

+amphithecium

+amphitricha

+amphora

+amphoteric

+ampulla

+amravati

+amrita

+amstrad

+amur

+amygdala

+amygdalate

+amygdale

+amygdalin

+amygdaline

+amygdaloidal

+amylaceous

+amylase

+amylene

+amyloid

+amylolysis

+amylopectin

+amylopsin

+amylose

+amyotonia

+anabantid

+anabolite

+anabranch

+anacardiaceous

+anachorism

+anaclinal

+anacoluthia

+anacoluthon

+anacoustic

+anacrusis

+anadem

+anadex

+anadromous

+anadyr

+anaglypta

+anagnorisis

+anagoge

+anak

+analcite

+analects

+anambra

+anamnesis

+anamorphism

+anamorphoscope

+anamorphosis

+anandrous

+ananthous

+anapaest

+anaphrodisiac

+anaplasty

+anaptyxis

+anapurna

+anarthria

+anarthrous

+anasarca

+anastomose

+anatase

+anatolia

+anatto

+anaxagoras

+anaximander

+anaximenes

+anbury

+anchoveta

+anchylose

+ancipital

+ancohuma

+ancon

+ancy

+ancylostomiasis

+andalusia

+anderlecht

+andizhan

+andreanof

+andreotti

+androcles

+androclinium

+androecium

+androgenous

+androgyne

+andros

+androsphinx

+androsterone

+andvari

+ane

+anear

+anelace

+anele

+anemochore

+anemography

+anemology

+anemophilous

+anemoscope

+anergy

+anestrus

+anethole

+aneto

+aneuploid

+aneurin

+angelico

+angell

+angelology

+angiology

+angioma

+angostura

+angra

+anguilliform

+anguine

+angwantibo

+anhalt

+anhinga

+anhwei

+aniakchak

+aniconic

+anil

+anilingus

+anima

+animatism

+animato

+anisodactyl

+anisogamy

+anisole

+anisometric

+anisometropia

+anking

+ankus

+ankylosaur

+ankylose

+ankylosis

+ankylostomiasis

+anlace

+anlage

+annaba

+annabergite

+annates

+annatto

+annecy

+annhilate

+anno

+annulose

+anoa

+anoestrus

+anole

+anorak

+anorthositic

+anoxaemia

+ansate

+anschluss

+anshan

+antemeridian

+antependium

+antepenultimate

+antetype

+anteversion

+antevert

+anthelmintic

+anthemion

+antheridium

+antherozoid

+anthocyanin

+anthophore

+anthotaxy

+anthozoan

+anthracene

+anthracoid

+anthraquinone

+anthropomorphosis

+anthropomorphous

+anthropopathy

+anthropophagi

+anthropophagite

+antibaryon

+antibes

+anticathode

+antichlor

+anticholinesterase

+antichrist

+anticlastic

+anticlinorium

+anticosti

+anticyclone

+anticyclones

+antidromic

+antiegalitarian

+antifebrile

+antifederalist

+antiferromagnetism

+antifluoridation

+antihalation

+antihelices

+antihelix

+antihero

+antiheros

+antilepton

+antileptons

+antilogism

+antilogy

+antimasque

+antimere

+antimilitarist

+antimilitarists

+antimissile

+antimissiles

+antimonous

+antimonyl

+antiochus

+antiparallel

+antipater

+antiperistalsis

+antipsychiatry

+antirachitic

+antiremonstrant

+antisana

+antiscorbutic

+antistatic

+antisthenes

+antitragus

+antitype

+antiworld

+antlia

+antlion

+antofagasta

+antoninus

+antonioni

+antonius

+antonomasia

+antre

+antrim

+antrum

+antung

+anu

+anuradhapura

+anuran

+anuresis

+anuria

+anurous

+anvers

+anyang

+anzio

+anzus

+aorangi

+aosta

+aoudad

+apagoge

+apanage

+aparri

+apatetic

+apeldoorn

+apelles

+apeman

+apennines

+apery

+apetalous

+aphagia

+apheliotropic

+aphesis

+aphonia

+aphtha

+apia

+apiezon

+apivorous

+aplanospore

+aplite

+apnoea

+apo

+apocarp

+apochromat

+apocopate

+apocynaceous

+apocynthion

+apoenzyme

+apogamy

+apogeotropism

+apollinaris

+apomict

+apopemptic

+apophasis

+apophthegm

+apophyge

+apophyllite

+apophysis

+apopolectic

+aposiopesis

+apospory

+apostil

+appaloosa

+apparitor

+appassionato

+appel

+appendicectomy

+appendicle

+appenzell

+applecart

+applecarts

+applesnits

+appointor

+appointors

+approximal

+approximator

+approximators

+appulse

+apriorism

+apteral

+apterygial

+apuleius

+apulia

+apure

+apurimac

+apyretic

+aqaba

+aqualung

+aquashow

+aquileia

+aquire

+aquit

+aquitaine

+aquittal

+ara

+arabica

+arabinose

+arad

+arafura

+aragats

+aragon

+aragonite

+araguaia

+arak

+arakan

+araks

+araldite

+araliaceous

+aram

+aran

+araneid

+arany

+arapaima

+ararat

+araroba

+aras

+araucania

+araxes

+arbalest

+arbil

+arbitress

+arboraceous

+arbroath

+arbuthnot

+arcature

+archaean

+archaeomagnetism

+archaeozoic

+archegonium

+archenteron

+archerfish

+archespore

+archicarp

+archidiaconal

+archidiaconate

+archiepiscopal

+archiepiscopate

+archil

+archilochus

+archimage

+archimandrite

+archine

+archipenko

+archiphoneme

+archiplasm

+archoplasm

+arcograph

+arcus

+ardeb

+ardennes

+areg

+arenicolous

+arenite

+areography

+aretino

+arezzo

+argal

+argali

+argand

+argenteuil

+argentum

+argil

+argilliferous

+argillite

+argol

+argolis

+argonon

+argovie

+arica

+arietta

+aril

+arillode

+arimathea

+ariminum

+ariose

+arioso

+ariosto

+arista

+aristaeus

+aristarchus

+aristophanes

+arjuna

+arkose

+arkwright

+arles

+arlon

+armagh

+armagnac

+armband

+armes

+armet

+armiger

+armillary

+arminius

+armipotent

+armorica

+armure

+arne

+arnhem

+arnica

+arnim

+arno

+aroid

+aroint

+arp

+arpent

+arquebus

+arran

+arrestable

+arretium

+arrivisme

+arroba

+arru

+arse

+arsenopyrite

+arsphenamine

+artaud

+artaxerxes

+arteriovenous

+arthralgia

+arthromere

+artic

+artifical

+artifically

+artistical

+artois

+arunachal

+arundel

+arundinaceous

+aruspex

+aruwimi

+arvo

+arytenoid

+asantehene

+asarabacca

+asben

+ascariasis

+ascarid

+asch

+asci

+asclepiadaceous

+ascocarp

+ascogonium

+ascoli

+ascomycete

+ascorbic

+aseity

+asepalous

+asgard

+ashcroft

+ashe

+ashet

+ashkey

+ashlar

+ashlared

+ashlaring

+ashlars

+ashplant

+ashtoreth

+ashurbanipal

+asir

+askari

+askja

+aslef

+asmara

+asmodeus

+aso

+asoka

+aspergillosis

+aspergillus

+asphyxiant

+asphyxiants

+aspinwall

+asquint

+asquith

+assad

+assentient

+asshur

+assibilate

+assiniboine

+assistents

+assiut

+associationism

+assuan

+assurbanipal

+astable

+astaire

+asternal

+asti

+astolat

+astomatous

+astraphobia

+astrict

+astrobotany

+astrocompass

+astrodynamics

+astrogeology

+astroid

+astrometry

+asturias

+astyanax

+asur

+aswan

+asyllabic

+asymptotical

+asyut

+atacama

+atactic

+ataghan

+atahualpa

+ataman

+atbara

+athabaska

+athamas

+athanasius

+athelstan

+athematic

+athermanous

+atheroma

+athodyd

+athos

+atli

+atmolysis

+atomy

+atrabilious

+attaboy

+attedance

+attemper

+attenuant

+attercliffe

+attlee

+attu

+atween

+aubade

+aube

+aude

+audiotypist

+audiphone

+auer

+auklet

+aulic

+aulis

+aurangzeb

+aurelian

+aureus

+auriferous

+auriol

+aurist

+aurum

+ausforming

+ausonius

+austen

+austenitic

+autacoid

+autarchy

+autarky

+autecious

+autecology

+auteur

+autochanger

+autochthon

+autocode

+autocue

+autocycle

+autoicous

+autokinetic

+autoload

+autoloaded

+autoloads

+autolycus

+autolyse

+automorphic

+autopista

+autoput

+autoradiographs

+autoroute

+autostability

+autostrada

+autotimer

+autotoxaemia

+autotoxin

+autotype

+autoxidation

+auvergne

+auxanometer

+auxochrome

+avadavat

+avagadro

+avalon

+avebury

+aveiro

+avellaneda

+avens

+averno

+aveyron

+avicenna

+aviemore

+avignon

+avizandum

+avlona

+avunculate

+awheel

+awlwort

+axseed

+axum

+ayacucho

+ayah

+ayahuasca

+aycliffe

+aydin

+ayesha

+ayr

+ayub

+ayurveda

+ayutthaya

+azan

+azazel

+azbine

+azikiwe

+aznavour

+azo

+azobenzene

+azoic

+azole

+azotemia

+azoth

+azotic

+baa

+baas

+baba

+babar

+babassu

+babbage

+babeuf

+babiche

+babirusa

+babu

+babul

+babur

+babylonia

+bacchius

+bacciform

+baccivorous

+baccy

+backbench

+backbencher

+backbenchers

+backblocks

+backbreaker

+backbreaking

+backchat

+backcloth

+backcomb

+backdate

+backdated

+backdates

+backdating

+backend

+backends

+backhaus

+backmost

+backscratcher

+backsheesh

+backstreet

+backus

+backwardation

+baclava

+bacolod

+bacteraemia

+bacteriological

+bacteriology

+bacteriolysis

+bacteriophage

+bacteriostasis

+bacteroid

+bactria

+baculiform

+baculum

+badajoz

+badalona

+badderlocks

+baddie

+badman

+badoglio

+baeda

+bael

+baeyer

+baez

+bagasse

+bagehot

+bagh

+baghlan

+bagie

+bagnio

+baguio

+bagwash

+bagwig

+bagworm

+bahadur

+bahasa

+bahia

+baht

+bahuvrihi

+baikal

+baile

+baines

+bairnsfather

+baja

+bajan

+bakeapple

+bakehouse

+bakewell

+bakra

+baksheesh

+bakst

+bakunin

+balaclava

+balanchine

+balas

+balata

+balbo

+balbriggan

+baldmoney

+baldric

+balibuntal

+balikpapan

+baliol

+balkh

+balkhash

+balladmonger

+ballance

+ballarat

+ballflower

+balliol

+ballocks

+ballonet

+balmain

+balmung

+balneal

+balneology

+balpa

+balsamiferous

+balsaminaceous

+banaras

+banat

+banc

+bandaranaike

+banderilla

+banderillero

+bandh

+bandicoot

+bandjarmasin

+bandobust

+bandoline

+bandore

+bandsaw

+bandspreading

+bandung

+bangalore

+bangka

+bangweulu

+banian

+banja

+banjermasin

+banjul

+banka

+banket

+banknote

+banknotes

+bannerol

+bansela

+banstead

+bant

+banting

+bap

+baranof

+baraza

+barbel

+barbellate

+barbet

+barbette

+barbican

+barbicel

+barbituric

+barbizon

+barbule

+barbusse

+barca

+barcarole

+barce

+barchart

+barcharts

+bardot

+barehanded

+bareilly

+barents

+baresark

+bargee

+bargepole

+barilla

+barite

+barkentine

+barkhan

+barletta

+barm

+barnardo

+barnaul

+barnsley

+barnum

+barocchio

+baroda

+baroja

+barong

+baroscope

+barostat

+barouche

+barozzi

+barque

+barquentine

+barquisimeto

+barracoon

+barracouta

+barranquilla

+barrault

+barrenwort

+barret

+barrie

+barros

+bartizan

+bartolommeo

+barycentre

+barye

+barysphere

+baryta

+barytes

+barytone

+basaltware

+bascinet

+baseburner

+basenji

+bashan

+bashibazouk

+basifixed

+basilan

+basildon

+basilicata

+basle

+basotho

+bassein

+bassenthwaite

+basseterre

+bastardry

+bastia

+bastinado

+bastnaesite

+bastogne

+batangas

+batata

+bateleur

+batesian

+bathetic

+batholith

+bathsheba

+bathyal

+bathymetry

+bathyscaph

+bathysphere

+batley

+battels

+battersea

+battik

+battledore

+battlepiece

+batum

+batwoman

+bauchi

+baucis

+baudouin

+bautzen

+bawbee

+bawdyhouse

+bawdyhouses

+bayern

+bayeux

+bayle

+baysian

+baywood

+bazoo

+bdellium

+beachie

+beadledom

+beanery

+beanfeast

+beano

+beanpole

+beasty

+beatles

+beatty

+beauharnais

+beaumarchais

+beaut

+beauvais

+beauvoir

+beaverbrook

+bebeerine

+bebel

+beccafico

+bechet

+becquerel

+beddable

+bedesman

+bedight

+bedivere

+bedizen

+bedrail

+bedsit

+bedsits

+bedsitter

+bedspaces

+bedwarmer

+bedwetting

+bedworth

+beeb

+beechnut

+beefburger

+beento

+beerbohm

+beersheba

+beeswing

+beetfly

+beetroot

+beetroots

+beezer

+beforeimage

+beforeimages

+begad

+beggarweed

+begird

+begorra

+begum

+behan

+behistun

+beiderbecke

+beigel

+beira

+bejabers

+bejewel

+belah

+belemnite

+belfort

+belga

+belitung

+bellarmine

+bellay

+belleau

+belletrist

+bellinzona

+belloc

+bellybutton

+belmopan

+belovo

+bemean

+benadryl

+benares

+bendel

+bendigo

+bendy

+benedicite

+benempt

+benevento

+benfleet

+bengaline

+benghazi

+benguela

+benoni

+bentinck

+bentwood

+benue

+benzaldehyde

+benzidine

+benzine

+benzoate

+benzocaine

+benzofuran

+benzoic

+benzoin

+benzol

+benzophenone

+benzoquinone

+benzoyl

+benzyl

+berar

+berbera

+berberidaceous

+berbice

+bergdama

+bergerac

+bergius

+beria

+bering

+berio

+beriosova

+berk

+berks

+berley

+berlichingen

+berlinguer

+berm

+bermejo

+bermondsey

+bernadette

+bernadotte

+bernhardt

+bernicle

+bernina

+berretta

+bersagliere

+berseem

+bertillon

+bertolucci

+berzelius

+bespangle

+bespread

+bestrode

+bethe

+bethral

+bethralled

+bethralling

+bethrals

+bethsaida

+betjeman

+betook

+betti

+betulaceous

+beuthen

+bevan

+bevanite

+bevanites

+bevatron

+bevin

+bevvy

+bexley

+beyrouth

+bezique

+bezoar

+bezonian

+bezwada

+bhagalpur

+bhai

+bhakti

+bhang

+bharal

+bharat

+bharatiya

+bhatpara

+bhavan

+bhavnagar

+bhindi

+bhishti

+bhopal

+bhubaneswar

+bhutto

+biafra

+biak

+biannulate

+biarritz

+biauriculate

+bibliomancy

+bicarb

+bicephalous

+bicester

+bicollateral

+bicorn

+bida

+bidarka

+biddle

+bidentate

+bidistill

+bidistilled

+bidistilling

+bidistills

+biel

+bield

+bienne

+bierkeller

+biestings

+bifarious

+biffin

+bifoliate

+bifoliolate

+biforate

+bifrost

+bigarreau

+bigener

+bigmouth

+bignoniaceous

+biguanide

+bihar

+bijapur

+bijugate

+bikaner

+bikie

+bikila

+bilander

+bilbao

+bilberry

+bilboes

+bilection

+bilestone

+bilirubin

+biliverdin

+billabong

+billfish

+billyo

+bilobate

+biltong

+bimah

+bimanous

+bimbo

+bimorph

+binal

+binate

+bingey

+binghi

+binh

+binodal

+binominal

+binturong

+biocellate

+biochip

+biochips

+bioclimatology

+biocycle

+biodynamics

+bioenergetics

+bioherm

+biolysis

+bioplasm

+biopoiesis

+bioscope

+bioscopy

+biosis

+biostatics

+biostrome

+biparietal

+biparous

+bipetalous

+bipyramidal

+biquadrate

+biquarterly

+birendra

+biriani

+biro

+birobidzhan

+biros

+birthweight

+birthweights

+birtwhistle

+bis

+bisayas

+biscay

+bise

+bisectrix

+biserrate

+bish

+bishopbird

+bisitun

+bisk

+biskra

+bismuthic

+bismuthinite

+bismuthous

+bissextile

+bist

+bistability

+bisulcate

+bisulphate

+bisulphide

+bisulphite

+bisutun

+bisymmetric

+bithynia

+bitolj

+bitterling

+bitterwood

+bivvy

+bizerte

+blackbuck

+blackbutt

+blackcurrant

+blackett

+blackmore

+blackpool

+blackshirt

+blackstrap

+blackwall

+blackwood

+bladdernose

+bladderwrack

+blague

+blah

+blain

+blamey

+blanquette

+blasco

+blastocoel

+blastocyst

+blastoderm

+blastoff

+blastogenesis

+blastomere

+blastopore

+blaubok

+blaydon

+bleb

+bleep

+bleeped

+bleeper

+bleeping

+blennioid

+blenny

+blent

+blepharitis

+blet

+blewits

+blida

+bligh

+blighty

+blimey

+blindage

+blindstorey

+blockboard

+bloemfontein

+blois

+bloodbaths

+bloodsport

+bloodsports

+bloomery

+blotto

+blowback

+blowie

+blowlamp

+blub

+bludge

+bluethroat

+bluetit

+blundell

+blunge

+blunger

+boabdil

+boadicea

+boarfish

+boarhound

+boarish

+boatbill

+boathook

+bobbysoxer

+bobfloat

+boblet

+bobol

+bobotie

+bobowler

+bobsleigh

+bocage

+boccaccio

+boccherini

+boccioni

+bochum

+bocklogged

+bodensee

+bodge

+bodger

+bodgie

+bodh

+bodmin

+bodybuild

+bodycheck

+boethius

+boeuf

+bofors

+bogan

+bogarde

+bogart

+bogbean

+bognor

+bogong

+bogor

+bogtrotter

+bogwood

+boh

+bohea

+bohol

+bohunk

+boiardo

+boileau

+boilover

+bokassa

+bokmakierie

+bolection

+boleyn

+bolide

+bolingbroke

+boliviano

+bollocks

+bolzano

+boma

+bombacaceous

+bombora

+bombycid

+bomu

+bonaire

+bonaventura

+bonce

+bondservant

+boneblack

+boneshaker

+bonhoeffer

+bonin

+bonism

+bonnard

+bonsela

+bontebok

+boobialla

+boobook

+boohoo

+bookeeper

+booklouse

+boole

+boomkin

+boomslang

+boong

+boothia

+boothroyd

+bootloader

+bophuthatswana

+boracic

+boracite

+boraginaceous

+borborygmus

+bordure

+borecole

+boree

+borehole

+boreholes

+borgerhout

+borges

+borgholm

+borgia

+bornholm

+bornu

+borodino

+borrowable

+bors

+borstal

+borzoi

+boschbok

+boschvark

+bosh

+bosk

+boskop

+bossa

+bossboy

+bossuet

+bosworth

+botargo

+botha

+bothnia

+bothwell

+bothy

+botryoidal

+bott

+botticelli

+bottlebrush

+bottlenose

+bottomost

+bottrop

+botvinnik

+boucicault

+boudicca

+boulanger

+bourges

+bourgogne

+bovid

+bovril

+bovver

+bowden

+bowsaw

+bowshot

+bowyangs

+boxboard

+boxfish

+boxroom

+boyla

+boyne

+boyoma

+boysenberry

+boz

+bozen

+brabant

+brach

+brachiopod

+brachycephalic

+brachydactylic

+brachylogy

+brachypterous

+brachyuran

+bracknell

+bracteate

+bracteole

+bradawl

+bradman

+bradycardia

+bradykinin

+braga

+brahe

+braillex

+braillink

+braillo

+brailtel

+brainchildren

+brakesman

+brakpan

+bramante

+bramley

+branchiopod

+brancusi

+brando

+branle

+brasenose

+brashy

+brasier

+brasil

+brasilein

+brasilin

+brassie

+bratislava

+braunite

+braunschweig

+bravais

+bravissimo

+braxy

+brazils

+breadline

+breadmaking

+breadnut

+breadnuts

+breakbone

+breakeven

+breastpin

+breathalyse

+breathalyzer

+brecht

+brecon

+breda

+brede

+bree

+breenger

+bregenz

+brekky

+brevier

+brewis

+brey

+brezhnev

+briand

+briarroot

+bricklay

+bricole

+bridie

+bridlewise

+bridoon

+brie

+brierroot

+brigalow

+brighouse

+brightside

+brinell

+brinjal

+brinny

+briony

+brittonic

+britzka

+brix

+broadbill

+broadmoor

+broca

+broch

+brocken

+broddle

+broderie

+broederbond

+brogan

+brolga

+bromal

+brome

+bromeosin

+bromoform

+bromsgrove

+bronchia

+bronchiectasis

+bronchopneumonia

+bronchoscope

+brookite

+brooklet

+brooklime

+brookweed

+broomgrove

+broomhill

+broonzy

+brose

+browband

+broz

+brubeck

+brucine

+bruges

+bruin

+brumal

+brumby

+brume

+brummell

+brummie

+brundisium

+brunel

+brunelleschi

+brunhild

+brusa

+brushless

+brutify

+brynhild

+bryology

+bryony

+bryozoan

+btu

+bub

+bubal

+bubaline

+buber

+bubonocele

+bucaramanga

+buccinator

+bucentaur

+buchan

+buchner

+buchu

+buckeen

+buckhound

+buckish

+buckjumper

+buckra

+buckram

+bucovina

+budgerigar

+budgetted

+budgetting

+budweis

+buffon

+buganda

+bugbane

+bugong

+buhl

+buibui

+buitenzorg

+bukavu

+bukhara

+bukharin

+bukovina

+bul

+bulawayo

+bulbiferous

+bulganin

+bulimia

+bulle

+bullpen

+bullroarer

+bulnbuln

+bumbailiff

+bumf

+bummaree

+bumph

+bumsucking

+bunche

+buncombe

+bundelkhand

+bundesrat

+bundh

+bundobust

+bunin

+bunraku

+buntal

+bunyip

+buonaparte

+buonarroti

+buoyage

+buprestid

+bur

+buran

+buraydah

+burbage

+burbot

+burgas

+burghley

+burgomaster

+burgomasters

+burgrave

+burhel

+burk

+burka

+burleigh

+burnet

+burney

+burnley

+buroo

+burrawang

+bursarial

+bursiform

+burstone

+buryat

+busbar

+busera

+bushbaby

+bushcraft

+bushhammer

+bushido

+bushie

+bushpig

+bushranger

+bushtit

+bushveld

+bushwheel

+busoni

+busra

+bustee

+busuuti

+butanone

+butat

+butcherbird

+butenedioic

+butskellism

+butskellite

+butterbur

+butterine

+buttonmould

+butung

+butyrin

+buzzsaw

+byelovo

+byng

+byrnie

+byssinosis

+byssus

+bytom

+cabanatuan

+cabbageworm

+cabezon

+cabimas

+cabob

+cabochon

+cabora

+cabral

+cabretta

+cabrilla

+cachexia

+cachinnate

+cachucha

+cacique

+caciquism

+cacodyl

+cacoepy

+cacoethes

+cacology

+cacomistle

+cadaster

+cadelle

+cadi

+caecilian

+caecum

+caen

+caenozoic

+caeoma

+caerleon

+caernarfon

+caesalpiniaceous

+caesaraugusta

+caesarea

+caesium

+caespitose

+caesura

+caetano

+cafard

+caff

+cagliari

+cagliostro

+cagmag

+cagney

+cagoule

+cagoules

+caiaphas

+cainogenesis

+cainozoic

+caird

+cairngorm

+caithness

+caius

+cajeput

+cajuput

+calabria

+calalu

+calamanco

+calamondin

+calandria

+calathus

+calaverite

+calcar

+calcariferous

+calceiform

+calces

+calchas

+calcicole

+calciferol

+calcitonin

+calcsinter

+calculational

+caldarium

+calefacient

+calefactory

+cali

+calices

+caliche

+calicle

+califate

+caligula

+calimere

+calipash

+calipee

+calisaya

+calix

+callais

+callao

+callicrates

+callimachus

+callipash

+callipygian

+callisthenics

+calor

+caloyer

+calpe

+caltanissetta

+calutron

+calvaria

+calvities

+calx

+calyces

+calycine

+calycle

+calyptra

+calyptrogen

+camail

+camass

+cambay

+camberwell

+cambist

+camboose

+cambrai

+cambrel

+cambria

+cambyses

+cameral

+camerlengo

+camiknickers

+camisado

+camoodi

+campagna

+campania

+campanulaceous

+campeche

+campestral

+campina

+campinas

+campo

+camus

+camwood

+canaigre

+canakin

+canaletto

+canaliculus

+canara

+canarese

+canaster

+candia

+candleberry

+candlefish

+candlelit

+candlenut

+candlewood

+candyfloss

+candytuft

+canea

+canella

+cangue

+canikin

+cannabin

+cannae

+cannelloni

+cannelure

+cannes

+cannock

+cannula

+cannulate

+canoewood

+canonicate

+canonry

+canoodle

+canova

+canso

+cantal

+cantala

+cantatrice

+cantharides

+cantilena

+cantorial

+cantoris

+cantrip

+canula

+canzona

+canzone

+canzonet

+capabilites

+caparison

+capelin

+capercaillie

+capillaceous

+caplin

+caporetto

+capote

+cappadocia

+capparidaceous

+cappie

+cappuccino

+capreolate

+capric

+capriccioso

+caprifig

+caprifoliaceous

+caproic

+capsaicin

+capsid

+capua

+capuche

+caput

+caracal

+caracalla

+caracara

+caracul

+carageen

+caramba

+carangid

+caratacus

+caravanserai

+carbamate

+carbamic

+carbamidine

+carbanion

+carbene

+carbineer

+carbonade

+carbonado

+carboxylase

+carburation

+carburetted

+carburetter

+carby

+carbylamine

+carcajou

+carcanet

+carcassonne

+carchemish

+carcinomatosis

+cardin

+cardinalate

+cardiod

+carditis

+cardoon

+carduaceous

+carducci

+caretaking

+carew

+carfax

+carfuffle

+caria

+caribbees

+cariboo

+caries

+carifta

+carillon

+carillonneur

+carina

+carinate

+carinthia

+cariocan

+cariogenic

+carline

+carlota

+carlow

+carmagnole

+carmarthen

+carminative

+carnarvon

+carnassial

+carnatic

+carnauba

+carnet

+carnify

+carniola

+carnot

+carnotite

+carny

+carolus

+carotenoid

+carotid

+carpel

+carpentaria

+carpentier

+carpogonium

+carpology

+carpometacarpus

+carpophagous

+carpophore

+carrack

+carrycot

+carryng

+carse

+carstensz

+cartagena

+carteret

+cartful

+carthorse

+cartouche

+cartulary

+cartwright

+caruncle

+carvel

+cary

+caryatid

+caryophyllaceous

+caryopsis

+carzey

+casablanca

+casals

+casaubon

+cascabel

+cascarilla

+casease

+casebound

+casefy

+caseload

+caseloads

+caseose

+caserta

+caseworm

+casimere

+cassareep

+cassata

+cassation

+cassatt

+cassel

+cassimere

+cassini

+cassiodorus

+cassirer

+cassiterite

+cassoulet

+cassowary

+castellammare

+castellan

+castellany

+castellated

+castiglione

+castile

+castries

+casuist

+catabasis

+catacaustic

+cataclasis

+cataclinal

+catalase

+catalo

+cataloguers

+catalonia

+catalyzed

+catamenia

+catamite

+catania

+catanzaro

+cataphoresis

+cataphyll

+cataplasia

+catarrhine

+catastrophism

+catchfly

+catchweight

+catechol

+catechu

+catechumen

+catenane

+catenoid

+catfall

+cathar

+cathepsin

+catholicon

+catiline

+catling

+catmint

+cato

+cattalo

+cattegat

+cattermole

+cattery

+catullus

+cauca

+caucasia

+caudad

+caudex

+caudine

+caulis

+causalgia

+cauterant

+cauvery

+cavafy

+cavalla

+cavan

+cavatina

+caveator

+cavefish

+cavicorn

+cavie

+cavite

+cavy

+cecity

+cecum

+cedi

+ceefax

+ceilidh

+celaya

+celestite

+cella

+celle

+cellini

+cellobiose

+celloidin

+cellulase

+cellulitis

+cellulous

+celom

+cembalo

+cementum

+cenacle

+cenesthesia

+cenis

+cenogenesis

+cenote

+centimetric

+centipoise

+centisecond

+centiseconds

+centrefold

+centreing

+centrobaric

+centroclinal

+centurial

+ceorl

+cep

+cephalalgia

+cephalin

+cephalochordate

+cephalometer

+cephalonia

+cephalopod

+cephalothorax

+ceram

+ceramal

+cerargyrite

+cerastes

+ceratoid

+cercaria

+cercopithecoid

+cercus

+cerebrospinal

+cerecloth

+ceresin

+ceria

+ceric

+cermet

+cero

+cerography

+ceroplastic

+ceroplastics

+cerotic

+cerotype

+cerous

+cerro

+cert

+cerussite

+cervelat

+cervicitis

+cervid

+cervin

+cesena

+cespitose

+cess

+cesser

+cessionary

+cestode

+cestoid

+cestus

+cesura

+cetane

+cetatea

+ceteris

+cetinje

+cetology

+ceuta

+chabazite

+chabrol

+chacma

+chaconne

+chadic

+chaeronea

+chaeta

+chaetognath

+chaetopod

+chaffinch

+chagall

+chagres

+chainman

+chainplate

+chairborne

+chalaza

+chalcanthite

+chalcidice

+chalcography

+chalcolithic

+chalcopyrite

+chaldea

+chaliapin

+chalicothere

+chalkpit

+chalkstone

+challah

+challis

+chalybeate

+chamade

+chamaephyte

+chambord

+chamonix

+champac

+champignon

+champollion

+chandernagore

+chandigarh

+chandragupta

+chanel

+changan

+changchiakow

+changchow

+changchun

+changsha

+changteh

+chanterelle

+chanukah

+chaoan

+chaochow

+chaparejos

+chapatti

+chappal

+chappie

+chapstick

+chapterhouse

+charas

+charcot

+chardin

+charente

+charivari

+charkha

+charladies

+charlady

+charleroi

+charlock

+charminar

+charollais

+charpoy

+charqui

+charr

+charterage

+charterhouse

+chartless

+chartography

+chasuble

+chauffer

+chaulmoogra

+chaunt

+chausses

+chavannes

+chayote

+cheb

+cheboksary

+checkbits

+checkerbloom

+checky

+cheddite

+cheekpiece

+cheerlead

+cheeseboard

+cheesemonger

+cheesewood

+chefoo

+cheiron

+cheju

+chekiang

+chela

+chelicera

+chelicerate

+cheliform

+cheloid

+chelp

+chemin

+chemisette

+chemmy

+chemnitz

+chemometrics

+chemosmosis

+chemosphere

+chemostat

+chemosynthesis

+chemotaxis

+chemotropism

+chempaduk

+chemulpo

+chemurgy

+chenab

+chenopod

+cheribon

+chersonese

+chervonets

+cheshunt

+chetah

+chevet

+chevrette

+chewa

+chewie

+chiack

+chiapas

+chiastic

+chiastolite

+chiat

+chiba

+chibouk

+chicane

+chiccory

+chichagof

+chichen

+chichester

+chichewa

+chichihaerh

+chickabiddy

+chickenpox

+chiclayo

+chiffchaff

+chifley

+chigetai

+chigwell

+chihli

+childbear

+childcare

+childminder

+childminders

+childminding

+chiliad

+chiliasm

+chilkoot

+chilli

+chillon

+chillum

+chilopod

+chilpancingo

+chilung

+chimb

+chimborazo

+chimbote

+chimkent

+chimneypot

+chinaberry

+chinagraph

+chinan

+chincapin

+chincherinchee

+chindit

+chindwin

+ching

+chinghai

+chingtao

+chinkapin

+chinkiang

+chino

+chinwag

+chios

+chipolata

+chippewa

+chippy

+chirac

+chirau

+chirico

+chirm

+chirurgeon

+chishima

+chisimaio

+chital

+chitarrone

+chittagong

+chiv

+chivaree

+chlamydate

+chlamydeous

+chlamydospore

+chlodwig

+chloracne

+chlorambucil

+chloramine

+chloramphenicol

+chlorenchyma

+chloroacetic

+chloropicrin

+chloroprene

+chloroquine

+chlorosis

+chlorothiazide

+chlorotic

+chlorous

+chlorpromazine

+chlorpropamide

+chlortetracycline

+choanocyte

+chogyal

+choiseul

+chokebore

+chokecherry

+chokedamp

+choko

+cholecalciferol

+cholecyst

+cholecystectomy

+choli

+cholic

+cholla

+chollers

+cholon

+cholula

+chon

+chondrify

+chondriosome

+chondroma

+chondrule

+choof

+chook

+choom

+chopine

+choplogic

+choragus

+chordophone

+chorea

+choreodrama

+choriamb

+chorley

+choroid

+chorology

+chorusmaster

+chota

+chott

+chough

+choux

+chrematistic

+chresard

+chrism

+chrismatory

+chrisom

+chromatology

+chromatolysis

+chromatophore

+chromogen

+chromogenic

+chromolithograph

+chromolithography

+chromomere

+chromonema

+chromophore

+chromoplast

+chromoprotein

+chromous

+chromyl

+chronaxie

+chronobiology

+chronon

+chrysalid

+chrysarobin

+chryselephantine

+chrysoberyl

+chrysoprase

+chrysostom

+chrysotile

+chthonian

+chubb

+chubbyness

+chudskoye

+chufa

+chukar

+chukka

+chukker

+chunder

+chunderous

+chunnel

+chunter

+chupatti

+chupattis

+chuppah

+chur

+churchgo

+churchwarden

+churchwardens

+churidars

+churinga

+churr

+chuttie

+chyack

+chyle

+chyme

+chymosin

+chymotrypsin

+chymotrypsinogen

+cibber

+ciborium

+cic

+cicala

+cicatricle

+cicatrix

+cicerone

+cichlid

+cichlids

+cienfuegos

+cig

+cii

+cil

+cilice

+cilicia

+ciliolate

+cilium

+cimabue

+cimex

+cimon

+cinchonidine

+cinchonine

+cinchonism

+cine

+cineaste

+cinematheque

+cinematographs

+cineol

+cinerarium

+cinereous

+cinerin

+cingulum

+cinna

+cinnamic

+cinquain

+cinque

+cinquecento

+cinzano

+cipolin

+circassia

+circlorama

+circumbendibus

+circummartian

+circumnutate

+circumsolar

+cirenaica

+cirencester

+cirrate

+cirri

+cirripede

+cirrocumulus

+cirrose

+cirrostratus

+cirsoid

+ciscaucasia

+cisco

+ciskei

+cispadane

+cissoid

+cistaceous

+cisterna

+cistron

+cithara

+cither

+citole

+citreous

+citriculture

+citrin

+citrine

+citrulline

+cittern

+citterns

+ciudad

+civ

+civism

+clachan

+clackmannan

+clactonian

+cladded

+cladoceran

+cladode

+cladophyll

+clairaudience

+clamworm

+clamworms

+clapperboard

+clapperboards

+clapperclaw

+clarino

+claro

+clarts

+clary

+classis

+clastic

+clathrate

+claudication

+clavate

+clavicembalo

+clavicorn

+claviform

+clavius

+claymore

+claypan

+claystone

+cleanskin

+cleanthes

+clearcole

+clearstory

+clearway

+clearways

+clearwing

+cleck

+cleek

+cleethorpes

+cleg

+cleidoic

+cleisthenes

+cleistogamy

+clem

+clemenceau

+cleon

+clepsydra

+cleptomania

+clerestory

+clerihew

+clerkess

+cleruchy

+cleveite

+clianthus

+clichy

+cliffhang

+clii

+clinandrium

+clingfish

+clinkstone

+clinostat

+clinquant

+clippie

+clishmaclaver

+clisthenes

+clitellum

+clitic

+cliv

+clix

+clockmaker

+clomb

+clonus

+closedown

+cloudberry

+cloudscape

+clouet

+clough

+clovis

+clubhaul

+clubland

+clubman

+clucky

+clueless

+clumber

+cluny

+clupeid

+clupeoid

+clustan

+clusterability

+clusterable

+clvi

+clvii

+clwyd

+clxi

+clxii

+clxiv

+clxix

+clxvi

+clxvii

+clydebank

+clype

+clypeus

+clyster

+cnidarian

+cnidoblast

+cnidus

+cnossus

+cnut

+coacervate

+coachwood

+coadjutant

+coagulum

+coahuila

+coalface

+coalfield

+coalfields

+coalfish

+coalmine

+coalmines

+coalport

+coaming

+coatee

+coati

+cobaltite

+cobaltous

+cobber

+cobden

+cobnut

+coburg

+coccid

+coccidioidomycosis

+cocciferous

+coccolith

+coccyx

+cochabamba

+cochleate

+cockalorum

+cockatiel

+cockayne

+cockboat

+cockchafer

+cockcroft

+cockleboat

+cockloft

+cockneyfy

+cocksfoot

+cockspur

+cockswain

+cockup

+cocopan

+cocotte

+cocoyam

+cocteau

+codasyl

+codder

+codicology

+codominate

+codominated

+codominates

+codominating

+codswallop

+coedit

+coelacanth

+coelenterate

+coelenteron

+coeliac

+coelom

+coelostat

+coenacle

+coenobite

+coenocyte

+coenurus

+coercibility

+coessential

+coetaneous

+coeur

+coexecutor

+coextend

+coff

+cofferdam

+coggan

+coglike

+cogon

+cohabitee

+cohabitees

+cohesional

+cohobate

+cohune

+coimbatore

+coimbra

+coir

+coire

+coit

+cokuloris

+colbert

+colcannon

+colchester

+colchicine

+colcothar

+colectomy

+colemanite

+coleopteran

+coleoptile

+coleorhiza

+coles

+colet

+colewort

+coley

+colicroot

+colicweed

+coligny

+collapsar

+collarette

+collectanea

+collembolan

+collenchyma

+collisionless

+collocutor

+colloid

+collop

+collotype

+colluvium

+collywobbles

+colmar

+colocynth

+colombes

+colonitis

+colonsay

+coloquintida

+colorate

+colossae

+colossians

+colotomy

+colpitis

+colporteur

+colquhoun

+colubrid

+colubrine

+colugo

+colum

+columbarium

+columbic

+columbite

+columbium

+columbous

+columella

+columnwise

+colure

+coly

+comaneci

+comate

+comatulid

+combe

+comecon

+comedo

+comenius

+comfrey

+comines

+comitia

+commeasure

+commedia

+commendam

+commines

+commis

+commo

+commodus

+commonable

+communicatie

+comnenus

+como

+comorin

+comoro

+comp

+compadre

+compander

+companders

+compilability

+complect

+compony

+compossible

+compostela

+compotation

+comprador

+comstockery

+comte

+conan

+conation

+conative

+conatus

+concelebrate

+concensus

+concent

+concertino

+concha

+conchie

+conchiferous

+conchiolin

+conchobar

+conchoid

+conchoidal

+conchology

+condillac

+condottiere

+condyle

+condyloid

+condyloma

+confessant

+configurationism

+confirmand

+confiteor

+confiture

+conformability

+congeneric

+congius

+conglobate

+conglutinant

+congou

+congrats

+congruential

+congruentially

+conidiophore

+conidium

+coniine

+coniology

+conjuction

+connacht

+connaught

+connemara

+connexions

+conodont

+conoid

+conoscenti

+conquian

+conscionably

+consentient

+conservatoire

+conservatorium

+consett

+consocies

+consolute

+constantan

+constatation

+contactor

+contango

+contemn

+continously

+conto

+contradance

+contrasuggestible

+contrate

+contravallation

+contrayerva

+contredanse

+controllee

+controllees

+conure

+convertite

+convolvulaceous

+cooee

+cookhouse

+coolabah

+coolgardie

+coom

+cooncan

+coontie

+cooperativity

+coopt

+coordinal

+cootch

+copaiba

+copal

+copalm

+copepod

+copita

+copley

+coprolalia

+coprology

+coprophagous

+coprophilia

+coprophilous

+copygraph

+copyread

+coquelicot

+coquilla

+coquito

+coraciiform

+coracle

+coracoid

+corallite

+coralloid

+coralroot

+coranto

+corban

+corbeil

+corbicula

+corbie

+corbusier

+corby

+corcyra

+corday

+cordeliers

+cordierite

+cordillera

+cordilleras

+cordoba

+cordova

+corella

+corelli

+corf

+corfam

+corfu

+corgi

+coriaceous

+corinthians

+coriolis

+corium

+corkage

+corkwood

+cormel

+cormophyte

+corncockle

+corncrake

+corneille

+cornel

+cornelian

+cornetcy

+cornett

+cornflakes

+cornflour

+cornhusk

+corniculate

+cornmonger

+corno

+cornstone

+cornu

+cornute

+corody

+corollaceous

+coromandel

+coronach

+corot

+corozo

+correggio

+corregidor

+correlator

+corrida

+corrientes

+corrival

+corrodent

+corrody

+corrugator

+corsac

+corselet

+corsetry

+corticosterone

+corticotrophin

+cortisol

+cortot

+corunna

+corves

+corvine

+corymb

+coryphaeus

+coryza

+cosa

+cosecant

+cosech

+coseismal

+cosenza

+cosgrave

+cosignatory

+cosmine

+cosmodrome

+cosmoid

+cosmopolis

+cosmotron

+cospar

+coss

+cossie

+costard

+costate

+costermonger

+costotomy

+costrel

+cotan

+cotemporary

+cotenant

+coterminosity

+coth

+cothurnus

+cotidal

+cotonou

+cotopaxi

+cotquean

+cotswold

+cotswolds

+cottbus

+cottian

+cottonade

+cottonweed

+cotyloid

+coucal

+couchant

+couchette

+coulee

+coulibiaca

+couloir

+coulometer

+coulometers

+coumarin

+coumarone

+counterattraction

+counterblast

+countercharge

+counterculture

+counterfactual

+counterglow

+counterinsurgency

+counterposition

+counterproof

+countershade

+countershaded

+countershades

+countershading

+countersubject

+countertype

+counterweigh

+counterword

+counterwork

+courante

+courantyne

+courbet

+courbevoie

+coureur

+courgette

+courlan

+coursework

+courtelle

+courtrai

+couthie

+couvade

+coverdale

+coverley

+coversed

+covin

+cowberry

+cowbind

+cowes

+cowfish

+cowherb

+cowitch

+cowk

+cowley

+cowpat

+cowper

+cowskin

+coxa

+coxalgia

+coxcombry

+coxsackie

+coxswain

+coyotillo

+coz

+crabbe

+crabmeat

+crabstick

+crackbrain

+crackbrained

+cracket

+crackjaw

+cracknel

+cracksman

+cracow

+craddock

+cradlesong

+craigie

+craiova

+crake

+crambo

+cramoisy

+cran

+cranach

+cranage

+cranesbill

+craniology

+craniometer

+craniometry

+craniotomy

+cranko

+crankpin

+cranmer

+crannog

+cranwell

+crapaud

+crapulent

+craquelure

+crashable

+crashaw

+crasis

+crassulaceous

+crassus

+cratch

+craunch

+crawley

+cray

+creamcups

+creamlaid

+creatine

+creatinine

+credendum

+creel

+creels

+creepie

+cremator

+cremona

+crenel

+creodont

+creophagous

+crepitus

+cressy

+cresylic

+creuse

+crewe

+cribellum

+cricoid

+crikey

+crim

+crimmer

+crimple

+crimplene

+cringle

+crinite

+crinkleroot

+criollo

+cripes

+crippen

+cripps

+criseyde

+crispate

+crispation

+crispbread

+crispi

+crissum

+crista

+cristate

+cristobalite

+croce

+crocein

+crocidolite

+crocoite

+croesus

+crombec

+cromlech

+cronk

+cronus

+crosier

+crossbeam

+crosscheck

+crosse

+crossfire

+crosshead

+crossjack

+crossopterygian

+crosspool

+crossruff

+crosstabulate

+crosstabulation

+crosstie

+crossties

+crotone

+crotonic

+croute

+crowboot

+crownpiece

+crownwork

+croze

+crozier

+cru

+cruces

+crucian

+cruck

+cruiserweight

+cruiseway

+crumhorn

+crummock

+crunode

+crura

+crural

+crus

+crusado

+cruse

+cruyff

+cruzado

+cruzeiro

+crwth

+cryer

+cryocable

+cryohydrate

+cryometer

+cryophyte

+cryoplankton

+cryptaesthesia

+cryptanalyze

+cryptoclastic

+cryptocrystalline

+cryptogam

+cryptozoic

+cryptozoite

+crystallographica

+ctenidium

+ctenoid

+ctenophore

+ctesiphon

+cubane

+cubeb

+cubiculum

+cubital

+cucking

+cuckooflower

+cuckoopint

+cuculiform

+cudbear

+cudgerie

+cudweed

+cuenca

+cuernavaca

+cuesta

+cufic

+cuirass

+cuirassier

+cuisse

+culch

+culebra

+culet

+culicid

+cullet

+cullis

+culloden

+cully

+culm

+culmiferous

+cultrate

+culverin

+cum

+cumae

+cumber

+cumbernauld

+cumbria

+cummerbund

+cumquat

+cumshaw

+cumulet

+cumuliform

+cumulonimbus

+cumulostratus

+cunaxa

+cuneal

+cuneo

+cunjevoi

+cupel

+cuppa

+cuprum

+curacy

+curare

+curarine

+curassow

+curch

+curiosa

+curitiba

+curlpaper

+currajong

+currawong

+currycomb

+curtin

+curzon

+cusco

+cusec

+cush

+cushat

+cusk

+cuso

+customable

+custos

+custumal

+cutcherry

+cuticula

+cutin

+cutis

+cuttack

+cuttle

+cutty

+cuvette

+cuxhaven

+cuyp

+cuzco

+cwmbran

+cyan

+cyanamide

+cyanine

+cyanite

+cyanocobalamin

+cyanogen

+cyanohydrin

+cyanosis

+cyanotype

+cybele

+cyber

+cybernate

+cyclamen

+cyclicity

+cycloalkane

+cyclograph

+cycloheptatrienyl

+cyclohexane

+cyclohexyl

+cyclonite

+cycloparaffin

+cyclopedia

+cyclopentadienyl

+cyclopentane

+cycloplegia

+cyclopropane

+cyclosis

+cyclostome

+cyclostyle

+cyclothymia

+cyclotomy

+cyder

+cydnus

+cylindroid

+cylix

+cyma

+cymar

+cymatium

+cymbalo

+cyme

+cymene

+cymogene

+cymograph

+cymoid

+cymophane

+cymose

+cymru

+cynghanedd

+cyperaceous

+cyprinid

+cyprinodont

+cyprinoid

+cypsela

+cyrenaica

+cyrene

+cystectomy

+cysticercoid

+cystine

+cystitis

+cystocarp

+cystocele

+cystoid

+cystolith

+cystoscope

+cystotomy

+cythera

+cytidine

+cytochemical

+cytochemically

+cytochrome

+cytogenesis

+cytogenetics

+cytokinesis

+cyton

+cytoplast

+cytotaxonomy

+cyzicus

+czardas

+czarevna

+dabchick

+dabster

+dace

+dacha

+dachau

+dachsund

+dacia

+dacoit

+dacoity

+dacron

+dactylogram

+dactylography

+dactylology

+dado

+dadra

+dagan

+dagga

+daggerboard

+dagoba

+dagon

+daguerre

+dahna

+daimyo

+dairen

+daisycutter

+dak

+dal

+daladier

+dalai

+dalasi

+dalesman

+dalhousie

+dallapiccola

+dalmatia

+damietta

+damodar

+dampcourse

+dampier

+damselfish

+dandie

+dandiprat

+daraf

+darbies

+dardanelles

+dardanus

+daresbury

+darfur

+darg

+dargah

+daric

+dario

+dariole

+darkend

+darlan

+darmstadt

+darnel

+darnley

+darogha

+dartboard

+dasheen

+dashiki

+dashpot

+dassie

+dasyure

+databank

+datary

+datatype

+datcha

+dato

+datolite

+datuk

+daube

+daubery

+daubigny

+daudet

+daugava

+daugavpils

+daumier

+davao

+daw

+dawes

+dayak

+dayan

+dayboy

+dayfile

+dayflower

+dayfly

+dayspring

+deaconry

+deadstarting

+deakin

+dealfish

+dearchive

+dearchived

+dearchives

+dearchiving

+deary

+deassignment

+deathtrap

+debag

+debarred

+debe

+debrecen

+debs

+debus

+debye

+decanal

+decane

+decanedioic

+decani

+decanoic

+decapolis

+decarboxylation

+decastyle

+deccan

+decelerometer

+decemvirate

+decenary

+decentralist

+decern

+decimetric

+decisionmaker

+declinometer

+declog

+declogged

+declogging

+declogs

+decluster

+declustered

+declustering

+declusters

+declutch

+declutched

+declutches

+declutching

+decoke

+decompound

+deconstruct

+decreet

+decubitus

+decurion

+decurrent

+decury

+dedal

+deek

+deemster

+deergrass

+deerhound

+deferable

+defilade

+definiendum

+definiens

+deflocculate

+degassed

+degasses

+deglutinate

+deglutition

+degression

+degust

+dehisce

+dehiscent

+dehorn

+dehra

+dehydrogenase

+dehydrogenate

+dehydroretinol

+deianira

+deicide

+deictic

+deific

+deiform

+deil

+deipnosophist

+deixis

+dejecta

+dekker

+dekko

+delacroix

+delagoa

+delaine

+delaunay

+dele

+deledda

+delegatory

+delgado

+delimeter

+delimeters

+deliquescence

+delitescence

+deltiology

+demavend

+deme

+dement

+demerara

+demesne

+demeter

+demibastion

+demicanton

+demilune

+demimondaine

+demimonde

+demirel

+demirelief

+demirep

+demisemiquaver

+demist

+demivierge

+demivolt

+demob

+democritus

+demoiselle

+demonism

+demonolater

+demonolatry

+demould

+demoulded

+demoulding

+demoulds

+dempster

+demulsify

+demy

+denarius

+denary

+dendral

+dendrochronologist

+dendrochronologists

+dendrochronology

+dendrogram

+dendrograms

+dengue

+denitrate

+deniz

+denning

+dentex

+dentilabial

+dentilingual

+dentoid

+denudate

+deodand

+deodar

+deontic

+deoxygenate

+departmentalism

+depasture

+dependant

+dependants

+depicture

+deplume

+depressomotor

+depside

+depurative

+deraign

+derailleur

+derain

+derbent

+deregister

+deregulatory

+derestrict

+derisible

+dermatitis

+dermatogen

+dermatoglyphics

+dermatome

+dermatophyte

+dermatophytosis

+dermatoplasty

+dermis

+dermoid

+dero

+derringer

+derry

+derv

+derwent

+derwentwater

+desai

+desalinate

+deschamps

+deschool

+descriptional

+descriptivism

+deselect

+deselected

+deselecting

+deselection

+deselections

+deselects

+desicate

+designational

+desinence

+deskill

+deskilled

+deskilling

+desman

+desmid

+desmoid

+desmoulins

+despenser

+despoilation

+despoliation

+despumate

+desquamate

+dessalines

+dessau

+dessertspoon

+dessiatine

+dessicator

+dessicators

+deterge

+detmold

+detrend

+detrended

+detrending

+detrends

+detrition

+detrude

+detruncate

+deurne

+deuteragonist

+deuteranope

+deuteride

+deuterogamy

+deutoplasm

+deutsch

+deva

+devanagari

+deventer

+devi

+devilfish

+dewan

+dewberry

+dewclaw

+dewsbury

+dextran

+dextrin

+dextroamphetamine

+dextroglucose

+dextrogyrate

+dextrorotation

+dextrorse

+dezhnev

+dhahran

+dhak

+dharna

+dhaulagiri

+dhobi

+dhole

+dhoti

+dhow

+diablerie

+diabolo

+diacaustic

+diacetylmorphine

+diacid

+diacidic

+diactinic

+diadelphous

+diadic

+diaeresis

+diagenesis

+diageotropism

+diaghilev

+diagraph

+diallage

+dialogism

+diamantine

+diamegnetism

+diamine

+diamondback

+diandrous

+dianetics

+dianoetic

+dianoia

+diapedesis

+diapente

+diaphoresis

+diaphoretic

+diaphototropism

+diaphysis

+diapir

+diarch

+dias

+diascope

+diastalsis

+diastase

+diastasis

+diastema

+diastyle

+diatessaron

+diathermancy

+diazine

+diazo

+diazole

+diazomethane

+diazonium

+dibasic

+dibbuk

+dibranchiate

+dibromide

+dicarbonyl

+dicast

+dicephalous

+dichasium

+dichlamydeous

+dichloroethanol

+dichromaticism

+dichromic

+dichroscope

+diclinous

+dicuss

+dicynodont

+diderot

+didgeridoo

+didymium

+didymous

+didynamous

+dieback

+diecious

+diefenbaker

+dien

+diencephalon

+dieppe

+diesis

+diestock

+diestrus

+diffusivity

+digamy

+digestant

+digged

+dight

+digitalism

+digitiform

+digitoxin

+digitron

+dihydric

+dihydrofolate

+dikkop

+diktat

+dilatancy

+dilatant

+dilly

+dimashq

+dimenhydrinate

+dimercaprol

+dimethylformamide

+dimethylpropane

+dimethylsulphoxide

+dimetric

+dimissory

+dimity

+dimorph

+dinar

+dineric

+dinge

+dinitrobenzene

+dinitrogen

+dink

+dinkum

+dinky

+dinoflagellate

+dinothere

+dio

+diodorus

+dioestrus

+diol

+diomede

+diomedes

+dionysius

+diophantus

+diopside

+dioptase

+dior

+dioxan

+dipeptide

+dipetalous

+diphenylamine

+diphenylhydantoin

+diphosgene

+diphyletic

+diphyllous

+diphyodont

+diplegia

+diploblastic

+diplocardiac

+diplococcus

+diplont

+diplopia

+diplopod

+diplosis

+diplostemonous

+dipnoan

+dippy

+diprotodont

+dipteral

+dipteran

+dipterocarpaceous

+dipterous

+diriment

+dirk

+dirndl

+disaccredit

+disafforest

+disbranch

+disbud

+discalced

+disciplinant

+disciplinarianism

+disclimax

+discobolus

+discommodity

+discommon

+disconsider

+discotheque

+discovert

+disembogue

+disembroil

+disenable

+disentail

+disentitle

+disentomb

+disentwine

+disepalous

+disforest

+dishpan

+dishtowel

+disject

+disjunctor

+disjunctors

+disoperation

+dispend

+dispermous

+dispersability

+dispersable

+dispersity

+dispersoid

+displayable

+disproven

+dissappear

+disseminule

+dissentious

+dissepiment

+distich

+distichous

+distrainee

+distringas

+distrito

+distrubuted

+disulfiram

+disulphate

+disulphide

+disulphuric

+dita

+ditheism

+dithionite

+dithionous

+dithyramb

+dithyrambic

+dittander

+dittany

+dittography

+diu

+diuresis

+diuretic

+div

+divaricator

+diversiform

+diverticulitis

+diverticulosis

+diverticulum

+divi

+divinylbenzene

+divisibly

+divulgate

+diyarbakir

+dizen

+djailolo

+djaja

+djajapura

+djambi

+djebel

+djerba

+djinni

+djokjakarta

+doab

+dobby

+dobla

+dobro

+dobruja

+dobsonfly

+dockland

+docklands

+doddle

+dodecagon

+dodecanese

+dodecanoic

+dodecaphonic

+dodecasyllable

+dodgem

+dodoma

+doek

+doenitz

+doeskin

+dogfishs

+dogger

+doggo

+dogman

+dogsbody

+dogvane

+dogy

+doh

+doha

+dojo

+dolabriform

+dolby

+dolerite

+dolichocephalic

+doline

+dollarbird

+dollarfish

+dollfuss

+dolman

+dolmas

+dolmen

+dolmetsch

+dolorimetry

+doloroso

+dom

+domett

+dominee

+dominie

+dominium

+dominoes

+donatello

+donatus

+donau

+donbass

+donga

+donjon

+donne

+donnert

+donny

+doodah

+doorframe

+doorn

+doornik

+dopa

+dordogne

+dordrecht

+dormobile

+dornbirn

+dornick

+dorp

+dorpat

+dorsad

+dorsiferous

+dorsigrade

+dorsiventral

+dorsoventral

+dorsum

+dort

+dorty

+dory

+dosshouse

+dost

+dotation

+dottle

+douai

+douala

+douay

+doublure

+doubs

+douc

+douceur

+doukhobors

+doum

+doura

+dourine

+douro

+douroucouli

+dovap

+dowable

+dowding

+dowery

+downcome

+downcomer

+downhole

+downpatrick

+downpipe

+downthrow

+downwash

+downweight

+downweighted

+downweighting

+downwell

+dowsabel

+doxastic

+doxographer

+doxology

+doxy

+doyen

+doyley

+drabbet

+draff

+draggletailed

+draghound

+dragoman

+dragonnade

+dragonroot

+dragrope

+drail

+dramatis

+drammen

+drancy

+drava

+drayhorse

+dree

+dreggy

+dreich

+dreiser

+drenthe

+dresden

+drillstock

+drin

+drinkwater

+dripstone

+drogheda

+drogue

+droit

+dromond

+drongo

+drongos

+droob

+dropsonde

+droshky

+druffen

+drunkeness

+drupelet

+dryopithecine

+drysdale

+drystone

+dubai

+dubbin

+dubrovnik

+dubuffet

+duccio

+duchamp

+dudeen

+duello

+duero

+dufy

+duhamel

+duiker

+duka

+dukhobors

+dulciana

+dulia

+dulosis

+dumas

+dumbell

+dumbells

+dumfries

+dumortierite

+dumyat

+duna

+dunaj

+dunant

+dundalk

+dundee

+dunfermline

+dungas

+dungeness

+dunite

+duniwassal

+dunkerque

+dunlin

+dunnage

+dunnakin

+dunnite

+dunno

+dunnock

+dunny

+dunois

+dunoon

+dunsany

+dunsinane

+dunstable

+dunstan

+dunt

+duntroon

+dunwoody

+duodenary

+duodenitis

+duotone

+dup

+duparc

+dupatta

+dupleix

+duplet

+dupondius

+duppy

+duque

+duramen

+durative

+durazzo

+durbar

+durex

+durgah

+durian

+durmast

+duro

+durra

+durst

+durum

+durzi

+dushanbe

+dustability

+dustable

+dustcart

+dustcarts

+dustmen

+dustsheet

+dustsheets

+duumvir

+duumvirate

+duvalier

+duvet

+dux

+dwale

+dybbuk

+dyfed

+dykes

+dynameter

+dynamicism

+dynamoelectric

+dyscrasia

+dysgraphia

+dysmenorrhoea

+dysphemism

+dyspnoea

+dysteleology

+dysthymia

+dysuria

+dytiscid

+dyula

+ealdorman

+ealing

+eanes

+earbash

+earhart

+earlap

+earless

+earom

+earthlight

+earthman

+earthmove

+earthnut

+earthrise

+eastmost

+eatage

+eblis

+ebon

+ebonite

+ebracteate

+ebullioscopy

+eburnation

+ecbatana

+ecbolic

+ecce

+ecchymosis

+ecclesall

+ecclesia

+ecclesiolatry

+eccrinology

+ecdysone

+ecevit

+echard

+echinate

+echinococcus

+echinoid

+echinus

+echoism

+echolalia

+echopraxia

+echovirus

+eck

+eckhart

+eclampsia

+eclipsis

+eclogite

+ecocide

+ecowas

+ecstacy

+ecthyma

+ectocrine

+ectoenzyme

+ectophyte

+ectopia

+ectoproct

+ectosarc

+ectype

+edale

+edam

+eddo

+eddystone

+ede

+edessa

+edgehill

+edgeworth

+edile

+edirne

+edom

+educatory

+educt

+eelpout

+eelworm

+eff

+effable

+effendi

+efficency

+effusiometer

+efta

+eftsoons

+egest

+egesta

+egis

+eigenfrequencies

+eigenfrequency

+eigenstructure

+eigensystem

+eigensystems

+eiger

+eightsome

+eirenic

+eirenicon

+eisegesis

+eisk

+elaeoptene

+elagabalus

+elam

+eland

+elasmobranch

+elasmosaur

+elastance

+elasticate

+elasticated

+elasticates

+elasticating

+elastoplast

+elat

+elaterid

+elaterin

+elaterium

+elbe

+elbrus

+elburz

+eld

+eldo

+eldritch

+elea

+elecampane

+electrochemist

+electrochemists

+electrograph

+electromerism

+electronvolt

+electrophone

+electrostriction

+electrotechnology

+electrotonus

+electrovalency

+electroviscous

+eleemosynary

+eleia

+elemi

+elenchus

+eleoptene

+eleusis

+elevon

+elflock

+elgon

+elidible

+elis

+elkhound

+eloign

+elsan

+elusion

+elyot

+embolectomy

+embolus

+embow

+embrectomy

+embryectomy

+embus

+emden

+emesis

+emetine

+emf

+emiscan

+emmen

+emmenagogue

+emmer

+emmetropia

+emotivism

+empale

+empassion

+empedocles

+emphasing

+empolder

+empyema

+empyrean

+empyreuma

+emulsoid

+enantiomorph

+enarthrosis

+enate

+encaenia

+enceladus

+encephalin

+encephalograph

+encephalography

+encephaloma

+encephalomyelitis

+enchiridion

+enchondroma

+enchorial

+encomiast

+encrinite

+enculturation

+enderby

+endo

+endocarditis

+endocardium

+endocarp

+endocentric

+endocranium

+endoneurium

+endopeptidase

+endosome

+endostosis

+endothecium

+endothelioma

+endothelium

+endover

+endplate

+endplay

+energid

+energumen

+enface

+enfeoff

+enfilade

+enforcable

+engadine

+engrail

+eniwetok

+ennage

+ennead

+enneagon

+enneahedron

+ennerdale

+ennervation

+ennis

+enniskillen

+ennius

+enosis

+enounce

+enow

+enphytotic

+enschede

+ensor

+entasis

+entebbe

+entelechy

+entellus

+enteritis

+enterogastrone

+enterokinase

+enteron

+enterostomy

+enterotomy

+enterovirus

+enthetic

+enthymeme

+entoblast

+entomic

+entomostracan

+entophyte

+entopic

+entozoic

+entozoon

+entrammel

+entrechat

+entremets

+entresol

+entryism

+entryist

+entryists

+entryname

+entrynames

+entrypoint

+entrypoints

+enugu

+enure

+enuresis

+enver

+enwomb

+enwreath

+enzed

+enzootic

+enzymolysis

+eobiont

+eogene

+eolian

+eolic

+eolipile

+eolith

+eolithic

+eonian

+eos

+eosin

+eosinophil

+epact

+epaminondas

+eparch

+eparchy

+epencephalon

+epenthesis

+epergne

+epexegesis

+ephah

+ephebe

+ephemeron

+ephesians

+ephod

+ephor

+epiblast

+epiboly

+epicalyx

+epicanthus

+epicedium

+epiclesis

+epicontinental

+epicotyl

+epicrisis

+epicritic

+epictetus

+epicycloidal

+epidaurus

+epideictic

+epidiascope

+epididymis

+epidote

+epidural

+epifocal

+epigastrium

+epigeal

+epigene

+epigenous

+epigeous

+epiglottis

+epigone

+epigynous

+epilate

+epileptoid

+epilimnion

+epimere

+epimerism

+epimorphosis

+epimysium

+epinasty

+epinephrine

+epineurium

+epiphenomenalism

+epiphenomenon

+epiphragm

+epiphytotic

+epirogeny

+epirus

+episcopacy

+episematic

+epispastic

+epistasis

+epistaxis

+episternum

+epithalamium

+epithelioma

+epizoic

+epizoon

+epizootic

+eponym

+eponymy

+epos

+epoxide

+epping

+eprom

+eproms

+epyllion

+equifrequent

+equifrequently

+equilibrant

+equimolecular

+equipartition

+equites

+equuleus

+eradiate

+erciyas

+erebus

+eremite

+erepsin

+erethism

+erevan

+erfurt

+ergastoplasm

+ergatocracy

+erhard

+ericaceous

+eridanus

+erinaceous

+eringo

+erinyes

+eris

+eristic

+erith

+erivan

+erk

+erlang

+erlangen

+erlanger

+erlking

+erne

+erotema

+erotology

+erotomania

+errhine

+errupt

+erruptive

+erst

+erubescence

+eruct

+erumpent

+erymanthus

+eryngo

+erysipelas

+erysipeloid

+erythema

+erythrism

+erythrite

+erythritol

+erythroblast

+erythroblastosis

+erythrocyte

+erythrocytometer

+erythromycin

+erythropoiesis

+erzgebirge

+erzurum

+esaki

+esau

+esbjerg

+escalope

+escaut

+eschalot

+escharotic

+eschatology

+escoffier

+escolar

+escribe

+escuage

+escudo

+escurial

+esdraelon

+eserine

+esher

+esky

+espalier

+esparto

+espoo

+esquimau

+esro

+essaouira

+essequibo

+essonite

+essonne

+estancia

+este

+esterase

+esterify

+esthonia

+estienne

+estipulate

+estival

+estivate

+estivation

+estoppel

+estovers

+estrade

+estradiol

+estragon

+estreat

+estremadura

+estrin

+estriol

+etaerio

+etalon

+etamine

+etaoin

+etchant

+eteocles

+eterne

+etesian

+ethene

+etherege

+etherify

+ethmoid

+ethnarch

+ethnobotany

+ethnogeny

+ethonone

+ethoxide

+ethoxyethane

+ethylbenzene

+ethyne

+etiolate

+etna

+etymon

+etzel

+eubacteria

+euboea

+eucaine

+eucalyptol

+euchlorine

+euchromatin

+eucken

+eudemon

+eudemonia

+eudemonics

+eudiometer

+eudoxus

+eugenol

+eulachon

+eulogia

+eupatrid

+eupen

+eupepsia

+euphausiid

+euphonic

+euphorbiaceous

+euphoriant

+euphrasy

+euphroe

+euploid

+eupnoea

+euratom

+eure

+eurhythmy

+euripus

+eurypterid

+eurythermal

+eurytropic

+eusebius

+eusporangiate

+eutectoid

+euxenite

+evacuant

+evaginate

+evanish

+evaporable

+evaporimeter

+evaporimeters

+evite

+exanthema

+exarate

+exarch

+exarchate

+excaudate

+exclaustration

+exeat

+executability

+exedra

+exemplum

+exequatur

+exequies

+exergue

+exigible

+eximious

+exine

+exitance

+exo

+exocarp

+exocentric

+exoderm

+exodontics

+exonym

+exopeptidase

+exophthalmic

+exophthalmos

+exoplasm

+exorable

+exosystem

+exosystems

+exotoxin

+expellant

+experientialism

+explicite

+explicitely

+explicity

+explictly

+exponible

+expressivity

+expresso

+exsanguine

+exsect

+exstrophy

+extention

+extentions

+extine

+extinguishant

+extracanonical

+extrados

+extraposition

+extremadura

+exuviae

+exuviate

+eyas

+eyebath

+eyeblack

+eyehook

+eyeleteer

+eyetie

+eyot

+eyots

+eyra

+eyrir

+eysenck

+fab

+fabaceous

+fabians

+fabius

+fabliau

+fabre

+facebar

+facetiae

+facia

+facilties

+faculae

+fadden

+fadge

+faecal

+faeces

+faenza

+faeroes

+faeroese

+faff

+fagaceous

+fahlband

+faial

+faille

+fairbanks

+fairweather

+fairyfloss

+faiyum

+falbala

+falchion

+falconiform

+falconine

+faldstool

+falerii

+fallal

+fallfish

+falseties

+falsety

+falsework

+falsies

+falster

+faltboat

+falun

+famagusta

+familist

+famulus

+fanagalo

+fandangle

+fanfani

+fanfaronade

+fangio

+fango

+fankle

+fanon

+fantail

+fantasm

+fantast

+fantoccini

+fantom

+faqir

+faradic

+faradism

+farandole

+farci

+farcy

+fard

+fardel

+farinaceous

+farinose

+farl

+farrier

+farriery

+farside

+fart

+fasciate

+fascine

+fash

+fashoda

+fastback

+fastigiate

+fatah

+fatidic

+faucal

+fauces

+faugh

+faunus

+fauteuil

+fauve

+faveolate

+favrile

+favus

+fayalite

+fayum

+feal

+fearnought

+featheredge

+featherstitch

+feaze

+febricity

+febrifacient

+febrifuge

+fechner

+feck

+fecula

+fedayee

+feedbag

+feeze

+feininger

+felafel

+fellmonger

+felloe

+felo

+felucca

+fencible

+fenestella

+fenestra

+fennelflower

+feoff

+feoffee

+feoffment

+ferbam

+fere

+feretory

+fergana

+feria

+fermanagh

+fernandel

+ferrari

+ferreous

+ferricyanic

+ferricyanide

+ferritin

+ferrocene

+ferrochromium

+ferroconcrete

+ferrocyanic

+ferrocyanide

+ferrofluid

+ferrol

+ferromagnesian

+ferromanganese

+ferrosilicon

+ferula

+ferule

+fesse

+festal

+festschrift

+fetial

+feticide

+fetiparous

+fetterlock

+feverfew

+feverwort

+feydeau

+fiacre

+fibrefill

+fibriform

+fibrinogen

+fibrinolysin

+fibrinolysis

+fibrinous

+fibro

+fibroblast

+fibrocement

+fibroid

+fibroin

+fibroma

+fibrositis

+fichte

+ficino

+ficticious

+fid

+fiddlewood

+fideicommissary

+fideicommissum

+fidelism

+fidge

+fidus

+fieldmouse

+fieldpiece

+fieldsman

+fieri

+fiesole

+fifa

+figuline

+figurant

+figwort

+filable

+filariasis

+filecard

+filefish

+filespace

+filestore

+filiate

+filicide

+fillagree

+fillmore

+filmset

+filmsetting

+filoplume

+filose

+filoselle

+fimble

+finable

+finalism

+finchley

+fineable

+finfoot

+fingerbreadth

+fingermark

+fingermarked

+fingermarking

+fingermarks

+fingerstall

+fingerstalls

+fingo

+finisterre

+finitary

+finnan

+finner

+finney

+finnmark

+fino

+finochio

+fiorin

+fipple

+firdausi

+fireback

+firebomb

+firebrat

+firecrest

+firedog

+firedrake

+firenze

+firepan

+firestorm

+firethorn

+firewarden

+firewater

+firkin

+firry

+fishbolt

+fishfinger

+fishgig

+fishskin

+fissipalmate

+fissiped

+fissirostral

+fistmele

+fistula

+fistulous

+fitchew

+fittipaldi

+fitzsimmons

+fiume

+fivepenny

+fivepins

+fizgig

+flabellum

+flagelliform

+flagellum

+flaggy

+flagrante

+flagstad

+flambeau

+flamborough

+flamelet

+flamelets

+flamingoes

+flamininus

+flaminius

+flamsteed

+flanch

+flannelette

+flashcube

+flashcubes

+flasket

+flatette

+flatfish

+flatfishes

+flatlet

+flatlets

+flatling

+flatmate

+flatmates

+flatways

+flaubert

+flaunch

+flavescent

+flavin

+flavine

+flavone

+flavoprotein

+flavopurpurin

+flavorous

+flaxman

+fleabite

+fleabites

+fleam

+fleapit

+fleapits

+fledgy

+flense

+fleurette

+fleury

+flexitime

+flexo

+fley

+fleysome

+flinders

+flitch

+flite

+floccose

+flocculant

+flocculants

+flocculent

+flocculus

+floccus

+flodden

+flong

+floreated

+flores

+florey

+floribunda

+florilegium

+florio

+flory

+flos

+flotow

+flowability

+flowerbed

+flowerless

+fluorene

+fluoric

+fluorometer

+fluorophore

+fluoroscope

+fluoroscopy

+fluorosis

+fluorosulphuric

+fluviomarine

+fluxmeter

+fluxmeters

+flyback

+flyblow

+flybook

+flyleaves

+flyte

+flytrap

+flytraps

+foch

+fock

+foehn

+foetal

+foetation

+foeticide

+foetor

+fogbow

+fogbows

+fogdog

+foggia

+foie

+foin

+folacin

+foliar

+folie

+foliolate

+foliose

+foliot

+foliots

+folium

+folkestone

+folketing

+folkmoot

+folliculin

+folsom

+fonda

+fondant

+fondants

+fonseca

+fontanelle

+fonteyn

+footpaths

+footplate

+footplates

+footsie

+footslogged

+footslogging

+footstalk

+footstock

+footworn

+foramen

+foraminifer

+forasmuch

+forby

+forcemeat

+fordone

+forecourse

+forecourt

+forecourts

+foredo

+foredoom

+foredoomed

+forefend

+foregut

+forehock

+foreshock

+forespent

+forestaysail

+foretooth

+foretop

+foretriangle

+forewent

+forewind

+forewing

+forfar

+forficate

+forgat

+forint

+forme

+formfeed

+formfeeds

+formicary

+formicate

+formication

+formulism

+formwork

+fornenst

+fornix

+forsee

+forseen

+forspeak

+forster

+forsterite

+fortaleza

+fortepiano

+fortis

+fortissimo

+fortuitism

+fortuna

+forwhy

+forzando

+fosbury

+fossa

+fosse

+fossette

+fossick

+fotheringhay

+foucault

+foucquet

+foulard

+fourpence

+fourpenny

+foveola

+fowey

+fowliang

+foxfire

+foyboat

+fractocumulus

+fractostratus

+frae

+fraenum

+fragonard

+fraise

+fraktur

+framboesia

+francolin

+franger

+frangipane

+frankalmoign

+frass

+fratchy

+fraxinella

+freebie

+freedomites

+freelance

+freemartin

+freemason

+freesheet

+freesheets

+freightliner

+fremantle

+fremitus

+frenulum

+frenum

+friarbird

+fricasee

+fringilline

+frippet

+frisket

+froe

+froebel

+frogfish

+frogged

+frogging

+froghopper

+frogmarch

+frogmouth

+frogspawn

+froissart

+frome

+fromenty

+fromm

+fronde

+frondescence

+frons

+frontenac

+frontlet

+frontogenesis

+frontolysis

+frontrunner

+frontwards

+frore

+froude

+frow

+frowst

+fructiferous

+frugivorous

+fruitarian

+frumentaceous

+frumenty

+frunze

+frustule

+frutescent

+fuad

+fubsy

+fuchsin

+fuckwit

+fucoid

+fugacious

+fugard

+fugato

+fugger

+fugio

+fukien

+fukuda

+fukuoka

+fukushima

+fula

+fulani

+fulgurite

+fulmar

+fulminic

+fulminous

+fulvous

+fumaric

+fumatorium

+fumatory

+fumitory

+funchal

+fundi

+fundus

+fundy

+funfair

+fungistat

+funicle

+furan

+furfur

+furfuraceous

+furfuraldehyde

+furfuran

+furioso

+furmenty

+furnivall

+furphy

+furred

+fusain

+fuscous

+fushih

+fushun

+fusionism

+fustanella

+fustic

+futtock

+futurist

+futurists

+futurology

+fuzzily

+fyke

+fylde

+fylfot

+fyn

+fyrd

+gabar

+gabelle

+gaberlunzie

+gabion

+gabionade

+gablet

+gabo

+gabor

+gaborone

+gaby

+gaddafi

+gadhelic

+gadid

+gadoid

+gadolinite

+gadroon

+gadsden

+gaea

+gaekwar

+gaffsail

+gagauzi

+gahnite

+gaikwar

+gaillard

+gaiseric

+gaitskell

+gaius

+galactagogue

+galactometer

+galactopoietic

+galah

+galangal

+galantine

+galanty

+galashiels

+galata

+galatians

+galba

+galbanum

+galbraith

+galea

+galileo

+galimatias

+galingale

+galiot

+galipot

+galle

+galleass

+gallfly

+gallia

+galliambic

+galliard

+gallice

+galligaskins

+gallimaufry

+gallinacean

+gallinaceous

+gallinas

+galliot

+gallipoli

+gallipot

+galliwasp

+gallnut

+galloglass

+galloon

+galloot

+gallous

+galoot

+galop

+galsworthy

+galvani

+galvanoscope

+galvanostat

+galvanotropism

+galvo

+galyak

+gama

+gamba

+gambado

+gambrel

+gambrinus

+gamelan

+gamesman

+gametangium

+gametocyte

+gametogenesis

+gametophore

+gametophyte

+gammadion

+gammer

+gamogenesis

+gamopetalous

+gamophyllous

+gamosepalous

+gamp

+gan

+gance

+gand

+gandalf

+gandhi

+gandy

+gandzha

+ganesa

+gangbang

+gangrel

+gangtok

+gangue

+ganister

+ganja

+ganof

+ganoid

+gansey

+gapeworm

+gapped

+garam

+garand

+garbanzo

+garbo

+garboard

+garboil

+gard

+garda

+gardant

+garderobe

+gardiner

+garfish

+garganey

+garget

+garnierite

+garonne

+garpike

+garrick

+gasconade

+gaselier

+gasiform

+gaskell

+gaskin

+gasman

+gasohol

+gasometry

+gasteropod

+gastralgia

+gastroenteric

+gastroenteritis

+gastroenterology

+gastroenterostomy

+gastrolith

+gastrology

+gastropod

+gastroscope

+gastrostomy

+gastrotomy

+gastrotrich

+gastrovascular

+gastrula

+gatehouse

+gatekeep

+gateshead

+gath

+gatling

+gatt

+gauffer

+gaugeing

+gauhati

+gaumless

+gauntry

+gaup

+gaussmeter

+gautama

+gautier

+gavage

+gavial

+gawp

+gaya

+gayomart

+gazankulu

+gazehound

+gaziantep

+gazump

+gdynia

+gean

+geanticline

+gearwheel

+geber

+gec

+gedact

+gedanken

+geelong

+gefilte

+gehlenite

+gelada

+gelatinoid

+gelibolu

+gell

+gelligaer

+gelt

+gemeinschaft

+gemmiparous

+gemmulation

+gemmule

+gemology

+gemot

+gen

+genappe

+generalism

+generalissimo

+genet

+genip

+genipap

+genitor

+genitourinary

+genizah

+genk

+genro

+gens

+genseric

+genstat

+gentianaceous

+gentianella

+genu

+geodynamics

+geognosy

+geoid

+geomechanics

+geometrid

+geophagy

+geosphere

+geostatic

+geostatics

+geosyncline

+geotaxis

+geotectonic

+gera

+gerah

+geraniaceous

+geranial

+geraniol

+geratology

+gerent

+gerenuk

+gerfalcon

+gerlachovka

+germander

+germanicus

+germanous

+germinant

+germiston

+gerona

+geronimo

+gerontological

+gers

+geryon

+gesellschaft

+gesso

+gest

+gestatorial

+gesualdo

+gey

+geyserite

+gezira

+ghat

+ghats

+gibberellic

+gibbsite

+gibeon

+gibli

+gibran

+gid

+gide

+gidgee

+gie

+giftwrap

+gifu

+gigabit

+gigabyte

+gigabytes

+gigaherz

+gigantomachy

+gigli

+gigue

+gilet

+gilgai

+gilgamesh

+gillies

+gillion

+gillray

+gillyflower

+gilolo

+gilsonite

+gilthead

+gimcrack

+gimel

+gimme

+gingiva

+gingivitis

+gink

+ginnel

+giorgione

+giotto

+gip

+gipon

+giraldus

+girandole

+girdlecake

+girgenti

+gironde

+gironny

+girosol

+gisarme

+gish

+gissing

+gittern

+giusto

+glabella

+glabrous

+glacialist

+gladbeck

+gladdon

+gladiate

+gladrags

+glaikit

+glair

+glaive

+glamorgan

+glandule

+glarus

+glaser

+glassman

+glastonbury

+glauce

+glauconite

+glebe

+gleeman

+gleet

+gleiwitz

+glencoe

+glendower

+glenoid

+glenrothes

+gley

+glia

+gliadin

+glissando

+glister

+gliwice

+globate

+globeflower

+globin

+globoid

+globose

+globuliferous

+glochidium

+glockenspiel

+glogg

+glomerate

+glomeration

+glomerule

+glomerulus

+glomma

+glossa

+glossator

+glossectomy

+glosseme

+glossitis

+glossography

+glossology

+glossopharyngeal

+glottic

+glottochronology

+gloze

+glucagon

+glucinum

+glucocorticord

+gluconeogenesis

+glucoprotein

+glucoside

+glucosuria

+glume

+gluon

+glutathione

+glutelin

+gluteus

+glyceric

+glycerophosphate

+glycogenesis

+glycolic

+glycolysis

+glyconeogenesis

+glycoside

+glycosuria

+glyoxaline

+glyphography

+glyptal

+glyptic

+glyptics

+glyptodont

+glyptography

+gnatcatcher

+gnathic

+gnathion

+gnathite

+gnathonic

+gnocchi

+gnosis

+gnotobiotics

+goalmouth

+goanna

+goatfish

+goatherd

+goatsbeard

+goatskin

+goatsucker

+gobbet

+gobi

+gobioid

+gobo

+gobstopper

+goby

+godard

+godavari

+godefroy

+goderich

+godown

+godroon

+gogga

+gogglebox

+goglet

+gogol

+gogra

+goldarn

+goldcrest

+goldeye

+goldilocks

+goldoni

+goldschmidt

+goldthread

+goliard

+goliardery

+golliwog

+gollop

+goloshes

+gombroon

+gomel

+gomorrah

+gompers

+gomphosis

+gomulka

+gomuti

+gonadotropin

+goncourt

+gondar

+gonfalon

+gonfalonier

+gongola

+gonidium

+goniometer

+gonk

+gonna

+gonococcus

+gonocyte

+gonof

+gonophore

+gonopore

+googly

+gook

+goole

+gooney

+goosander

+goosefoot

+goosegog

+goosegrass

+goosy

+gopak

+gorakhpur

+goral

+gorbals

+gorblimey

+goreng

+gorgerin

+gorgias

+gorgoneion

+gorica

+gorizia

+gormless

+gorsedd

+gosport

+gosse

+gossipmonger

+gossipmongers

+gossoon

+goster

+gotama

+gotta

+gouache

+gourami

+gourmont

+goutweed

+gowan

+gower

+gowk

+gowon

+goy

+gracile

+gracioso

+graduand

+gradus

+graecism

+graffito

+grahame

+graiae

+grainger

+grallatorial

+grama

+gramarye

+gramercy

+gramineous

+graminivorous

+grammatology

+grampian

+grampus

+granada

+granadilla

+granados

+grandaunt

+grandmaster

+grandmasters

+granduncle

+granduncles

+grangemouth

+granicus

+graniteware

+granitite

+granodiorite

+granolith

+granophyre

+granta

+granuloma

+granulose

+graphomotor

+grappa

+grappelli

+graptolite

+grasmere

+grassfinch

+grasshook

+grassquit

+grassroot

+gratian

+grattan

+gratulate

+graupel

+grav

+gravamen

+gravenhage

+gravettian

+gravimetrical

+graz

+gree

+greegree

+greeley

+greenaway

+greenbottle

+greenbrier

+greenfinch

+greenfly

+greengage

+greenhead

+greenheart

+greenock

+greenockite

+greensand

+greenshank

+greensickness

+greenstick

+greenstone

+greenstuff

+greige

+gremial

+gressorial

+greuze

+greyback

+greybeard

+greyhen

+greystones

+greywacke

+gribble

+griddlecake

+gridfile

+gridfiles

+grillparzer

+grilse

+grimalkin

+grimsby

+grindelwald

+grindery

+grisaille

+griseofulvin

+griseous

+grisette

+grishun

+griskin

+grisons

+grivation

+grivet

+grockle

+grodno

+grogram

+gromyko

+groningen

+gropius

+gros

+groschen

+grosgrain

+grosseteste

+grosswardein

+grosz

+grot

+grote

+grotius

+groundage

+groundsill

+groundsman

+groundspeed

+groundswell

+groupwork

+grouty

+grovet

+groyne

+grozing

+grozny

+grugru

+grumous

+grundy

+grysbok

+guacharo

+guaco

+guadalajara

+guadalcanal

+guadalquivir

+guadiana

+guaiacum

+guan

+guanabara

+guanaco

+guanajuato

+guanase

+guanosine

+guardafui

+guarneri

+guayaquil

+guayule

+gubbins

+gudeance

+gudrun

+guelders

+guenon

+guesthouse

+guidon

+guienne

+guilloche

+guipure

+guiscard

+guitarfish

+guizot

+gujranwala

+gulag

+gulags

+gular

+gulbenkian

+gulden

+gulfweed

+gumma

+gummite

+gummosis

+gummous

+gumshield

+gumtree

+gunge

+gunnel

+gunpaper

+gunstock

+gunter

+guntur

+gunwale

+gunyah

+gur

+gurdwara

+gurgitation

+gurglet

+gurjun

+gurkhali

+gurnard

+gustavo

+gutbucket

+guthrun

+gutta

+guv

+guyenne

+guyot

+gwalior

+gwelo

+gwent

+gwynedd

+gwyniad

+gyani

+gybe

+gymnasiarch

+gymnasiast

+gymslip

+gynaeceum

+gynaecocracy

+gynaecoid

+gynaecomastia

+gynandrous

+gynarchy

+gynecium

+gyniatrics

+gynophore

+gyronny

+gyrose

+gyrostatic

+gyrostatics

+gyve

+habu

+hachure

+hackamore

+hackbut

+hadaway

+hadhramaut

+hadj

+hadji

+hadrosaur

+hae

+haecceity

+haeckel

+haem

+haemachrome

+haemacytometer

+haemagglutinate

+haemagglutinin

+haemagogue

+haemal

+haematein

+haematemesis

+haematic

+haematin

+haematinic

+haematite

+haematoblast

+haematocele

+haematocrit

+haematocryal

+haematogenesis

+haematogenous

+haematoid

+haematological

+haematology

+haematolysis

+haematoma

+haematopoiesis

+haematosis

+haematothermal

+haematoxylin

+haematozoon

+haematuria

+haemic

+haemin

+haemochrome

+haemocoel

+haemocyanin

+haemocyte

+haemocytometer

+haemodialysis

+haemoflagellate

+haemoglobin

+haemoglobinuria

+haemoid

+haemolysin

+haemolysis

+haemophile

+haemophilia

+haemophiliac

+haemophilic

+haemopoiesis

+haemoptysis

+haemorrhage

+haemorrhagic

+haemorrhoidectomy

+haemorrhoids

+haemostasis

+haemostat

+haemostatic

+haeres

+haftarah

+hagar

+hagbut

+hagfish

+haggadah

+haggai

+hagiarchy

+hagiocracy

+hagiographer

+hagiolatry

+hagiology

+hagioscope

+hahnemann

+haidar

+haig

+haik

+haile

+hainaut

+haiphong

+hairball

+hairgrip

+hairif

+hairnet

+hairtail

+hairweaving

+hairworm

+hajj

+hake

+hakim

+hakluyt

+hakodate

+halafian

+halakah

+halal

+halation

+halberd

+halcyone

+haldane

+haleakala

+halesowen

+halfbeak

+halfwit

+halicarnassus

+hallah

+hallam

+hallel

+hallux

+halm

+halmahera

+halmstad

+halobiont

+haloid

+halophyte

+halothane

+hals

+haltemprice

+hama

+hamadryad

+hamadryas

+hamamatsu

+hamamelidaceous

+hambletonian

+hame

+hamelin

+hameln

+hamersley

+hamhung

+hamilcar

+hamm

+hammerfest

+hammersmith

+hammerstein

+hammurabi

+hampden

+hampstead

+hamshackle

+hamsun

+hamulus

+hamza

+hanaper

+hanau

+handbarrow

+handbell

+handbrake

+handfeed

+handleability

+handstroke

+hangbird

+hangchow

+hankerchief

+hankow

+hannover

+hanratty

+hapax

+haphtarah

+haplite

+haplography

+haplosis

+hapten

+hapteron

+haptic

+hapto

+haptotropism

+harakiri

+harald

+harambee

+harappa

+harar

+hardecanute

+hardhack

+hardicanute

+hardie

+hardily

+harebell

+hargeisa

+haricot

+harijan

+harikari

+harmattan

+harmonist

+harmonograph

+harmonographs

+harmotome

+harney

+harpenden

+harquebus

+harquebusier

+harrar

+harrogate

+harslet

+hartal

+harte

+hartebeest

+harthacanute

+hartlepool

+hartnell

+hartree

+hartshead

+harun

+haruspex

+harvestmen

+harwell

+harwich

+haryana

+harz

+hasa

+hasdrubal

+hashemite

+hask

+haslet

+hassan

+hasselt

+hatchback

+hatpin

+hatshepsut

+haubergeon

+hauberk

+haugh

+haulm

+hauraki

+haustellum

+haustorium

+havant

+havel

+havelock

+havildar

+havre

+hawes

+hawfinch

+hawhaw

+hawkbill

+hawksbill

+hawkweed

+haworth

+hawse

+hawsehole

+hawsepipe

+haybox

+hazelhen

+hazlitt

+headlamp

+headrace

+headrail

+headreach

+headscarf

+headsquare

+headward

+headwards

+heald

+healds

+hearths

+heartworm

+heathberry

+heathfowl

+heaume

+hebbel

+hebephrenia

+hebetate

+hebetic

+heckelphone

+hectocotylus

+hedjaz

+heehaw

+heelpost

+heenan

+heerlen

+heffer

+hegira

+hegumen

+heh

+heiduc

+heilbronn

+heilungkiang

+heirdom

+heitiki

+heitler

+hejira

+hekate

+hekla

+hel

+helichrysum

+helicline

+helicograph

+heliolithic

+heliotherapy

+heliotropin

+heliotype

+hellbent

+helle

+hellery

+helles

+helmand

+helminth

+helminthiasis

+helminthic

+helminthology

+helmont

+helpmann

+helsingborg

+helvellyn

+hemel

+hemelytron

+hemeralopia

+hemialgia

+hemianopsia

+hemicellulose

+hemichordate

+hemicycle

+hemidemisemiquaver

+hemielytron

+hemiola

+hemipode

+hemipteran

+hemipterous

+hemispheroid

+hemistich

+hemiterpene

+hemstitch

+henbit

+hencoop

+hendecagon

+hendecahedron

+henge

+hengelo

+hengist

+henhouse

+hepcat

+hepplewhite

+hepta

+heptad

+heptadecanoic

+heptahedron

+heptamerous

+heptangular

+heptarchy

+heptastich

+heptatriene

+heptavalent

+heptose

+hepworth

+heraclea

+heracles

+herakleion

+herby

+hercegovina

+herculaneum

+hereat

+heredes

+hereditable

+hereditist

+hereinto

+heresiarch

+hereward

+heriot

+herisau

+herl

+herm

+hermannstadt

+hermon

+hermosillo

+hermoupolis

+herne

+herniorrhaphy

+herod

+herodias

+herophilus

+herrick

+herriot

+herstmonceux

+hesiod

+hesperidin

+hesperidium

+hestia

+hetaera

+hetaerism

+heterocercal

+heterochromatic

+heterochromatin

+heterochromatins

+heterochromosome

+heterochromous

+heteroclite

+heterodactyl

+heterodont

+heterogenous

+heterography

+heterogynous

+heterolecithal

+heterologous

+heteromerous

+heteronym

+heteroplasty

+heterosporous

+heterostyly

+heterotaxis

+heterothallic

+heterotopia

+heth

+hevelius

+hevesy

+hexachloroethane

+hexachlorophene

+hexachord

+hexacosanoic

+hexadecane

+hexaemeron

+hexamerous

+hexangular

+hexanoic

+hexapla

+hexapody

+hexastich

+hexastyle

+hexavalent

+hexene

+hexone

+hexosan

+hexose

+hexyl

+hexylresorcinol

+heyduck

+heyerdahl

+hibernaculum

+hic

+hiddenite

+hiemal

+hieracosphinx

+hierocracy

+hierodule

+hierogram

+hierology

+hierophant

+highchair

+highjack

+highlife

+highveld

+hijaz

+hijinks

+hilla

+hillery

+hillfort

+hilliard

+hillingdon

+hilus

+hilversum

+himachal

+himalayas

+himeji

+himmler

+hin

+hinckley

+hindgut

+hindoo

+hindustan

+hinny

+hinshelwood

+hipparch

+hipparchus

+hippolyta

+hiragana

+hircine

+hiri

+hirohito

+hiroshige

+hirundine

+hispid

+histiocyte

+histogen

+histogenesis

+histoid

+histone

+historiated

+hitparade

+hmso

+hoactzin

+hoad

+hoarhound

+hoatching

+hoatzin

+hobbema

+hochhuth

+hockney

+hodden

+hodeida

+hodman

+hodometer

+hoek

+hofei

+hofmannsthal

+hofuf

+hogarth

+hogg

+hogged

+hogmanay

+hognosed

+hogtie

+hogue

+hogweed

+hohenlinden

+hohenlohe

+hohenstaufen

+hoick

+hoicks

+hoiden

+hokkaido

+hokku

+hokusai

+holarctic

+holbein

+holinshed

+holkar

+holmic

+holocaine

+holoenzyme

+holofernes

+holoplankton

+holothurian

+holp

+holpen

+hols

+holyhead

+holyoake

+holytide

+homebuild

+homecome

+homecraft

+homeopaths

+homeown

+homocentric

+homochromous

+homocyclic

+homodont

+homogenous

+homophobe

+homophobes

+homotaxis

+homothermal

+honan

+honecker

+honegger

+honewort

+honeybunch

+honeysucker

+honiara

+hoo

+hoofbound

+hoogh

+hooghly

+hooke

+hooknose

+hoopoe

+hoopoes

+hoovered

+hoovering

+hoovers

+hopeh

+hoplology

+hoppus

+hopsack

+horae

+horal

+hordein

+horeb

+horme

+hormuz

+hornbook

+hornby

+hornfels

+hornstone

+horologe

+horologium

+horoscopy

+horripilation

+horsa

+horsebox

+horseboxs

+horseleech

+horseleeches

+horseriding

+horst

+horta

+horthy

+horticulturalist

+hortus

+hosea

+hosier

+hospitalet

+hospitaller

+hospodar

+hosteller

+hostelling

+hostie

+hotien

+hotplate

+hotpot

+hotspur

+hottie

+houdon

+houmous

+hounslow

+housebuilding

+housecarl

+housel

+houseleek

+houseleeks

+houseline

+housemaster

+housemasters

+housman

+houting

+hovercraft

+hoverport

+hovertrain

+hovertrains

+howdah

+howitzer

+howlet

+howrah

+howtowdie

+hoxha

+hoylake

+hradec

+hrvatska

+hsi

+hsian

+hsiang

+hsining

+hsinking

+hua

+huambo

+huang

+hubble

+hubli

+huckel

+huckle

+hucklebone

+huelva

+huesca

+hufuf

+huggermugger

+hughie

+huhehot

+hula

+hulme

+humber

+humberside

+humblebee

+hunan

+hungnam

+huns

+huntingdon

+hunyadi

+huon

+hupeh

+huppah

+hurds

+hurstmonceux

+hus

+husain

+husein

+hushaby

+huss

+hussein

+husserl

+hutchie

+hutment

+hutu

+huygens

+huysmans

+hwang

+hwyl

+hyaluronic

+hydantoin

+hydathode

+hydatid

+hyderabad

+hydnocarpate

+hydnocarpic

+hydracid

+hydrastinine

+hydrazoic

+hydria

+hydriodic

+hydrobromic

+hydrocele

+hydrocellulose

+hydrocoral

+hydrocortisone

+hydrogenolysis

+hydrogenous

+hydrograph

+hydrolyte

+hydromedusa

+hydromel

+hydrometallurgy

+hydrometeor

+hydronaut

+hydrophilous

+hydropower

+hydroquinone

+hydrostat

+hydrosulphate

+hydrosulphide

+hydrosulphurous

+hydrotaxis

+hydrotherapeutics

+hydroxonium

+hydroxylamine

+hyetograph

+hyetography

+hygristor

+hygrophilous

+hygrostat

+hyksos

+hylomorphism

+hylophagous

+hylotheism

+hylozoism

+hymenopteran

+hymenopterous

+hymettus

+hymnist

+hyoid

+hyoscyamine

+hypabyssal

+hypaesthesia

+hypaethral

+hypallage

+hypanthium

+hyperaemia

+hyperbaton

+hypercatalectic

+hypercorrect

+hypercorrection

+hyperdulia

+hyperextension

+hyperfocal

+hyperglycaemia

+hyperinsulinism

+hyperion

+hyperkinesia

+hypermarket

+hyperpnoea

+hyperpyrexia

+hyperstability

+hyperstable

+hypersthene

+hyperterm

+hyperterms

+hypervitaminosis

+hypesthesia

+hypethral

+hyphae

+hypnology

+hypnopaedia

+hypnopompic

+hypoacidity

+hypoblast

+hypochondrium

+hypocotyl

+hypoderm

+hypoeutectic

+hypogastrium

+hypogeal

+hypogene

+hypogenous

+hypogeous

+hypogeum

+hypoglossal

+hypoglycaemia

+hypognathous

+hypogynous

+hypoid

+hypolimnion

+hypomania

+hyponasty

+hyponitrite

+hyponitrous

+hypophosphate

+hypophosphite

+hypophosphoric

+hypophosphorous

+hypophyge

+hypophysis

+hypopituitarism

+hypoplasia

+hypoploid

+hypopnoea

+hyposthenia

+hypostyle

+hyposulphite

+hyposulphurous

+hypotaxis

+hypothec

+hypoxanthine

+hyracoid

+hyrax

+hyrcania

+hyssop

+hysterogenic

+hysteroid

+hysterotomy

+hystricomorph

+iamb

+iata

+iatric

+ibadan

+ibarruri

+ibert

+ibibio

+ibiza

+ichang

+ichinomiya

+ichnography

+ichnology

+ichor

+ichthyic

+ichthyoid

+ichthyolite

+ichthyology

+ichthyophagous

+ichthyosaur

+ichthyosis

+iconium

+iconomatic

+iconostasis

+icterus

+ictinus

+ictus

+ide

+ideatum

+identifers

+identikit

+ideosyncrasies

+ideosyncrasy

+idioblast

+idiopathy

+idiophone

+idiosyncracies

+idiosyncracy

+idocrase

+idolum

+idun

+ieper

+ieyasu

+ife

+igbo

+igdrasil

+igfet

+ignis

+ignitability

+ignoratio

+ignotum

+igraine

+ihram

+ikan

+ikebana

+ikeja

+ikhnaton

+ilea

+ileac

+ileitis

+ileostomy

+ilesha

+ileus

+ilex

+ilia

+iliamna

+iligan

+ilion

+ilium

+ilkley

+illampu

+illawarra

+illich

+illimani

+illinium

+illocution

+illude

+illyria

+illyricum

+ilmen

+iloilo

+ilorin

+imagen

+imbros

+iminourea

+immersionism

+immobilism

+immortelle

+immoveables

+immunoassay

+immunoglobulin

+immunomicrosphere

+immunoreaction

+impanation

+imparipinnate

+imparisyllabic

+impaste

+impasto

+impearl

+impeccant

+impedimenta

+impennate

+imperium

+imperscriptible

+impetigo

+imphal

+impi

+implacental

+impolder

+impolicy

+imponderabilia

+imponent

+imposable

+impostume

+impower

+impresa

+imprescriptible

+impressure

+imprest

+improbity

+imroz

+inappellable

+inapprehensive

+inarch

+inartificial

+inbeing

+incaparina

+incapsulate

+incardinate

+incensory

+inchmeal

+inchon

+incipit

+incisure

+incluse

+incomprehensive

+incrementation

+incunabula

+indaba

+indeces

+indene

+indetermine

+indexation

+indigestive

+indigoid

+indiscernability

+indo

+indoleacetic

+indolebutyric

+indomethacin

+indophenol

+indore

+indorsee

+indoxyl

+indra

+indre

+induna

+induplicate

+indusium

+indy

+inearth

+inequable

+inerrable

+inescutcheon

+inessive

+inextirpable

+infallibilism

+infante

+infare

+infeudation

+infibulate

+infight

+infill

+infold

+infracostal

+infralapsarian

+infulae

+infundibuliform

+infundibulum

+infuscate

+infusionism

+inge

+ingeminate

+ingenerate

+ingesta

+ingleborough

+inglenook

+ingoing

+ingolstadt

+ingraft

+ingravescent

+ingres

+ingulf

+inhambane

+inhaul

+inhesion

+inkberry

+inkblot

+inlace

+inmesh

+inmigrant

+inniskilling

+innoxious

+innsbruck

+innumerate

+innutrition

+inoculable

+inodorous

+inofficious

+inqilab

+insalivate

+inscape

+insectarium

+inshrine

+insipience

+insnare

+insomuch

+instalation

+installant

+inswing

+intarsia

+integrant

+integratable

+intendancy

+interagency

+interbedded

+interchannel

+interconnectable

+interconsole

+interflow

+interfluent

+interfluve

+intergranal

+interjacent

+interlaken

+interlap

+interlay

+interlocation

+interlunation

+intermesh

+intermigration

+intermittency

+interosculate

+interpage

+interparticle

+interpellant

+interphone

+interpolant

+interprete

+interpretes

+interradial

+interrex

+interrobang

+interrogable

+interstratify

+intersystem

+intertexture

+intertrigo

+intracoastal

+intranational

+intranuclear

+intrasocietal

+intratelluric

+intravasation

+intuc

+intuitivism

+intwine

+inuit

+inurbane

+invercargill

+involucel

+involutory

+invultuation

+inwrap

+inyala

+iodism

+iodometry

+iolite

+iona

+ionone

+ionopause

+iontophoresis

+iphigenia

+ipoh

+ipsambul

+ipsus

+ipswich

+iqbal

+iquique

+iquitos

+iracund

+irade

+irbid

+irbil

+irenicon

+irian

+iridectomy

+irido

+iridotomy

+iritis

+ironbark

+ironfounding

+irradiant

+irrelievable

+irremissible

+irretentive

+irriguous

+irtysh

+isagoge

+isagogics

+isallobar

+isar

+isarithmic

+isatin

+isauria

+ischaemia

+ischia

+ischium

+isentropically

+isherwood

+islay

+ismailia

+iso

+isoamyl

+isobath

+isocept

+isochor

+isochroous

+isocracy

+isocrates

+isocyanic

+isocyanide

+isodiametric

+isodiaphere

+isodimorphism

+isodynamic

+isoelectric

+isoelectronic

+isoenergetic

+isogamete

+isogenous

+isogeotherm

+isogloss

+isogon

+isogonic

+isohel

+isohyet

+isolecithal

+isoleucine

+isolex

+isoline

+isologous

+isophone

+isopod

+isoprene

+isopropyl

+isorhythmic

+isosceles

+isoseismal

+isosmotic

+isospondylous

+isostasy

+isosteric

+isotactic

+isothere

+isotone

+isotron

+isotropical

+israfil

+issachar

+issus

+istana

+isthmian

+istle

+istria

+itacolumite

+itaconic

+italicity

+italicy

+ithunn

+ithyphallic

+iulus

+iviza

+ixtle

+iyar

+iyeyasu

+izmir

+izmit

+iznik

+izzard

+jacamar

+jacdaw

+jackeroo

+jackfish

+jackfruit

+jackshaft

+jacksmelt

+jacksnipe

+jackstay

+jackstraws

+jaconet

+jadeite

+jael

+jaffa

+jaffna

+jaguarondi

+jahveh

+jahweh

+jailhouse

+jaipur

+jalap

+jalapa

+jalisco

+jambeau

+jambi

+jambo

+jammu

+jammy

+jamnagar

+jampan

+jamshedpur

+jamshid

+jana

+janata

+janina

+jarl

+jarp

+jarrah

+jarrow

+jarry

+jarvey

+jassy

+jato

+javari

+jawan

+jawara

+jawbreak

+jaxartes

+jayawardena

+jaywalk

+jebel

+jedda

+jefe

+jehad

+jehol

+jehoshaphat

+jehu

+jekyll

+jellaba

+jellicoe

+jellify

+jellybean

+jemadar

+jemappes

+jembe

+jequirity

+jerba

+jerbil

+jerboa

+jerez

+jerid

+jerreed

+jevons

+jewelfish

+jewfish

+jhansi

+jhelum

+jibbons

+jibouti

+jidda

+jiggermast

+jihad

+jillaroo

+jillion

+jilolo

+jinghis

+jinja

+jinnah

+jipijapa

+jissom

+jitterbugger

+jitterbugging

+jiujitsu

+jobcentre

+jobcentres

+jobname

+jocko

+jodhpuri

+jodrell

+joffre

+jogged

+jogjakarta

+johore

+jokjakarta

+jollify

+jolo

+jongleur

+jonnock

+jook

+joppa

+jordaens

+jorum

+jos

+josquin

+jota

+jotter

+jotun

+joual

+journalled

+jowett

+joypop

+juba

+jubbah

+jube

+judezmo

+judicative

+judicator

+judogi

+judoka

+jugal

+jugfet

+juggins

+juglandaceous

+jugulate

+jugum

+jugurtha

+juiz

+jullundur

+jumbuck

+jumna

+juncaceous

+jungfrau

+junkman

+jupon

+juratory

+juryman

+jus

+justiceship

+justiciary

+justle

+juvenal

+kabalega

+kabaragoya

+kabbala

+kabob

+kachang

+kachina

+kadi

+kadiyevka

+kaduna

+kaffirs

+kafiristan

+kagera

+kagoshima

+kagu

+kaiak

+kaieteur

+kaif

+kaifeng

+kail

+kailyard

+kain

+kainogenesis

+kairouan

+kaka

+kakapo

+kakemono

+kaki

+kalat

+kalends

+kaleyard

+kalgan

+kalgoorlie

+kali

+kalian

+kalidasa

+kalif

+kalimantan

+kalinin

+kaliningrad

+kalisz

+kaliyuga

+kalmar

+kalong

+kalpa

+kalpak

+kalsomine

+kaluga

+kama

+kamakura

+kamala

+kamasutra

+kame

+kamerun

+kamet

+kami

+kampong

+kampuchea

+kamseen

+kana

+kanamycin

+kananga

+kanara

+kanazawa

+kanchenjunga

+kanchipuram

+kandahar

+kandy

+kanga

+kangwane

+kannada

+kano

+kanpur

+kansu

+kantar

+kanu

+kanzu

+kaohsiung

+kaolack

+kaoliang

+kaon

+kapellmeister

+kaph

+karabiner

+karafuto

+karaganda

+karakoram

+karakorum

+karamanlis

+karbala

+karelia

+kariba

+karnataka

+karoo

+kaross

+kart

+karyogamy

+karyokinesis

+karyolymph

+karyolysis

+karyoplasm

+karyosome

+karyotin

+karyotype

+kasai

+kasbah

+kasher

+kashgar

+kashmir

+kassa

+kassala

+kassel

+kat

+katabasis

+katabolism

+katakana

+katanga

+katar

+kathak

+katharevusa

+katharsis

+kathiawar

+katmai

+katsina

+kattegat

+katzenjammer

+kauai

+kaunas

+kaunda

+kauri

+kaveri

+kawasaki

+kayseri

+kazachok

+kazakh

+kazan

+kazantzakis

+kazbek

+kea

+kean

+kearney

+keble

+keck

+ked

+kedah

+kedge

+kedgeree

+kediri

+kedron

+keef

+keelung

+keepnet

+kef

+keffiyeh

+kegler

+keister

+keitel

+keitloa

+kekkonen

+kelantan

+keloid

+kelpie

+kelt

+kelter

+kemal

+kemble

+kemerovo

+kempe

+kempis

+kempt

+kenaf

+kendal

+kendo

+kenogenesis

+kenosis

+kenspeckle

+kente

+kentledge

+kenyatta

+keos

+kep

+kerala

+keramic

+keramics

+keratin

+keratitis

+keratogenous

+keratoid

+keratoplasty

+keratose

+keratosis

+kerb

+kerbaya

+kerbela

+kerbing

+kerbstone

+kerch

+kerf

+kerguelen

+kerkrade

+kerman

+kermes

+kermis

+kermits

+kero

+kerouac

+kersey

+kerseymere

+kesselring

+kesteven

+ketonuria

+ketoxime

+kevel

+kew

+kewpie

+kex

+keytop

+keytops

+kickdown

+kicksorter

+kicktail

+kidd

+kiddle

+kidron

+kief

+kike

+kilung

+kimberley

+kimberlite

+kina

+kinabalu

+kinase

+kincardine

+kinchinjunga

+kincob

+kinematograph

+kingbolt

+kingcraft

+kingcup

+kingwana

+kinin

+kino

+kioto

+kirtle

+kitbag

+kitbags

+kitchenless

+kitenge

+kithara

+kittiwake

+kitwe

+kiushu

+klaipeda

+klepht

+klieg

+klong

+klootchman

+klopstock

+knackwurst

+knag

+knap

+knar

+knawel

+knickpoint

+kniferest

+knop

+knossos

+knotgrass

+knotwork

+knurly

+koa

+koan

+kob

+kobarid

+kobe

+kobold

+kochi

+kodok

+koel

+kofta

+koftgar

+kofu

+kokura

+kolar

+kolding

+koniology

+konya

+koodoo

+koph

+korfball

+koto

+kurchatovium

+kyanite

+kylin

+kylix

+kyloe

+kymograph

+kymric

+kymry

+kyphosis

+kythera

+labarum

+labe

+labefaction

+labiche

+labionasal

+labiovelar

+lablab

+labret

+labroid

+labrum

+labuan

+labyrinthodont

+laccolith

+lacedaemon

+lacerant

+lacertilian

+lachlan

+lachryma

+lachrymatory

+laclos

+laconia

+lactalbumin

+lactam

+lactary

+lactescent

+lactiferous

+lactoflavin

+lactometer

+lactophenol

+lactoprotein

+lactoscope

+ladislaus

+ladoga

+ladrone

+ladyfy

+ladysmith

+ladysnow

+laertes

+laevogyrate

+laevorotatory

+laevulin

+laevulose

+laforgue

+lagan

+lagena

+lagerkvist

+lah

+laik

+lairy

+laius

+lala

+lalang

+lalapalooza

+lallans

+lallation

+lamartine

+lambdacism

+lambdoid

+lambkin

+lambrequin

+lamellicorn

+lamellirostral

+lamina

+laminitis

+lammergeier

+lampas

+lampedusa

+lampern

+lampeter

+lampholder

+lampion

+lamppost

+lampposts

+lamprophyre

+lampshade

+lampshades

+lanark

+lanate

+lancejack

+lancelot

+lancewood

+lanchow

+landammann

+landeshauptmann

+landgrave

+landgraviate

+landgravine

+landloper

+landor

+landowska

+landrace

+landscapist

+landscapists

+landseer

+landshark

+landshut

+landsknecht

+landtag

+landwaiter

+lanfranc

+langlauf

+langouste

+langrage

+langres

+langsyne

+langue

+languedoc

+languet

+laniard

+laniary

+laniferous

+lankester

+lanner

+lanneret

+lanose

+lansquenet

+lanthorn

+lanugo

+laoag

+laodicea

+laomedon

+laotze

+lapidate

+lapidify

+lapillus

+lapis

+lapsus

+laptev

+lardon

+largen

+larine

+larisa

+larmor

+larn

+larnax

+larousse

+larrigan

+larrikin

+larrup

+larum

+larwood

+laryngotomy

+lascaux

+lashio

+lashkar

+lasker

+lasket

+lassa

+lassalle

+lassus

+lat

+lateroversion

+lathi

+lathy

+latifundium

+latimer

+latium

+latria

+lattermost

+lauda

+lauraceous

+laurasia

+lauric

+laurier

+laurustinus

+lauryl

+lautrec

+lav

+laval

+lavolta

+lawbreak

+lawes

+lawgive

+lawks

+lawmake

+laxey

+layamon

+layard

+laycock

+layshaft

+lazaretto

+lazio

+lazuli

+lazulite

+lazurite

+leadbelly

+leadwort

+leafcutter

+leafletting

+leakey

+leal

+leaseback

+leat

+leatherhead

+leatherjacket

+leatherwood

+leavis

+leben

+lebkuchen

+leblanc

+lebowa

+lebrun

+lecce

+lech

+lecky

+leconte

+lector

+lecythus

+leet

+leeuwarden

+lefthand

+lefthanded

+leftwing

+leftwinger

+leftwingers

+legaspi

+legnica

+legumin

+lehmann

+lehmbruck

+lehr

+leiria

+leishmaniasis

+leister

+leitrim

+leix

+lek

+lekker

+lely

+leman

+lemniscate

+lemnos

+lempira

+lemuroid

+lenglen

+lengthman

+lentamente

+lentic

+lenticel

+lentigo

+leoben

+lepaya

+lepidopteran

+lepidote

+lepidus

+lepontine

+leporid

+leporine

+leprosarium

+leprose

+leptophyllous

+leptosome

+leptospirosis

+leptotene

+lesbos

+lesseps

+letchworth

+letterset

+leucas

+leuco

+leucocratic

+leucocyte

+leucocytosis

+leucoderma

+leucomaine

+leucopenia

+leucoplast

+leucopoiesis

+leucorrhoea

+leucotomy

+leuctra

+leukas

+leuven

+levalloisian

+leverrier

+leviable

+levkas

+lewes

+lexeme

+lexicology

+lexigraphy

+lexis

+liard

+liase

+liason

+libau

+libava

+libeccio

+liberec

+liberticide

+libia

+lichenin

+lichenology

+lichi

+liddell

+lidice

+liebig

+liebknecht

+liegeman

+liegnitz

+lienal

+lientery

+liestal

+lietuva

+liffey

+liftboy

+liftoff

+ligan

+liger

+ligeti

+ligniform

+lignocaine

+ligroin

+ligula

+liguria

+lii

+likasi

+liklihood

+likuta

+lilburne

+liliaceous

+lilienthal

+liliuokalani

+lille

+lilo

+lilongwe

+limacine

+limassol

+limbate

+limewater

+limicoline

+limicolous

+limitarian

+limoges

+limousin

+linacre

+linalool

+linares

+lincrusta

+linctus

+lindane

+lindesnes

+lindisfarne

+lindwall

+lineate

+lineations

+linefeed

+linefeeds

+linenumber

+linestyle

+linewidth

+lingam

+lingayen

+lingcod

+linguiform

+linguini

+linhay

+linkwork

+linlithgow

+linn

+linnaeus

+linnet

+linnhe

+lino

+linocut

+linolenic

+linstock

+lintwhite

+linz

+lionfish

+lipari

+lipase

+lipchitz

+lipography

+lipoid

+lipoma

+lipophilic

+lipoprotein

+lippe

+lippi

+lippie

+liquefacient

+liquesce

+liquidus

+liquorish

+liripipe

+lisieux

+literae

+lithoid

+lithomarge

+lithometeor

+lithotrity

+littoria

+liu

+livingstone

+livonia

+livorno

+livraison

+livy

+lix

+lixivium

+loadstar

+loadstone

+loanda

+lobengula

+lobito

+lobola

+lobworm

+lochia

+lockyer

+locl

+locoman

+locris

+locum

+lod

+lodi

+lodicule

+loewi

+lofoten

+loganberry

+loganiaceous

+logaoedic

+logicism

+loglog

+logoff

+logography

+logopaedics

+lohengrin

+loiret

+lollapalooza

+lomax

+lombok

+lombroso

+loment

+lomond

+londrina

+longan

+longcase

+longcloth

+longe

+longicorn

+longinus

+longlasting

+longleaf

+longship

+longshore

+longueuil

+longueur

+longus

+longways

+longyearbyen

+loofah

+lookin

+loopy

+loosebox

+lophobranch

+lophophore

+lor

+lordy

+lorentz

+lorica

+lorient

+lorikeet

+lorimer

+lorrain

+lorris

+losey

+lothair

+lothario

+lothian

+lothians

+lothringen

+lotic

+louche

+loudish

+loudspeak

+louth

+louvain

+louvar

+lovage

+lovat

+lovell

+lovey

+lowan

+lowerclassman

+lowestoft

+lowveld

+loyang

+lozengy

+lozi

+lualaba

+luanda

+luang

+luau

+lublin

+lubra

+lubumbashi

+lucarne

+lucca

+luce

+luciferin

+lucilius

+lucullus

+lud

+ludhiana

+ludo

+luff

+luffed

+luffing

+luffs

+lugo

+lugsail

+lugworm

+luichow

+luik

+lumberjacket

+lumbricalis

+lumbricoid

+lumiere

+lumisterol

+lumme

+lumpenproletariat

+lumumba

+luna

+lunarian

+lungan

+lungi

+lungki

+lungworm

+lungwort

+lunik

+luns

+lunula

+lunulate

+lupin

+lurdan

+lurex

+lusatia

+lusus

+luteolin

+lutestring

+luthern

+luthuli

+lutine

+lutist

+luxor

+luxulianite

+lvi

+lvii

+lxi

+lxii

+lxiv

+lxix

+lxvi

+lxvii

+lyallpur

+lyautey

+lycanthrope

+lycaon

+lycaonia

+lycia

+lycopod

+lycurgus

+lydda

+lyddite

+lydgate

+lyell

+lyly

+lymphangial

+lymphangitis

+lymphoadenoma

+lyncean

+lynchet

+lysias

+lysippus

+lysol

+lyssa

+lytic

+lytta

+lytton

+mabela

+mabuse

+macaco

+maccaroni

+macebearer

+macedoine

+machado

+machan

+machel

+machin

+machmeter

+machree

+machu

+macroclimate

+macroencephaly

+macrograph

+macrophysics

+macroprocessor

+macropterous

+macrosporangium

+macrospore

+macrosystem

+macruran

+macula

+macumba

+madafu

+madhya

+madina

+madre

+madrepore

+madura

+madurai

+maduro

+madwort

+maebashi

+maenad

+maestoso

+maestricht

+maewo

+mafeking

+maffick

+mag

+magallanes

+magdalena

+mage

+magen

+maggiore

+magilp

+maginot

+magistery

+magnetochemistry

+magnetopause

+magnetosheath

+magnificats

+magnoliaceous

+magnus

+magot

+magritte

+maguey

+mahabharata

+mahalla

+mahanadi

+maharashtra

+mahewu

+mahjong

+mahometan

+mahratta

+mahseer

+maidan

+maidstone

+maiduguri

+maigre

+maihem

+maikop

+mailcoach

+maillol

+maimonides

+mainbrace

+maintenence

+maintopsail

+mainz

+maiolica

+majunga

+makalu

+makarios

+makeyevka

+makhachkala

+makkah

+makurdi

+makuta

+malabo

+malachi

+malacophyllous

+malacopterygian

+maladdress

+malam

+malang

+malassimilation

+malatesta

+malatya

+maldon

+maleable

+malebranche

+maleic

+malevich

+malherbe

+malihini

+malimprinted

+malines

+malinke

+malkin

+mallam

+mallee

+mallenders

+malleolus

+mallorca

+malm

+malonic

+malonylurea

+malory

+malpighi

+malpighiaceous

+maltha

+malthus

+maltman

+maluku

+malvaceous

+malvern

+malwa

+mamaguy

+mamba

+mamelon

+mamilla

+mamillate

+mammee

+mammet

+mammiferous

+mammilla

+mampara

+manado

+managerialism

+manakin

+manassas

+manasseh

+manaus

+manche

+manchineel

+manchukuo

+manchuria

+mandatorily

+mandi

+mandir

+manet

+mangabey

+mangalore

+manganin

+mangelwurzel

+mangonel

+mangosteen

+mani

+manichaeus

+manilla

+manille

+maninke

+maniple

+manipur

+manisa

+manitoulin

+manizales

+manky

+mannar

+manolete

+manresa

+mansart

+mansholt

+manteau

+mantegna

+mantelletta

+manteltree

+mantilla

+mantinea

+mantoux

+mantova

+manufacturable

+manuka

+manukau

+manus

+manutius

+manyplies

+manzanilla

+manzoni

+maoism

+maputo

+maquette

+mara

+marabunta

+maraca

+maracanda

+maracay

+maraging

+marasca

+marat

+maravedi

+marcasite

+marcellus

+marcescent

+marche

+marcos

+marcuse

+marduk

+mardy

+maremma

+marg

+margaric

+margarite

+margate

+margravate

+margrave

+margravine

+margrethe

+marianao

+maribor

+mariculture

+mariposa

+maritage

+maritain

+maritsa

+marlite

+marmara

+marmite

+marmolada

+maroc

+marocain

+maroquin

+maros

+marprelate

+marquand

+marquesas

+marquessate

+marram

+marrano

+marriageability

+marron

+marryat

+marsilius

+marsipobranch

+martaban

+martagon

+martel

+martellato

+martello

+martineau

+marvell

+marxists

+masaccio

+masan

+masaryk

+masbate

+mascarene

+mascle

+mascon

+masharbrum

+mashhad

+mashie

+masinissa

+masjid

+maskanonge

+masqat

+massa

+massachuset

+massasauga

+massasoit

+massine

+massinissa

+massorete

+massotherapy

+mastaba

+mastigophoran

+mastitis

+masuria

+masurium

+matadi

+matamoros

+matanzas

+matapan

+matchbox

+matchmark

+matchstick

+mathura

+matlo

+matlock

+mato

+matoke

+matopo

+matozinhos

+matrass

+matriclinous

+matrilocal

+matroclinous

+matronage

+matsu

+matsuyama

+mattamore

+matterhorn

+matthias

+mattins

+mattoid

+mattrass

+matzoon

+maubeuge

+mauby

+maui

+maulana

+maulmain

+maulstick

+maumet

+mauna

+maund

+maunder

+maundy

+maungy

+maupassant

+maupertuis

+mauretania

+mauriac

+maurois

+maury

+maurya

+mawger

+mawkin

+mawsie

+maximin

+maximus

+maxint

+maxisingle

+maxixe

+mayday

+mayence

+mayon

+mazard

+mazarin

+mazuma

+mazzini

+mealworm

+meany

+meatus

+mecamylamine

+mechanotherapy

+mechelen

+meck

+meconium

+medan

+medawar

+mediastinum

+medway

+mee

+meed

+meerkat

+meerut

+mega

+megacephaly

+megadeath

+megaflop

+megaflops

+megalocardia

+megalocephaly

+megalosaur

+megapode

+megara

+megaron

+megathere

+megger

+meghalaya

+megiddo

+megilp

+mehemet

+meilhac

+meiny

+meir

+meitner

+mekka

+melanchthon

+melanous

+melaphyre

+melba

+melchior

+meliaceous

+melilla

+melilot

+melinite

+melisma

+melodeon

+meloid

+melos

+meltage

+mem

+memel

+memling

+memoire

+memorex

+memphremagog

+memsahib

+menadione

+menado

+menai

+menam

+menander

+menaquinone

+mencius

+menderes

+mendips

+menes

+mengistu

+meningocele

+menispermaceous

+meno

+menology

+menomini

+menon

+menotti

+mensa

+mentalism

+menuhin

+mepacrine

+meperidine

+meprobamate

+merano

+merbromin

+merca

+mercaptan

+mercaptide

+mercaptopurine

+merchet

+mercia

+mercians

+merengue

+mergui

+meristem

+meristic

+merkin

+merlon

+meroplankton

+merozoite

+merrymake

+merse

+mersin

+merthyr

+mesarch

+mesencephalon

+mesenchyme

+mesenteritis

+mesentery

+meshach

+meshuga

+mesitylene

+mesnalty

+mesobenthos

+mesocephalic

+mesocratic

+mesogastrium

+mesoglea

+mesognathous

+mesolithic

+mesolonghi

+mesomeric

+mesophyll

+mesophyte

+mesothelioma

+mesothelium

+messalina

+messene

+messenia

+messiaen

+messina

+messmate

+messmates

+mestee

+mester

+mestranol

+metacentres

+metacharacter

+metacharacters

+metachromatism

+metacinnabarite

+metafemale

+metagnathous

+metalline

+metallocene

+metallophone

+metamale

+metamer

+metanotion

+metanotions

+metaperiodate

+metaphosphoric

+metaphrase

+metaphrast

+metapolitics

+metaproduction

+metaproductions

+metasymbol

+metasymbols

+metasyntax

+metasyntaxes

+metatheory

+metatherian

+metathorax

+metaxylem

+metchnikoff

+metempirical

+metempirics

+metestrus

+methacrylic

+methaemoglobin

+methenamine

+metho

+methodius

+methotrexate

+methoxide

+meths

+methylcyclohexane

+methyldopa

+methylphthalate

+methylthionine

+metic

+metoestrus

+metonic

+metopic

+metricate

+metrify

+metritis

+metronidazole

+metronymic

+metrorrhagia

+metz

+meu

+meung

+meuse

+mezcal

+mezcaline

+mezereon

+mezereum

+mho

+miaou

+miaul

+micawber

+michelozzo

+mick

+mickery

+mickiewicz

+mickle

+microbalance

+microbalances

+microbarographs

+microbodies

+microbody

+microbrailler

+microchip

+microchips

+microconcrete

+microcrack

+microcracked

+microcracking

+microcracks

+microdetector

+microdont

+microdot

+microfabric

+microgel

+micrographs

+microkink

+microkinking

+micromixing

+micropalaeontology

+microphyte

+micropyrometer

+microsporophyll

+microstomatous

+microswitch

+microswitches

+microsystem

+microsystems

+microtherm

+microtomy

+microwatt

+microwatts

+microwriter

+microwriters

+micrurgy

+middlebreaker

+middlemost

+mideast

+midheaven

+midian

+midinette

+midiron

+midlothian

+mieres

+miffy

+mihrab

+milage

+milazzo

+mileometer

+miletus

+milkfish

+milkhouse

+milkwort

+millais

+millefleurs

+millepede

+millepore

+milli

+milligan

+millrun

+millwheel

+millwheels

+millwork

+milne

+milo

+milometer

+milometers

+milreis

+miltiades

+mimas

+mimetite

+mimir

+mimosaceous

+minacious

+minas

+minch

+mindoro

+mindszenty

+minelayer

+mineralocorticoid

+mineworker

+mineworkers

+minge

+mingus

+minho

+minibike

+minicab

+minicabs

+minimus

+minipill

+ministerialist

+ministerium

+minitab

+minivet

+minna

+minnesinger

+mintoff

+miombo

+mirabeau

+miracidium

+mirador

+miraflores

+mirepoix

+mirk

+mirza

+misallocate

+misallocated

+misallocates

+misallocating

+misallocation

+misapplys

+miscarrys

+misdeclared

+misdefined

+mise

+miseno

+misericord

+miskolc

+mislaid

+misplead

+misposition

+mispositioned

+mispositioning

+mispositions

+missal

+missals

+missel

+missis

+mississauga

+mississipi

+missolonghi

+misspelt

+missus

+mistal

+mistassini

+misti

+mistigris

+mistle

+mistral

+mistrals

+mither

+mithgarthr

+mithridate

+mithridates

+mithridatism

+miticide

+mitis

+mitrailleuse

+mitrewort

+mixolydian

+mizoram

+mizzen

+moa

+moab

+mobutu

+modena

+moderne

+modge

+modigliani

+modillion

+mofette

+mog

+mogador

+mogen

+moho

+mohole

+mohs

+mohur

+moidore

+moirai

+moke

+mokha

+mokpo

+molina

+molise

+mollah

+mollescent

+mollusc

+molluscoid

+molluscs

+mollweide

+molopo

+moltke

+molybdenous

+mombasa

+momism

+monacid

+monadelphous

+monadnock

+monaghan

+monal

+monanthous

+monas

+monaxial

+monazite

+monck

+monecious

+moneme

+monetarist

+moneychanger

+mong

+moniliform

+monkeypot

+monkfish

+monkshood

+monnet

+monoatomic

+monobasic

+monocarp

+monocarpellary

+monocarpic

+monocausal

+monochasium

+monochloride

+monochloroethanol

+monochord

+monoclinous

+monodispersity

+monody

+monohull

+monohydrate

+monohydric

+monohydroxy

+monoicous

+monolatry

+monoliths

+monomark

+monomerous

+mononucleosis

+monopetalous

+monophagous

+monophobia

+monophyllous

+monoplegia

+monopode

+monopodium

+monopteros

+monosemy

+monosepalous

+monosized

+monosodium

+monosome

+monospermous

+monostich

+monostichous

+monostome

+monostrophe

+monostylous

+monothetic

+monotower

+monotropism

+mons

+monsignor

+montagnard

+montagu

+montagues

+montale

+montane

+montauban

+montbretia

+montcalm

+montefiore

+montego

+monteith

+montenegro

+montero

+monterrey

+montesquieu

+montessori

+montfort

+montgolfier

+montherlant

+montmorillonite

+montparnasse

+montpellier

+montreuil

+montreux

+montrose

+monza

+monzonite

+moog

+moolvie

+moonfish

+moonflower

+moonraker

+moonshot

+moonwort

+moorfowl

+moorhen

+moorwort

+mopboard

+mopoke

+moquette

+mor

+mora

+moraceous

+morar

+morava

+morbific

+morbihan

+morbilli

+morcha

+mordecai

+mordred

+morea

+moreau

+morecambe

+moreen

+moreish

+morelia

+morello

+morelos

+morepork

+moresco

+morish

+mornay

+moroni

+morphallaxis

+morphogenesis

+morphophoneme

+morphosis

+morphotype

+morphotypes

+morphy

+morro

+mors

+morula

+morwong

+mos

+mosasaur

+moschatel

+moseley

+moshav

+moshesh

+moskva

+mosley

+mosotho

+mossbunker

+mossie

+mosso

+mosstrooper

+motherfucker

+motherwell

+motherwort

+mothy

+motmot

+motocross

+motorable

+motorbicycle

+motorbus

+motorcoach

+motown

+motte

+motu

+mouflon

+moujik

+mouldboard

+mouldy

+moulmein

+mousebird

+mousetail

+mousseline

+mouthbrooder

+mouthwash

+mouthwatering

+movietone

+moviola

+mowburnt

+moxa

+mucin

+muckamuck

+muckle

+mucksweat

+muckworm

+mucoid

+mucopolysaccharide

+mucoprotein

+mucopurulent

+mucro

+mucronate

+mudcat

+mudfish

+mudir

+mudlark

+mudpack

+mudra

+mudskipper

+mudskippers

+muenster

+muesli

+mufulira

+mugabe

+muggins

+mugwort

+muhammadan

+mujik

+muldoon

+muleta

+muleteer

+mulga

+mulhouse

+mulki

+mulley

+mulliken

+mullock

+mulloway

+multan

+multangular

+multeity

+multicide

+multidrop

+multifid

+multifile

+multiflora

+multifoil

+multifoliate

+multigravida

+multihop

+multihull

+multihulls

+multikey

+multikeys

+multilateralist

+multilateralists

+multimembered

+multinuclear

+multipacket

+multipara

+multiped

+multiplane

+multiplepoinding

+multipunch

+multipunched

+multireel

+multirole

+multiscreen

+multispectral

+multistorey

+multisubject

+multivariable

+multivibrator

+multivocal

+multiway

+multiword

+multure

+mumbo

+mumchance

+munga

+mungo

+muniment

+muniments

+munnion

+munro

+munsell

+munster

+munt

+muntin

+muntjac

+muntz

+murage

+murasaki

+murat

+murcia

+mure

+murex

+muricate

+murine

+murman

+murra

+murrelet

+murrhine

+murrumbidgee

+murther

+musaceous

+muscadel

+muscae

+muscarine

+muscid

+muscleman

+musclemen

+muscovado

+museology

+musil

+musjid

+muskeg

+muso

+musquash

+musset

+mustafa

+mustee

+musteline

+musth

+mutch

+mutchkin

+mutism

+mutsuhito

+muttonhead

+muttra

+mutule

+muzorewa

+muzz

+myalgia

+myalism

+myall

+myasthenia

+mycelium

+mycetoma

+mycetozoan

+mycin

+mycostatin

+mydriasis

+mydriatic

+myelencephalon

+myelin

+myelitis

+myeloma

+myiasis

+mylonite

+myna

+myocardiograph

+myogenic

+myograph

+myology

+myoma

+myope

+myrmecology

+myrmecophagous

+myrmecophile

+myrobalan

+myrtaceous

+mysia

+mystagogue

+mythopoeia

+mytilene

+myxoedema

+myxoma

+myxomatosis

+myxomycete

+myxovirus

+mzee

+mzungu

+nabis

+nabla

+nablas

+nablus

+nabob

+naboth

+nacre

+nae

+naevus

+nagor

+naha

+nailbrush

+nailfile

+nailhead

+nainsook

+naira

+nairn

+naissant

+naker

+nakhichevan

+nakuru

+nalchik

+nalgo

+namangan

+namas

+namelist

+namelists

+namen

+nametape

+namhoi

+namur

+nanak

+nanchang

+nanda

+nanga

+nankeen

+nanning

+nanometric

+nanoplankton

+nanterre

+nantes

+nantung

+naphtali

+naphthyl

+napiform

+nappa

+nara

+narbada

+narceine

+narcoanalysis

+narcosynthesis

+narcotism

+nardoo

+nares

+narial

+nark

+narmada

+narthex

+narva

+narvik

+naseberry

+naseby

+nashe

+nasho

+nasion

+nasofrontal

+nasopharynx

+nasser

+nastase

+natheless

+natrium

+natrolite

+natron

+natsopa

+natter

+natterjack

+naturism

+naturopathy

+nauch

+naucratis

+naumachia

+nauplius

+naur

+nautch

+nautiloid

+navar

+navarin

+navarino

+navarre

+navew

+navicert

+navratilova

+navvy

+naxalite

+naxos

+naze

+ndola

+neagh

+neap

+nearside

+neb

+nebo

+nebuchadnezzar

+neckar

+neckband

+neckcloth

+neckpiece

+neckwear

+necrobiosis

+necrolatry

+necromania

+necrophobia

+necrose

+necrotomy

+neddy

+needlecord

+needlecraft

+needlefish

+needleful

+neep

+nefertiti

+negev

+negresses

+negrillo

+negritude

+negropont

+negros

+neisse

+nek

+nekton

+neman

+nemathelminth

+nemea

+nemertean

+nemery

+nene

+neoarsphenamine

+neocolonialism

+neoconservative

+neoimpressionism

+neoplasty

+neoscholasticism

+neper

+nephogram

+nephograph

+nephology

+nephralgia

+nephridium

+nephrite

+nephritic

+nephritis

+nephron

+nephrosis

+nephrotomy

+nepos

+neral

+nereus

+neritic

+nernst

+neroli

+neruda

+nerva

+nerval

+nervate

+nervine

+nervure

+nesh

+nesselrode

+nessus

+nestorius

+netaji

+netball

+neto

+netsuke

+nett

+neume

+neurasthenia

+neurectomy

+neurilemma

+neuro

+neuroblast

+neurocoele

+neurogram

+neurohypophysis

+neurolemma

+neuroma

+neuropath

+neuropsychiatry

+neuropteran

+neuropterous

+neurotomy

+neurotransmitter

+neurotransmitters

+neurovascular

+neusatz

+neuss

+neustria

+neutretto

+newshawk

+newspeak

+ney

+nez

+niblick

+nicknack

+nickpoint

+nicotinism

+nictheroy

+nictitate

+nictitating

+nidaros

+niddering

+nide

+nidicolous

+nidify

+nidus

+niebuhr

+niello

+niemen

+nieve

+niff

+nightlife

+nightrider

+nightspot

+nightwear

+nigrescent

+nigrify

+nigritude

+nihon

+niigata

+nilgai

+nilgiri

+nim

+nimblewit

+nimonic

+ningsia

+ninus

+niobic

+niobous

+niort

+nipa

+nipigon

+nipplewort

+nippur

+nishinomiya

+nisus

+niton

+nitramine

+nitrobacteria

+nitrochloroform

+nitrohydrochloric

+nitrometer

+nitromethane

+nitroso

+nitrosyl

+nival

+nivation

+niven

+niveous

+nivernais

+nixie

+nizhni

+njord

+nkomo

+nkrumah

+nobbut

+nobiliary

+noctilucent

+noctuid

+noctule

+noesis

+nofretete

+noh

+noil

+noisette

+nolde

+nolle

+nomarch

+nomarchy

+nombles

+nombril

+nome

+nomen

+nomism

+nomocracy

+nonactive

+nonaggression

+nonaligned

+nonanalytic

+nonanoic

+nonappearance

+nonblank

+nonblanks

+noncausal

+noncomputable

+noncontributory

+noncritical

+nondirected

+nondispersive

+noneffective

+nonego

+nonet

+nonevent

+nonexecutable

+nong

+nonharmonic

+nonhierarchic

+nonhierarchical

+nonhuman

+nonidentical

+noninteger

+noninvertible

+nonnumeric

+nono

+nonowner

+nonowners

+nonparametrical

+nonparous

+nonparty

+nonproliferation

+nonrecursive

+nonrecursively

+nonredundant

+nonrelevance

+nonrelevant

+nonsequenced

+nonsmoker

+nonsmokers

+nonstarter

+nonstative

+nonstick

+nonstriated

+nonsuch

+nonsuit

+nonunionism

+nonvocal

+nonvoter

+nonvoting

+noordbrabant

+nopal

+nord

+nordau

+norepinephrine

+norge

+noria

+noricum

+norite

+nork

+norodom

+northmost

+noseband

+nosography

+nostology

+notelet

+noticeboard

+noticeboards

+notifiable

+notitia

+notochord

+notum

+noumenon

+novalis

+novara

+novation

+novaya

+novelese

+novello

+novercal

+nowel

+nowhence

+nowt

+nox

+noyade

+noyau

+noyon

+nubecula

+nubians

+nucha

+nuddy

+nudicaul

+nudum

+nuevo

+nuggar

+nuggety

+nuissance

+nuke

+nukus

+nullah

+nullarbor

+nullifidian

+nullipara

+numantia

+numbat

+numberplate

+numbfish

+numbles

+numdah

+numen

+numerary

+numidia

+nummary

+nummulite

+numnah

+nunatak

+nunc

+nuncio

+nuncle

+nunhood

+nunny

+nureyev

+nuri

+nuristan

+nurmi

+nusa

+nutant

+nutbrown

+nutcase

+nutgall

+nuthouse

+nutlet

+nutter

+nutwood

+nyala

+nyanza

+nyasa

+nyctaginaceous

+nyctalopia

+nyctinasty

+nyctitropism

+nyctophobia

+nye

+nyeman

+nyerere

+nylghau

+nympha

+nymphaeaceous

+nympho

+nystatin

+nyx

+oakum

+oarfish

+oarlock

+oast

+oates

+oba

+oban

+obasanjo

+obconic

+obedientiary

+oblanceolate

+obligato

+obmutescence

+obolus

+obote

+obreption

+obscurum

+obsecrate

+obsequent

+obstipation

+obvolute

+oca

+occasionalism

+occular

+occultate

+oceanid

+oceanus

+ochlophobia

+ochone

+ochrea

+ockeghem

+ocker

+ocode

+octachord

+octad

+octahedrite

+octamerous

+octanedioic

+octangle

+octangular

+octarchy

+octaroon

+octavalent

+octavo

+octocentenary

+octonary

+octu

+octuple

+octylphenylether

+ocularist

+oddfellow

+odense

+odoacer

+odontalgia

+odontoblast

+odontograph

+odontoid

+odontophore

+odovacar

+odra

+odyl

+oecology

+oenone

+oestrin

+oestrogen

+oestrone

+oestrous

+oestrus

+ofay

+offa

+offaly

+offcut

+offcuts

+officinal

+offline

+ogaden

+ogasawara

+ogbomosho

+ogdoad

+ogee

+ogun

+oho

+oilbird

+oilcup

+oilfield

+oilfired

+oise

+oita

+oka

+okavango

+oke

+okta

+oldwife

+oleaceous

+olecranon

+olefine

+olefinic

+oleic

+olein

+oleograph

+oleoresin

+oleum

+olibanum

+olid

+oligopsony

+oligotrophic

+oliguria

+olio

+oliphant

+olivaceous

+olivary

+olivenite

+olivier

+olla

+olm

+ology

+olomouc

+oloroso

+olszyn

+omadhaun

+omagh

+omar

+omasum

+omayyad

+ombre

+omdurman

+ommatidium

+ommatophore

+omnicompetent

+omnific

+omophagia

+omphale

+omphalos

+omuta

+onager

+onagraceous

+onassis

+ondes

+ondo

+ondograph

+ondometer

+onega

+onitsha

+onlook

+onomasiology

+onychophoran

+onymous

+oof

+oogamy

+oogenesis

+oogonium

+ooh

+oolite

+oology

+oolong

+oomiak

+oompah

+oont

+oophorectomy

+oophoritis

+oophyte

+oose

+oosperm

+oosphere

+oospore

+oostende

+ootheca

+ootid

+opah

+opalesce

+ope

+opencast

+operose

+ophicleide

+ophir

+ophthalmia

+ophthalmitis

+opisometer

+opisthobranch

+opisthognathous

+opiumism

+oppidan

+oppilate

+oppugnant

+opsimath

+optacon

+optacons

+optoelectronic

+optometer

+oracy

+oradea

+oran

+orc

+orcein

+orchestrina

+orchidaceous

+orchil

+orchitis

+orcinol

+orczy

+ordinator

+ordinators

+ordonnance

+ordzhonikidze

+oread

+orectic

+orel

+orense

+orfe

+orfray

+organogenesis

+organography

+organoleptic

+organology

+organon

+organotherapy

+organum

+organza

+organzine

+orgeat

+oribi

+oriel

+oriente

+origen

+orinasal

+orissa

+orizaba

+orjonikidze

+orkneys

+orle

+orlon

+orlop

+ormer

+ormolu

+ormuz

+orne

+ornis

+ornithischian

+ornithomancy

+ornithopod

+ornithopter

+ornithoscopy

+ornithosis

+orobanchaceous

+oroide

+orometer

+orontes

+orozco

+orpharion

+orphrey

+orpiment

+orpine

+orrery

+orris

+orsini

+ortegal

+orthohydrogen

+orthophosphoric

+orthophosphorous

+orthopter

+orthopterous

+orthoptic

+orthoptics

+orthostichy

+orthotone

+ortles

+oruro

+oryol

+oscitancy

+osculant

+oscular

+osman

+osmious

+ossa

+ossein

+ossetia

+ossie

+ossietzky

+ossiferous

+osso

+osteal

+ostend

+ostensory

+osteoclasis

+osteogenesis

+osteomalacia

+osteomyelitis

+osteotome

+osteotomy

+ostia

+ostinato

+ostiole

+ostium

+ostler

+ostmark

+ostosis

+ostracoderm

+ostracon

+ostrava

+ostwald

+otalgia

+othergates

+othman

+otho

+otic

+otitis

+otocyst

+otolaryngology

+otology

+otoscope

+otranto

+ottar

+ottava

+otterburn

+otway

+ouachita

+ouananiche

+oubangui

+oudh

+ouessant

+oujda

+oulu

+ouse

+ousel

+outasight

+outdate

+outjockey

+outlist

+outman

+outrunner

+outrush

+outswing

+outwash

+outwith

+ovenproof

+ovenproofed

+ovenproofing

+ovenproofs

+ovenware

+overachieve

+overachieved

+overachiever

+overachieves

+overachieving

+overarch

+overblouse

+overboot

+overcheck

+overcloud

+overcompetence

+overconsolidate

+overconsolidated

+overconsolidates

+overconsolidating

+overconsolidation

+overcrop

+overdetermine

+overdetermines

+overdetermining

+overdye

+overfold

+overground

+overhype

+overhyped

+overhypes

+overhyping

+overleaf

+overlive

+overmantel

+overmatter

+overnice

+overpitch

+overrunning

+overscale

+overscore

+overset

+oversew

+overside

+oversleeve

+overspent

+overstaff

+overstaffed

+overstaffing

+overstaffs

+overstepped

+overstress

+overstressed

+overstruck

+overtask

+overtype

+overtyping

+oviedo

+oviferous

+ovisac

+owelty

+owerri

+owt

+oxenstierna

+oxhide

+oxidimetry

+oxime

+oxon

+oxonium

+oxpecker

+oxter

+oxtongue

+oxus

+oxyacetylene

+oxyacid

+oxycephaly

+oxychloride

+oxyhaemoglobin

+oxysalt

+oxysulphide

+oxytetracycline

+oxytocic

+oxytocin

+oxytone

+oyer

+oyez

+oyo

+oystercatcher

+ozalid

+ozonolysis

+ozs

+pabulum

+paca

+paceway

+pacha

+pachalic

+pachuca

+pachuco

+padang

+padauk

+paddlefish

+pademelon

+paderborn

+padishah

+padma

+padouk

+padova

+padsaw

+padua

+paduasoy

+paederast

+paediatrician

+paediatrics

+paedogenesis

+paedology

+paedomorphosis

+paedophilia

+paeony

+pageful

+pagefuls

+pagurian

+pah

+pahang

+pahsien

+paigle

+paillasse

+paillette

+painkiller

+paintbox

+paisa

+paisano

+pakeha

+paki

+palaeanthropic

+palaeethnology

+palaeoanthropology

+palaeobotany

+palaeoclimatology

+palaeoecological

+palaeoecology

+palaeoethnobotany

+palaeogene

+palaeography

+palaeolith

+palaeolithic

+palaeomagnetism

+palaeontography

+palaeozoology

+palais

+palawan

+palea

+palembang

+palencia

+palestra

+palestrina

+paletot

+paley

+palikar

+palimpsest

+palindromicity

+palk

+palladic

+palladio

+palladous

+pallete

+palma

+palmaceous

+palmira

+palolo

+palooka

+palos

+palour

+palpebrate

+palsgrave

+palstave

+pamirs

+pampero

+pamphrey

+pamphylia

+pamplona

+panada

+panatella

+panatellas

+panay

+panchax

+panchayat

+panchen

+pancosmism

+pancreatin

+pandanaceous

+pandore

+pandour

+pandowdy

+pandurate

+pandy

+pandybat

+panellist

+panellists

+panettone

+panga

+panicmonger

+paniculate

+panjim

+pankhurst

+panmixia

+panmunjom

+pannage

+panne

+pannikin

+pannonia

+panocha

+panoptic

+pansophy

+pantechnicon

+pantelleria

+pantihose

+panto

+pantoum

+paoting

+paotow

+papadopoulos

+papain

+papandreou

+papaveraceous

+papaverine

+papaya

+papeete

+paperbark

+paperclip

+paperclips

+paperknife

+paperknives

+paperless

+paperthrow

+papeterie

+paphlagonia

+paphos

+papier

+papilionaceous

+pappus

+papule

+papyraceous

+papyrology

+parabasis

+parablast

+parabrake

+paracasein

+paracetamol

+parachronism

+paraclete

+paradrop

+paraesthesia

+paraformaldehyde

+paragoge

+parahydrogen

+paralanguage

+paraldehyde

+paralipomena

+paramaribo

+paramatta

+paramo

+paramorph

+paramorphine

+paramorphism

+parang

+parapraxis

+parashah

+parasitology

+parastichy

+parasyntheton

+parcae

+parcheesi

+parclose

+pardalote

+pardubice

+pareira

+parergon

+paresis

+paresthesia

+pareu

+pareve

+parfleche

+parget

+parhelic

+parhelion

+paripinnate

+parishad

+parison

+parisyllabic

+parkin

+parky

+parlando

+parleyvoo

+parliamentarianism

+parm

+parmenides

+parmentier

+parmigianino

+parnell

+paroicous

+parotic

+parotoid

+parousia

+parramatta

+parrel

+parrotfish

+parthia

+particlar

+partita

+partlet

+parturifacient

+parulis

+parzival

+pasargadae

+pasay

+pase

+pash

+pashalik

+pashka

+pashm

+pasionaria

+pasolini

+pasqueflower

+pasquinade

+passacaglia

+passade

+passant

+passepied

+passifloraceous

+passionflower

+pastis

+pasto

+patagium

+patellate

+pathfind

+pathic

+pathlength

+pathognomy

+patiala

+paticularly

+patin

+patisserie

+patmore

+patna

+paton

+patras

+patrial

+patriclinous

+patrilocal

+patroclus

+patrology

+pau

+paua

+paucal

+pauldron

+pauling

+paumotu

+pausanias

+pav

+pavage

+pavane

+pavis

+pavlodar

+pavlova

+pavonine

+pawky

+pawnees

+paxwax

+paynim

+peag

+peake

+pean

+pearlwort

+pearmain

+peart

+peary

+peasouper

+peau

+peavey

+pechora

+peckinpah

+peckish

+pectase

+pecten

+peculium

+pedalo

+pedate

+pedatifid

+pedi

+pedicular

+pediform

+pedunculate

+peebles

+peen

+peened

+peening

+peens

+peepshow

+peepul

+peetweet

+peewit

+pegmatite

+pegu

+peipus

+peiraeus

+peirce

+pejoration

+pekan

+peke

+pelagius

+pelargonic

+pelargonium

+pelerine

+pelf

+pelion

+pelisse

+pelite

+pella

+pelles

+pelletier

+pellicle

+pelmet

+peloponnese

+peltast

+peltier

+pemba

+pemphigus

+penang

+penchi

+pendente

+penderecki

+pendragon

+peneplain

+peneus

+pengpu

+penillion

+peninsulate

+penki

+pennine

+pennines

+penninite

+pennon

+pennoncel

+pennycress

+pennyweight

+pennywort

+pennyworth

+penrith

+penstemon

+penstock

+penta

+pentachlorophenol

+pentangular

+pentanoic

+pentaprism

+pentastich

+pentatomic

+pentelikon

+pentene

+penthesileia

+pentheus

+pentimento

+pentlandite

+pentose

+pentothal

+pentoxide

+pentyl

+pentylenetetrazol

+penuchle

+penza

+penzance

+pepin

+peplos

+peplum

+pepo

+pepperwort

+pepsinate

+pera

+peracid

+peraea

+perak

+perborate

+perchloric

+perchloride

+percoid

+perdido

+perdu

+pereira

+perfin

+pergamum

+pergolesi

+peri

+perianth

+periapt

+periblem

+periclase

+periclinal

+pericline

+pericope

+periglacial

+perigon

+perigordian

+perinephrium

+perineuritis

+perineurium

+periodate

+perionychium

+periosteum

+periostitis

+peripteral

+perique

+perisarc

+perisperm

+perispomenon

+perissodactyl

+peristalsis

+peristome

+peristyle

+perithecium

+peritoneum

+peritrack

+periwig

+perlis

+perlocution

+permanganate

+permanganic

+pernambuco

+pernickety

+pernik

+pernod

+perogative

+peroxysulphuric

+perpignan

+perrault

+perrin

+perron

+persalt

+perse

+persephone

+persepolis

+persiennes

+personalty

+perspectivism

+perspex

+persulphate

+persulphuric

+pertussis

+perugia

+perugino

+peruke

+perutz

+peruzzi

+perv

+pes

+pesade

+pesaro

+pescadores

+pescara

+peseta

+pesewa

+peshawar

+peshitta

+pestalozzi

+pesthole

+pesthouse

+petaliferous

+petalody

+petechia

+pethidine

+petrarch

+petrodollar

+petrograd

+petrolic

+petsamo

+pettifogging

+pettitoes

+petuntse

+pevsner

+pewit

+phagedaena

+phagomania

+phagophobia

+phalangeal

+phanerocrystalline

+phanerophyte

+phanerozoic

+pharmacophore

+pharmacophores

+pharmacophoric

+pharsalus

+pharyngology

+pharyngoscope

+pharyngotomy

+phatic

+pheidippides

+phelloderm

+phellogen

+phenacaine

+phenacetin

+phenacite

+phenanthrene

+phenazine

+phenetic

+phenformin

+phenix

+phenolphthalein

+phenomenom

+phenylamine

+phenylketonuria

+phew

+phidias

+phidippides

+philae

+philby

+philemon

+philhellene

+philibeg

+philippi

+philippics

+philippopolis

+philips

+philistines

+phillips

+phillumenist

+philomel

+phimosis

+phiz

+phlebosclerosis

+phlogopite

+phlyctena

+phnom

+phocaea

+phocine

+phocis

+phocomelia

+phoebus

+phoenicians

+phomvihane

+phonendoscope

+phonetist

+phonometer

+phonoscope

+phonotactics

+phonotype

+phonotypes

+phonotypy

+phooey

+phosgenite

+phosophoric

+phosphatase

+phosphaturia

+phosphino

+phosphonium

+phosphoprotein

+phosphorate

+phosphoroscope

+phossy

+phot

+photoactinic

+photoactive

+photochronograph

+photoconduction

+photoelastic

+photoelasticity

+photoelectrotype

+photofit

+photonasty

+photoneutron

+photophysical

+photophysics

+photopolymer

+photoselected

+photoselection

+phototherapy

+photothermic

+phototonus

+phototopography

+phototransistor

+phototype

+phototypeset

+photozincography

+phrasal

+phrenitis

+phrixus

+phrygia

+phthalein

+phthalic

+phthalocyanine

+phthiriasis

+phthisic

+phthisis

+phut

+phyfe

+phyllite

+phylloquinone

+phyllotaxis

+physicochemical

+physiocrat

+physoclistous

+physostomous

+phytogenesis

+phytohormone

+phytolith

+phytoliths

+phytotoxin

+phytotron

+piacenza

+piacular

+piaf

+piaffe

+piaget

+piave

+piaza

+picardy

+piccanin

+piccaninny

+piccard

+pichiciego

+pickerelweed

+pickin

+pico

+picong

+picot

+picotee

+picrate

+picric

+picrite

+picrotoxin

+pictogram

+pictor

+picts

+picul

+piddock

+piedmontite

+pieman

+piemonte

+pieria

+pieridine

+piero

+piezo

+piezochemistry

+pigface

+pigfaced

+pigfish

+piggin

+piggledy

+piggott

+pigmeat

+pignut

+pigswill

+pigweed

+pika

+pikelet

+pikeperch

+pilatus

+pilau

+pilch

+pilcomayo

+pileous

+pili

+piliferous

+piliform

+pilliwinks

+pillwort

+pilocarpine

+pilose

+pimiento

+pimpernel

+pinaceous

+pinchpenny

+pinckney

+pindar

+pindus

+pinero

+pinfeather

+pinfish

+pinguid

+pinite

+pinnatifid

+pinnatipartite

+pinnatiped

+pinnatisect

+pinny

+pinochet

+pinole

+pintadera

+pinturicchio

+pinwork

+pinworm

+piny

+piolet

+pipa

+pipeclay

+pipefitting

+piperaceous

+pipewort

+pipistrelle

+pipsqueak

+piragua

+pirandello

+piranesi

+pirhouette

+pirn

+pirog

+pirozhki

+piscary

+piscatorial

+pisgah

+pish

+pishogue

+pishpek

+pisistratus

+pissarro

+pistareen

+piste

+pistoia

+pitapat

+pitchometer

+pitchometers

+pithos

+pitot

+pitsaw

+pituri

+pityriasis

+piura

+pix

+pize

+pizzle

+placet

+placoderm

+placoid

+plafond

+plagioclimax

+plagiotropism

+plainchant

+plainsong

+planchette

+planform

+planimetry

+plano

+planogamete

+planometer

+plantagenet

+plantigrade

+plantocracy

+plash

+plashy

+plasmodesma

+plasmosome

+plassey

+plastometer

+plata

+plataea

+platan

+platelayer

+platelayers

+platemark

+platemarks

+plath

+platiniferous

+platiniridium

+platinocyanic

+platinocyanide

+platinoid

+platinotype

+platy

+platyhelminth

+platyrrhine

+plauen

+playgroup

+playgroups

+playlet

+playschool

+pleach

+pleasance

+pleb

+plebby

+plectognath

+pled

+pleiad

+pleiocene

+pleiotropism

+pleochroism

+pleomorphism

+pleonasm

+pleopod

+plesiosaur

+plessor

+plethysmograph

+pleurodynia

+pleuron

+pleuropneumonia

+pleurotomy

+pleuston

+pleven

+plexor

+plica

+plicate

+ploat

+plodge

+plonk

+plonko

+plotinus

+plottable

+ploughboys

+ploughmen

+ploughs

+ploughstaff

+plumate

+plumbaginaceous

+plumbicon

+plumbum

+pluriliteral

+pluripresence

+plutus

+pluviometer

+pluvious

+pma

+pneuma

+pneumobacillus

+pneumoconiosis

+pneumodynamics

+pneumogastric

+pneumograph

+pneumonectomy

+pneumonitis

+pneumothorax

+pnom

+poaceous

+pochard

+pococurante

+pocus

+poddy

+podesta

+podgorica

+podophyllin

+podsol

+poenology

+pogey

+pogge

+pogy

+pohai

+pohutukawa

+poind

+pointsman

+poitiers

+poitou

+pokeberry

+pokelogan

+pokeweed

+pokie

+pola

+polacre

+poleaxe

+polemarch

+polemoniaceous

+polenta

+poleyn

+pollaiuolo

+pollan

+pollinosis

+polliwog

+polony

+poltava

+poly

+polyadelphous

+polyamide

+polyatomic

+polybasic

+polybius

+polyconic

+polycrates

+polydemic

+polydeuces

+polydipsia

+polydisperse

+polydispersity

+polyembryony

+polygalaceous

+polygnotus

+polygonaceous

+polyhydric

+polyisoprene

+polymerous

+polynices

+polyoxyethene

+polyphosphoric

+polyphyodont

+polypod

+polyprotodont

+polypus

+polysulphide

+polysyllogism

+polythetic

+polythionic

+polyvinylidene

+polyxena

+pom

+pombal

+pombe

+pomfret

+pomiculture

+pommern

+pommy

+pomorze

+pompidou

+pondicherry

+pondokkie

+pondweed

+pone

+pongee

+pongid

+poniard

+ponta

+pontchartrain

+pontefract

+pontevedra

+pontianak

+pontifex

+pontil

+pontormo

+pontus

+pontypool

+pontypridd

+pooftah

+poon

+poona

+poonce

+poove

+popedom

+popeyed

+poppadom

+popsicle

+popsy

+porbeagle

+pori

+porirua

+porism

+porkpie

+pornocracy

+poromeric

+porosimeter

+porphyrogenite

+porsena

+portadown

+portfire

+portlaoise

+portobello

+portulacaceous

+posho

+posology

+poss

+possie

+postcava

+postcode

+postcodes

+postexilian

+posticous

+postie

+postil

+postimpressionism

+postliminy

+postmeridian

+postrider

+potamic

+potamology

+potatory

+potch

+potentiostat

+pothecary

+potherb

+potiche

+potiphar

+potman

+potoroo

+potyomkin

+pouncet

+powan

+powys

+poyang

+pozsony

+pozzuolana

+pozzuoli

+pozzy

+pracharak

+pradesh

+praemunire

+praenomen

+praetor

+praetorius

+pragmat

+pragmats

+praha

+prajna

+pralltriller

+prang

+prat

+prato

+prau

+praxiteles

+preadamite

+precall

+precatory

+precedential

+preceed

+precis

+precompile

+precompiled

+precompiles

+precompiling

+preconnected

+preconnection

+preconsolidate

+preconsolidated

+preconsolidates

+preconsolidating

+preconsolidation

+predella

+predeterminate

+predial

+predicant

+predikant

+prednisone

+predrilled

+prefill

+prefilled

+prefilling

+prefills

+preglacial

+preincubate

+preincubated

+preincubates

+preincubating

+prelacy

+prelatism

+prelect

+prelexical

+prelims

+premaxilla

+premedication

+premiership

+premultiplied

+premultiply

+premultiplying

+premultiplys

+prenomen

+prenominal

+preopened

+preoxidation

+prepositor

+prerelease

+presa

+prescan

+prescriptible

+prescriptivism

+presentationism

+pression

+prestel

+prestonpans

+prestwich

+preterhuman

+pretonic

+pretor

+pretorius

+previse

+priapism

+pribilof

+priestcraft

+prill

+primaeval

+primaquine

+primatives

+primigravida

+primine

+primordium

+primulaceous

+prisage

+proc

+procarp

+proceleusmatic

+prochronism

+proclus

+procopius

+proctoscope

+procuratory

+producable

+proem

+profiterole

+progenitive

+proleg

+prolegomenon

+prolepsis

+promethazine

+promycelium

+propanoic

+propenamide

+propene

+propertius

+propionic

+propjet

+propontis

+propylaeum

+propylite

+proserpina

+prostheses

+prostyle

+protagoras

+protandrous

+protanopia

+proters

+protestantism

+protoactinium

+protochordate

+protogynous

+protomorphic

+protosemitic

+prototherian

+protoxide

+protrusile

+protuberate

+protude

+protudes

+protuding

+protyle

+proudhon

+proustite

+prout

+proventriculus

+provo

+provocate

+provocations

+proxima

+prudentius

+prunelle

+prut

+prynne

+prytaneum

+psammite

+psephite

+pseudaxis

+pseudepigrapha

+pseudocarp

+pseudocode

+pseudomorph

+pseudomutuality

+pseudopodium

+pseudorandom

+pshaw

+psilocybin

+psilomelane

+psittacine

+psittacosis

+psoas

+psoriasis

+psst

+psychasthenia

+psychohistory

+psychomimetic

+psychotechnics

+ptah

+pteridology

+pteridophyte

+pteridosperm

+pteropod

+pterosaur

+pterygoid

+pteryla

+ptisan

+ptochocracy

+ptolemaeus

+ptosis

+ptyalin

+ptyalism

+pudsey

+puebla

+puerilism

+puffbird

+puffbirds

+puget

+puglia

+pugwash

+pula

+pullorum

+pulsatile

+pulsejet

+pulvinate

+punakha

+punce

+punchable

+punchbowl

+punchbowls

+pune

+punjab

+punka

+punnet

+punnets

+punta

+purana

+puri

+purim

+purpurin

+pushkin

+pushrod

+pushrods

+pushto

+putamen

+putto

+putumayo

+puvis

+puy

+pya

+pyaemia

+pydna

+pye

+pyelography

+pylorectomy

+pylos

+pym

+pyogenesis

+pyoid

+pyosis

+pyramus

+pyranometer

+pyrazole

+pyrenees

+pyroconductivity

+pyrogallate

+pyrognostics

+pyrographic

+pyrography

+pyrolysed

+pyrolysing

+pyromagnetic

+pyrone

+pyrophosphoric

+pyrophotometer

+pyrophyllite

+pyrostat

+pyrosulphate

+pyrosulphuric

+pyrrha

+pyrrho

+pyrrolidine

+pyrruvic

+pythias

+qaboos

+qaddafi

+qaddish

+qadi

+qairwan

+qattara

+qeshm

+qibla

+qintar

+qishm

+qoph

+quadragenarian

+quadragesimal

+quadraplegic

+quadrella

+quadriga

+quadrinomial

+quadriplegia

+quadrophonics

+quadrumanous

+quadruplex

+quaere

+quagga

+quaggy

+quaky

+quale

+quango

+quangos

+quaquaversal

+quare

+quarrian

+quarterlight

+quarterlights

+quartersaw

+quashi

+quasicontinuous

+quasiorder

+quasiperiodic

+quasistationary

+quass

+quathlamba

+quatre

+quebracho

+queencake

+queensberry

+quelpart

+quelquechose

+quemoy

+queneau

+quenelle

+quercetin

+quercine

+quesnay

+quetta

+quetzalcoatl

+quiberon

+quidnunc

+quillet

+quillon

+quilmes

+quim

+quinacrine

+quinary

+quinate

+quincentenary

+quindecagon

+quindecaplet

+quindecennial

+quinic

+quinnat

+quinol

+quinone

+quinonoid

+quinquagenarian

+quinquecentenary

+quinquefoliate

+quinquepartite

+quinquereme

+quinsy

+quintan

+quintana

+quintero

+quintilian

+quinze

+quipu

+quire

+quirinus

+quist

+quiverful

+qum

+qumran

+quokka

+quotha

+rabato

+rabaul

+rabbath

+rabbitfish

+rabbitoh

+racecard

+racecards

+racegoer

+racegoers

+raceme

+rachmanism

+rada

+radicel

+radiguet

+radioactivate

+radiocommunication

+radioligand

+radioluminescence

+radiomicrometer

+radiophonic

+radioscope

+radiotelegram

+radiotelemetry

+radioteletype

+radiothermy

+radiotoxic

+radom

+raeburn

+raf

+raffinate

+ragbolt

+ragusa

+ragworm

+ragworms

+ragwort

+rahman

+railcar

+railcars

+railwayman

+rainband

+rainbird

+raincheck

+rainforest

+rainout

+raison

+rajab

+rajahs

+rajasthan

+rajkot

+rajputana

+rajya

+rakata

+rakehell

+raki

+rallentando

+ralline

+rallycross

+ramachandra

+ramakrishna

+ramat

+ramayana

+rambert

+rambutan

+rameau

+ramjet

+ramjets

+rammish

+rampur

+ramsay

+ramsgate

+ramsons

+ramtil

+ramulose

+rancagua

+rance

+rancherie

+ranchero

+ranchi

+randan

+randers

+ranee

+rangefinder

+rani

+ranjit

+ranmoor

+ransome

+ranunculaceous

+rapacki

+rapeseed

+raphe

+raphide

+rapparee

+rara

+raree

+rareripe

+rarotonga

+rasbora

+rase

+rasht

+rask

+raspatory

+rasputin

+rasse

+ratan

+ratatouille

+ratbag

+ratbaggery

+ratbite

+rateen

+ratfink

+ratfish

+ratha

+rathenau

+ratiometer

+ratisbon

+ratite

+ratlam

+rato

+ratsbane

+rattigan

+rattish

+rattlebox

+rattoon

+ravelin

+ravenna

+ravin

+rawalpindi

+rawsthorne

+raylet

+razee

+razoo

+razzia

+razzle

+reade

+readonly

+readwrite

+realgar

+reallot

+reallotment

+reapplied

+reapplies

+reapply

+rearguard

+rearguards

+reassertion

+reassociation

+reast

+rebato

+rebec

+rebell

+rebellow

+rebid

+rebond

+rebonded

+rebonding

+rec

+recalesce

+recaption

+receiptor

+recept

+recipience

+recluster

+reclustering

+recodified

+recodifies

+recodify

+recodifying

+recognizee

+recompilation

+reconsolidate

+reconsolidating

+recrement

+rectillinear

+rectocele

+recuperator

+recurrency

+recursivity

+recurvate

+recurve

+redan

+redback

+redbrick

+redbug

+redcurrant

+redd

+redditch

+reddle

+redeye

+redfin

+rediffusion

+redingote

+redon

+redose

+redowa

+reductionalist

+redware

+reebok

+reedling

+reen

+reflate

+reflated

+reflates

+reflating

+reflet

+regelate

+reger

+reggae

+reggio

+regin

+regiomontanus

+rego

+regrate

+regulable

+reigate

+reims

+reinsertion

+reintroduction

+reinvoke

+reinvoking

+reith

+rejig

+rejuvenesce

+relatum

+relearn

+religionism

+reluct

+remainderman

+remittee

+remix

+remixes

+remixing

+remontant

+remontoir

+remora

+remould

+remoulded

+remoulding

+removalist

+remscheid

+rendzina

+renegado

+reni

+rennes

+renvoi

+reorientate

+reorientated

+reorientates

+reorientating

+repassivation

+repechage

+replevy

+replicable

+replicator

+replicators

+repoint

+repone

+repot

+reprocessor

+reprography

+reptant

+resample

+resampling

+resaturate

+resaturating

+resaturation

+rescissible

+reseat

+reseau

+reselection

+resequence

+resettle

+residentiary

+resiniferous

+resipiscence

+resistencia

+resit

+resnais

+resnatron

+respecifies

+respecify

+resrict

+restiform

+restorationism

+restransmit

+resubmission

+resurrectionism

+rete

+retene

+retension

+retensioned

+retentionist

+retiary

+retinite

+retro

+retroact

+retrochoir

+retrodiction

+retroject

+reuchlin

+reus

+reuter

+reutlingen

+reval

+revanchism

+revelationist

+reverberator

+reversi

+reverso

+revoice

+rewire

+rewiring

+rexine

+reynaud

+reynosa

+rhabdomyoma

+rhachis

+rhaetia

+rhee

+rhein

+rheobase

+rheotaxis

+rheotropism

+rhetic

+rheydt

+rhigolene

+rhinology

+rhinoplasty

+rhizomorph

+rhodic

+rhodinal

+rhodos

+rhotacism

+rhotic

+rhumbatron

+rhynchocephalian

+rhyton

+ria

+ribbentrop

+ribble

+ribbonfish

+ribbonwood

+ribera

+ribwort

+ribworts

+ricardo

+riccio

+ricercare

+richelieu

+richthofen

+ricinoleic

+rickettsial

+rident

+ridgetree

+ridgeway

+ridley

+riefenstahl

+riempie

+rienzi

+rightable

+righthand

+righthanded

+rightish

+righto

+rightwinger

+rightwingers

+rigi

+rigil

+rimester

+rimu

+rinforzando

+ringgit

+ringhals

+ringinglow

+ringster

+ripcord

+ripon

+ripplet

+rissole

+risus

+ritardando

+ritenuto

+ritornello

+rivage

+rizal

+rizzio

+roadholding

+roadroller

+roadrollers

+robben

+robbia

+roborant

+roca

+rocaille

+rockery

+rockweed

+rodomontade

+roentgenopaque

+roeselare

+rogatory

+roget

+rollaway

+rollbar

+rollmop

+rollmops

+rollneck

+rollway

+rone

+roneo

+ronggeng

+roo

+rooinek

+rootle

+ropable

+roquefort

+roquet

+roraima

+rorschach

+rort

+rosace

+rosario

+rosarium

+roscius

+roscoe

+roscommon

+roseberry

+rosehip

+rosewall

+rosh

+rosinante

+roskilde

+rospa

+rossetti

+rossiya

+rostand

+rostock

+roti

+rotorua

+roucou

+rouget

+roulers

+roumelia

+rowntree

+roxas

+rubbra

+rubby

+rubefy

+rubescent

+rubiaceous

+rubinstein

+rubrician

+rubstone

+rudderhead

+rudish

+ruisdael

+rumelia

+runcible

+runcorn

+ruthenia

+ruthful

+rutilated

+ruwenzori

+ruysdael

+ruyter

+ryazan

+rydal

+ryobu

+ryokan

+ryot

+sabadell

+sabah

+sabatier

+sabayon

+sabretache

+sabulous

+saccharic

+saccharoid

+sacco

+sadat

+saddlebill

+sade

+sadhu

+sadi

+sadiron

+sadowa

+saffian

+safid

+sagamore

+saghalien

+sagitta

+saguache

+saguenay

+saguia

+sagunto

+saharanpur

+sahitya

+saida

+saiga

+sainsbury

+saipan

+sakhalin

+saktas

+sakti

+salade

+saladin

+salado

+salamanca

+salambria

+salchow

+salduba

+salep

+salet

+salicaceous

+salicional

+salicylic

+saliferous

+salify

+salique

+sallee

+sallust

+salmanazar

+salonika

+saloop

+salop

+salopette

+salpicon

+salpingectomy

+salpingitis

+salpinx

+salta

+saltant

+saltchuck

+saltchucker

+saltfish

+saltigrade

+saltillo

+salto

+saltpan

+saltus

+salvatorian

+salween

+salyut

+salzgitter

+samarang

+samaria

+sambre

+samekh

+samfoo

+samiel

+samiti

+samizdat

+samnium

+samos

+samothrace

+samsara

+samshu

+samsun

+sanctitude

+sandakan

+sandfly

+sandgrouse

+sandhi

+sandpit

+sandwort

+sandworts

+sango

+sangre

+sangria

+sanies

+sankey

+sankt

+sanmicheli

+santalaceous

+santana

+santander

+saorstat

+sapajou

+sapanwood

+sapele

+saphena

+sapiential

+sapindaceous

+sapir

+sapotaceous

+sappanwood

+sapphira

+sapporo

+sapraemia

+sapropel

+sapwood

+saragossa

+sarawak

+sarcocarp

+sarcous

+sardar

+sardegna

+sarmatia

+sarmentose

+sarnen

+sarnia

+saronic

+saros

+sarpanch

+sarpedon

+sarraceniaceous

+sarraute

+sarre

+sarrusophone

+sarthe

+sarto

+sartor

+sarum

+sarvodaya

+sasebo

+sasin

+sassaby

+sassari

+sassoon

+sastruga

+satai

+satellitium

+satinflower

+satinpod

+satrap

+satrapy

+saturnism

+satyagraha

+satyagrahi

+saurischian

+saury

+saussure

+sav

+sava

+savaii

+savannahs

+savas

+saveloy

+savoie

+savoir

+savona

+sawbill

+sawder

+sawhorse

+sawn

+saxicolous

+saxifragaceous

+saxo

+saxons

+sayan

+sazerac

+scafell

+scaldfish

+scaleboard

+scalenus

+scaliger

+scall

+scaloppine

+scammel

+scandaroon

+scanderbeg

+scandic

+scansorial

+scapa

+scapewheel

+scaphopod

+scarabaeus

+scarcement

+scarificator

+scarlatina

+scarron

+scattergram

+scatterplot

+scatterplots

+scend

+schappe

+scheel

+scheele

+scheelite

+scheldt

+scherzando

+schiaparelli

+schickard

+schilling

+schizogenesis

+schizophyceous

+schizopod

+schizothymia

+schlegel

+schmo

+schmooze

+schnook

+schnorkle

+schnorrer

+schnozzle

+schola

+schongauer

+schoolie

+schorl

+schottische

+schouten

+schrodinger

+schul

+schwa

+schwaben

+schwann

+schwarzwald

+schweinfurt

+schweiz

+schwerin

+schwitters

+schwyz

+sciaenid

+sciamachy

+scienter

+scilly

+scincoid

+sciomachy

+scipio

+scire

+scissel

+scissure

+sciurine

+sciuroid

+sclera

+sclerenchyma

+scleritis

+sclerodermatous

+scleroid

+scleroma

+sclerometer

+sclerophyll

+scleroprotein

+sclerotomy

+sclerous

+scolopendrid

+scop

+scopas

+scorify

+scorpaenoid

+scorper

+scotopia

+scotswomen

+scotus

+scramb

+scran

+scraperboard

+scraperboards

+scrapheap

+scrapheaps

+scrimshank

+scrobiculate

+scroop

+scrophulariaceous

+scrump

+scrumpy

+scry

+scudo

+scullin

+scuncheon

+scunge

+scungy

+scunthorpe

+scut

+scuta

+scutage

+scutate

+scutch

+scutcheon

+scute

+scutellation

+scutellum

+scutiform

+scyphiform

+scyphistoma

+scyphozoan

+scyphus

+scyros

+seaborg

+seacock

+seakale

+seami

+seanad

+seasonality

+seato

+seawan

+seaworthyness

+sebacic

+sebiferous

+secam

+secern

+sech

+sectoral

+secundine

+secundines

+seddon

+seferis

+seg

+seif

+seise

+seismism

+seismometer

+seismoscope

+selah

+selangor

+selectedly

+selenodont

+selenomorphology

+seleucia

+seleucus

+selfheal

+sellotape

+selsyn

+selva

+semanteme

+semarang

+sematology

+semele

+sememe

+semeru

+semibituminous

+semibold

+semicompile

+semination

+seminumerical

+semipalmate

+semivitreous

+semivocal

+sempach

+sena

+senarmontite

+sendai

+sendal

+sendoff

+senegambia

+senghor

+sennacherib

+sennar

+senussi

+sepaloid

+seppuku

+septarium

+septavalent

+septenary

+septennium

+septet

+septicaemia

+septilateral

+septime

+septivalent

+septuagesima

+septuple

+septuplet

+septuplicate

+seq

+sequestrant

+serajevo

+seram

+serang

+sercq

+serdab

+serein

+seremban

+serenata

+sergipe

+seriema

+seringa

+seringapatam

+serjeant

+serotine

+serpigo

+serpulid

+serriform

+serrulate

+serrulation

+sertorius

+servetus

+servia

+servicewoman

+servicewomen

+servient

+sesotho

+sesquialtera

+sesquioxide

+sestos

+setiferous

+setiform

+sett

+settable

+sevan

+sewan

+sewell

+sexangular

+sexcentenary

+sexennial

+sexivalent

+sexpartite

+sextain

+sextan

+sextile

+seyfert

+seyhan

+sfax

+sforza

+sfumato

+sgraffito

+shaba

+shabbat

+shadrach

+shaduf

+shadwell

+shaef

+shaftesbury

+shaftsbury

+shahaptin

+shahjahanpur

+shakhty

+shamash

+shamba

+shameface

+shamo

+shangaan

+shango

+shanny

+shantow

+sharefarmer

+sharefarmers

+shareown

+sharksucker

+sharrow

+shavuot

+sheading

+shearlegs

+shearling

+sheba

+shechina

+sheene

+sheepcote

+sheepdog

+sheepwalk

+sheerlegs

+shellbark

+shelta

+shem

+shema

+shembe

+shenyang

+sherbrooke

+sheria

+sherwani

+shes

+shetlands

+shewbread

+shewn

+shiai

+shicker

+shickered

+shihchiachuang

+shikoku

+shillyshally

+shily

+shinar

+shinkin

+shinty

+shipka

+shiralee

+shirtsleeve

+shithead

+shittah

+shittim

+shiva

+shive

+shizuoka

+shockheaded

+shockstall

+shoeshine

+shoetree

+shofar

+sholapur

+shoogle

+shool

+shopfloor

+shopfloors

+shophar

+shopsoiled

+shopwalker

+shopwork

+shopworker

+shoreless

+shortlist

+shortlisted

+shortlisting

+shortlists

+shortlived

+shoshone

+shote

+shott

+shouse

+showd

+showerproof

+showgirl

+showjumping

+shrewdie

+shrewmouse

+shrieval

+shufty

+shufu

+shuggy

+shushan

+shuteye

+shypoo

+sialkot

+sialoid

+siang

+siangtan

+sibiu

+sicilia

+sickbay

+sickert

+sickie

+sicyon

+siddons

+sidechain

+sidechains

+sideffect

+sideffects

+sideplate

+sideplates

+siderophilin

+siderosis

+siderostat

+sidesman

+sidewheel

+sidewheeler

+sidi

+sidon

+sidra

+siegbahn

+siegler

+sieglinde

+sienkiewicz

+sifaka

+sightscreen

+sigil

+sigismund

+sigla

+siglos

+sigmate

+sigmoidoscope

+signac

+signore

+signorelli

+sigurd

+sikang

+silastic

+sile

+siliciferous

+silicium

+siliculose

+siliqua

+siloam

+silurid

+silverpoint

+silvertail

+simar

+simaroubaceous

+simchath

+simitar

+simla

+simoniac

+simonides

+simplicidentate

+simplon

+simsim

+simula

+simulant

+sinanthropus

+sinarquist

+sinatra

+singultus

+sinhailien

+sinistrodextral

+sinn

+sint

+siple

+siqueiros

+sirdar

+siret

+sisera

+sismondi

+sitar

+sitcom

+sitella

+sitfast

+sithole

+sitology

+sitsang

+situla

+sitwell

+sitz

+sitzkrieg

+sitzmark

+sixain

+sixte

+sjambok

+skagerrak

+skara

+skatepark

+skatole

+skaw

+skean

+skelf

+skelly

+skelmersdale

+sken

+skerrick

+sket

+skewwhiff

+skiamachy

+skibob

+skidlid

+skidpan

+skidproof

+skidway

+skillion

+skilly

+skiplane

+skippet

+skirret

+skite

+skydive

+skylab

+skyscape

+slade

+slaister

+slapshot

+slaughterman

+slaughtermen

+slavs

+sleave

+sleezy

+slezsko

+slickenside

+sligo

+slimmed

+slingback

+slipnoose

+slipperwort

+slipsheet

+slipway

+sloot

+sloughs

+slowcoach

+slowworm

+slubberdegullion

+slype

+smallage

+smallboy

+smallclothes

+smallholding

+smallmouth

+smallsword

+smaltite

+smalto

+smaragd

+smaragdite

+smarm

+smarmy

+smatch

+smew

+smilacaceous

+smit

+smokeho

+smokejack

+smoko

+smoodge

+smriti

+snackette

+sned

+snib

+snicket

+snipefish

+snog

+snorri

+snowberry

+snowbird

+snowblink

+snowdon

+snowdonia

+snowplough

+snuck

+snye

+soakaway

+soapberry

+soapolallie

+soares

+sobeit

+soche

+socinus

+sociobiology

+socman

+socred

+sodamide

+soddy

+soekarno

+soemba

+soembawa

+soenda

+soerabaja

+sofar

+softa

+sogat

+sogdiana

+soh

+soho

+soilage

+soissons

+sokoto

+sokotra

+solan

+solander

+solarimeter

+solarism

+soldo

+solent

+soleure

+solfeggio

+solferino

+soli

+solidary

+solifidian

+solihull

+soliman

+sollicker

+solonchak

+solothurn

+solum

+solvay

+solway

+solyman

+somewise

+somme

+somniloquy

+somnus

+sondage

+songkok

+soniferous

+sonobuoy

+soo

+soochow

+sook

+soong

+sophistocated

+sorata

+sorbefacient

+sorbic

+sorbitol

+soredium

+sorn

+sorocaba

+sororicide

+sorosis

+sorrento

+sosnowiec

+sotto

+soudan

+soult

+soundbox

+soundpost

+soupfin

+sourdine

+southmost

+soutine

+sozzled

+spacewalk

+spadefish

+spadiceous

+spagyric

+spalato

+spalpeen

+spam

+spancel

+sparable

+sparce

+sparerib

+sparid

+sparoid

+sparrowhawk

+sparry

+spatchcock

+spatterdash

+spearwort

+spectrobolometer

+speedo

+speedwriting

+speight

+spelaean

+spelk

+spellican

+speos

+spermatorrhoea

+spermic

+spermine

+spermogonium

+spermophyte

+spermous

+spey

+speyer

+sphenic

+sphenogram

+spheroidicity

+sphingomyelin

+sphragistics

+sphygmic

+sphygmoid

+spiderman

+spif

+spiffing

+spiflicate

+spignel

+spina

+spindlelegs

+spiniferous

+spinose

+spiritus

+spirketting

+spiroid

+spironolactone

+spitchcock

+spithead

+spitsticker

+spiv

+splake

+splanchnic

+splashback

+splashbacks

+splenitis

+splodge

+spock

+spode

+spoilfive

+spondulix

+spongin

+spongioblast

+sponsion

+spoonbill

+sporades

+sporocyte

+sporran

+sportscast

+sportswrite

+sporule

+sprag

+sprechgesang

+sprechstimme

+springhalt

+springhead

+springhouse

+springlet

+springvale

+spruik

+spue

+spuggy

+spumescent

+squacco

+squalane

+squarrose

+squattocracy

+squeteague

+squireen

+squirrelfish

+squit

+squiz

+srinagar

+stableboy

+stabroek

+stackframe

+stacte

+staddlestone

+stadholder

+stadiometer

+staffa

+staffman

+stagflation

+staggard

+stagira

+staines

+stairhead

+stambul

+staminode

+standalone

+standfast

+stane

+stanniferous

+stannite

+stannum

+stanovoi

+stans

+staphyloplasty

+staphylorrhaphy

+stara

+starflower

+startc

+starwort

+statius

+stauroscope

+staysail

+steakhouse

+steamie

+steamtight

+stearoptene

+steatorrhoea

+stecher

+stedfast

+stellarator

+stelliferous

+stellular

+stemhead

+stendhal

+stenopetalous

+stenophyllous

+stenotropic

+stepdame

+stercoricolous

+sterculiaceous

+stereochrome

+stereochromy

+stereometry

+stereotaxis

+stereotomy

+stereovision

+sterlitamak

+sterne

+stevenage

+stevengraph

+steyr

+sthenic

+stheno

+stibium

+stich

+stichometry

+stickybeak

+stilicho

+stillage

+stillicide

+stilliform

+stingo

+stinko

+stitchwort

+stiver

+stoa

+stob

+stockfish

+stockjobber

+stomack

+stomatic

+stomatoplasty

+stoneboat

+stonecast

+stonechat

+stonefish

+stonefly

+stoneground

+stonk

+stonkered

+stook

+stoppard

+storeyed

+storiated

+stormproof

+stornoway

+storr

+storrs

+stoss

+stot

+stotinka

+stotious

+stotter

+stound

+stoup

+stour

+stoush

+strabo

+strabotomy

+strachey

+strandloper

+strategem

+strategems

+stratificational

+stratigraphical

+stratigraphically

+stratopause

+strawworm

+streamy

+streetlight

+strepitous

+stretchy

+striction

+strigiform

+strimon

+strine

+strobic

+strobilaceous

+stroganoff

+strokefinder

+stromboli

+strongman

+strongyle

+strontian

+stroppy

+stroy

+strychnic

+stubbs

+studdingsail

+studwork

+sturmer

+sty

+stylostixis

+stypsis

+styracaceous

+styria

+suakin

+subacetate

+subah

+subangular

+subapostolic

+subaqua

+subarid

+subassemblage

+subassemblages

+subastral

+subauricular

+subaxillary

+subbass

+subcalibre

+subcartilaginous

+subception

+subchannels

+subcluster

+subclusters

+subdelirium

+subduct

+subelement

+subelements

+subepidermis

+subequatorial

+suberic

+suberin

+suberose

+subfloor

+subfusc

+subinstance

+subinstances

+subjectify

+sublanguage

+sublanguages

+sublapsarianism

+submental

+subordinary

+subordinationism

+subotica

+subpanel

+subpanels

+subparameter

+subparameters

+subprocessor

+subscan

+subscans

+subscapular

+subsocial

+subsolar

+substantialism

+substomatal

+subtangent

+subternatural

+subtorrid

+subtreasury

+subufd

+subufds

+suburbicarian

+subvene

+subzero

+succentor

+succeptibility

+successsive

+succinic

+succoth

+succursal

+succuss

+suckerfish

+sudarium

+sudbury

+sudd

+sudetes

+sudor

+suetonius

+sufferage

+suffiency

+sufflate

+suffruticose

+suffumigate

+sufu

+suggestibly

+suharto

+suisse

+sukarnapura

+sukhumi

+sukkoth

+suleiman

+sulla

+sulphadiazine

+sulphanilamide

+sulphathiazole

+sulphide

+sulphinyl

+sulphisoxazole

+sulphite

+sulphonamide

+sulphonate

+sulphonated

+sulphone

+sulphonic

+sulphonium

+sulphonmethane

+sulphonyl

+sulphurate

+sulphuret

+sulphuretted

+sulphuryl

+summerweight

+sump

+sumpter

+sumy

+sunbake

+sundog

+sundress

+sundresses

+sundsvall

+sungari

+sungkiang

+sunglow

+sungrebe

+sunhat

+sunray

+sunstar

+suntrap

+suo

+superaltar

+superbazaar

+supercede

+superceded

+supercedes

+supercolumnar

+supercomputing

+superconduction

+supercurrent

+superdense

+supererogate

+superfemale

+superfuse

+superglacial

+superhero

+superhet

+superhigh

+superhumeral

+superlanguage

+superload

+supermale

+supermodel

+supermodels

+supermundane

+supernational

+superorganic

+superoxide

+supersex

+superstruct

+suplex

+supralapsarian

+suprematism

+supremo

+suqutra

+sur

+sura

+surakarta

+sural

+surat

+surculose

+surd

+surfbird

+surfbirds

+surfcasting

+surfie

+surgeoncy

+surgeonfish

+suribachi

+suricate

+surrebuttal

+sursum

+susa

+susah

+suseptible

+suslik

+suss

+susso

+susurrate

+sutlej

+sutler

+suva

+sverige

+svizzera

+swacked

+swanage

+swaraj

+sward

+swarf

+sweelinck

+sweetiewife

+sweetman

+sweetmeal

+sweptback

+sweptwing

+sweven

+sweyn

+swiftie

+swiftlet

+swindon

+swinepox

+swingboat

+swingle

+swingometer

+swingometers

+switchgirl

+swob

+swordbill

+swordcraft

+swordsmen

+swordstick

+swordsticks

+swound

+swounds

+swy

+sybaris

+sydneysider

+syene

+syktyvkar

+syllabism

+syllabogram

+syllabography

+sylva

+sylvanus

+sympathectomy

+symphile

+sympodium

+symposiac

+synarchy

+syncarp

+synchrocyclotron

+synchrometer

+synclastic

+synclinorium

+syncom

+syncrisis

+syndactyl

+synecious

+synovia

+syntagma

+synthetism

+sypher

+syphiloma

+syr

+syssarcosis

+systematology

+sytactic

+syzran

+taata

+tabaret

+tabescent

+tachograph

+tachylyte

+tachymetry

+tachyphylaxis

+tacket

+tacmahack

+tadmor

+taegu

+taejon

+tael

+taenia

+taeniafuge

+taffrail

+tafia

+tafilelt

+taganrog

+taggers

+tagliatelle

+tagmeme

+tagmemics

+tagore

+tagus

+tahina

+tahr

+tahsil

+tahsildar

+taig

+tailpipe

+tailplane

+tailskid

+tailstock

+taimyr

+tain

+taine

+taiyuan

+taj

+tajo

+taka

+takahe

+takamatsu

+takao

+takeaway

+takin

+takoradi

+talapoin

+talaria

+talavera

+talbot

+talca

+talcahuano

+taliesin

+taligrade

+taliped

+tallinn

+tallis

+talos

+taluk

+talweg

+tamasha

+tamatave

+tamaulipas

+tambac

+tambora

+tamburlaine

+tamis

+tammerfors

+tammuz

+tammy

+tampere

+tampico

+tana

+tanana

+tancred

+tandjungpriok

+tandoori

+tanga

+tangleberry

+tangshan

+tanguy

+tanis

+tanist

+tanjore

+tanta

+tantalous

+tanto

+tantrism

+tapadera

+tapemark

+tapemarks

+taphouse

+tarabulus

+taradiddle

+taramasalata

+tarantass

+tarantella

+taranto

+tarawa

+tarbes

+tarentum

+tarim

+tarnal

+tarnation

+tarnishs

+tarpan

+tarradiddle

+tarragona

+tarrasa

+tarshish

+tarsia

+tarsometatarsus

+tartarous

+tartu

+tashi

+tashkent

+tasimeter

+tasman

+tasset

+tassie

+tassle

+tatchell

+tati

+tatouay

+tatra

+taupo

+tauranga

+tauromachy

+tav

+tavel

+tawney

+taxaceous

+taxiplane

+taxiplanes

+teacake

+teashop

+technocommercial

+technography

+tectorial

+tecumseh

+tedder

+teesside

+teet

+tef

+teg

+tegular

+tehuantepec

+teide

+teilhard

+tejo

+tela

+telanaipura

+telautograph

+telecom

+telecomunications

+telega

+telegenic

+telegnosis

+telegonus

+telemachus

+telescopy

+telescript

+telespectroscope

+telestereoscope

+telestich

+teletext

+teletranscription

+teletube

+teletypesetter

+televideo

+telewriter

+telexed

+telexes

+telexing

+telfer

+telferage

+tellurate

+tellurion

+tellus

+telpherage

+temuco

+tenaille

+tenedos

+teng

+tengri

+teniafuge

+teniers

+tenner

+tenniel

+tenno

+tenorite

+tenorrhaphy

+tenotomy

+tensible

+tentation

+tenzing

+tepal

+tepefy

+tephrite

+tepic

+teratism

+teratoid

+terbia

+terceira

+terephthalic

+tereshkova

+terminosity

+termor

+terne

+terni

+ternion

+terotechnology

+terrestial

+terrine

+territorian

+tertial

+tertium

+tertullian

+teruel

+terylene

+terza

+terzetto

+tesla

+tesseract

+tessin

+testbed

+testiculate

+testudinal

+tetrabrach

+tetrabutylammonium

+tetrachlorethylene

+tetracyclic

+tetragram

+tetraphenyl

+tetraplegia

+tetrapody

+tetrapterous

+tetrastich

+tetrastichous

+tetrasyllable

+tetrazzini

+tetroxide

+tetzel

+teutoburger

+tevere

+tevet

+textualism

+teyde

+tezel

+thackeray

+thaddeus

+thadentsonyane

+thales

+thalweg

+thammuz

+thanatopsis

+thanet

+thanjavur

+thapsus

+thatcherism

+thaumatology

+thaumatrope

+theaceous

+theanthropism

+thearchy

+thebaine

+thegn

+theine

+themistocles

+thenardite

+theocrasy

+theocritus

+theodorakis

+theomachy

+theomancy

+theomania

+theomorphic

+theopathy

+theophagy

+theophobia

+theophrastus

+theorbo

+theravada

+therezina

+therfore

+therianthropic

+thermaesthesia

+thermobarograph

+thermobarometer

+thermoelectricity

+thermogenesis

+thermomotor

+thermophysical

+thermoregularity

+thermostatical

+thermotensile

+thermotherapy

+theroid

+theropod

+thersitical

+thesauri

+thespis

+thickleaf

+thimblewit

+thingumabob

+thioalcohol

+thiofuran

+thionine

+thionyl

+thiopentone

+thiophen

+thiosinamine

+thiosulphate

+thiosulphuric

+thirdstream

+thirlage

+thirlmere

+thisbe

+tholos

+thonburi

+thoracoplasty

+thornbill

+thoron

+thoroughpaced

+thorp

+thorshavn

+thrave

+threadneedle

+threadworm

+threap

+throatlash

+thrombogen

+thrombose

+thumbnut

+thumbstall

+thummim

+thun

+thunderbox

+thundery

+thuner

+thuya

+thymelaeaceous

+thyristor

+tia

+tiberias

+tibesti

+tibiotarsus

+tibullus

+tibur

+ticino

+tiddler

+tiddly

+tidewaiter

+tiebreaker

+tiepolo

+tierra

+tiffin

+tiflis

+tightknit

+tiglic

+tigrinya

+tihwa

+tikoloshe

+tiliaceous

+tillicum

+timaru

+timberyard

+timbuktu

+timecard

+timescale

+timescales

+timeslice

+timeslices

+timestamp

+timestamped

+timestamping

+timestamps

+tindal

+tineid

+tinpot

+tintinnabulum

+tipcat

+tiptop

+tipu

+tiran

+tiresias

+tirich

+tiro

+tiros

+tirpitz

+tirso

+tisza

+titanite

+titanosaur

+titanothere

+titfer

+tithonus

+titicaca

+titman

+titubation

+tiu

+tiv

+toadeater

+toadeater's

+toadeaters

+toadfish

+toadfish's

+toadfishes

+toadflax

+toadstone

+toadstone's

+toadstones

+tobit

+tobol

+tocantins

+tocology

+toea

+toecap

+toey

+toheroa

+tolpuddle

+toluyl

+tolylphosphine

+tomalley

+toman

+tombola

+tombouctou

+tomograph

+tonle

+tonsillotomy

+toowoomba

+toparch

+topazolite

+topotype

+topspin

+torbay

+torc

+torchier

+toric

+torii

+torino

+torose

+torquay

+torquemada

+torre

+torrefy

+torres

+torricelli

+torsibility

+tortelier

+tortellini

+tortile

+tortola

+tortuga

+toscana

+toscanini

+toul

+toulon

+touraine

+tourane

+tourcoing

+touristy

+tournai

+tourneur

+toussaint

+touzle

+towbar

+towkay

+townhall

+townscape

+townshend

+toxaemia

+toxalbumin

+toyama

+trabzon

+tracasserie

+tracheostomy

+tracksuit

+tractile

+trad

+tradeability

+traditor

+traducianism

+trafalgar

+traherne

+trailblaze

+trajan

+tralee

+trammie

+tranformed

+tranmission

+tranmitted

+trannie

+transcalent

+transculturation

+transcurrent

+transformism

+transgranular

+transilient

+transkei

+transliterator

+translunar

+transmigrant

+transmittancy

+transmundane

+transpadane

+transpassive

+transpond

+transponders

+transportaion

+transput

+transputer

+transputers

+transshipped

+tranverse

+trapan

+trapani

+trapes

+trapeziform

+trappean

+trasimene

+travancore

+traymobile

+trebizond

+treen

+treename

+treenames

+treenware

+tref

+trehala

+treitschke

+trengganu

+trente

+trento

+tressure

+tret

+trevally

+trevithick

+triac

+triazole

+tribade

+triblet

+tribromoethanol

+tricarbonyl

+tricentenary

+trichinopoly

+trichloro

+trichloroethanol

+trichloroethylene

+trichology

+trichosis

+trichroism

+tricktrack

+tricostate

+tricritical

+tricriticality

+tricrotic

+tricyclohexyl

+tridactyl

+tridentate

+tridentum

+triecious

+trieste

+trifold

+trihedron

+trihydrate

+trihydric

+triiodomethane

+trike

+trilateration

+trilemma

+trilithon

+trimethadione

+trimetric

+trimolecular

+trimurti

+trinacria

+trincomalee

+trinitrobenzene

+trinitrocresol

+trinitroglycerin

+trinitrophenol

+trioecious

+triolein

+tripalmitin

+tripersonal

+triphenyl

+tripody

+tripolitania

+tripterous

+triptolemus

+triptyque

+tripura

+tripwire

+triserial

+triskaidekaphobia

+trismegistus

+tristich

+tristichous

+trisulphide

+tritanopia

+tritiate

+triunitarian

+trivandrum

+troas

+troat

+trobriand

+trocar

+trochelminth

+trode

+trog

+troilism

+troilus

+trois

+trollope

+tromba

+tropaeolin

+trophoplasm

+tropicbird

+tropine

+tropophyte

+troppo

+tropylium

+trossachs

+trotskyist

+trotyl

+troubador

+trouse

+troyes

+trucial

+truckie

+trudgen

+trug

+trugs

+truk

+trumeau

+tryma

+tryptophanyl

+tsade

+tsana

+tsarevitch

+tsarevna

+tsaritsyn

+tselinograd

+tshiluba

+tshombe

+tsinan

+tsinghai

+tsingtao

+tsingyuan

+tso

+tsonga

+tsotsi

+tsugaru

+tsukahara

+tsushima

+tsutsugamushi

+tswana

+tuart

+tuatara

+tubate

+tubman

+tubuai

+tubuliflorous

+tucotuco

+tugela

+tugrik

+tuileries

+tula

+tularaemia

+tull

+tully

+tumblehome

+tumefacient

+tumefy

+tumular

+tumulose

+tungstous

+tungting

+tunguska

+tunnage

+tupamaro

+tuppenny

+tupungato

+turaco

+turbary

+turbogenerator

+turdine

+turenne

+turgenev

+turgent

+turgite

+turgot

+turishcheva

+turkestan

+turku

+turncock

+turnround

+turpeth

+turpin

+tusculum

+tussaud

+tussis

+tutankhamen

+tutiorism

+tutsan

+tutsi

+tutty

+tutuila

+tuva

+tuxtla

+tver

+twat

+twattle

+twayblade

+twee

+tweeddale

+tweedledum

+tweedsmuir

+tweeny

+twelvemo

+twite

+tychism

+tycho

+tye

+tylopod

+tylosis

+tympanist

+tympanitis

+tyndall

+tyndareus

+tynemouth

+tyneside

+typebar

+typhlitis

+typhlology

+typhoeus

+typhogenic

+typhoidin

+typothetae

+tyr

+tyumen

+tzekung

+tzetze

+ubbelohde

+ubiety

+ucayali

+ucca

+uccello

+udaipur

+udal

+udine

+udmurt

+udo

+udometer

+uele

+ufa

+ufd

+ufo

+ufology

+ugali

+ugaritic

+ugli

+uhlan

+uintathere

+ulfilas

+ulmaceous

+ulpian

+ultramicrometer

+ultramicrometers

+ultramicroscopic

+ultramundane

+ultrared

+ultrathin

+ultravirus

+ultrawet

+umayyad

+umbellule

+umberto

+umbles

+umbo

+umbria

+umiak

+umpy

+umrcc

+umtali

+unaesthetic

+unallocateed

+unamuno

+unaneled

+unaskable

+unassign

+unban

+unbelt

+unbirthday

+unbonnet

+unchurch

+unclad

+unco

+uncodeable

+unconservative

+uncontroversial

+undated

+undefine

+underachieve

+underbuy

+undercart

+underclay

+undercroft

+undercutting

+underdevelop

+underemphasis

+underfelt

+underfilled

+underfloor

+underfur

+undergrown

+underhung

+underletting

+underlinen

+undermentioned

+undernourish

+underpainting

+underpay

+underpinned

+underpitch

+underpitched

+underpitches

+underpitching

+underprice

+underpriced

+underprices

+underpricing

+underprop

+underquote

+underseal

+underset

+undersheriff

+undersmooth

+undersmoothed

+undersmoothing

+undersmooths

+underspent

+understaff

+underthrust

+undertint

+undertrump

+undertype

+undialectical

+undirectional

+undro

+undset

+unenforcable

+unexcited

+unforced

+unforseen

+ungaretti

+ungava

+unguiculate

+unguinous

+unguis

+ungula

+unguligrade

+uni

+unibus

+unicef

+unicolour

+unicostate

+unidirection

+uniformally

+unilateralist

+unilateralists

+uniliteral

+unimak

+unimodular

+uninfluential

+uninterruptable

+unipersonal

+unipod

+uniseptate

+uniserial

+uniterm

+unlead

+unlettable

+unmodeled

+unmusical

+unpaddable

+unpolitic

+unprepossessing

+unreactive

+unreckonable

+unreligious

+unrepair

+unrwa

+unskilful

+unspecifed

+unspecify

+unsteel

+unsuggestive

+unsupportive

+unterwalden

+untravelled

+untypical

+unwarrant

+upanishad

+upcountry

+uphroe

+upolu

+upperbound

+upperbounds

+uppsala

+uprouse

+upsadaisy

+upsala

+upstand

+upstretched

+upswell

+upto

+uranalysis

+uranism

+uranite

+uredosorus

+uredospore

+uretic

+urey

+urfa

+urga

+urim

+urinant

+uriniferous

+urmia

+urogenous

+uroscopy

+urquhart

+urticaceous

+uruapan

+urumchi

+urundi

+username

+ushant

+ushas

+usnach

+uspallata

+usquebaugh

+ussher

+ussuri

+ustashi

+ustulation

+ustyurt

+usumbura

+utamaro

+utgard

+uther

+utriculitis

+utrillo

+uttar

+uvedale

+uvulitis

+uxmal

+vacherin

+vadodara

+vadose

+vagal

+vaginate

+vaginectomy

+vaginismus

+vaginitis

+vagotonia

+vagus

+vahana

+vaisya

+valais

+valdai

+valdemar

+valdivia

+valencies

+valency

+valens

+valera

+valerianaceous

+valeric

+valeta

+valetta

+valgus

+valladolid

+vallation

+vallecula

+vallombrosa

+valona

+valonia

+valuta

+valvate

+valvule

+valvulitis

+vambrace

+vanadate

+vanadic

+vanadinite

+vanadous

+vanaspati

+vanbrugh

+vang

+vansittart

+vanua

+vanzetti

+vaporescence

+vaporetto

+vaporific

+vaporimeter

+vara

+varactor

+varanasi

+vardar

+vardon

+varec

+varese

+vargas

+varia

+variablity

+varicella

+varicellate

+varicelloid

+varicocele

+varicosis

+varicotomy

+variola

+variolate

+variole

+variolite

+variscite

+varityper

+varna

+varro

+vas

+vasari

+vasco

+vashti

+vasoinhibitor

+vasoregulatory

+vaticide

+vauban

+vaucluse

+vaud

+vav

+vavasor

+vedette

+veg

+vegan

+veii

+veinstone

+veinule

+vela

+velate

+velcro

+veldskoen

+veleta

+veliger

+velites

+vellicate

+vellore

+vena

+venenose

+venepuncture

+venlo

+venose

+venosity

+ventris

+verbenaceous

+vercelli

+vercingetorix

+verderer

+verdun

+verecund

+vereeniging

+vergeboard

+verglas

+verifiably

+verkrampte

+verlaine

+verligte

+vermeer

+vermination

+vermis

+vermivorous

+verny

+verrazano

+verrocchio

+verruca

+verrucae

+verrucose

+versabraille

+versant

+versatec

+verst

+vert

+verticillaster

+verticillate

+vertu

+verulamium

+vervain

+vervet

+verwoerd

+vesalius

+vespasian

+vespertilionine

+vespucci

+vesuvius

+vetiver

+viareggio

+viator

+vibraculum

+vibronic

+vicenary

+vicenza

+vico

+vicomte

+victoriana

+videlicet

+videotex

+vidhan

+vienne

+viewport

+viewport's

+viewports

+viewscan

+vignola

+vigny

+vigo

+villous

+vimineous

+vina

+vinasse

+vinegarette

+vinificator

+vinnitsa

+violoncello

+violone

+viren

+virial

+virtu

+viscoid

+vistula

+vitaceous

+vitaphone

+vitascope

+vitoria

+vitrain

+vitrescence

+vitrescent

+vitric

+vitriform

+vitruvius

+vitta

+vittle

+vituline

+viverrine

+viyella

+vocate

+voidage

+voiotia

+voir

+voix

+vojvodina

+volitant

+vologda

+volost

+volsung

+volsunga

+voltaism

+voltammeter

+volturno

+volvulus

+vomer

+voortrekker

+vorster

+vosges

+vostok

+vouge

+vox

+vuillard

+vulgaris

+vulvovaginitis

+vyborg

+wabble

+wabbled

+wabbles

+wabbling

+wace

+wadai

+wadmal

+wadset

+wagram

+wagtail

+waistcloth

+walfish

+walhalla

+walkable

+walkley

+wallah

+wallasey

+wame

+wanderoo

+wandoo

+wanganui

+wanhsien

+wank

+wankel

+wankie

+wanna

+waratah

+wardian

+wardle

+wardmote

+warhorse

+warhorses

+warrigal

+warsle

+warta

+washaway

+washday

+washdays

+washerwomen

+washery

+washin

+washwomen

+wassermann

+wasteweir

+watap

+watchstrap

+waterage

+waterbrain

+waterbuck

+waterspout

+watertower

+wattlebird

+waul

+waveband

+wavebands

+wavefunction

+wavefunctions

+wavellite

+wavemeter

+waveoff

+waw

+wawa

+wawl

+waxberry

+waxbill

+waxplant

+wayzgoose

+waziristan

+weakfish

+weald

+weaponeer

+wearproof

+weasand

+weaverbird

+webbs

+webwheel

+weddell

+wedekind

+wedeling

+weedkiller

+weelkes

+ween

+weeny

+weighbridge

+weighbridges

+weightlifter

+weightlifting

+weihai

+weka

+welkom

+welland

+wellesz

+wellies

+welterweight

+welwyn

+wentletrap

+wernerite

+wersh

+weser

+wesker

+wessex

+westmost

+whacko

+whangarei

+whare

+wharfie

+wharve

+whatsit

+whaup

+wheatworm

+whereafter

+wherrit

+wheyface

+whidah

+whimbrel

+whin

+whinchat

+whinge

+whipstall

+whipworm

+whirlabout

+whitby

+whitebeam

+whitedamp

+whitefly

+whitethorn

+whitewood

+who've

+wholefood

+wholemeal

+wholism

+whortleberry

+whyalla

+whydah

+wicketkeeper

+wicketkeepers

+wicketkeeping

+wickthing

+wicopy

+widdershins

+widgery

+widgie

+widnes

+widukind

+wien

+wikiup

+wildcard

+wildcarded

+wildcarding

+wildcards

+wilde

+wilhelmshaven

+wilhelmstrasse

+willemstad

+willowherb

+wilmslow

+wilno

+wincey

+windbound

+windcheater

+windcheaters

+windchill

+windermere

+windflower

+windgall

+windhoek

+windhover

+windlestraw

+windrow

+windsail

+windsock

+winebibber

+winkelried

+winnipegosis

+winterfeed

+winterthur

+winterweight

+wipo

+wirepuller

+wiretapping

+wirewalker

+wirra

+wirral

+wis

+wishlist

+wishlists

+wislany

+wismar

+wist

+witan

+witchetty

+wite

+witenagemot

+withershins

+wittol

+wivern

+woad

+woaded

+woadwaxen

+woald

+wodge

+wodges

+wog

+woggle

+wolfbane

+wolfenden

+wolffish

+wolfit

+wolframite

+wolfsbane

+wollastonite

+wolly

+wolsey

+wolve

+wolver

+womera

+wonsan

+woodborer

+woodcarving

+woodchat

+woodgrouse

+woodhook

+woodlark

+woodlouse

+woodrush

+woodscrew

+woodseats

+woodwaxen

+woodworm

+woolf

+woolfell

+woolgrower

+woolley

+woollybutt

+woop

+woorali

+workaday

+workbag

+workfile

+workfiles

+workgroup

+workgroups

+workmate

+workmates

+workperson

+workshy

+worksop

+wormcast

+wormseed

+wormwood

+worsley

+wot

+wran

+wrapover

+wrapround

+wreckfish

+wreckful

+wrekin

+wroclaw

+wrongdo

+wrongdoers

+wroth

+wrybill

+wryneck

+wuchang

+wuhsien

+wuhu

+wulfenite

+wulfila

+wundt

+wuppertal

+wurley

+wurst

+wus

+wusih

+wuthering

+wutsin

+wycherley

+wycliffe

+wye

+wynd

+wyvern

+xanthein

+xanthippe

+xanthochroid

+xanthochroism

+xanthoma

+xanthophyll

+xanthous

+xanthus

+xci

+xcii

+xciv

+xcix

+xcvi

+xcvii

+xenakis

+xenocrates

+xenocryst

+xenogamy

+xenogenesis

+xenoglossia

+xenolith

+xenomorphic

+xenophanes

+xenophon

+xeroderma

+xeromorphic

+xerophthalmia

+xerophyte

+xerosere

+xerosis

+xhosa

+xiphisternum

+xiphoid

+xiphosuran

+xuthus

+xxi

+xxii

+xxiii

+xxiv

+xxix

+xxv

+xxvi

+xxvii

+xxviii

+xxx

+xxxi

+xxxii

+xxxiii

+xxxiv

+xxxix

+xxxv

+xxxvi

+xxxvii

+xxxviii

+xylan

+xylidine

+xylocarp

+xylograph

+xylography

+xyloid

+xylol

+xylophagous

+xylyl

+xyst

+xyster

+yabber

+yabby

+yaffle

+yafo

+yagi

+yahata

+yamagata

+yamani

+yamashita

+yammer

+yanina

+yapok

+yapon

+yarwood

+yataghan

+yate

+yauld

+yaunde

+yaup

+yaupon

+yautia

+yawata

+yawp

+yazd

+yean

+yeanling

+yegg

+yeld

+yelk

+yellowbark

+yellowbird

+yellowhammer

+yellowlegs

+yellowtail

+yellowweed

+yellowwood

+yenan

+yentai

+yerevan

+yestreen

+yeti

+yezd

+ygerne

+yike

+yingkow

+yippee

+yirr

+ylem

+ymir

+yob

+yod

+yodle

+yogh

+yohimbine

+yoicks

+yokefellow

+yola

+yom

+yoni

+yonne

+yonnie

+ytterbia

+ytterbite

+yttria

+yttriferous

+yuk

+yulan

+yurt

+yvelines

+ywis

+zacynthus

+zaffer

+zagazig

+zagreus

+zagros

+zama

+zamindar

+zamindari

+zamora

+zante

+zanu

+zapata

+zaporozhye

+zappa

+zapu

+zaqaziq

+zaragoza

+zarathustra

+zaratite

+zareba

+zarf

+zarga

+zaria

+zarzuela

+zastruga

+zayin

+zeami

+zebec

+zebedee

+zebrawood

+zebu

+zebulun

+zecchino

+zechariah

+zed

+zedekiah

+zedoary

+zee

+zein

+zeist

+zemindar

+zenana

+zener

+zephaniah

+zephyrus

+zeugma

+zeuxis

+zia

+ziaur

+zibeline

+zibet

+ziff

+ziggurat

+zigzagger

+zila

+zilpah

+zinciferous

+zincite

+zinckenite

+zincograph

+zincography

+zingiberaceous

+zinjanthropus

+zinkenite

+zipangu

+zircalloy

+ziska

+zlatoust

+zoaea

+zoan

+zoea

+zoffany

+zohar

+zola

+zond

+zonk

+zonking

+zonks

+zonule

+zoochemistry

+zoochore

+zoogloea

+zoography

+zooid

+zoolatry

+zoometry

+zoomorphism

+zoophile

+zoophilia

+zoophilism

+zoophobia

+zooplasty

+zoosperm

+zoosporangium

+zootomy

+zootoxin

+zootoxins

+zorilla

+zorrilla

+zoster

+zoug

+zsigmondy

+zucchetto

+zugzwang

diff --git a/hlship-20080520/tapestry-test/src/site/apt/index.apt b/hlship-20080520/tapestry-test/src/site/apt/index.apt
new file mode 100644
index 0000000..a042828
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/site/apt/index.apt
@@ -0,0 +1,76 @@
+ ----
+ Tapestry Test Utilities
+ ----
+ 
+Tapestry Test Utilities
+
+  This library is just a couple of base classes to make it easier to build integration test suites around 
+  {{{http://www.openqa.org/selenium/}Selenium}}.
+  
+  This library is currently based on Selenium 0.8.1.
+  
+  The strategy is to start, in process, a Selenimum Server (which, in turn, starts and manages a web browser),
+  a Jetty instance (for the web browser to talk to), and a Selenium client (which talks to the server).
+  
+  The client is able to request URLs, fill in form data, click links, and make assertions about output
+  and behavior.
+  
+Usage and Configuration
+
+  The core part of this library is a base class for you to extend your tests cases from: 
+  {{{../apidocs/org/apache/tapestry/test/AbstractIntegrationTestSuite.html}AbstractIntegrationTestSuite}}.
+  
+  This class is responsible for starting an instance of Jetty to server your web application, as well
+  as a copy of Selenium Server. It also implements the
+  {{{http://release.openqa.org/selenium-remote-control/0.9.0/doc/java/}Selenium}} interface.
+  
+  You must inform the suite about the location of your web application. The default location is 
+  <<<src/main/webapp>>> (as this is the default directory for storing a web application when building
+  using Maven).  This can be changed by provided a public constructor for your test suite.
+  
+  Here's an example from one of the Tapestry modules:
+  
+     
+----
+package org.apache.tapestry.spring;
+
+import org.apache.tapestry.test.AbstractIntegrationTestSuite;
+import org.testng.annotations.Test;
+
+public class TapestrySpringIntegrationTest extends AbstractIntegrationTestSuite
+{
+    public TapestrySpringIntegrationTest()
+    {
+        super("src/test/webapp");
+    }
+    
+    @Test
+    public void integration_test() throws Exception
+    {
+        open(BASE_URL);
+
+        type("input", "paris in the springtime");
+        clickAndWait("//input[@value='Convert']");
+
+        assertFieldValue("input", "PARIS IN THE SPRINGTIME");
+    }
+
+    @Test
+    public void access_to_spring_context() throws Exception
+    {
+        open(BASE_URL);
+
+        assertTextPresent("[upcase]");
+    }
+}
+----
+
+  This is a very simple example, and demonstrates a mix of Selenium methods (such as open() and type()) and
+  methods added by the AbstractIntegrationTestSuite base class (clickAndWait() and assertFieldValue()).
+  
+  Of course, a real integration test would contain many methods, and may need to single thread their execution, or
+  even specify an execution order.
+  
+  In addition, the AbstractIntegrationTestSuite base class extends the normal exception reporting provided by Selenium; when a failure occurs inside Selenium server,
+  a more detailed message, including the current page's HTML source, is reported to System.err.
+    
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-test/src/site/site.xml b/hlship-20080520/tapestry-test/src/site/site.xml
new file mode 100644
index 0000000..ba41711
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/site/site.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 
+   Copyright 2006, 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry Core">

+    <bannerLeft>

+        <name>Tapestry 5</name>

+        <href>http://tapestry.apache.org/tapestry5/</href>

+        <src>images/tapestry_banner.gif</src>

+    </bannerLeft>

+    <bannerRight>

+        <name>Apache</name>

+        <href>http://www.apache.org</href>

+        <src>images/asf_logo_wide.gif</src>

+    </bannerRight>

+    <skin>

+        <groupId>org.apache.tapestry</groupId>

+        <artifactId>maven-skin</artifactId>

+        <version>1.1</version>

+    </skin>

+

+    <publishDate format="dd MMM yyyy"/>

+

+    <body>

+

+

+        <menu ref="reports"/>

+

+    </body>

+</project>

diff --git a/hlship-20080520/tapestry-test/src/test/conf/testng.xml b/hlship-20080520/tapestry-test/src/test/conf/testng.xml
new file mode 100644
index 0000000..3bc38b0
--- /dev/null
+++ b/hlship-20080520/tapestry-test/src/test/conf/testng.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!--
+   Copyright 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Test" annotations="1.5" verbose="2">
+    <!-- This avoids a build error when performing a non-clean build.  Just another Maven fuckup to be worked around. -->
+    <test name="Placeholder (no tests)"/>
+</suite>
diff --git a/hlship-20080520/tapestry-tutorial1/.classpath b/hlship-20080520/tapestry-tutorial1/.classpath
new file mode 100644
index 0000000..df0c639
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="src" output="bin-test" path="src/test/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="lib" path="src/test/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-tutorial1/.project b/hlship-20080520/tapestry-tutorial1/.project
new file mode 100644
index 0000000..1541d79
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-tutorial1</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.core.prefs b/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d7ef1a3
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,248 @@
+#Sat Jun 09 09:09:30 PDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=48
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=true
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=2
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
diff --git a/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.ui.prefs b/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..5a37e1e
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Sat Jun 09 09:09:30 PDT 2007
+eclipse.preferences.version=1
+formatter_profile=_Tapestry Tutorial
+formatter_settings_version=10
diff --git a/hlship-20080520/tapestry-tutorial1/LICENSE-2.0.txt b/hlship-20080520/tapestry-tutorial1/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/LICENSE-2.0.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/hlship-20080520/tapestry-tutorial1/NOTICE.txt b/hlship-20080520/tapestry-tutorial1/NOTICE.txt
new file mode 100644
index 0000000..439eb83
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/NOTICE.txt
@@ -0,0 +1,3 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/hlship-20080520/tapestry-tutorial1/pom.xml b/hlship-20080520/tapestry-tutorial1/pom.xml
new file mode 100644
index 0000000..005cc55
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/pom.xml
@@ -0,0 +1,148 @@
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tutorial1</artifactId>
+    <packaging>war</packaging>
+    <name>Tapestry 5 Tutorial</name>
+    <description>Introductory topics in Tapestry application development.</description>
+    <organization>
+        <name>Apache Software Foundation</name>
+        <url>http://www.apache.org</url>
+    </organization>
+
+    <scm>
+        <connection>scm:svn:https://svn.apache.org/repos/asf/tapestry/tapestry5/trunk/tapestry-tutorial1/</connection>
+        <url>http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/</url>
+    </scm>
+
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-hibernate</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate</artifactId>
+            <version>3.2.2.ga</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.transaction</groupId>
+                    <artifactId>jta</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-annotations</artifactId>
+            <version>3.2.1.ga</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.5</version>
+        </dependency>
+
+
+        <!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the tests)
+will fail, preventing Maven from packaging the WAR. Tapestry includes a large number
+of testing facilities designed for use with TestNG (http://testng.org/), so it's recommended. -->
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.1</version>
+            <classifier>jdk15</classifier>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <version>2.3</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <finalName>tapestry-tutorial1</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                    <optimize>true</optimize>
+                </configuration>
+            </plugin>
+
+            <!-- Run the application using "mvn jetty:run" -->
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>maven-jetty-plugin</artifactId>
+                <version>6.1.9</version>
+                <configuration>
+                    <!-- Log to the console. -->
+                    <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
+                        <!-- This doesn't do anything for Jetty, but is a workaround for a Maven bug
+                 that prevents the requestLog from being set. -->
+                        <append>true</append>
+                    </requestLog>
+                </configuration>
+            </plugin>
+
+
+            <!-- This changes the WAR file packaging so that what would normally go into WEB-INF/classes
+     is instead packaged as WEB-INF/lib/tutorial1.jar.  This is necessary for Tapestry
+     to be able to search for page and component classes at startup. Only
+     certain application servers require this configuration, please see the documentation
+     at the Tapestry 5 project page (http://tapestry.apache.org/tapestry5/). -->
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <configuration>
+                    <archiveClasses>true</archiveClasses>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+
+        <!-- Adds a report detailing the components, mixins and base classes defined by this module. -->
+        <plugins>
+            <plugin>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-component-report</artifactId>
+                <version>${project.version}</version>
+                <configuration>
+                    <rootPackage>org.apache.tapestry.tutorial</rootPackage>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+
+</project>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java
new file mode 100644
index 0000000..a1dc38f
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.data;
+
+public enum Honorific
+{
+    MR, MRS, MISS, DR
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/entities/Address.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/entities/Address.java
new file mode 100644
index 0000000..3d175f4
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/entities/Address.java
@@ -0,0 +1,168 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.entities;
+
+import org.apache.tapestry.beaneditor.NonVisual;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.tutorial.data.Honorific;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Address
+{
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Honorific honorific;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String street1;
+
+    private String street2;
+
+    private String city;
+
+    private String state;
+
+    private String zip;
+
+    private String email;
+
+    private String phone;
+
+    @NonVisual
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Honorific getHonorific()
+    {
+        return honorific;
+    }
+
+    @Validate("required")
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    @Validate("required")
+    public String getStreet1()
+    {
+        return street1;
+    }
+
+    public String getStreet2()
+    {
+        return street2;
+    }
+
+    @Validate("required")
+    public String getCity()
+    {
+        return city;
+    }
+
+    @Validate("required")
+    public String getState()
+    {
+        return state;
+    }
+
+    @Validate("required,regexp")
+    public String getZip()
+    {
+        return zip;
+    }
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setCity(String city)
+    {
+        this.city = city;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setHonorific(Honorific honorific)
+    {
+        this.honorific = honorific;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+    }
+
+    public void setState(String state)
+    {
+        this.state = state;
+    }
+
+    public void setStreet1(String street1)
+    {
+        this.street1 = street1;
+    }
+
+    public void setStreet2(String street2)
+    {
+        this.street2 = street2;
+    }
+
+    public void setZip(String zip)
+    {
+        this.zip = zip;
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/GameOver.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/GameOver.java
new file mode 100644
index 0000000..6607694
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/GameOver.java
@@ -0,0 +1,45 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+
+public class GameOver
+{
+    @Persist
+    @Property
+    private int count;
+
+    Object initialize(int count)
+    {
+        this.count = count;
+
+        return this;
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Guess.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Guess.java
new file mode 100644
index 0000000..0a7bbfd
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Guess.java
@@ -0,0 +1,65 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+
+public class Guess
+{
+    @Persist
+    private int target;
+
+    @Property
+    private int guess;
+
+    @Persist
+    @Property
+    private String message;
+
+    @Persist
+    private int count;
+
+    @InjectPage
+    private GameOver gameOver;
+
+    Object onActionFromLink(int guess)
+    {
+        count++;
+
+        if (guess == target) return gameOver.initialize(count);
+
+        if (guess < target)
+            message = String.format("%d is too low.", guess);
+        else
+            message = String.format("%d is too high.", guess);
+
+        return null;
+    }
+
+    Object initialize(int target)
+    {
+        this.target = target;
+        count = 0;
+
+        return this;
+    }
+
+    public int getTarget()
+    {
+        return target;
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Index.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Index.java
new file mode 100644
index 0000000..a9a30e5
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/Index.java
@@ -0,0 +1,47 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.pages;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.tutorial.entities.Address;
+import org.hibernate.Session;
+
+import java.util.List;
+import java.util.Random;
+
+public class Index
+{
+    private final Random random = new Random();
+
+    @InjectPage
+    private Guess guess;
+
+    @Inject
+    private Session session;
+
+    Object onAction()
+    {
+        int target = random.nextInt(10) + 1;
+
+        return guess.initialize(target);
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    public List<Address> getAddresses()
+    {
+        return session.createCriteria(Address.class).list();
+    }
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java
new file mode 100644
index 0000000..e910bad
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java
@@ -0,0 +1,43 @@
+// Copyright 2007, 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.pages.address;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.tutorial.entities.Address;
+import org.apache.tapestry.tutorial.pages.Index;
+import org.hibernate.Session;
+
+public class CreateAddress
+{
+    @Property
+    private Address address;
+
+    @Inject
+    private Session session;
+
+    @InjectPage
+    private Index index;
+
+    @CommitAfter
+    Object onSuccess()
+    {
+        session.persist(address);
+
+        return index;
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/AppModule.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/AppModule.java
new file mode 100644
index 0000000..626bd6f
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/AppModule.java
@@ -0,0 +1,97 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.services;
+
+import org.apache.tapestry.SymbolConstants;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.annotation.Marker;
+import org.apache.tapestry.services.Request;
+import org.apache.tapestry.services.RequestFilter;
+import org.apache.tapestry.services.RequestHandler;
+import org.apache.tapestry.services.Response;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+
+/**
+ * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to configure and extend
+ * Tapestry, or to place your own services.
+ */
+@Marker(Local.class)
+public class AppModule
+{
+    public static void contributeApplicationDefaults(
+            MappedConfiguration<String, String> configuration)
+    {
+        // Contributions to ApplicationDefaults will override any contributions to
+        // FactoryDefaults (with the same key). Here we're restricting the supported
+        // locales to just "en" (English). As you add localised message catalogs and other assets,
+        // you can extend this list of locales (it's a comma seperated series of locale names;
+        // the first locale name is the default when there's no reasonable match).
+
+        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
+        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
+    }
+
+    /**
+     * This is a service definition, the service will be named TimingFilter. The interface, RequestFilter, is used
+     * within the RequestHandler service pipeline, which is built from the RequestHandler service configuration.
+     * Tapestry IoC is responsible for passing in an appropriate Log instance. Requests for static resources are handled
+     * at a higher level, so this filter will only be invoked for Tapestry related requests.
+     */
+    public RequestFilter buildTimingFilter(final Logger logger)
+    {
+        return new RequestFilter()
+        {
+            public boolean service(Request request, Response response, RequestHandler handler)
+                    throws IOException
+            {
+                long startTime = System.currentTimeMillis();
+
+                try
+                {
+                    // The reponsibility of a filter is to invoke the corresponding method
+                    // in the handler. When you chain multiple filters together, each filter
+                    // received a handler that is a bridge to the next filter.
+
+                    return handler.service(request, response);
+                }
+                finally
+                {
+                    long elapsed = System.currentTimeMillis() - startTime;
+
+                    logger.info(String.format("Request time: %d ms", elapsed));
+                }
+            }
+        };
+    }
+
+    /**
+     * This is a contribution to the RequestHandler service configuration. This is how we extend Tapestry using the
+     * timing filter. A common use for this kind of filter is transaction management or security.
+     */
+    public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
+
+                                         @Local
+                                         RequestFilter filter)
+    {
+        // Each contribution to an ordered configuration has a name, When necessary, you may
+        // set constraints to precisely control the invocation order of the contributed filter
+        // within the pipeline.
+
+        configuration.add("Timing", filter);
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/Local.java b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/Local.java
new file mode 100644
index 0000000..8b1dfa9
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/services/Local.java
@@ -0,0 +1,33 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ *
+ */
+package org.apache.tapestry.tutorial.services;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target(
+        {PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface Local
+{
+}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/resources/hibernate.cfg.xml b/hlship-20080520/tapestry-tutorial1/src/main/resources/hibernate.cfg.xml
new file mode 100644
index 0000000..a948a96
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/resources/hibernate.cfg.xml
@@ -0,0 +1,23 @@
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+<hibernate-configuration>
+    <session-factory>
+        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
+        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/t5_tutorial1</property>
+        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
+
+        <!--
+
+        To create user, login a root and:
+
+            grant all on t5_tutorial1.* to 't5tutorialuser'@'localhost' identified by 'secret';
+
+        -->
+        <property name="hibernate.connection.username">t5tutorialuser</property>
+        <property name="hibernate.connection.password">secret</property>
+        <property name="hbm2ddl.auto">update</property>
+        <property name="hibernate.show_sql">true</property>
+        <property name="hibernate.format_sql">true</property>
+    </session-factory>
+</hibernate-configuration>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/resources/log4j.properties b/hlship-20080520/tapestry-tutorial1/src/main/resources/log4j.properties
new file mode 100644
index 0000000..cfe2113
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/resources/log4j.properties
@@ -0,0 +1,37 @@
+# Copyright 2007, 2008 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootCategory=info, A1
+
+# A1 is set to be a ConsoleAppender. 
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=[%p] %c{1} %m%n
+
+log4j.category.org.apache.tapestry.TapestryFilter=info
+log4j.category.org.apache.tapestry.services.TapestryModule.ComponentClassResolver=info
+
+log4j.category.org.apache.tapestry=error
+log4j.category.tapestry=error
+
+log4j.category.org.apache.tapestry.tutorial=error
+log4j.category.app=error
+log4j.category.app.TimingFilter=info
+
+# Turning on debug mode for a page or component will show all of the code changes that occur when the
+# class is loaded.  Turning on debug mode for a page will enable verbose output about rendering
+# the page (and its components).
+# log4j.category.org.apache.tapestry.tutorial.pages.Index=debug
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties b/hlship-20080520/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties
new file mode 100644
index 0000000..c2bbfb1
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties
@@ -0,0 +1,28 @@
+# Copyright 2007 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+street1-label=Street 1
+street2-label=Street 2
+email-label=E-Mail
+zip-label=Zip Code
+phone-label=Phone Number
+
+MR=Mr.
+MRS=Mrs.
+DR=Dr.
+
+submit-label=Create Address
+
+zip-regexp=\\d{5}(-\\d{4})?
+zip-regexp-message=Zip Codes are five or nine digits.  Example: 02134 or 90125-1655.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/GameOver.tml b/hlship-20080520/tapestry-tutorial1/src/main/webapp/GameOver.tml
new file mode 100644
index 0000000..adb4510
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/GameOver.tml
@@ -0,0 +1,13 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Game Over!</title>
+  </head>
+  <body>
+
+    <h1>Game Over</h1>
+
+    <p> You guessed the secret number in ${count} guesses!  </p>
+
+
+  </body>
+</html>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/Guess.tml b/hlship-20080520/tapestry-tutorial1/src/main/webapp/Guess.tml
new file mode 100644
index 0000000..8238569
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/Guess.tml
@@ -0,0 +1,15 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>Guess A Number</title>
+    </head>
+    <body>
+
+        <p>Make a guess between one and ten:</p>
+
+        <p>${message}</p>
+
+        <t:loop source="1..10" value="guess" xml:space="preserve">
+            <t:actionlink t:id="link" context="guess">${guess}</t:actionlink>
+        </t:loop>
+    </body>
+</html>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/Index.tml b/hlship-20080520/tapestry-tutorial1/src/main/webapp/Index.tml
new file mode 100644
index 0000000..8033343
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/Index.tml
@@ -0,0 +1,26 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>tutorial1 Start Page</title>
+    </head>
+    <body>
+
+        <h1>Hi/Lo Guess</h1>
+
+        <p>I'm thinking of a number between one and ten ...</p>
+
+        <p>
+            <t:actionlink>Start guessing</t:actionlink>
+        </p>
+
+        <h1>Address Book</h1>
+
+        <t:grid source="addresses"/>
+
+        <ul>
+            <li>
+                <t:pagelink page="address/create">Create new address</t:pagelink>
+            </li>
+        </ul>
+
+    </body>
+</html>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/WEB-INF/web.xml b/hlship-20080520/tapestry-tutorial1/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..6732c5a
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Tapestry 5 Tutorial #1</display-name>
+    <context-param>
+        <!-- The only significant configuration for Tapestry 5, this informs Tapestry
+of where to look for pages, components and mixins. -->
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.apache.tapestry.tutorial</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+</web-app>
+      
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/address/CreateAddress.tml b/hlship-20080520/tapestry-tutorial1/src/main/webapp/address/CreateAddress.tml
new file mode 100644
index 0000000..1f1dc73
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/address/CreateAddress.tml
@@ -0,0 +1,18 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Create New Address</title>
+  </head>
+  <body>
+
+    <style>
+      DIV.t-beaneditor LABEL { 
+        width: 200px;
+      }
+    </style>
+
+    <h1>Create New Address</h1>
+
+    <t:beaneditform submitlabel="message:submit-label" object="address"/>
+
+  </body>
+</html>
diff --git a/hlship-20080520/tapestry-tutorial1/src/main/webapp/favicon.ico b/hlship-20080520/tapestry-tutorial1/src/main/webapp/favicon.ico
new file mode 100644
index 0000000..ffd53d6
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/main/webapp/favicon.ico
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/env.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/env.apt
new file mode 100644
index 0000000..9ebeffb
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/env.apt
@@ -0,0 +1,65 @@
+ ---
+ Setting up your Environment
+ ---
+ 
+Chapter 1: Setting Up Your Environment
+
+ As much as I would like to dive into Tapestry right now, we must first talk about your development environment. The joy and the pain of Java development is the volume of choice available. There's just a bewildering number of JDKs, IDEs and other TLA1s out there.
+
+ Let's talk about a stack of tools, all open source and freely available, that you'll need to setup. Likely you have some of these, or some version of these, already on your development machine.
+
+* JDK 1.5
+
+  Tapestry 5 makes use of features of JDK 1.5.  This includes Java Annotations, and a little bit of Java Generics.
+  
+* Eclipse 3.3
+
+  Since we're emphasizing a free and open source stack, we'll concentrate on the best <free> IDE.
+  
+  Eclipse 3.3 comes in various flavors, and includes a reasonable XML editor built-in.
+  
+* Jetty 5.1
+
+  Jetty is an open source servlet container created by Greg Wilkins of Webtide (which offers commercial support for Jetty). Jetty is high performance and designed for easy embedding in other software.
+   I've chosen the 5.1 release, rather than the cutting edge Jetty 6, because it is compatible with Jetty Launcher (see below).
+   
+  You can find out more about Jetty from its home page: {{{http://mortbay.org}http://mortbay.org}}.
+  
+  You can download Jetty from {{{http://docs.codehaus.org/display/JETTY/Downloading+and+Installing}http://docs.codehaus.org/display/JETTY/Downloading+and+Installing}}.
+  
+* Jetty Launcher
+
+  Jetty Launcher is a plugin for Eclipse that makes it easy to launch Jetty applications from within Eclipse. This is a great model, since you can run or debug directly from you workspace without wasting time packaging and deploying.
+  
+  Jetty Launcher was created by Geoff Longman, and is available from http://jettylauncher.sourceforge.net/. Installation is easy, simply point Eclipse's update manager at 
+  {{{http://jettylauncher.sourceforge.net/updates/}http://jettylauncher.sourceforge.net/updates/}}.
+
+  If you are behind a firewall, you will need to set up a manual proxy configuration in Eclipse (Window, Preferences..., General, Network Connections).
+
+  <<Caution: JettyLauncher is only compatible with Jetty 4 and Jetty 5. It does not work with Jetty 6.>>
+  
+* Maven 2.0.8
+
+  Maven is a software build tool of rather epic ambitions. It has a very sophisticated plugin system that allows it to do virtually anything, though compiling Java code, building WAR and JAR files, and creating reports and web sites are its forte.
+  
+  Perhaps the biggest advantage of Maven over, say, Ant, is that it can download project dependencies (such as the Tapestry JAR files, and the JAR files Tapestry itself depends on) automatically for you, from one of several central repositories.
+  
+  We'll be using Maven to set up our Tapestry applications.  Maven 2.0.8 is available from {{{http://maven.apache.org/download.html}http://maven.apache.org/download.html}}.
+  
+* Maven Plugin
+
+  The Maven Plugin for Eclipse integrates Maven and Eclipse. It includes some features for editing the pom.xml (the Maven project description file which identifies, among many other things, what JAR files are needed by the project). 
+  More importantly, a Maven-enabled project automatically stays synchronized with the POM, automatically linking Eclipse project classpath to files from the local Maven repository.
+  
+  The plugin is available by pointing the Eclipse update manager at {{{http://m2eclipse.codehaus.org/update/}http://m2eclipse.codehaus.org/update/}}.  Make sure to use version 0.0.10.
+  
+* Tapestry 5.0.x
+
+  You should not have to download this directly; as we'll see, Maven should take care of downloading Tapestry, and its dependencies, as needed.
+  
+  <<Caution: this book is being written in parallel with Tapestry 5. In some cases, the screenshots may not be entirely accurate and the version number for Tapestry is in flux, with snapshot releases occurring frequently, and new dot releases every few weeks. 
+  So, for example, is 5.0.5 is not available, you can use 5.0.4 instead.>>
+  
+===
+  
+  {{{first.html}Continue on to Chapter 2: Your First Tapestry Application}}
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/first.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/first.apt
new file mode 100644
index 0000000..89273e5
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/first.apt
@@ -0,0 +1,322 @@
+ ---
+ Your First Tapestry Application
+ ---
+ 
+Chapter 2: Your First Tapestry Application
+
+  Before we can get down to the fun, we have to create an empty application.  Tapestry uses a feature of Maven to do this: <<archetypes>> (a too-clever way of saying "project templates").
+  
+  What we'll do is create an empty shell application using Maven, then import the application into Eclipse to do the rest of the work.
+    
+  Before proceeding, we have to decide on three things:  A Maven <group id> and <artifact id> for our project and a <root package name>. 
+  
+  Maven uses the group id and artifact id to provide a unique identity for the application, and Tapestry needs to have a base package name so it knows where to look for pages and components.
+  
+  For this example, we'll use the group id <<org.apache.tapestry>> and the artifact id <<tapestry-tutorial1>>, and we'll use <<org.apache.tapestry.tutorial>> as the base package.
+  
+  Our final command line is thus:
+
+----
+mvn archetype:create
+  -DarchetypeGroupId=org.apache.tapestry
+  -DarchetypeArtifactId=quickstart
+  -DgroupId=org.apache.tapestry
+  -DartifactId=tutorial1
+  -DpackageName=org.apache.tapestry.tutorial
+----
+
+  We've shown this as several lines, but it would normally be entered as a single long line.
+  
+  As a command, it's quite a doozy!  If you are going to create lots of projects, creating a wrapper script for this is a smart idea.
+  
+  Execute this in a temporary directory, it will create a sub-directory: tapestry-tutorial1.
+    
+  The first time you execute this command, Maven will spend quite a while downloading all kinds of JARs into
+  your local repository, which can take a minute or more. Later, once all that is already available locally,
+  the whole command executes in under a second.
+
+  If you are behind a firewall, before running any "mvn" commands, you will need to configure your proxy settings in settings.xml. Here is an example:
+
+----
+<settings>
+ <proxies>
+    <proxy>
+       <active>true</active>
+       <protocol>http</protocol>
+       <host>myProxyServer.com</host>
+       <port>8080</port>
+       <username>joeuser</username>
+       <password>myPassword</password>
+       <nonProxyHosts></nonProxyHosts>
+    </proxy>
+ </proxies>
+ <localRepository>C:/Documents and Settings/joeuser/.m2/repository</localRepository>
+</settings>
+----
+
+  Of course, adjust  the \<localRepository\> element to match the correct path for your computer.  
+
+  One of the first things you can do is use Maven to run Jetty directly.
+  
+  Change into the newly created directory, and execute the command:
+  
+---
+mvn jetty:run
+---
+
+  Again, the first time, there's a dizzying number of downloads, but before you know it, the Jetty servlet container
+  is up and running.
+
+  You can open a web browser to {{{http://localhost:8080/tutorial1/}http://localhost:8080/tutorial1/}}
+  to see the running application:
+  
+[startpage.png] Default Start page for Application
+
+  The date and time in the middle of the page proves that this is a live application.
+  
+  Let's look at what Maven has generated for us. To do this, we're going to load the project inside Eclipse and continue from there.
+  
+  Start by hitting Control-C in the Terminal window to close down Jetty..
+  
+  Launch Eclipse and switch over to the Java Browser Perspective.
+  
+  Right click inside the Projects view and select <<Import ...>>
+  
+  Choose the "existing projects" option:
+  
+[eclipse-import.png] Import Project into Eclipse
+
+  Now select the folder created by Maven:
+  
+[eclipse-import-folder.png] Select folder to import
+
+  When you click the Finish button, the project will be imported into the Eclipse workspace.
+  
+  <<TODO: Picture of Java Browsing Perspective>>
+  
+  Maven dictates the layout of the project:
+  
+  * Java source files under src/main/java
+  
+  * Web application files under src/main/webapp (including src/main/webapp/WEB-INF)
+  
+  * Java test sources under src/test/java
+  
+  * Non-code resources under src/main/resources and src/test/resources
+  
+  []
+  
+  (Tapestry uses a number of non-code resources, such as template files and message catalogs, which will ultimately be packaged into
+  the WAR file.)
+  
+  The Maven Plugin, inside Eclipse, has found all the referenced libraries in your local Maven repository, and compiled the two classes created by quickstart archetype.
+  
+  Let's look at what the archetype has created for us, starting with the web.xml file:
+  
+  <<src/main/webapp/WEB-INF/web.xml>>
+  
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app
+      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+      "http://java.sun.com/dtd/web-app_2_3.dtd">
+      <web-app>
+          <display-name>tutorial1 Tapestry 5 Application</display-name>
+          <context-param>
+              <!-- The only significant configuration for Tapestry 5, this informs Tapestry
+                   of where to look for pages, components and mixins. -->
+              <param-name>tapestry.app-package</param-name>
+              <param-value>org.apache.tapestry.tutorial</param-value>
+          </context-param>
+          <filter>
+              <filter-name>app</filter-name>
+              <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+          </filter>
+          <filter-mapping>
+              <filter-name>app</filter-name>
+              <url-pattern>/*</url-pattern>
+          </filter-mapping>
+      </web-app>
+----
+  
+  This is short and sweet: you can see that the package name you provided earlier shows up as the tapestry.app-package context parameter; the TapestryFilter instance will use
+  this information to locate the Java classes we'll look at next.
+  
+  Tapestry 5 operates as a <servlet filter> rather than as a traditional <servlet>. In this way, Tapestry has a chance to intercept all incoming requests, to determine
+  which ones apply to Tapestry pages (or other resources). The net effect is that you don't have to maintain any additional configuration
+  for Tapestry to operate, regardless of how many pages or components you add to your application.
+  
+  Tapestry pages minimally consist of an ordinary Java class plus a component template file.
+
+  In the root of your web application, a page named "Index" will be used for any request that specifies no additional
+  path after the context name.
+    
+  Let's start with the template, which is stored in the webapp's WEB-INF folder.  Tapestry component templates are well-formed XML documents.  This means that you can use
+  any available XML editor.  Templates may even have a DOCTYPE or an XML schema to validate the structure of the template.  <That is, your build process may use a tool to validate your
+  templates.  At runtime, when Tapestry reads the template, it does not use a validating parser.> For the most part, the template looks like
+  ordinary XHTML:
+  
+  <<src/main/webapp/Index.tml:>>
+  
+----
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <head>
+        <title>tutorial1 Start Page</title>
+    </head>
+    <body>
+        <h1>tutorial1 Start Page</h1>
+
+        <p> This is the start page for this application, a good place to start your modifications.
+            Just to prove this is live: </p>
+
+        <p> The current time is: ${currentTime}. </p>
+
+
+        <p>
+            [<t:pagelink t:page="Index">refresh</t:pagelink>]
+        </p>
+    </body>
+</html>
+----
+
+ The goal in Tapestry is for component templates, such as Index.tml, to look as much as possible like ordinary, static
+ HTML files. <By static, we mean unchanging, as opposed to a dynamically generated Tapestry page.>  In fact, the expectation
+ is that in many cases, the templates will start as static HTML files, created by a web developer and then be
+ <instrumented> to act as live Tapestry pages.
+ 
+  Tapestry hides non-standard element and attributes inside the XML namespace. By convention, the prefix "t:" is used for
+  this namespace, but that is not a requirement.
+  
+  There only two bits of Tapestry instrumentation on this page.
+  
+  First is the way we display the current date and time: <<<$\{currentTime}>>>.  This syntax is used to access a property
+  of the page object, a property named currentTime.  Tapestry calls this an <expansion>.  The value inside the braces is the name of a 
+  standard JavaBeans property supplied by the page. As we'll see in later chapters, this is just the tip of the iceberg for what is possible
+  using expansions.
+  
+  The other item is the link used to refresh the page. We're specifying a component as an XML <element> within the Tapestry namespace. The element name, "pagelink",
+  defines the type of component.  PageLink (Tapestry is case insensitive) is a component built into the framework; it is part of the
+  core component library.  The attribute, page, is a string - the name of the page to link to.  Here, we're linking back to the same page, page "Index".
+  
+  This is how Tapestry works; the Index page contains an <instance> of the PageLink component. The PageLink component is configured via its parameters, which controls what
+  it does and how it behaves.
+  
+  The URL that the PageLink component will render out is <<<http://localhost:8080/tapestry-tutorial1/>>> ."Index" pages are special and
+  are identified just by the folder name.    In later examples,
+  when we link to pages besides "Index", the page name will be part of the URL.
+  
+  Tapestry ignores case where ever it can. Inside the template, we configured the PageLink component's page parameter with the name of the page, "Index".  Here too we could be
+  inexact on case.  Feel free to use "index" if that works for you. 
+  
+  <You do have to name your component template file, Index.html, with the exact same case as the component class name, Index. If you get the case wrong, it may work on some
+  operating systems (such as Windows) and not on others (Mac OS X, Linux, and most others). This can be really vexing, as it is common to develop on Windows and deploy on Linux or
+  Solaris, so be careful about case in this one area.>
+  
+  Clicking the link in the web browser sends a request to re-render the page; the template and Java object are
+  re-used to generate the HTML sent to the browser, which results in the updated time showing up in the web browser.
+  
+  The final piece of the puzzle is the Java class for the page.  Tapestry has very specific rules for where page classes go.  Remember the package name (configured inside web.xml)?  Tapestry adds a
+  sub-package, "pages", to it and the Java class goes there. Thus the full Java class name is org.apache.tapestry.tutorial.pages.Index.
+  
+  <<src/main/java/org/apache/tapestry/tutorial/pages/Index.java>>
+
+---
+package org.apache.tapestry.tutorial.pages;
+
+import java.util.Date;
+
+/**
+ * Start page of application tutorial1.
+ */
+public class Index
+{
+  public Date getCurrentTime()
+  {
+    return new Date();
+  }
+}
+---
+  
+  That's pretty darn simple: No classes to extend, no interfaces to implement, just a very pure POJO (Plain Old Java Object). You do have to meet the Tapestry framework
+  halfway:
+  
+  * You need to put the Java class in the expected package, org.apache.tapestry.tutorial.pages
+  
+  * The class must be public
+  
+  * You need to make sure there's a public, no-arguments constructor (here, the Java compiler has silently provided one for us)
+  
+  []
+  
+  The template referenced the property currentTime and we're providing that as a property, as a <synthetic property>, a property that is computed on the fly
+  (rather than stored in an instance variable).
+  
+  This means that every time the page renders, a fresh Date instance is created, which is just what we want.
+  
+  As the page renders, it generates the HTML markup that is sent to the client web browser.  For most of the page, that markup is
+  exactly what came out of the component template: this is called the <static content> (we're using the term "static" to mean "unchanging").
+  
+  The expansion, <<<$\{currentTime}>>>, is <dynamic:> different every time.  Tapestry will read that property and convert the result
+  into a string, and that string is mixed into the stream of markup sent to the client. <We'll often talk about the "client" and we don't mean
+  the people you send your invoices to: we're talking about the client web browser. Of course, in a world of web spiders and other
+  screen scrapers, there's no guarantee that the thing on the other end of the HTTP pipe is really a web browser. You'll often see low-level HTML
+  and HTTP documentation talk about the "user agent".>  Likewise, the PageLink component is dynamic, in that it generates a URL that is
+  (potentially) different every time.
+  
+  Tapestry follows the rules defined by Sun's JavaBeans specification: a property name of currentTime maps to two methods: getCurrentTime() and setCurrentTime(). If you omit one of the other of these
+  methods, the property is either read only (as here), or write only.
+  
+  Tapestry does go one step further: it ignores case when matching properties inside the expansion to properties of the page. In the template we could say
+  <<<$\{currenttime}>>> or <<<$\{CurrentTime}>>> or any variation, and Tapestry will <still> invoke the getCurrentTime() method.
+  
+  In the next chapter, we'll start to build a simple hi-lo guessing game, but we've got one more task before then, plus a magic trick.
+  
+  The task is to set up Jetty to run our application directly out of our Eclipse workspace. This is a great way to develop web applications,
+  since we don't want to have to use Maven to compile and run the application ... or worse yet, use Maven to package and deploy the application. That's for later, when
+  we want to put the application into production.  For development, we want a fast, agile environment that can keep up with our changes, and that means we can't wait for redeploys
+  and restarts.
+  
+  Choose the <<Run ...>> item from the Eclipse <<Run>> menu to get the launch configuration dialog:
+  
+[eclipse-run.png] Eclipse Run Dialog
+
+  Select Jetty Web and click the <New> button:
+  
+[eclipse-launch.png] Eclipse Launch Configuration  
+  
+  We've filled in a name for our launch configuration, and identified the project.  We've also told Jetty Launcher where our Jetty installation is.  We've identified
+  the web context as src/main/webapp, and we've turned on NCSA logging for good measure.
+  
+  In addition, we've set up the context as "/tutorial1", which matches what our eventual WAR file, tutorial1.war, would be deployed as inside an application server.
+  
+  Once you click Run, Jetty will start up and launch (it should take about two seconds).
+  
+  You may now start the application with the URL {{{http://localhost:8080/tutorial1/}http://localhost:8080/tutorial1/}}.
+  
+  Now it's time for the magic trick. Edit Index.java and change the getCurrentTime() method to:
+  
+---
+  public String getCurrentTime()
+  {
+    return "A great day to learn Tapestry";
+  }
+---  
+
+  Make sure you save changes; then click the refresh link in the web browser:
+  
+[app-live-reload.png] Application after live class reloading
+
+  This is one of Tapestry's early <wow factor> features: changes to your component classes are picked up immediately. No restart. No re-deploy.  Make the changes and see them <now>.
+  Nothing should slow you down or get in the way of you getting your job done.
+  
+  Now that we have our basic application set up, and ready to run (or debug) directly inside Eclipse, we can start working on implementing our
+  Hi/Lo game in earnest.
+  
+===
+  
+  {{{hilo.html}Continue on to chapter 3: Implementing The Hi/Lo Game}}
+ 
+
+  
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/forms.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/forms.apt
new file mode 100644
index 0000000..7a2ce57
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/forms.apt
@@ -0,0 +1,485 @@
+ ---
+ Forms in Tapestry
+ ---
+ 
+Chapter 4: Forms in Tapestry
+
+  In the previous chapters, we saw how Tapestry can handle simple links, even links that pass information in the URL. In this chapter,
+  we'll see how Tapestry can do the same, and quite a bit more, for HTML forms.  
+  
+  Form support in Tapestry is deep and rich, more than can be covered in a single chapter. However, we can show the basics, including
+  some very common development patterns. To get started, let's create a simple address book application.
+  
+  We'll start with the entity data, a simple object to store the information we'll need. These classes go in an <<<entities>>> sub-package.  Unlike
+  the use of the <<<pages>>> sub-package (for page component classes), this is not enforced by Tapestry; it's just a convention (but
+  as we'll see shortly, a handy one).
+  
+  
+  <<src/main/java/org/apache/tapestry/tutorial/entities/Address.java:>>
+  
+----
+package org.apache.tapestry.tutorial.entities;
+
+import org.apache.tapestry.tutorial.data.Honorific;
+
+public class Address
+{
+  private Honorific honorific;
+
+  private String firstName;
+
+  private String lastName;
+
+  private String street1;
+
+  private String street2;
+
+  private String city;
+
+  private String state;
+
+  private String zip;
+
+  private String email;
+
+  private String phone;
+
+  public String getCity()
+  {
+    return city;
+  }
+
+  public String getEmail()
+  {
+    return email;
+  }
+
+  public String getFirstName()
+  {
+    return firstName;
+  }
+
+  public Honorific getHonorific()
+  {
+    return honorific;
+  }
+
+  public String getLastName()
+  {
+    return lastName;
+  }
+
+  public String getPhone()
+  {
+    return phone;
+  }
+
+  public String getState()
+  {
+    return state;
+  }
+
+  public String getStreet1()
+  {
+    return street1;
+  }
+
+  public String getStreet2()
+  {
+    return street2;
+  }
+
+  public String getZip()
+  {
+    return zip;
+  }
+
+  public void setCity(String city)
+  {
+    this.city = city;
+  }
+
+  public void setEmail(String email)
+  {
+    this.email = email;
+  }
+
+  public void setFirstName(String firstName)
+  {
+    this.firstName = firstName;
+  }
+
+  public void setHonorific(Honorific honorific)
+  {
+    this.honorific = honorific;
+  }
+
+  public void setLastName(String lastName)
+  {
+    this.lastName = lastName;
+  }
+
+  public void setPhone(String phone)
+  {
+    this.phone = phone;
+  }
+
+  public void setState(String state)
+  {
+    this.state = state;
+  }
+
+  public void setStreet1(String street1)
+  {
+    this.street1 = street1;
+  }
+
+  public void setStreet2(String street2)
+  {
+    this.street2 = street2;
+  }
+
+  public void setZip(String zip)
+  {
+    this.zip = zip;
+  }
+}
+----
+
+  It's just a collection of getter and setter methods.  We also need to define the enum type, Honorific:
+  
+  <<src/main/java/org/apache/tapestry/tutorial/data/Honorific.java:>>
+  
+---
+package org.apache.tapestry.tutorial.data;
+
+public enum Honorific
+{
+  MR, MRS, MISS, DR
+}
+---
+
+* Address Pages
+
+  We're probably going to create a few pages related to addresses: pages for creating them, for editing them, for searching and listing them.
+  We'll create a sub-folder, address, to hold them.  Let's get started on the first of these pages, "address/Create"  (that's the real name, including
+  the slash --- we'll see in a minute how that maps to classes and templates).
+  
+  First, we'll update the Index.tml template, to create a link for creating a new page:
+  
+  <<src/main/webapp/Index.tml:>>
+
+----
+    <h1>Address Book</h1>
+
+    <ul>
+      <li><t:pagelink page="address/create">Create new address</t:pagelink></li>
+    </ul>
+----
+
+   Now we need the page, let's start with an empty shell, just to test our navigation.
+  
+  <<src/main/webapp/address/CreateAddress.tml:>>
+  
+---
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Create New Address</title>
+  </head>
+  <body>
+
+    <h1>Create New Address</h1>
+
+    <em>coming soon ...</em>
+
+  </body>
+</html>
+---
+
+  And the corresponding class:
+  
+  <<src/main/java/org/apache/tapestry/tutorial1/pages/address/CreateAddress.java:>>
+  
+----
+package org.apache.tapestry.tutorial.pages.address;
+
+public class CreateAddress
+{
+
+}
+----
+   
+   So ... why is the class named "CreateAddress" and not simply "Create"?  Actually, we could have named it "Create", and 
+   the application would still work, but the longer <class> name is equally valid.  Tapestry noticed the redundancy in the
+   class name:  <<<org.apache.tapestry.tutorial.pages.>>><address><<<.Create>>><Address> and just stripped it out.
+   
+   Eventually, your application will probably have more entities:  perhaps you'll have a "user/Create" page and a "payment/Create" page and an "account/Create" page.
+   Now, you <could> have a bunch of different classes named <<<Create>>> spread across a number of different packages.  That's legal Java, but it isn't ideal.  You may find yourself
+   accidentally editing the Java code for creating an Account when your really want to be editting the code for creating a Payment.
+   
+   Tapestry is encouraging you to use a more descriptive name: <<<Create>>><Address> not just <<<Create>>>, but it isn't making you pay the cost (in terms of longer,
+   uglier URLs).  The URL to access the page will still be http://localhost:8080/tutorial1/address/create.
+
+   Another note:  Index pages work in folders as well.  A class named org.apache.tapestry.tutorial.pages.address.AddressIndex would be given the name
+   "address/Index".  However, Tapestry has special rules for pages named "Index" and the render URL would be
+   http://localhost:8080/tutorial1/address/ .  In other words, you can place Index pages in any folder and Tapestry will
+   build a short URL for that page ... and you <don't> have to keep naming the classes Index (it's confusing to have many classes with the same
+   name, even across multiple packages); instead, you can name each index page after the package
+   that contains it.  Tapestry users a smart <convention> to keep it all straight and generate short, to the point URLs.
+   
+* Using the BeanEditForm component
+
+  Time to start putting together the logic for this form.  In fact, let's use a magic trick ... the BeanEditForm component.  This component can analyze a class and create an editor UI for it all in one go.
+  Let's give it a try.
+  
+  Add the following to the CreateAddress template (replacing the "coming soon ..." message):
+  
+---
+  <t:beaneditform object="address"/>
+---
+
+  And match that up with a property in the CreateAddress class:
+  
+----
+  @Property
+  private Address address
+----
+   
+   When you refresh the page, you'll see the following:
+   
+[address-v1.png] Initial version of the create address form
+
+  <There have been minor changes to the default CSS since this screenshot was taken; for example, the labels are a bit
+   wider now.  In addition, the Honorific field (being optional) would include a blank option, rather than the first real selection, "Mr".>
+
+  Tapestry's done quite a bit of work here.  It has created a form that includes a field for each property.  Further, its seen that the
+  honorific property is an enumerated type, and presented that as a drop-down list.
+  
+  In addition, Tapestry has converted the property names ("city", "email", "firstName") to user presentable labels ("City", "Email", "First Name").
+  In fact, these are \<label\> elements, so clicking a label will move the cursor into the corresponding field.
+  
+  This is an awesome start; it's a presentable interface, quite nice in fact for a few  minute's work.  But it's far from perfect; let's get started
+  with some customizations.
+  
+* Changing field order
+
+  It looks like the fields are being displayed in alphabetical order, ("city" first, "zip" last).  That's not quite the reality, however:  If you check the listing
+  for the Address class, you'll see that the getter and setter methods are in alphabetical order (care of Eclipse, which generated all those methods from the fields).
+     
+  The BeanEditForm works in the order in which the <getter methods> are defined in the class.  Let's reorder them into a more reasonable order:
+  
+  * honorific
+  
+  * firstName
+  
+  * lastName
+  
+  * street1
+  
+  * street2
+  
+  * city
+  
+  * state
+  
+  * zip
+  
+  * email
+  
+  * phone
+  
+  []
+  
+  (This is also the order of in which the fields are defined.)
+  
+  Because Address is not a component class, it is necessary to restart Jetty to see the effects of these changes.
+  
+  Once Jetty is restarted, hit the browser's refresh button to see the fields in the correct order:
+  
+[address-v2.png] Create address form with fields in proper order
+
+* Customizing labels
+
+  Tapestry makes it pretty easy to customize the labels used on the fields.  It's just a matter of creating a <message catalog> for the page.
+  
+  In Tapestry, every page and component may have its own message catalog.  This is a standard Java properties file, and it is named the same
+  as the page or component class, with a ".properties" extension.  A message catalog consists of a series of lines, each line is a message key and a message value
+  separated with an equals sign.
+  
+  All it takes is to create a message entry with a particular name:  the name of the property suffixed with "-label". As elsewhere, Tapestry is forgiving of case.
+  
+  <<src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties:>>
+  
+----
+street1-label=Street 1
+street2-label=Street 2
+email-label=E-Mail
+zip-label=Zip Code
+phone-label=Phone Number
+----
+
+  Since this is a <new> file (and not a change to an existing file), you may have to restart Jetty to force Tapestry to pick up the change.
+  
+[address-v3.png] Create Address form with field labels corrected
+  
+   We can also customize the options in the drop down list.  All we have to do is add some more entries to the message catalog matching the enum names to the desired labels.
+   Update CreateAddress.properties and add:
+   
+----
+MR=Mr.
+MRS=Mrs.
+DR=Dr.
+----
+
+  Notice that we don't have to include an option for MISS, because that is converted to "Miss" anyway.  You might just want to include it for
+  sake of consistency ... the point is, each option label is searched for seperately.
+
+  Lastly, the default label on the submit button is "Create/Update" (BeanEditForm doesn't know how it is being used). Let's change that to "Create Address".
+  
+  That button is a component within the BeanEditForm component. It's not a property, so we can't just put a message into the 
+  message catalog, the way we can with the fields.  Fortunately, the BeanEditForm component includes a parameter expressly for
+  re-labelling the button. Simply change the CreateAddress component template:
+  
+----
+  <t:beaneditform submitlabel="Create Address" object="address"/>
+----
+
+  The default for the submitlabel parameter is "Create/Update", but here we're overriding that default to a specific value.
+
+  The final result shows the reformatting and relabeling:
+  
+[address-v5.png] Create Address form with proper labels
+
+  Before continuing on to validation, a side note about message catalogs. 
+  Message catalogs are not just for re-labeling fields and options; we'll see in later chapters how message catalogs are used in the context of
+  localization and internationalization. 
+  
+  Instead of putting the label for the submit button directly inside the template, we're going to provide a reference to the label; the actual
+  label will go in the message catalog. 
+  
+  In Tapestry, when binding a parameter, the value you provide may include a prefix.  The prefix guides Tapestry in how to interpret the rest of the
+  the parameter value ... is it the name of a property?  The id of a component? A message key?  Most fields have a default prefix, usually "prop:", that
+  is used when you fail to provide one (this helps to make the templates as terse as possible).
+  
+  Here we want to reference a message from the catalog, so we use the "message:" prefix:
+  
+----
+  <t:beaneditform submitlabel="message:submit-label" object="address"/>
+----
+
+  And then define the submit-label key in the message catalog:
+  
+---
+submit-label=Create Address
+----
+
+  At then end of the day, the exact same HTML is sent to the client, regardless of whether you include the label text directly in the template,
+  or indirectly in the message catalog. In the long term, the latter approach will work better if you later chose to internationalize your application.
+   
+*  Adding Validation
+
+  Before we worry about storing the Address object, we should make sure that the user provides reasonable values. For example,several of the fields should be required,
+  and phone numbers and email address have specific formats.
+  
+  The BeanEditForm checks for a Tapestry-specific annotation, @org.apache.tapestry.beaneditor.Validate, on the getter <or> setter method of each property.   
+
+  Update the getter methods for the lastName, firstName, street1, city, state and zip fields, 
+  adding a @Validate annotation to each:
+  
+----
+  @Validate("required")
+  public String getFirstName()
+  {
+    return firstName;
+  }
+----
+
+  What is that string, "required"?  That's how you specify the desired validation.  It is a series of names that identify what type of validation is desired.
+  A number of validators are built in, such as "required", "minLength" and "maxLength".  As elsewhere, Tapestry is case insensitive.  
+  
+  You can apply multiple validations, by seperating the validator names with commas.  Some validators can be configured (with an equals sign). Thus you might say "required,minLength=5" for
+  a field that must be specified, and must be at least five characters long.
+  
+  Restart the application, and refresh your browser, then hit the submit button.
+    
+[address-v6.png] Form with client side validations visible
+
+  This is a shot just after hitting the submit button; all the fields have been validated and pop-up error bubbles are displayed.  This looks a bit cluttered, but all the bubbles, except for the one
+  for the focus field (the field the user is actively typing into), will fade out after a moment.  As you tab from field to field, Tapestry will validate your input and briefly display the error bubble.  And <all> of this
+  is taking place on the client side, without any communication with the application.
+
+  Each field in error has been highlighted (it's a bit subtle) and marked with a red "X".  Further, the label
+  for each of the fields has also been highlighted in red, to even more clearly identify what's in error.  The cursor has also been moved to the first field
+  that's in error.
+  
+  Once all the errors are corrected, and the form does submit,
+  all validations are performed on the server side as well (just in
+  case the client has JavaScript disabled).
+
+  So ... how about some more interesting validation than just "required or not".  Tapestry has built in support for validating based on field length and several variations
+  of field value, including regular expressons.  Zip codes are pretty easy to express as a regular expression.
+  
+----
+  @Validate("required,regexp=\\d{5}(-\\d{4})?")
+  public String getZip()
+  {
+    return zip;
+  }    
+----
+
+  Let's give it a try; restart the application and enter an "abc" for the zip code.
+  
+[address-v7.png] Regexp validation
+
+  This is what you'll see after typing "abc" and tabbing out of the field, then tabbing back in. It's a little hard to capture all the animation
+  effects in a still photo.
+
+  In any case, that's the right validation behavior, but it's the wrong message. Your users are not going to know or care about regular expressions.
+
+  Fortunately, it's easy to customize validation messages.  All we need to know is the name of the
+  property ("zip") and the name of the validator ("regexp").  We can then put an entry into the CreateAddress message catalog:
+  
+----
+zip-regexp-message=Zip Codes are five or nine digits.  Example: 02134 or 90125-1655.
+----
+
+  Refresh the page and submit again:
+  
+[address-v8.png] Regexp validation with corrected message
+
+  This trick isn't limited to just the regexp validator, it works equally well with <any> validator.
+  
+  Let's go one step further.  Turns out, we can move the
+  regexp pattern to the message catalog as well.  If you only provide the name of the validator in the @Validate annotation, Tapestry will search the containing
+  page's message catalog of the constraint value, as well as the validation message.  The constraint value for the regexp validator is the regular expression to match against.
+  
+----
+  @Validate("required,regexp")
+  public String getZip()
+  {
+    return zip;
+  }
+----
+
+  Now, just put the regular expression  into the CreateAddress message catalog:
+  
+----
+zip-regexp=\\d{5}(-\\d{4})?
+zip-regexp-message=Zip Codes are five or nine digits.  Example: 02134 or 90125-1655.
+----
+
+  After a restart you'll see the ... the same behavior.  But when we start creating more complicated regular expressions, it'll be much, much nicer
+  to put them in the message catalog rather than inside the annotation value.  And inside the message catalog, you can change and tweak the regular expressions
+  without having to restart the application each time.
+ 
+  We could go a bit further here, adding more regular expression validation for
+  phone numbers and e-mail addresses. We're also far from done in terms of 
+  further customizations of the BeanEditForm component.
+  
+  By now you are likely curious about what happens <after> the form submits
+  successfully (without validation errors), so that's what we'll focus on next.
+  
+====
+
+  {{{forms2.html}Continue on to Chapter 5: Forms in Tapestry, Part Two}}
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/forms2.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/forms2.apt
new file mode 100644
index 0000000..431683c
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/forms2.apt
@@ -0,0 +1,478 @@
+ ---
+ Forms in Tapestry
+ ---
+ 
+Chapter 5: Forms in Tapestry (Part Two)
+
+  So, you fill in all the fields, submit the form (without validation errors) and voila:  you get back the same
+  form, blanked out.  What happened, and where did the data go?
+
+  What happened is that we haven't told Tapestry what to do after the form is succesfully submitted (by succesful, we mean,
+  with no validation errors).  Tapestry's default behavior is to redisplay the active page, and that occurs in a new
+  request, with a new instance of the Address object (because the address field is not a peristent field).
+
+  Well, since we're creating objects, we might as well store them somewhere ... in a database.  We're going to
+  quickly integrate Tapestry with {{{http://hibernate.org}Hibernate}} as the object/relational mapping layer,
+  and ultimately store our data inside a {{{http://www.mysql.com/}MySQL}} database.  You'll have to download
+  and install MySQL on your own.
+
+  In addition, we need to create the database and user.  The database will be "t5_tutorial1" and
+  the user will be "t5tutorialuser" with password "secret". This is accomplished from the
+  command line using the mysql shell.
+
+  The two commands are:
+
+  *   create database t5_tutorial1;
+
+  *   grant all on t5_tutorial1.* to 't5tutorialuser'@'localhost' identified by 'secret';
+
+  []
+
+  Log into the MySQL monitor shell as user root to execute the commands:
+
+----
+$ mysql -u root -p
+Enter password:
+Welcome to the MySQL monitor.  Commands end with ; or \g.
+Your MySQL connection id is 4
+Server version: 5.0.51a MySQL Community Server (GPL)
+
+Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
+
+mysql> create database t5_tutorial1;
+Query OK, 1 row affected (0.08 sec)
+
+
+mysql> grant all on t5_tutorial1.* to 't5tutorialuser'@'localhost' identified by 'secret';
+Query OK, 0 rows affected (0.00 sec)
+
+mysql>
+---
+
+Re-configuring the Project
+
+  We're going to bootstrap this project from a simple Tapestry project to one that uses Hibernate and MySQL.
+
+
+* Updating the Dependencies
+
+  First, we must update the POM to list a new set of dependencies, that includes Hibernate,
+  the Tapestry/Hibernate integration library, and the MySQL JDBC driver.
+
+  <<src/pom.xml (partial):>>
+
+----
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-hibernate</artifactId>
+            <version>${tapestry-release-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate</artifactId>
+            <version>3.2.2.ga</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.transaction</groupId>
+                    <artifactId>jta</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-annotations</artifactId>
+            <version>3.2.1.ga</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.5</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.1</version>
+            <classifier>jdk15</classifier>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <version>2.3</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+----
+
+* Hibernate Configuration
+
+  Hibernate has a master configuration file used to store connection and other data.
+
+  <<src/main/resources/hibernate.cfg.xml:>>
+
+----
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+<hibernate-configuration>
+    <session-factory>
+        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
+        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/t5_tutorial1</property>
+        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
+        <property name="hibernate.connection.username">t5tutorialuser</property>
+        <property name="hibernate.connection.password">secret</property>
+        <property name="hbm2ddl.auto">update</property>
+        <property name="hibernate.show_sql">true</property>
+        <property name="hibernate.format_sql">true</property>
+    </session-factory>
+</hibernate-configuration>
+----
+
+
+  Most of the configuration is to identify the JDBC driver and connection URL.
+
+  In addition, we are configuring Hibernate to <update> the database schema; when Hibernate initializes
+  it will create or even modify tables to match the entities.  Finally, we are configuring Hibernate
+  to output any SQL it executes, which is very useful when initially building an application.
+
+  But what entities?  Normally, the available entities are listed inside hibernate.cfg.xml, but that's not necessary
+  with Tapestry; in another example of convention over configuration, Tapestry locates all entity classes
+  inside the entities package and adds them to the configuration. Currently, that is just the Address entity.
+
+Adding Hibernate Annotations
+
+  For an entity class to be used with Hibernate, some Hibernate annotations must be added to the class.
+
+  Below is the updated Address class, with the Hibernate annotations (as well as the Tapestry ones).  Hibernate
+  annotations can be applied to fields or to accessor methods, but the Tapestry annotations we use below
+  are for methods only.
+
+  <<src/main/java/org/apache/tapestry/tutorial/entities/Address.java:>>
+
+----
+package org.apache.tapestry.tutorial.entities;
+
+import org.apache.tapestry.beaneditor.NonVisual;
+import org.apache.tapestry.beaneditor.Validate;
+import org.apache.tapestry.tutorial.data.Honorific;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Address
+{
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Honorific honorific;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String street1;
+
+    private String street2;
+
+    private String city;
+
+    private String state;
+
+    private String zip;
+
+    private String email;
+
+    private String phone;
+
+    @NonVisual
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Honorific getHonorific()
+    {
+        return honorific;
+    }
+
+    @Validate("required")
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    @Validate("required")
+    public String getStreet1()
+    {
+        return street1;
+    }
+
+    public String getStreet2()
+    {
+        return street2;
+    }
+
+    @Validate("required")
+    public String getCity()
+    {
+        return city;
+    }
+
+    @Validate("required")
+    public String getState()
+    {
+        return state;
+    }
+
+    @Validate("required,regexp")
+    public String getZip()
+    {
+        return zip;
+    }
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setCity(String city)
+    {
+        this.city = city;
+    }
+
+    public void setEmail(String email)
+    {
+        this.email = email;
+    }
+
+    public void setFirstName(String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    public void setHonorific(Honorific honorific)
+    {
+        this.honorific = honorific;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+    }
+
+    public void setState(String state)
+    {
+        this.state = state;
+    }
+
+    public void setStreet1(String street1)
+    {
+        this.street1 = street1;
+    }
+
+    public void setStreet2(String street2)
+    {
+        this.street2 = street2;
+    }
+
+    public void setZip(String zip)
+    {
+        this.zip = zip;
+    }
+}
+----
+
+Updating the Database
+
+  So we have a database up and running, and Hibernate is configured to connect to it.  Let's make use of that
+  to store our Address object in the database.
+
+  What we need is to provide some code to be executed when the form is submitted.  When a Tapestry form
+   is submitted, there is a whole series of events that get fired.  The event we are interested in is the "success"
+   event, which comes late in the process, after all the values have been pulled out of the request and
+   applied to the page properties, and after all server-side validations have occured.
+
+   The success event is only fired if there are no validation errors.
+
+  Our event handler must do two things:
+
+  * Use the Hibernate Session object to persist the new Address object.
+
+  * Commit the transaction to force the data to be written to the database.
+
+  []
+
+  <<src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java:>>
+
+----
+package org.apache.tapestry.tutorial.pages.address;
+
+import org.apache.tapestry.annotation.InjectPage;
+import org.apache.tapestry.annotation.Property;
+import org.apache.tapestry.hibernate.annotations.CommitAfter;
+import org.apache.tapestry.ioc.annotation.Inject;
+import org.apache.tapestry.tutorial.entities.Address;
+import org.apache.tapestry.tutorial.pages.Index;
+import org.hibernate.Session;
+
+public class CreateAddress
+{
+    @Property
+    private Address address;
+
+    @Inject
+    private Session session;
+
+    @InjectPage
+    private Index index;
+
+    @CommitAfter
+    Object onSuccess()
+    {
+        session.persist(address);
+
+        return index;
+    }
+}
+----
+
+  The {{{../apidocs/org/apache/tapestry/ioc/annotations/Inject.html}Inject}} annotation tells Tapestry to inject a service into the
+  annotated field; 
+  Tapestry includes a sophisticated
+  Inversion of Control container (similar in many ways to Spring) that is very good at locating available services
+  by type, rather than by a string id.  In any case, the Hibernate Session object is exposed as a Tapestry IoC service,
+  ready to be injected (this is one of the things provided by the tapestry-hibernate module).
+
+  Tapestry automatically starts a transaction as necessary; however that transaction will be <aborted> at the end
+  of the request.  If we make changes to persistent objects, such as adding a new Address object,
+  then it is necessary to commit the transaction.
+
+  The {{{../apidocs/org/apache/tapestry/hibernate/annotations/CommitAfter.html}CommitAfter}} annotation can be applied to any component method; if the method completes normally, the transaction
+  will be committed (and a new transaction started to replace the committed transaction).
+
+  After persisting the new address, we return to the main Index page of the application.
+
+  <Note: In real applications, it is rare to have pages and components directly use the Hibernate Session. It
+  is generally a better approach to define your own Data Access Object layer to perform common update operations
+  and queries.>
+
+Showing Addresses
+
+  As a little preview of what's next, let's display all the Addresses entered by the user on the Index page
+  of the application.  After you enter a few names, it will look something like:
+
+[index-grid-v1.png] Adding the Grid to the Index page
+
+  So, how is this implemented?  Primarily, its accomplished by the
+  {{{../tapestry-core/ref/org/apache/tapestry/corelib/components/Grid.html}Grid}} component.
+
+  The Grid component is based on the same concepts as the BeanEditForm component; it can pull apart
+  a bean into columns. The columns are sortable, and when there are more entries than will fit on a single
+  page, page navigation is automatically added.
+
+  A minimal Grid is very easy to add to the template:
+
+  <<src/main/webapp/Index.tml (partial):>>
+
+----
+  <t:grid source="addresses"/>
+----
+
+  And all we have to do is supply the addresses property in the Java code:
+
+  <<src/main/java/org/apache/tapestry/tutorial/pages/Index.java (partial):>>
+
+----
+    @Inject
+    private Session session;
+
+    public List<Address> getAddresses()
+    {
+        return session.createCriteria(Address.class).list();
+    }
+----
+
+  Here, we're using the Hibernate Session object to find all Address objects in the database.
+  Any sorting that takes place will be done in memory.  This is fine for now (with only
+  a handful of Address objects in the database). Later we'll
+  see how to optimize this for very large result sets.
+  
+What's Next?
+
+  We have lots more to talk about: more components, more customizations, built-in Ajax support,
+  more common design and implementation patterns,
+  and even writing your own components (which is easy!).
+
+  ... but Tapestry and this tutorial are a work in progress, so stay patient, and check out
+  the other Tapestry tutorials and resources available on the
+  {{{../index.html}Tapestry 5 home page}}.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/hilo.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/hilo.apt
new file mode 100644
index 0000000..b5e9c30
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/hilo.apt
@@ -0,0 +1,541 @@
+ ---
+ Implementing the Hi/Lo Guessing Game
+ ---
+ 
+Chapter 3: Implementing the Hi/Lo Guessing Game
+
+  Let's start building the Hi/Lo Guessing game. 
+  
+  In the game, the computer selects a number between 1 and 10.  You try and guess the number, clicking links.
+  At the end, the computer tells you how many guesses you required.
+  
+  We'll build it in small pieces, using the kind of iterative development
+  that Tapestry makes so easy.
+  
+[hilo-flow.png] Page flow for Hi/Lo Game
+
+  Our page flow is very simple, consisting of three pages: Start, Guess and GameOver.  The Start page introduces the application and includes
+  a link to start guessing.  The Guess page presents the user with ten links, plus feedback such as "too low" or "too high".  
+  The GameOver page tells the user how many guesses they took.
+  
+  Let's get to work on the Index page and template.
+  
+  <<src/main/webapp/Index.tml:>>
+  
+----
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>tutorial1 Start Page</title>
+  </head>
+  <body>
+
+    <h1>Hi/Lo Guess</h1>
+
+    <p>I'm thinking of a number between one and ten ... </p>
+
+    <p>
+      <t:actionlink>Start guessing</t:actionlink>
+    </p>
+
+  </body>
+</html>
+----
+
+  Here we've taken the template created by the quickstart archetype and changed it around to fit our needs. The ActionLink
+  component will create a link that will trigger a method inside our Java class.  You can launch the application to try it out:
+  
+[hilo-start.png] Start page with Hi/Lo Game link
+
+  However, clicking the link doesn't do anything yet.  We haven't told Tapestry what to do when the link gets clicked.
+  
+  Let's fix that. We'll change the Start class so that it will react when the link is clicked ... but what should it do?
+  Well, to start the guessing process, we need to come up with a random number (between one and ten).  We need to tell
+  the Guess page about that number, and we need to make sure the Guess page is started up to display the response.
+  
+  First, the Guess page.  Just to get started, we'll create a Guess page without much guessing: it'll just show us the 
+  target number, the number we're supposed to be guessing.
+  
+  <<src/main/webapp/Guess.tml:>>
+  
+----
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Guess A Number</title>
+  </head>
+  <body>
+
+    <h1>The target number is ${target}.</h1>
+
+  </body>
+</html>
+----
+
+  On the Java side, the Guess page needs to have a target property:
+  
+----
+package org.apache.tapestry.tutorial.pages;
+
+public class Guess
+{
+  private int target;
+
+  Object initialize(int target)
+  {
+    this.target = target;
+
+    return this;
+  }
+}
+----
+
+  The key method here is initialize():  It is invoked to tell the Guess page what the target number is.  Notice that the
+   method is package private, not public;
+  it is only expected to be invoked from the Index page (as we'll see in a moment), so there's no need to make it public.  Later we'll see that
+  there's more initialization to be done
+  than just storing a value into the target instance variable (which is why we don't simply name the method setTarget() ).
+
+  Now we can move back to the Index page.  What we want is to have the ActionLink component invoke a method on the Index page. We can then generate
+  a random target number. We'll tell the Guess page what the target number is and then make sure that it is  the Guess page, and not the
+  Index page,
+  that renders the response into the user's web browser.  That's actually quite a few concepts to take in all at once.
+  
+  Let's start with the code, and break it down:
+  
+  <<src/main/java/org/apache/tapestry/tutorial/pages/Index.java>>
+
+----
+package org.apache.tapestry.tutorial.pages;
+
+import java.util.Random;
+
+import org.apache.tapestry.annotation.InjectPage;
+
+public class Start
+{
+  private final Random random = new Random();
+
+  @InjectPage
+  private Guess guess;
+
+  Object onAction()
+  {
+    int target = random.nextInt(10) + 1;
+
+    return guess.initialize(target);
+  }
+}
+----
+  
+  What we're talking about here is <communication> of information from the Index page to the Guess page.  In traditional servlet development, this is done
+  in a bizarre way ... storing attributes into the shared HttpSession object.  Of course, for that to work, both (or all) parties have to agree on the type
+  of object stored, and the well-known name used to access the attribute.  That's the source of a large number of bugs.  It's also not very object oriented ... state
+  is something that should be <inside> objects (and private), not <outside> objects (and public).
+  
+  The Tapestry way is very object oriented: everything is done in terms of objects and methods and properties of those objects.
+  
+  This communication starts with the connection between the two pages:  in this case, the
+  {{{../apidocs/org/apache/tapestry/annotations/InjectPage.html}InjectPage}} annotation allows another page in the application
+  to be injected into the Index page.
+
+  Injection can be a somewhat nebulous concept.  In terms of Tapestry, it means that some cooperating object needed by one class is provided to it.  The other
+  object is often referred to as a "dependency"; in this case, the Index page <depends on> the Guess page to be fully functional, and an instance of the Guess
+  page is made available as the guess instance variable.  The Index page doesn't, and can't, <create> the Guess page, it can only
+  advertise, to Tapestry, that it needs the Guess page.  Tapestry will take care of the rest.
+    
+  Let's see what we do with this injected page.  It's used inside onAction().  You might guess that this method is invoked when the link ("Start guessing") is clicked.  But
+  why?
+  
+  This is a strong example of <convention over configuration>. Tapestry has a naming convention for certain methods:  "on<EventType>[From<ComponentId>]".  Here, the event type 
+  is "action" and the component id is not even specified. This translates to "when the action event is fired from any component, invoke this method".
+  
+  "The action event?"  This underlines a bit about how Tapestry processes requests. When you click a link generated by the ActionLink component, Tapestry is able
+  to identify the underlying component inside the request: it knows that the component is on the Index page, and it knows the component within the page.  Here we didn't give
+  the ActionLink component a specific id, so Tapestry supplied one.  An "action" event is triggered inside the ActionLink component, and that event bubbles
+  up to the page, where the onAction() method acts as an <event handler method>.
+  
+  So ... ActionLink component --> action request --> onAction() event handler method.
+  
+  Event handler methods don't have to be public; they are usually package private (as in this example).  Also, it isn't an error if a request never matches
+  an event handler. Before we added the onAction() event handler, that's exactly what happened; the request passed through without any event handler
+  match, and Tapestry simply re-rendered the Start page.
+  
+  What can you do inside an event handler method?  Any kind of business logic you like; Tapestry doesn't care.  Here we're using a random number generator
+  to set the target number to guess.
+  
+  We also use the injected Guess page; we invoke the initialize() method to tell it about the number the user is trying to guess.
+  
+  The <return value> of an event handler method is very important; the value returned informs Tapestry about what page will render the response to the client.
+  By returning the injected Guess page, we're telling Tapestry that the Guess page should be the one to render the response.
+
+  This idiom: having the Guess page provide an initialize() method and return itself, is very common in Tapestry. It allows the event handler method to be
+  very succinct; it's as if the event handler method says "initialize the Guess page and render it to the client".
+  
+  Again, this is a big difference between Tapestry and servlets (or Struts). Tapestry tightly binds the controller (the Java class) to the template.
+  Using JSPs, you would have extra configuration to select a view (usually by a logical name, such as "success") to a "view" (a JSP).  Tapestry cuts through
+  all that cruft for you. Objects communicate with, and defer to, other objects and all the templates and rendering machinery comes along for free.
+  
+  In later chapters, we'll see other possibilities besides returning a page instance from an event handler method.
+  
+  For the moment, make sure all the changes are saved, and click the "Start guessing" link.
+  
+[hilo-exception.png] Exception on the Guess page
+
+  This may not quite be what you were expecting ... but it is a useful digression into one of Tapestry's most important features: <<feedback>>.
+  
+  Something was wrong with the Guess page, and Tapestry has reported the error to you so that you can make a correction.
+  
+  Here, the root problem was that we didn't define a getTarget() method in the Guess class.  Ooops.  Deep inside Tapestry, a RuntmeException was thrown to explain this.
+  
+  As often happens in frameworks, that RuntimeException was caught and rethrown wrapped inside a new exception, the TapestryException. This added a bit more detail to the exception
+  message, and linked the exception to a <location>.  Since the error occurred inside a component template, Tapestry is able to display that portion of the
+  template, highlighting the line in error.
+  
+  If you scroll down, you'll see that after the stack trace, Tapestry provides a wealth of information about the current request, including headers and query parameters.
+  It also displays information stored in the HttpSession (if the session exists), and other information that may be of use.  
+  
+  Of course, in a production application,
+  this information can be hidden!
+  
+  Let's fix this problem, by adding the following to the Guess class:
+  
+---
+  public int getTarget()
+  {
+    return target;
+  }
+---
+
+* Persisting data between requests
+
+  That fixes the problem, but introduces another:
+  
+[hilo-guess-v1.png] Hi/Lo Guess Page
+
+  Why is the target number zero?  Didn't we set it to a random value between 1 and 10?
+  
+  At issue here is the how Tapestry organizes requests. Tapestry has two main types
+  of requests: <<action>> requests and <<render>> requests. Render requests
+  are easy, the URL includes just the page name, and that page is rendered out.
+  
+  Action requests are more complicated; the URL will include the name of the page
+  and the id of the component within the page, and perhaps the type of event.
+  
+  After your event handler method is executed, Tapestry determine what page will
+  render the response; as we've seen, that is based on the return value of
+  the event handler method.
+  
+  Tapestry doesn't, however, render the response directly, the way most servlet
+  applications would; instead it sends a <redirect URL> to the client web browser.
+  The URL is a render request URL for the page that will render the response.
+  
+  You may have seen this before.  It is commonly called the <redirect after post pattern>. Most often,
+  it is associated with form submissions (and as we'll see in later chapters, a form submission <is>
+  another type of action request). 
+  
+  So why does that affect the target value?  At the end of any request (action or render), Tapestry
+  will "clean house", resetting any instance variables back to their initial, default values (usually, null 
+  or zero). 
+  
+  This cleaning is very necessary to the basic way Tapestry operates: pages are expensive entities to
+  create; too expensive to create fresh each request, and too large and complicated to store in the HttpSession.
+  Tapestry <pools> pages, using and reusing them in request after request.  
+  
+  For the duration of a single request from a single user, a <page instance> is <bound> to the request.
+  It is only accessible to the one request. Other requests may be bound to other instances of the same page.
+  The same page instance will be used for request after request. 
+  
+  So, inside the action request, the code inside the onAction() event handler method <did> call the
+  initialize() method, and a value between 1 and 10 was stored in the target instance variable. But
+  at the end of that request, the value was lost, and in the subsequent render request for the Guess page,
+  the value was zero.
+  
+  Fortunately, it is very easy to transcend this behavior.  We'll use an annotation, {{{../apidocs/org/apache/tapestry/annotations/Persist.html}Persist}},
+  on the instance variable:
+  
+----
+  @Persist
+  private int target;
+----
+
+  Now we can use the browser back button to return to the Start page, and click the link again.
+ 
+[hilo-number.png] The target number
+  
+  One of the nice things about this approach, the use of redirects, is that hitting the refresh button
+  does <not> choose a new target number.  It simply redraws the Guess page with the 
+  target number previously selected. In many servlet applications, the URL would be for the action "choose a random number"
+  and refreshing would re-execute that action.
+  
+* Creating guessable links
+
+  Now it's time to start the game in earnest.  We don't want to just tell the user what the target number is,
+  we want to make them guess, and we want to track how many attempts they take.
+  
+  What we want is to create 10 links, and combine those links with logic on the server side, an event handler method,
+  that can interpret what value the user selected.
+  
+  Let's start with those links.  We're going to use a new component, Loop, to loop
+  over a set of values:
+  
+  <<src/main/webapp/Guess.tml:>>
+  
+---
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Guess A Number</title>
+  </head>
+  <body>
+
+  <p>Make a guess between one and ten:</p>
+  
+    <t:loop source="1..10" value="guess" xml:space="preserve">
+      <t:actionlink t:id="link" context="guess">${guess}</t:actionlink>
+    </t:loop>
+
+  </body>
+</html>
+---
+
+  The Loop component's source attribute identifies the values to loop over.
+  Often this is a list or array, but here the special
+  special syntax, "1..10" means iterate over the numbers between 1 and 10, inclusive.
+
+  What about the <<<xml:space="preserve">>> attribute?  Normally, Tapestry is pretty draconian
+  about stripping out unnecessary whitespace from the template.  Most whitespace (spaces, tabs,
+  newlines, etc.) is reduced to a single space.  This can help a lot with reducing the size
+  of the output and with making complex nested layouts easier to read ... but occasionally, as here,
+  the whitespace is needed to keep the numbers from running together.  <<<xml:space="preserve">>>
+  turns on full whitespace retention for the element.
+
+  The value attribute gets assigned the current item from the loop.  We'll use
+  a property of the Guess page as a kind of scratchpad for this purpose.  We could manually
+  write a getter and a setter method as we did before, or we can let Tapestry generate those
+  accessors:
+  
+---
+  @Property
+  private int guess;
+---
+
+  Tapestry will automatically create the methods needed so that the guess property (it's smart
+  about stripping off leading underscores) is accessible in the template.
+
+  The context parameter of the ActionLink is how we get extra information into
+  the action request URL. The context can be a single value, or an array or
+  list of values.  The values are converted to strings and tacked onto the action
+  request URL.  The end result is <<<http://localhost:8080/tutorial1/guess.link/4>>>.  
+  
+  What is "guess.link"?  That's the name of the page, "guess", and the id of the component 
+  ("link", as explicitly set with the t:id attribute).        Remember this is an action link:
+  as soon as the user clicks the click, it is replaced with a render link such
+  as <<<http://localhost:8080/tutorial1/guess>>>.
+  
+  Now, to handle those guesses. We're going to add an event handler method that gets
+  invoked when a link is clicked.  We're also going to add a new property, message, to
+  store the message that says "too high" or "too low".
+  
+---
+  @Persist
+  @Property
+  private String message;
+
+  String onActionFromLink(int guess)
+  {
+    if (guess == target) return "GameOver";
+
+    if (guess < target)
+      message = String.format("%d is too low.", guess);
+    else
+      message = String.format("%d is too high.", guess);
+
+    return null;
+  }
+---  
+
+
+  Here's the big news: Tapestry will convert the number from the URL back into
+  an integer automatically, so that it can pass it in to the onActionFromLink() event handler method as a
+  method parameter.
+  We can then compare the guess from the user to the secret target number.
+
+  Notice how Tapestry adapts to the return value.  Here it may be null ... Tapestry interprets that
+  as "stay on the same page".  You may also return a string ("GameOver"); Tapestry interprets <that>
+  as the name of the page to render the response.
+  
+
+  We need to update the Guess page to actually display the message; this is done by adding the following:
+  
+---
+  <p>${message}</p>
+---
+
+  This is truly bare bones and, when message is null, will output an empty \<p\> element.  A real application
+  would dress this up a bit more (using CSS and the like to make it prettier).
+  
+  
+  We do need a basic GameOver page.
+  
+  <<src/main/webapp/GameOver.tml:>>
+
+---
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Game Over!</title>
+  </head>
+  <body>
+
+    <h1>Game Over</h1>
+
+    <p> You guessed the secret number!  </p>
+
+
+  </body>
+</html>
+---
+
+  <<src/main/java/org/apache/tapestry/tutorial/pages/GameOver.java:>>
+
+---
+package org.apache.tapestry.tutorial.pages;
+
+public class GameOver
+{
+
+}
+---
+
+  With this in place, we can make guesses, and get feedback from the application:
+  
+[hilo-feedback.png] Feedback from the game
+
+* Counting the number of guesses
+
+ It would be nice to provide some feedback about how many guesses the
+ user took to find the number.  That's easy enough to do.
+ 
+ First we update Guess to store the number of guesses:
+ 
+---
+  @Persist
+  @Property
+  private int count;
+---
+
+  Next we modified initialize() to ensure that count is set to 0.  This is a safety
+  precaution in case we add logic to play the game again.
+  
+---
+  Object initialize(int target)
+  {
+    this.target = target;
+    this.count = 0;
+
+    return this;
+  }
+--- 
+
+  We have a couple of changes to make to the event handler method.  We want
+  to communicate to the GameOver page the guess count; so we'll inject the
+  GameOver page so we can initialize it.
+  
+---
+  Object onActionFromLink(int guess)
+  {
+    count++;
+
+    if (guess == target) return gameOver.initialize(count);
+
+    if (guess < target)
+      message = String.format("%d is too low.", guess);
+    else
+      message = String.format("%d is too high.", guess);
+
+    return null;
+  }
+---
+
+  So, we update the count before comparing and, instead of returning the
+  name of the GameOver page, we return the configured instance.
+  
+  Lastly, we need to make some changes to the GameOver class.
+  
+  <<src/main/java/org/apache/tapestry/tutorial/GameOver.java:>>
+  
+---
+package org.apache.tapestry.tutorial.pages;
+
+import org.apache.tapestry.annotation.Persist;
+import org.apache.tapestry.annotation.Property;
+
+public class GameOver
+{
+  @Persist
+  @Property
+  private int count;
+
+  Object initialize(int count)
+  {
+    this.count = count;
+
+    return this;
+  }
+}
+---
+  
+  <<src/main/webapp/GameOver.tml:>>
+  
+---
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Game Over!</title>
+  </head>
+  <body>
+
+    <h1>Game Over</h1>
+
+    <p> You guessed the secret number in ${count} guesses!  </p>
+
+
+  </body>
+</html>
+---
+
+* Parting thoughts
+
+  What we've gone after here is the Tapestry way: pages as classes that store
+  internal state and communicate with each other. We've also seen the Tapestry
+  development pattern: lots of simple small steps that leverage Tapestry's ability to
+  reload templates and classes on the fly.
+  
+  We've also seen how Tapestry stores data for us, sometimes in the session
+  (via the @Persist annotation) and sometimes in the URL.
+  
+  Our code is wonderfully free of anything related to HTTP or the Java Servlet API.
+  We're coding using real objects, with their own instance variables and internal state.
+  
+  Our application is still pretty simple; here's a few challenges:
+  
+  * Add a restart link to the GameOver page to allow a new game to start. Can you refactor the application
+  so that the code for the random number selection occurs in only one place?
+  
+  * As we guess, we're identifying ranges of valid and invalid numbers.  Can you only show valid
+   guesses to the user?
+   
+  * What would it take to change the the game to choose a number between 1 and 20? Between 1 and 100?
+  
+  * What about setting an upper-limit on the number of guesses allowed?
+  
+  [] 
+
+===
+  
+  {{{forms.html}Continue on to Chapter 4: Tapestry and Forms}}
+ 
+
+  
+  
+    
+  
+  
+  
+  
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/apt/index.apt b/hlship-20080520/tapestry-tutorial1/src/site/apt/index.apt
new file mode 100644
index 0000000..f5eebe4
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/apt/index.apt
@@ -0,0 +1,65 @@
+ ---
+ Tutorial: Introduction
+ ---
+
+Tapestry Tutorial: Introduction
+
+* What is Tapestry?
+
+  Welcome to Tapestry! 
+
+  This is a tutorial for people who will be creating Tapestry 5 applications.  It doesn't matter whether you have experience with Tapestry 4 (or Tapestry 3, for that matter) or whether you are completely new to Tapestry.  
+  In fact, in some ways, the less you know about web development in general, and Tapestry in particular, the better off you may be ... that much less to unlearn!
+
+  You do need to have a reasonable understanding of HTML, a smattering of XML, and a good understanding of basic Java language features, and a few newer things such as Java Annotations.
+  
+  If you're used to developing web applications using servlets and JSPs, or with Struts, you are simply used to a lot of pain. So much pain, you may not even understand the dire situation you are in! 
+  These are environments with no safety net; Struts and the Servlet API has no idea how your application is structured, or how the different pieces fit together.  
+  Any URL can be an action and any action can forward to any view (usually a JSP) to provide an HTML response to the web browser.  
+  The pain is the unending series of small, yet important, decisions you have to make as a developer (and communicate to the rest of your team).  
+  What are the naming conventions for actions, for pages, for attributes stored in the HttpSession or HttpServletRequest? 
+
+  The traditional approaches thrust something most unwanted in your face: multithreaded coding. Remember back to Object Oriented Programming 101 where an object was defined as a bundle of data and operations on that data?
+  You have to unlearn that lesson as soon as you build a web application, because web applications are multi-threaded. 
+  An application server could be handling dozens or hundreds of requests from individual users, each in their own thread, and each sharing the exact same objects.  
+  Suddenly, you can't store data inside an object (a servlet or a Struts Action) because whatever data you store for one user will be instantly overwritten by some other user.
+
+  Worse, your objects each have one operation: doGet() or doPost().
+
+  Meanwhile, most of your day-to-day work involves deciding how to package up some data already inside a particular Java object and squeeze that data into a URL's query parameters,
+  so that you can write more code to convert it back if the user clicks that particular link.  And don't forget editing a bunch of XML files to keep the servlet container, or the Struts framework, aware of these decisions.  
+
+  Just for laughs, remember that you have to rebuild, redeploy and restart your application after virtually any change.  Is any of this familiar?  Then perhaps you'd appreciate something a little <less> familiar: Tapestry.
+
+  Tapestry uses a very different model: a structured, organized world of pages, and components within pages. Everything has a very specific name (that you provide). 
+  Once you know the name of a page, you know the location of the Java class for that page, the location of the template for that page, and the total structure of the page. 
+  Tapestry knows all this as well, and can make things <<just work>>.
+
+  As well see in the following chapters, Tapestry lets you code in terms of your objects. You'll barely see any Tapestry classes, outside of a few Java annotations. 
+  If you have information to store, store it as fields of your classes, not inside the HttpServletRequest or HttpSession. 
+  If you need some code to execute, its just a simple annotation or method naming convention to get Tapestry to invoke that method, at the right time, 
+  with the right data. The methods don't even have to be public!
+
+  Tapestry also shields you from the multi-threaded aspects of web application development. 
+  Tapestry manages the life-cycles of your page and components objects, reserving particular objects to particular threads so 
+  that you never have to think twice about threading issues.
+
+  Tapestry began in January 2000, and now represents over seven years of experience: not just my experience, or that of the other 
+  Tapestry committers, but the experience of the entire Tapestry community. Tapestry brings to the table all that experience about the best ways to 
+  build scalable, maintainable, robust, internationalized (and more recently) Ajax-enabled applications. Tapestry 5 represents a completely new 
+  code base designed to simplify  the Tapestry coding model while at the same time, extending the power of Tapestry and improving performance.
+
+* About Releases and Documentation
+
+  If you are reading this documentation online, be aware that the online documentation generally represents the very latest version of the code, termed "the snapshot". The documentation is <written> as if the 
+  next release is available, but may reference version numbers, or even features, that are only available by building the latest Tapestry source.
+
+*  About the Author
+
+  Howard Lewis Ship is the creator of Tapestry, and the Chair of the  Tapestry Project Management Committee at Apache. 
+  Howard is the Director of Open Source Technology at {{{http://formos.com}Formos Software Development}}.
+  Howard lives in Portland, Oregon with his wife Suzanne, a novelist.
+
+====
+  
+  {{{env.html}Continue on to Chapter 1: Setting Up Your Environment}}
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v1.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v1.png
new file mode 100644
index 0000000..9bd23fa
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v2.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v2.png
new file mode 100644
index 0000000..debeadf
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v2.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v3.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v3.png
new file mode 100644
index 0000000..0a12a6c
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v3.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v5.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v5.png
new file mode 100644
index 0000000..d681906
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v5.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v6.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v6.png
new file mode 100644
index 0000000..c751268
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v6.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v7.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v7.png
new file mode 100644
index 0000000..349c359
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v7.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v8.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v8.png
new file mode 100644
index 0000000..324429e
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/address-v8.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/app-live-reload.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/app-live-reload.png
new file mode 100644
index 0000000..9a2c2c5
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/app-live-reload.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import-folder.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import-folder.png
new file mode 100644
index 0000000..73da010
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import-folder.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import.png
new file mode 100644
index 0000000..581fbf9
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-import.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-launch.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-launch.png
new file mode 100644
index 0000000..b1f903c
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-launch.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-run.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-run.png
new file mode 100644
index 0000000..de9b22b
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/eclipse-run.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-exception.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-exception.png
new file mode 100644
index 0000000..4bf1e46
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-exception.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-feedback.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-feedback.png
new file mode 100644
index 0000000..c4e820d
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-feedback.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-flow.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-flow.png
new file mode 100644
index 0000000..ca98005
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-flow.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-guess-v1.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-guess-v1.png
new file mode 100644
index 0000000..0ba2df8
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-guess-v1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-number.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-number.png
new file mode 100644
index 0000000..71fcc9a
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-number.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-start.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-start.png
new file mode 100644
index 0000000..39adcfc
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/hilo-start.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/index-grid-v1.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/index-grid-v1.png
new file mode 100644
index 0000000..fb35f7d
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/index-grid-v1.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/resources/startpage.png b/hlship-20080520/tapestry-tutorial1/src/site/resources/startpage.png
new file mode 100644
index 0000000..5424924
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/resources/startpage.png
Binary files differ
diff --git a/hlship-20080520/tapestry-tutorial1/src/site/site.xml b/hlship-20080520/tapestry-tutorial1/src/site/site.xml
new file mode 100644
index 0000000..bbf3490
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/site/site.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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="Tapestry 5 Tutorial #1">
+    <bannerLeft>
+        <name>Tapestry 5</name>
+        <href>http://tapestry.apache.org/tapestry5/</href>
+        <src>images/tapestry_banner.gif</src>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache</name>
+        <href>http://www.apache.org</href>
+        <src>images/asf_logo_wide.gif</src>
+    </bannerRight>
+    <skin>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>maven-skin</artifactId>
+        <version>1.1</version>
+    </skin>
+
+    <publishDate format="dd MMM yyyy"/>
+
+    <body>
+
+
+        <menu name="Quick Links">
+            <item name="Download" href="http://tapestry.apache.org/download.html"/>
+        </menu>
+
+        <menu name="Tutorial">
+            <item name="Introduction" href="index.html"/>
+            <item name="Environment" href="env.html"/>
+            <item name="Your First Application" href="first.html"/>
+            <item name="Hi/Lo Game" href="hilo.html"/>
+            <item name="Forms" href="forms.html"/>
+            <item name="Forms, pt 2" href="forms2.html"/>
+        </menu>
+
+
+        <menu ref="reports"/>
+
+    </body>
+</project>
diff --git a/hlship-20080520/tapestry-tutorial1/src/t5-chap-3-figures.graffle b/hlship-20080520/tapestry-tutorial1/src/t5-chap-3-figures.graffle
new file mode 100644
index 0000000..7011c66
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/t5-chap-3-figures.graffle
@@ -0,0 +1,931 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>CanvasColor</key>
+	<dict>
+		<key>w</key>
+		<string>1</string>
+	</dict>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>CanvasScale</key>
+	<real>1</real>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2007-02-24 11:43:21 -0800</string>
+	<key>Creator</key>
+	<string>Howard Lewis Ship</string>
+	<key>DisplayScale</key>
+	<string>1 in = 1 in</string>
+	<key>GraphDocumentVersion</key>
+	<integer>5</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>52</integer>
+			</dict>
+			<key>ID</key>
+			<integer>53</integer>
+			<key>Points</key>
+			<array>
+				<string>{328.1, 611}</string>
+				<string>{383.7, 611}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>50</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{384.2, 593}, {63, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>52</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 GameOver}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>50</integer>
+			</dict>
+			<key>ID</key>
+			<integer>22</integer>
+			<key>Points</key>
+			<array>
+				<string>{325.943, 622.545}</string>
+				<string>{347.8, 631}</string>
+				<string>{342, 655}</string>
+				<string>{315.8, 662}</string>
+				<string>{303.233, 629.466}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>50</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>50</integer>
+			</dict>
+			<key>ID</key>
+			<integer>51</integer>
+			<key>Points</key>
+			<array>
+				<string>{208.5, 611}</string>
+				<string>{264.1, 611}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>49</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{264.6, 593}, {63, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>50</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Guess}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{154, 593}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>49</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Start}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+			</dict>
+			<key>ID</key>
+			<integer>35</integer>
+			<key>Points</key>
+			<array>
+				<string>{316.8, 395.4}</string>
+				<string>{411.1, 395.4}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>33</integer>
+			</dict>
+			<key>ID</key>
+			<integer>23</integer>
+			<key>Points</key>
+			<array>
+				<string>{231, 395.4}</string>
+				<string>{315.8, 395.4}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>ID</key>
+			<integer>34</integer>
+			<key>Points</key>
+			<array>
+				<string>{231, 395.4}</string>
+				<string>{231, 431.4}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>ID</key>
+			<integer>33</integer>
+			<key>Points</key>
+			<array>
+				<string>{315.8, 395.4}</string>
+				<string>{315.8, 431.4}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>ID</key>
+			<integer>32</integer>
+			<key>Points</key>
+			<array>
+				<string>{411.1, 395.4}</string>
+				<string>{411.1, 431.4}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>ID</key>
+			<integer>31</integer>
+			<key>Points</key>
+			<array>
+				<string>{315.8, 363.8}</string>
+				<string>{315.8, 399.8}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>0</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{369.6, 431.4}, {84, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>30</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 ActionLink}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{284.8, 431.4}, {63, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>29</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Loop}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{200, 431.4}, {63, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 If}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{284.8, 327.8}, {63, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>27</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Guess}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{35, 159}, {99, 28}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>FontInfo</key>
+			<dict>
+				<key>Color</key>
+				<dict>
+					<key>w</key>
+					<string>0</string>
+				</dict>
+				<key>Font</key>
+				<string>Monaco</string>
+				<key>Size</key>
+				<real>9</real>
+			</dict>
+			<key>ID</key>
+			<integer>26</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.0941176</string>
+						<key>g</key>
+						<string>0.686275</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Embedded\
+Component}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{152, 116}, {79.4531, 14}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>ID</key>
+			<integer>25</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.0941176</string>
+						<key>g</key>
+						<string>0.686275</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+				<key>shadow</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+				<key>stroke</key>
+				<dict>
+					<key>Draws</key>
+					<string>NO</string>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 Container}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>5</integer>
+			</dict>
+			<key>ID</key>
+			<integer>24</integer>
+			<key>Points</key>
+			<array>
+				<string>{146, 109.5}</string>
+				<string>{146, 192.5}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>TailArrow</key>
+					<string>0</string>
+					<key>Width</key>
+					<real>2</real>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>4</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{104, 193}, {84, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>5</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 ActionLink}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{119, 73}, {54, 36}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>4</integer>
+			<key>Shape</key>
+			<string>RoundRect</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0</string>
+						<key>g</key>
+						<string>0.501961</string>
+						<key>r</key>
+						<string>0</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf1 Start}</string>
+			</dict>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>IsPalette</key>
+	<string>NO</string>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict/>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheet</key>
+	<string>Master 1</string>
+	<key>MasterSheets</key>
+	<array>
+		<dict>
+			<key>ActiveLayerIndex</key>
+			<integer>0</integer>
+			<key>AutoAdjust</key>
+			<true/>
+			<key>CanvasColor</key>
+			<dict>
+				<key>w</key>
+				<string>1</string>
+			</dict>
+			<key>CanvasOrigin</key>
+			<string>{0, 0}</string>
+			<key>CanvasScale</key>
+			<real>1</real>
+			<key>ColumnAlign</key>
+			<integer>1</integer>
+			<key>ColumnSpacing</key>
+			<real>36</real>
+			<key>DisplayScale</key>
+			<string>1 in = 1 in</string>
+			<key>GraphicsList</key>
+			<array/>
+			<key>GridInfo</key>
+			<dict/>
+			<key>HPages</key>
+			<integer>1</integer>
+			<key>IsPalette</key>
+			<string>NO</string>
+			<key>KeepToScale</key>
+			<false/>
+			<key>Layers</key>
+			<array>
+				<dict>
+					<key>Lock</key>
+					<string>NO</string>
+					<key>Name</key>
+					<string>Layer 1</string>
+					<key>Print</key>
+					<string>YES</string>
+					<key>View</key>
+					<string>YES</string>
+				</dict>
+			</array>
+			<key>LayoutInfo</key>
+			<dict/>
+			<key>Orientation</key>
+			<integer>2</integer>
+			<key>OutlineStyle</key>
+			<string>Basic</string>
+			<key>RowAlign</key>
+			<integer>1</integer>
+			<key>RowSpacing</key>
+			<real>36</real>
+			<key>SheetTitle</key>
+			<string>Master 1</string>
+			<key>UniqueID</key>
+			<integer>1</integer>
+			<key>VPages</key>
+			<integer>1</integer>
+		</dict>
+	</array>
+	<key>ModificationDate</key>
+	<string>2007-06-10 09:45:31 -0700</string>
+	<key>Modifier</key>
+	<string>Howard Lewis Ship</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>OutlineStyle</key>
+	<string>Basic</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{612, 792}</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>0</string>
+		</array>
+	</dict>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<true/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<string>0</string>
+		<key>DrawerOpen</key>
+		<false/>
+		<key>DrawerTab</key>
+		<string>Outline</string>
+		<key>DrawerWidth</key>
+		<real>209</real>
+		<key>FitInWindow</key>
+		<false/>
+		<key>Frame</key>
+		<string>{{517, 481}, {594, 870}}</string>
+		<key>ShowRuler</key>
+		<false/>
+		<key>ShowStatusBar</key>
+		<true/>
+		<key>VisibleRegion</key>
+		<string>{{-1, 0}, {579, 756}}</string>
+		<key>Zoom</key>
+		<string>1</string>
+	</dict>
+</dict>
+</plist>
diff --git a/hlship-20080520/tapestry-tutorial1/src/test/conf/testng.xml b/hlship-20080520/tapestry-tutorial1/src/test/conf/testng.xml
new file mode 100644
index 0000000..da08806
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/test/conf/testng.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapestry Tutorial #1" annotations="1.5" verbose="2">
+    <test name="Services">
+        <packages>
+            <package name="org.apache.tapestry.tutorial.services"/>
+        </packages>
+    </test>
+</suite>
diff --git a/hlship-20080520/tapestry-tutorial1/src/test/java/PLACEHOLDER b/hlship-20080520/tapestry-tutorial1/src/test/java/PLACEHOLDER
new file mode 100644
index 0000000..62c163c
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/test/java/PLACEHOLDER
@@ -0,0 +1 @@
+This placeholder exists to ensure the directory is created. It may be deleted when real files are placed under src/test/java.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-tutorial1/src/test/java/org/apache/tapestry/tutorial/services/AppSuite.java b/hlship-20080520/tapestry-tutorial1/src/test/java/org/apache/tapestry/tutorial/services/AppSuite.java
new file mode 100644
index 0000000..6daf26f
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/test/java/org/apache/tapestry/tutorial/services/AppSuite.java
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.tutorial.services;
+
+import org.apache.tapestry.ioc.test.TestBase;
+import org.testng.annotations.Test;
+
+public class AppSuite extends TestBase
+{
+    @Test
+    public void alway_pass()
+    {
+        assertEquals(true, true);
+    }
+}
diff --git a/hlship-20080520/tapestry-tutorial1/src/test/resources/PLACEHOLDER b/hlship-20080520/tapestry-tutorial1/src/test/resources/PLACEHOLDER
new file mode 100644
index 0000000..05ace36
--- /dev/null
+++ b/hlship-20080520/tapestry-tutorial1/src/test/resources/PLACEHOLDER
@@ -0,0 +1 @@
+This placeholder exists to ensure the directory is created. It may be deleted when real files are placed under src/test/resources.
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-upload/.classpath b/hlship-20080520/tapestry-upload/.classpath
new file mode 100644
index 0000000..02da654
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" output="bin" path="src/main/java"/>
+    <classpathentry kind="src" output="bin-test" path="src/test/java"/>
+    <classpathentry kind="lib" path="src/main/resources"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/hlship-20080520/tapestry-upload/.project b/hlship-20080520/tapestry-upload/.project
new file mode 100644
index 0000000..28dbce3
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/.project
@@ -0,0 +1,22 @@
+<projectDescription>
+    <name>tapestry-upload</name>
+    <comment></comment>
+    <projects>
+    </projects>
+    <buildSpec>
+        <buildCommand>
+            <name>org.eclipse.jdt.core.javabuilder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+        <buildCommand>
+            <name>org.maven.ide.eclipse.maven2Builder</name>
+            <arguments>
+            </arguments>
+        </buildCommand>
+    </buildSpec>
+    <natures>
+        <nature>org.eclipse.jdt.core.javanature</nature>
+        <nature>org.maven.ide.eclipse.maven2Nature</nature>
+    </natures>
+</projectDescription>
diff --git a/hlship-20080520/tapestry-upload/LICENSE.txt b/hlship-20080520/tapestry-upload/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/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/hlship-20080520/tapestry-upload/NOTICE.txt b/hlship-20080520/tapestry-upload/NOTICE.txt
new file mode 100644
index 0000000..439eb83
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/NOTICE.txt
@@ -0,0 +1,3 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/hlship-20080520/tapestry-upload/pom.xml b/hlship-20080520/tapestry-upload/pom.xml
new file mode 100644
index 0000000..b02f288
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/pom.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-upload</artifactId>
+    <name>Tapestry File Upload Component Library</name>
+    <packaging>jar</packaging>
+    <description>
+        Provides a file upload component for Tapestry, based on Jakarta
+        commons-fileupload.
+    </description>
+    <parent>
+        <groupId>org.apache.tapestry</groupId>
+        <artifactId>tapestry-project</artifactId>
+        <version>5.0.12-SNAPSHOT</version>
+    </parent>
+    <inceptionYear>2007</inceptionYear>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-test</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+            <!-- This gets the plugin to clean up the cobertura.ser file left
+        in the root directory. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Tapestry-Module-Classes>
+                                org.apache.tapestry.upload.services.UploadModule
+                            </Tapestry-Module-Classes>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>summary</report>
+                            <report>dependencies</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cobertura-plugin-version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.tapestry</groupId>
+                <artifactId>tapestry-component-report</artifactId>
+                <version>${project.version}</version>
+                <configuration>
+                    <rootPackage>org.apache.tapestry.upload</rootPackage>
+                    <apidocs>../apidocs</apidocs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java
new file mode 100755
index 0000000..340851a
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java
@@ -0,0 +1,178 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.components;

+

+import org.apache.tapestry.*;

+import org.apache.tapestry.annotation.Environmental;

+import org.apache.tapestry.annotation.Mixin;

+import org.apache.tapestry.annotation.Parameter;

+import org.apache.tapestry.corelib.base.AbstractField;

+import org.apache.tapestry.corelib.mixins.RenderDisabled;

+import org.apache.tapestry.ioc.annotation.Inject;

+import org.apache.tapestry.services.FieldValidatorDefaultSource;

+import org.apache.tapestry.services.FormSupport;

+import org.apache.tapestry.upload.services.MultipartDecoder;

+import org.apache.tapestry.upload.services.UploadedFile;

+

+import java.util.Locale;

+

+/**

+ * A component to upload a file.

+ */

+@SuppressWarnings({ "UnusedDeclaration" })

+public class Upload extends AbstractField

+{

+    public static final String MULTIPART_ENCTYPE = "multipart/form-data";

+

+    /**

+     * The uploaded file. Note: This is only guaranteed to be valid while processing the form submission. Subsequently

+     * the content may have been cleaned up.

+     */

+    @Parameter(required = true, principal = true)

+    private UploadedFile value;

+

+    /**

+     * The object that will perform input validation. The "validate:" binding prefix is generally used to provide this

+     * object in a declarative fashion.

+     */

+    @Parameter(defaultPrefix = "validate")

+    @SuppressWarnings("unchecked")

+    private FieldValidator<Object> validate = NOOP_VALIDATOR;

+

+    @Environmental

+    private ValidationTracker tracker;

+

+    @Inject

+    private MultipartDecoder decoder;

+

+    @Environmental

+    private FormSupport formSupport;

+

+    @Inject

+    private FieldValidatorDefaultSource fieldValidatorDefaultSource;

+

+    @Inject

+    private ComponentResources resources;

+

+    @Inject

+    private Locale locale;

+

+    @Inject

+    private FieldValidationSupport fieldValidationSupport;

+

+    @SuppressWarnings("unused")

+    @Mixin

+    private RenderDisabled renderDisabled;

+

+    /**

+     * Computes a default value for the "validate" parameter using {@link FieldValidatorDefaultSource}.

+     */

+    final FieldValidator defaultValidate()

+    {

+        Class type = resources.getBoundType("value");

+

+        if (type == null) return null;

+

+        return fieldValidatorDefaultSource.createDefaultValidator(this, resources.getId(),

+                                                                  resources.getContainerMessages(), locale, type,

+                                                                  resources.getAnnotationProvider("value"));

+    }

+

+    public Upload()

+    {

+    }

+

+    // For testing

+    Upload(UploadedFile value, FieldValidator<Object> validate, MultipartDecoder decoder, ValidationTracker tracker,

+           ComponentResources resources, FieldValidationSupport fieldValidationSupport)

+    {

+        this.value = value;

+        if (validate != null) this.validate = validate;

+        this.decoder = decoder;

+        this.tracker = tracker;

+        this.resources = resources;

+        this.fieldValidationSupport = fieldValidationSupport;

+    }

+

+    @SuppressWarnings({ "unchecked" })

+    @Override

+    protected void processSubmission(String elementName)

+    {

+        UploadedFile uploaded = decoder.getFileUpload(elementName);

+

+        if (uploaded != null)

+        {

+            if (uploaded.getFileName() == null || uploaded.getFileName().length() == 0) uploaded = null;

+        }

+

+        try

+        {

+            fieldValidationSupport.validate(uploaded, resources, validate);

+        }

+        catch (ValidationException ex)

+        {

+            tracker.recordError(this, ex.getMessage());

+        }

+

+        value = uploaded;

+    }

+

+    /**

+     * Render the upload tags.

+     *

+     * @param writer Writer to output markup

+     */

+    protected void beginRender(MarkupWriter writer)

+    {

+        formSupport.setEncodingType(MULTIPART_ENCTYPE);

+

+        writer.element("input", "type", "file", "name", getControlName(), "id", getClientId());

+

+        validate.render(writer);

+

+        resources.renderInformalParameters(writer);

+

+        decorateInsideField();

+    }

+

+    public void afterRender(MarkupWriter writer)

+    {

+        writer.end();

+    }

+

+    public UploadedFile getValue()

+    {

+        return value;

+    }

+

+    Binding defaultValue()

+    {

+        return createDefaultParameterBinding("value");

+    }

+

+    void injectDecorator(ValidationDecorator decorator)

+    {

+        setDecorator(decorator);

+    }

+

+    void injectFormSupport(FormSupport formSupport)

+    {

+        // We have our copy ...

+        this.formSupport = formSupport;

+

+        // As does AbstractField

+        setFormSupport(formSupport);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImpl.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImpl.java
new file mode 100755
index 0000000..8fedfb4
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImpl.java
@@ -0,0 +1,160 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.FileItem;

+import org.apache.commons.fileupload.FileItemFactory;

+import org.apache.commons.fileupload.FileUploadException;

+import org.apache.commons.fileupload.disk.DiskFileItemFactory;

+import org.apache.commons.fileupload.servlet.ServletFileUpload;

+import org.apache.tapestry.ioc.annotation.Inject;

+import org.apache.tapestry.ioc.annotation.Symbol;

+import org.apache.tapestry.ioc.internal.util.CollectionFactory;

+import org.apache.tapestry.ioc.services.ThreadCleanupListener;

+import org.apache.tapestry.upload.services.MultipartDecoder;

+import org.apache.tapestry.upload.services.UploadSymbols;

+import org.apache.tapestry.upload.services.UploadedFile;

+

+import javax.servlet.http.HttpServletRequest;

+import java.io.File;

+import java.io.UnsupportedEncodingException;

+import java.util.List;

+import java.util.Map;

+

+/**

+ * Implementation of multipart decoder for servlets.  This implementation is perthread scope.

+ */

+public class MultipartDecoderImpl implements MultipartDecoder, ThreadCleanupListener

+{

+    private final Map<String, UploadedFileItem> uploads = CollectionFactory.newMap();

+

+    private final String repositoryLocation;

+

+    private final int repositoryThreshold;

+

+    private final long maxRequestSize;

+

+    private final long maxFileSize;

+

+    public MultipartDecoderImpl(

+

+            @Inject @Symbol(UploadSymbols.REPOSITORY_LOCATION)

+            String repositoryLocation,

+

+            @Symbol(UploadSymbols.REPOSITORY_THRESHOLD)

+            int repositoryThreshold,

+

+            @Symbol(UploadSymbols.REQUESTSIZE_MAX)

+            long maxRequestSize,

+

+            @Symbol(UploadSymbols.FILESIZE_MAX)

+            long maxFileSize)

+    {

+        this.repositoryLocation = repositoryLocation;

+        this.repositoryThreshold = repositoryThreshold;

+        this.maxRequestSize = maxRequestSize;

+        this.maxFileSize = maxFileSize;

+    }

+

+    public UploadedFile getFileUpload(String parameterName)

+    {

+        return uploads.get(parameterName);

+    }

+

+    public HttpServletRequest decode(HttpServletRequest request)

+    {

+        List<FileItem> fileItems = parseRequest(request);

+

+        return processFileItems(request, fileItems);

+    }

+

+    public void threadDidCleanup()

+    {

+        for (UploadedFileItem uploaded : uploads.values())

+        {

+            uploaded.cleanup();

+        }

+    }

+

+    @SuppressWarnings("unchecked")

+    protected List<FileItem> parseRequest(HttpServletRequest request)

+    {

+        try

+        {

+            return createFileUpload().parseRequest(request);

+        }

+        catch (FileUploadException e)

+        {

+            throw new RuntimeException(UploadMessages.unableToDecode(), e);

+        }

+    }

+

+    protected ServletFileUpload createFileUpload()

+    {

+        FileItemFactory factory = new DiskFileItemFactory(repositoryThreshold, new File(repositoryLocation));

+        ServletFileUpload upload = new ServletFileUpload(factory);

+

+        // set maximum file upload size

+        upload.setSizeMax(maxRequestSize);

+        upload.setFileSizeMax(maxFileSize);

+

+        return upload;

+    }

+

+    protected HttpServletRequest processFileItems(HttpServletRequest request, List<FileItem> fileItems)

+    {

+        if (fileItems == null || fileItems.isEmpty())

+        {

+            return request;

+        }

+

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+

+        String encoding = request.getCharacterEncoding();

+

+        for (FileItem item : fileItems)

+        {

+            if (item.isFormField())

+            {

+                String fieldValue;

+

+                try

+                {

+

+                    fieldValue = encoding == null ? item.getString() : item.getString(encoding);

+                }

+                catch (UnsupportedEncodingException e)

+                {

+                    // TODO maybe log exception with level warn

+                    fieldValue = item.getString();

+                }

+

+                wrapper.addParameter(item.getFieldName(), fieldValue);

+            }

+            else

+            {

+                wrapper.addParameter(item.getFieldName(), item.getName());

+                addUploadedFile(item.getFieldName(), new UploadedFileItem(item));

+            }

+        }

+

+        return wrapper;

+    }

+

+    protected void addUploadedFile(String name, UploadedFileItem file)

+    {

+        uploads.put(name, file);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilter.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilter.java
new file mode 100755
index 0000000..497c490
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilter.java
@@ -0,0 +1,47 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.servlet.ServletFileUpload;

+import org.apache.tapestry.services.HttpServletRequestFilter;

+import org.apache.tapestry.services.HttpServletRequestHandler;

+import org.apache.tapestry.upload.services.MultipartDecoder;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+import java.io.IOException;

+

+/**

+ * Filter that decodes an incoming multipart request.

+ */

+public class MultipartServletRequestFilter implements HttpServletRequestFilter

+{

+    private final MultipartDecoder decoder;

+

+    public MultipartServletRequestFilter(MultipartDecoder multipartDecoder)

+    {

+        decoder = multipartDecoder;

+    }

+

+    public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler)

+            throws IOException

+    {

+        HttpServletRequest newRequest = ServletFileUpload.isMultipartContent(request) ? decoder.decode(

+                request) : request;

+

+        return handler.service(newRequest, response);

+    }

+

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParameterValue.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParameterValue.java
new file mode 100755
index 0000000..37aee84
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParameterValue.java
@@ -0,0 +1,81 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;

+

+import java.util.List;

+

+/**

+ * Holds single or multivalued values.

+ */

+public class ParameterValue

+{

+    private final List<String> values = newList();

+

+    public static final ParameterValue NULL = new ParameterValue()

+    {

+        @Override

+        public String single()

+        {

+            return null;

+        }

+

+        @Override

+        public String[] multi()

+        {

+            return null;

+        }

+    };

+

+    public ParameterValue(String value)

+    {

+        values.add(value);

+    }

+

+    public ParameterValue(String... values)

+    {

+        for (String v : values)

+        {

+            add(v);

+        }

+    }

+

+    /**

+     * @return Single value of parameter (or first value if there are multiple values)

+     */

+    public String single()

+    {

+        return values.get(0);

+    }

+

+    /**

+     * @return All values of parameter

+     */

+    public String[] multi()

+    {

+        return values.toArray(new String[values.size()]);

+    }

+

+    public void add(String value)

+    {

+        values.add(value);

+    }

+

+    public boolean isMulti()

+    {

+        return values.size() > 1;

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapper.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapper.java
new file mode 100755
index 0000000..0c261d3
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapper.java
@@ -0,0 +1,104 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;

+import org.apache.tapestry.services.Dispatcher;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletRequestWrapper;

+import java.io.UnsupportedEncodingException;

+import java.util.Collections;

+import java.util.Enumeration;

+import java.util.Map;

+

+/**

+ * Wrapper for HttpServletRequest that overrides the parameter methods of the wrapped request. i.e. parameters are

+ * retrieved from the wrapper rather than the real request.

+ */

+public class ParametersServletRequestWrapper extends HttpServletRequestWrapper

+{

+    private final Map<String, ParameterValue> parameters = newMap();

+

+    public ParametersServletRequestWrapper(HttpServletRequest httpServletRequest)

+    {

+        super(httpServletRequest);

+    }

+

+    @Override

+    public String getParameter(String name)

+    {

+        return getValueFor(name).single();

+    }

+

+    @Override

+    public Map<String, Object> getParameterMap()

+    {

+        Map<String, Object> paramMap = newMap();

+

+        for (Map.Entry<String, ParameterValue> e : parameters.entrySet())

+        {

+            ParameterValue value = e.getValue();

+

+            paramMap.put(e.getKey(), value.isMulti() ? value.multi() : value.single());

+        }

+

+        return paramMap;

+    }

+

+    @Override

+    public Enumeration getParameterNames()

+    {

+        return Collections.enumeration(parameters.keySet());

+    }

+

+    @Override

+    public String[] getParameterValues(String name)

+    {

+        return getValueFor(name).multi();

+    }

+

+    public void addParameter(String name, String value)

+    {

+        ParameterValue pv = parameters.get(name);

+        if (pv == null)

+        {

+            pv = new ParameterValue(value);

+            parameters.put(name, pv);

+        }

+        else

+        {

+            pv.add(value);

+        }

+    }

+

+    ParameterValue getValueFor(String name)

+    {

+        ParameterValue value = parameters.get(name);

+

+        return value == null ? ParameterValue.NULL : value;

+    }

+

+    /**

+     * Ignores any attempt to set the character encoding. Tapestry attempts to set the encoding <em>after</em> the page

+     * name has been identified by the correct {@link Dispatcher}, and that's too late from the perspective of the

+     * Servlet API as HttpServlet.getInputStream() will already have been called.

+     */

+    @Override

+    public void setCharacterEncoding(String enc) throws UnsupportedEncodingException

+    {

+

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadMessages.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadMessages.java
new file mode 100755
index 0000000..d44397c
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadMessages.java
@@ -0,0 +1,61 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.tapestry.ioc.Messages;

+import org.apache.tapestry.ioc.internal.util.MessagesImpl;

+import org.apache.tapestry.upload.services.UploadedFile;

+

+import java.io.File;

+

+class UploadMessages

+{

+    private static final Messages MESSAGES = MessagesImpl.forClass(UploadMessages.class);

+

+    static String unableToDecode()

+    {

+        return MESSAGES.format("unable-to-decode");

+    }

+

+    static String unsupportedEncoding(String encoding)

+    {

+        return MESSAGES.format("unsupported-encoding", encoding);

+    }

+

+    static String unableToOpenContentFile(UploadedFile item)

+    {

+        return MESSAGES.format("unable-to-open-content-file", item.getFilePath());

+    }

+

+    static String writeFailure(File file)

+    {

+        return MESSAGES.format("write-failure", file);

+    }

+

+    static String unableToCreateTempFile()

+    {

+        return MESSAGES.get("unable-to-create-temp-file");

+    }

+

+    static String encloseUploadInForm()

+    {

+        return MESSAGES.get("enclose-upload-in-form");

+    }

+

+    static String encodingTypeAlreadySet(String formId, String requiredEncType, String existingEncType)

+    {

+        return MESSAGES.format("enctype-already-set", formId, requiredEncType, existingEncType);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadedFileItem.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadedFileItem.java
new file mode 100755
index 0000000..cc15bde
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/internal/services/UploadedFileItem.java
@@ -0,0 +1,90 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.FileItem;

+import org.apache.commons.io.FilenameUtils;

+import org.apache.tapestry.upload.services.UploadedFile;

+

+import java.io.File;

+import java.io.IOException;

+import java.io.InputStream;

+

+/**

+ * Implentation of {@link org.apache.tapestry.upload.services.UploadedFile} for FileItems.

+ */

+public class UploadedFileItem implements UploadedFile

+{

+    private final FileItem item;

+

+    public UploadedFileItem(FileItem item)

+    {

+        this.item = item;

+    }

+

+    public String getContentType()

+    {

+        return item.getContentType();

+    }

+

+    public String getFileName()

+    {

+        return FilenameUtils.getName(getFilePath());

+    }

+

+    public String getFilePath()

+    {

+        return item.getName();

+    }

+

+    public long getSize()

+    {

+        return item.getSize();

+    }

+

+    public InputStream getStream()

+    {

+        try

+        {

+            return item.getInputStream();

+        }

+        catch (IOException e)

+        {

+            throw new RuntimeException(UploadMessages.unableToOpenContentFile(this), e);

+        }

+    }

+

+    public boolean isInMemory()

+    {

+        return item.isInMemory();

+    }

+

+    public void write(File file)

+    {

+        try

+        {

+            item.write(file);

+        }

+        catch (Exception e)

+        {

+            throw new RuntimeException(UploadMessages.writeFailure(file), e);

+        }

+    }

+

+    public void cleanup()

+    {

+        item.delete();

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/MultipartDecoder.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/MultipartDecoder.java
new file mode 100755
index 0000000..ce2ab96
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/MultipartDecoder.java
@@ -0,0 +1,41 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.upload.services;

+

+import javax.servlet.http.HttpServletRequest;

+

+/**

+ * Responsible for detecting and processing file upload requests, using Jakarta Commons FileUpload.

+ * Implementations of this service typically use the threaded service lifecycle model.

+ */

+public interface MultipartDecoder

+{

+

+    /**

+     * @param parameterName Name of the query parameter associated with the uploaded file

+     * @return a file upload with the given name, or null if no such file upload was in the request.

+     */

+    UploadedFile getFileUpload(String parameterName);

+

+    /**

+     * Decodes the request, returning a new {@link javax.servlet.http.HttpServletRequest}

+     * implementation that will allow access to the form fields submitted in the request (but omits

+     * uploaded files).

+     *

+     * @param request The incoming servlet request

+     * @return decoded http request

+     */

+    HttpServletRequest decode(HttpServletRequest request);

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadModule.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadModule.java
new file mode 100755
index 0000000..289c208
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadModule.java
@@ -0,0 +1,87 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.services;

+

+import org.apache.commons.fileupload.disk.DiskFileItemFactory;

+import org.apache.commons.io.FileCleaner;

+import org.apache.tapestry.ioc.*;

+import org.apache.tapestry.ioc.annotation.Scope;

+import org.apache.tapestry.ioc.services.PerthreadManager;

+import org.apache.tapestry.ioc.services.RegistryShutdownHub;

+import org.apache.tapestry.ioc.services.RegistryShutdownListener;

+import org.apache.tapestry.services.HttpServletRequestFilter;

+import org.apache.tapestry.services.LibraryMapping;

+import org.apache.tapestry.upload.internal.services.MultipartDecoderImpl;

+import org.apache.tapestry.upload.internal.services.MultipartServletRequestFilter;

+

+import java.util.concurrent.atomic.AtomicBoolean;

+

+public class UploadModule

+{

+    private static final AtomicBoolean needToAddShutdownListener = new AtomicBoolean(true);

+    private static final String NO_LIMIT = "-1";

+

+    public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)

+    {

+        // Add the component to the "core" library.

+

+        configuration.add(new LibraryMapping("core", "org.apache.tapestry.upload"));

+    }

+

+    @Scope(IOCConstants.PERTHREAD_SCOPE)

+    public static MultipartDecoder buildMultipartDecoder(PerthreadManager perthreadManager,

+

+                                                         RegistryShutdownHub shutdownHub,

+

+                                                         ObjectLocator locator)

+    {

+        MultipartDecoderImpl multipartDecoder = locator.autobuild(MultipartDecoderImpl.class);

+

+        // This is proabably overkill since the FileCleaner should catch temporary files, but lets

+        // be safe.

+        perthreadManager.addThreadCleanupListener(multipartDecoder);

+

+        if (needToAddShutdownListener.getAndSet(false))

+        {

+            shutdownHub.addRegistryShutdownListener(new RegistryShutdownListener()

+            {

+                public void registryDidShutdown()

+                {

+                    FileCleaner.exitWhenFinished();

+                }

+            });

+        }

+

+        return multipartDecoder;

+    }

+

+    /**

+     * Contributes a filter, "MultipartFilter" after "IgnoredPaths".

+     */

+    public static void contributeHttpServletRequestHandler(OrderedConfiguration<HttpServletRequestFilter> configuration,

+                                                           MultipartDecoder multipartDecoder)

+    {

+        configuration.add("MultipartFilter", new MultipartServletRequestFilter(multipartDecoder), "after:IgnoredPaths");

+    }

+

+    public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)

+    {

+        configuration.add(UploadSymbols.REPOSITORY_THRESHOLD, Integer

+                .toString(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD));

+        configuration.add(UploadSymbols.REPOSITORY_LOCATION, System.getProperty("java.io.tmpdir"));

+        configuration.add(UploadSymbols.REQUESTSIZE_MAX, NO_LIMIT);

+        configuration.add(UploadSymbols.FILESIZE_MAX, NO_LIMIT);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadSymbols.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadSymbols.java
new file mode 100755
index 0000000..1ff64a1
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadSymbols.java
@@ -0,0 +1,46 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.upload.services;

+

+/**

+ * Configuration symbols.

+ */

+public final class UploadSymbols

+{

+    /**

+     * Location where temporary files will be written. Defaults to java.io.tmpdir property

+     */

+    public static final String REPOSITORY_LOCATION = "upload.repository-location";

+

+    /**

+     * Threshold (in bytes) that determines when an uploaded file will be written to the repository

+     */

+    public static final String REPOSITORY_THRESHOLD = "upload.repository-threshold";

+

+    /**

+     * Maximum size (in bytes) of a single upload request Defaults to -1 ( no limit)

+     */

+    public static final String REQUESTSIZE_MAX = "upload.requestsize-max";

+

+    /**

+     * Maximum size (in bytes) of a single file within an upload request Defaults to -1 ( no limit)

+     */

+    public static final String FILESIZE_MAX = "upload.filesize-max";

+

+    private UploadSymbols()

+    {

+    }

+

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadedFile.java b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadedFile.java
new file mode 100755
index 0000000..7140c1e
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/java/org/apache/tapestry/upload/services/UploadedFile.java
@@ -0,0 +1,65 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.upload.services;

+

+import org.apache.tapestry.upload.components.Upload;

+

+import java.io.File;

+import java.io.InputStream;

+

+/**

+ * Represents an uploaded file.

+ *

+ * @see Upload

+ */

+public interface UploadedFile

+{

+    /**

+     * @return the MIME type specified when the file was uploaded.

+     */

+    String getContentType();

+

+    /**

+     * @return the name of the file that was uploaded.

+     */

+    String getFileName();

+

+    /**

+     * @return the complete path, as reported by the client browser.

+     */

+    String getFilePath();

+

+    /**

+     * @return the size, in bytes, of the uploaded content.

+     */

+    long getSize();

+

+    /**

+     * @return an input stream of the content of the file.

+     */

+    InputStream getStream();

+

+    /**

+     * @return true if the uploaded content is in memory.

+     */

+    boolean isInMemory();

+

+    /**

+     * Writes the content of the file to a known location.

+     *

+     * @param file Location to write file to

+     */

+    void write(File file);

+}

diff --git a/hlship-20080520/tapestry-upload/src/main/resources/org/apache/tapestry/upload/internal/services/UploadStrings.properties b/hlship-20080520/tapestry-upload/src/main/resources/org/apache/tapestry/upload/internal/services/UploadStrings.properties
new file mode 100755
index 0000000..5db9e57
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/main/resources/org/apache/tapestry/upload/internal/services/UploadStrings.properties
@@ -0,0 +1,21 @@
+# Copyright 2007, 2008 The Apache Software Foundation

+#

+# Licensed under the Apache License, Version 2.0 (the "License");

+# you may not use this file except in compliance with the License.

+# You may obtain a copy of the License at

+#

+#     http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing, software

+# distributed under the License is distributed on an "AS IS" BASIS,

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

+# See the License for the specific language governing permissions and

+# limitations under the License.

+

+unable-to-decode=Unable to decode multipart encoded request.

+unsupported-encoding=Unsupported character encoding '%s' when decoding multipart encoded request

+write-failure=Unable to write uploaded file content to %s

+unable-to-open-content-file=Unable to open uploaded file '%s'

+unable-to-create-temp-file=Unable to create a temporary file to write upload to.

+enclose-upload-in-form=Upload component must be enclosed by a Form component.

+enctype-already-set=Unable to set encoding type on form '%s' to '%s'.  Already has encoding type of '%s'.

diff --git a/hlship-20080520/tapestry-upload/src/site/apt/index.apt b/hlship-20080520/tapestry-upload/src/site/apt/index.apt
new file mode 100755
index 0000000..3e4148a
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/site/apt/index.apt
@@ -0,0 +1,73 @@
+ ----
+ Tapestry Upload Component
+ ----
+ 
+Tapestry Upload Component
+
+  Provides a file upload component for Tapestry based on
+  {{{http://jakarta.apache.org/commons/fileupload/}Jakarata Commons FileUpload}}.
+  
+  This is packaged as an add-on to Tapestry because of the number of additional dependencies
+  it adds.  However, Maven takes care of that for you!
+  
+  
+Usage
+
+  The upload component supports default value binding (based on id) and validation.
+
+* Component Template
+  
++---+
+    <t:form>
+        <t:errors/>
+        <input t:type="upload" t:id="file" validate="required"/>
+        <br/>
+        <input type="submit" value="Upload"/>
+    </t:form>
++---+
+
+  Here, because the value parameter was not bound, the component used the file property of its container (because the
+  component's id is 'file').  If you want to upload as a different property, either bind the value parameter or
+  change the component's id.
+
+* Page class
+
++---+
+    public class UploadExample
+    {
+        private UploadedFile file;
+
+        public UploadedFile getFile()
+        {
+            return file;
+        }
+
+        public void setFile(UploadedFile file)
+        {
+            this.file = file;
+        }
+
+        public void onSuccess()
+        {
+            File copied = new File("/my/file/location/" + file.getFileName());
+            
+            file.write(copied);
+        }
+    }
++---+
+
+
+
+
+Potential Issues
+
+   The Commons FileUpload library uses the CommonsIO file cleaner service to remove temporary files when
+   they are no longer needed.  This service creates a thread to carry out its work. If the commons-io library
+   is shared amongst multiple applications (e.g. added to server classpath) it is possible for an application
+   to terminate this thread prematurely and cause errors for the other applications.
+   (see the {{{http://jakarta.apache.org/commons/fileupload/using.html}Resource Cleanup}} section in  for more discussion)
+
+   Technically the file cleanup service is not needed by Tapestry Upload (which deletes temporary files at the end
+   of request processing).  However it is currently not possible to disable it (enhancement request has been filed
+    as {{{https://issues.apache.org/jira/browse/FILEUPLOAD-133}FILEUPLOAD-133}}).
+
diff --git a/hlship-20080520/tapestry-upload/src/site/site.xml b/hlship-20080520/tapestry-upload/src/site/site.xml
new file mode 100755
index 0000000..58cc51e
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/site/site.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 

+   Copyright 2007 The Apache Software Foundation

+

+   Licensed under the Apache License, Version 2.0 (the "License");

+   you may not use this file except in compliance with the License.

+   You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT 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="Tapestry File Upload">

+    <bannerLeft>

+        <name>Tapestry 5</name>

+        <href>http://tapestry.apache.org/tapestry5/</href>

+        <src>images/tapestry_banner.gif</src>

+    </bannerLeft>

+    <bannerRight>

+        <name>Apache</name>

+        <href>http://www.apache.org</href>

+        <src>images/asf_logo_wide.gif</src>

+    </bannerRight>

+    <skin>

+        <groupId>org.apache.tapestry</groupId>

+        <artifactId>maven-skin</artifactId>

+        <version>1.1</version>

+    </skin>

+

+    <publishDate format="dd MMM yyyy"/>

+

+    <body>

+

+

+        <menu name="Quick Links">

+            <item name="Download" href="http://tapestry.apache.org/download.html"/>

+        </menu>

+

+        <menu name="Documentation">

+            <item name="Reference" href="ref/index.html"/>

+        </menu>

+

+        <menu ref="reports"/>

+

+    </body>

+</project>

diff --git a/hlship-20080520/tapestry-upload/src/test/conf/testng.xml b/hlship-20080520/tapestry-upload/src/test/conf/testng.xml
new file mode 100755
index 0000000..6ea8a59
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/conf/testng.xml
@@ -0,0 +1,28 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<!-- 
+   Copyright 2007, 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<suite name="Tapesty Upload Component" parallel="false" annotations="1.5" verbose="2">
+    <test name="Tapesty Upload Component">
+        <parameter name="tapestry.integration-webapp" value="src/test/webapp"/>
+        <packages>
+            <package name="org.apache.tapestry.upload.components"/>
+            <package name="org.apache.tapestry.upload.internal.services"/>
+            <!-- One day might be able to run this too -->
+            <!--package name="org.apache.tapestry.upload.integration"/-->
+        </packages>
+    </test>
+</suite>
diff --git a/hlship-20080520/tapestry-upload/src/test/conf/webdefault.xml b/hlship-20080520/tapestry-upload/src/test/conf/webdefault.xml
new file mode 100755
index 0000000..5a40749
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/conf/webdefault.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!-- 
+   Copyright 2007 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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">

+

+    <description>

+        Default web.xml file.

+        This file is applied to a Web application before it's own WEB_INF/web.xml file

+    </description>

+

+

+    <!-- ==================================================================== -->

+    <!-- Context params to control Session Cookies                            -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <!-- UNCOMMENT TO ACTIVATE

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>

+      <param-value>127.0.0.1</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>

+      <param-value>/</param-value>

+    </context-param>

+

+    <context-param>

+      <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>

+      <param-value>-1</param-value>

+    </context-param>

+    -->

+

+

+    <!-- ==================================================================== -->

+    <!-- The default servlet.                                                 -->

+    <!-- This servlet, normally mapped to /, provides the handling for static -->

+    <!-- content, OPTIONS and TRACE methods for the context.                  -->

+    <!-- The following initParameters are supported:                          -->

+    <!--                                                                      -->

+    <!--   acceptRanges     If true, range requests and responses are         -->

+    <!--                    supported                                         -->

+    <!--                                                                      -->

+    <!--   dirAllowed       If true, directory listings are returned if no    -->

+    <!--                    welcome file is found. Else 403 Forbidden.        -->

+    <!--                                                                      -->

+    <!--   putAllowed       If true, the PUT method is allowed                -->

+    <!--                                                                      -->

+    <!--   delAllowed       If true, the DELETE method is allowed             -->

+    <!--                                                                      -->

+    <!--   redirectWelcome  If true, redirect welcome file requests           -->

+    <!--                    else use request dispatcher forwards              -->

+    <!--                                                                      -->

+    <!--   minGzipLength    If set to a positive integer, then static content -->

+    <!--                    larger than this will be served as gzip content   -->

+    <!--                    encoded if a matching resource is found ending    -->

+    <!--                    with ".gz"                                        -->

+    <!--                                                                      -->

+    <!--   resoureBase      Can be set to replace the context resource base   -->

+    <!--                                                                      -->

+    <!--   relativeResourceBase                                               -->

+    <!--                    Set with a pathname relative to the base of the   -->

+    <!--                    servlet context root. Useful for only serving     -->

+    <!--                    static content from only specific subdirectories. -->

+    <!--                                                                      -->

+    <!-- The MOVE method is allowed if PUT and DELETE are allowed             -->

+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

+    <servlet>

+        <servlet-name>default</servlet-name>

+        <servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>

+        <init-param>

+            <param-name>acceptRanges</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>dirAllowed</param-name>

+            <param-value>true</param-value>

+        </init-param>

+        <init-param>

+            <param-name>putAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>delAllowed</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>redirectWelcome</param-name>

+            <param-value>false</param-value>

+        </init-param>

+        <init-param>

+            <param-name>minGzipLength</param-name>

+            <param-value>8192</param-value>

+        </init-param>

+        <load-on-startup>0</load-on-startup>

+    </servlet>

+

+

+    <servlet-mapping>

+        <servlet-name>default</servlet-name>

+        <url-pattern>/</url-pattern>

+    </servlet-mapping>

+

+    <!-- ==================================================================== -->

+    <session-config>

+        <session-timeout>30</session-timeout>

+    </session-config>

+

+

+    <!-- ==================================================================== -->

+    <welcome-file-list>

+        <welcome-file>index.html</welcome-file>

+        <welcome-file>index.htm</welcome-file>

+    </welcome-file-list>

+

+    <!-- ==================================================================== -->

+    <locale-encoding-mapping-list>

+        <locale-encoding-mapping>

+            <locale>ar</locale>

+            <encoding>ISO-8859-6</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>be</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>bg</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ca</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>cs</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>da</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>de</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>el</locale>

+            <encoding>ISO-8859-7</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>en</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>es</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>et</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fi</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>fr</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hr</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>hu</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>is</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>it</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>iw</locale>

+            <encoding>ISO-8859-8</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ja</locale>

+            <encoding>Shift_JIS</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ko</locale>

+            <encoding>EUC-KR</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lt</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>lv</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>mk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>nl</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>no</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>pt</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ro</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>ru</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sh</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sk</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sl</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sq</locale>

+            <encoding>ISO-8859-2</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sr</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>sv</locale>

+            <encoding>ISO-8859-1</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>tr</locale>

+            <encoding>ISO-8859-9</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>uk</locale>

+            <encoding>ISO-8859-5</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh</locale>

+            <encoding>GB2312</encoding>

+        </locale-encoding-mapping>

+        <locale-encoding-mapping>

+            <locale>zh_TW</locale>

+            <encoding>Big5</encoding>

+        </locale-encoding-mapping>

+    </locale-encoding-mapping-list>

+

+

+</web-app>

+

diff --git a/hlship-20080520/tapestry-upload/src/test/data/upload.txt b/hlship-20080520/tapestry-upload/src/test/data/upload.txt
new file mode 100755
index 0000000..83e0ddb
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/data/upload.txt
@@ -0,0 +1,99 @@
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras at nisi. Nullam lobortis mi at dolor. Maecenas sit amet eros eu purus rhoncus suscipit. Quisque ipsum dolor, placerat eu, sagittis sed, viverra tristique, lectus. Nunc ultricies libero laoreet elit pharetra sodales. Praesent bibendum auctor odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla rhoncus facilisis diam. Mauris tincidunt consectetuer lectus. Curabitur fermentum sem sagittis magna. Suspendisse aliquet euismod sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut pede nibh, congue non, laoreet fermentum, rutrum condimentum, ligula. Nulla lorem magna, semper vitae, pharetra vel, tempus ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam semper ipsum non justo. Fusce placerat risus. Quisque nisi lectus, bibendum vel, tempus ac, hendrerit in, nunc. Integer sed nunc.

+

+Donec ac est. Vivamus egestas consequat eros. Praesent vehicula quam nec est. Aenean id ante ac quam sodales molestie. Duis hendrerit tellus vitae nulla. Sed nulla lectus, faucibus eu, eleifend vel, consectetuer vel, nulla. Vestibulum gravida ornare magna. Duis nunc dolor, iaculis ut, dapibus in, tincidunt eu, felis. Nam et libero. Donec aliquam magna id mi. Duis congue ligula non tortor. Vivamus luctus turpis. Pellentesque tristique aliquam tortor. Pellentesque auctor ullamcorper metus. Integer convallis pharetra quam. Duis bibendum ornare purus. Vivamus condimentum justo at orci.

+

+Pellentesque in dolor id elit suscipit pulvinar. Duis venenatis elementum lorem. Cras fermentum tellus vel justo. Aliquam molestie nunc a dui. Curabitur enim lorem, sollicitudin ut, euismod ac, gravida sit amet, diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Fusce porttitor, elit nec mattis fringilla, ligula risus faucibus urna, non lobortis risus ipsum eu urna. Ut risus nisl, consectetuer non, ullamcorper eu, euismod in, metus. Sed sem. Nulla lectus. Donec dolor arcu, tincidunt aliquam, sollicitudin eu, dapibus vel, tortor. Aenean arcu orci, tempor et, dictum ut, cursus ullamcorper, justo. Nulla molestie, nunc vitae facilisis laoreet, diam libero adipiscing nulla, sagittis dapibus lacus tortor non lacus. Etiam nonummy, est quis vulputate semper, mauris mauris scelerisque urna, eget venenatis enim risus a quam. Etiam vehicula lectus nec augue rutrum adipiscing. Donec suscipit quam commodo augue. Quisque scelerisque lorem ac turpis.

+

+Praesent ultricies, ipsum venenatis auctor gravida, enim nulla tempus urna, ac accumsan lacus diam id felis. Praesent vel nunc tincidunt pede placerat scelerisque. Donec justo. Sed nonummy. Donec rhoncus. Maecenas congue iaculis lorem. Morbi molestie risus vitae lacus. Nulla condimentum gravida dui. Nunc vestibulum, libero eget ultricies sagittis, dolor sem sollicitudin pede, vitae lobortis quam justo eget diam. Pellentesque neque ligula, interdum ut, cursus et, faucibus sit amet, nisi. Duis fermentum. Quisque odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Cras eget enim in ipsum facilisis sagittis. Donec pellentesque, orci vel pharetra luctus, neque orci laoreet sem, a pellentesque risus nibh vel velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec nulla. Nulla luctus nonummy metus. Nam in arcu. Praesent ut augue at tellus scelerisque aliquam.

+

+Vivamus imperdiet molestie urna. Ut condimentum mauris vel risus. Donec dui leo, consequat in, luctus vitae, tristique sit amet, libero. Nunc pede. Nam et libero non erat laoreet tempus. Curabitur rhoncus pellentesque velit. Etiam condimentum ligula semper urna. Sed ipsum risus, ultrices vel, mattis nec, laoreet tristique, libero. Curabitur pretium venenatis pede. In vestibulum. Nunc in nulla nec elit laoreet iaculis. Proin scelerisque, eros eu auctor accumsan, ligula pede porttitor lorem, sed adipiscing mi nisl et lorem. Proin at erat.

+

+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis varius. Duis vitae sem. Duis eu pede. Nulla vitae risus. Mauris molestie tellus quis ipsum. Cras facilisis vestibulum arcu. Cras at turpis eu odio lacinia cursus. Nulla a dolor. Cras vulputate urna eu mauris sodales porta. Quisque non metus. Suspendisse odio mi, ullamcorper vitae, lobortis in, lacinia eget, pede. Integer cursus leo nec ligula. Etiam ultricies massa eget lorem. Sed eget quam at eros gravida imperdiet. Phasellus libero. Aenean eros magna, luctus at, fringilla id, ultricies a, mauris. Sed non neque ac libero cursus luctus.

+

+Pellentesque dui ante, scelerisque vitae, luctus molestie, blandit sit amet, eros. Curabitur condimentum. Mauris eget leo a massa eleifend egestas. Proin neque quam, pellentesque eget, tempor at, rutrum sed, nunc. Vivamus hendrerit volutpat ipsum. Sed imperdiet pulvinar ligula. Aliquam mattis. Praesent aliquam molestie orci. Suspendisse nec lacus non mi consequat volutpat. Fusce felis. Phasellus ac elit. Aliquam erat volutpat. Vivamus tristique.

+

+Phasellus blandit. Integer tortor est, auctor non, hendrerit sit amet, aliquam dignissim, nibh. Aenean eleifend pede in metus pulvinar euismod. Morbi vitae nibh. Morbi sit amet sem et sapien condimentum adipiscing. Sed ligula nunc, molestie quis, elementum non, dapibus non, nulla. Suspendisse ultrices. Proin sed eros sit amet nisi auctor ornare. Nullam mattis. Sed vulputate. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin justo massa, dapibus non, rutrum at, eleifend vitae, metus. Maecenas porta varius mauris. Mauris mollis congue mi. Nunc sit amet ligula. Donec at est.

+

+Cras luctus sapien et arcu. Aenean purus erat, accumsan ac, placerat id, congue nec, urna. Proin lobortis tincidunt purus. Praesent tincidunt dui quis neque. Donec urna. Sed euismod, ligula ut sollicitudin faucibus, lorem neque suscipit enim, at dictum purus pede quis nisi. Aliquam vitae turpis. Sed pede nunc, commodo a, congue eget, lobortis quis, justo. Proin elementum ante sit amet purus. Nulla facilisi. Sed vel massa. Nam ornare.

+

+Aliquam erat volutpat. Vivamus non nulla a mi interdum interdum. Proin rutrum vestibulum odio. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec adipiscing, dolor eu faucibus iaculis, odio lorem condimentum lorem, feugiat rutrum enim urna vitae nisl. Vestibulum vehicula vehicula quam. Proin vehicula ante nec magna. Curabitur elementum odio in mi. Aenean ac urna vel turpis cursus tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent tempor consectetuer sem. In aliquam metus sed nunc. Fusce libero felis, iaculis at, convallis nec, sagittis nec, mauris. Curabitur pharetra facilisis ligula. Proin sollicitudin velit id erat.

+

+Fusce nec ipsum in nunc cursus pellentesque. Cras bibendum tellus non magna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam viverra lacinia est. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi facilisis dignissim pede. Sed odio arcu, ullamcorper vel, malesuada non, condimentum a, risus. Proin sed lacus quis ante convallis imperdiet. Nulla elementum, augue non ornare accumsan, felis purus imperdiet ipsum, a vulputate mauris turpis et nisl. Nunc mattis gravida enim. Donec nisl quam, ornare quis, congue vitae, fermentum a, massa. Duis sollicitudin sapien. Cras laoreet, nunc sed condimentum tristique, est orci egestas odio, eu feugiat risus metus facilisis dui. Nam faucibus. Sed lectus libero, nonummy nec, auctor in, tempor eleifend, massa. Duis orci. Quisque justo odio, dictum id, imperdiet quis, semper a, risus.

+

+Nam ut diam eget felis fermentum accumsan. Praesent congue auctor arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam pede. Maecenas dictum dignissim arcu. Nulla tristique, ante nec nonummy tincidunt, ipsum tortor lobortis nisl, ac fringilla magna ipsum a ipsum. Sed justo. Nunc ante. Quisque lectus sapien, bibendum a, varius consequat, congue sit amet, nisi. Sed pharetra. Vivamus dignissim convallis tellus. Fusce lobortis. Nulla lacinia suscipit velit. Duis tristique diam tristique tellus. Cras eget dui. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos.

+

+Nullam scelerisque pede sit amet lacus. Aliquam pulvinar, magna sed tincidunt sagittis, justo neque mollis lectus, nec aliquet sem neque egestas enim. Aenean velit. Sed facilisis lectus in magna. Aliquam rutrum hendrerit odio. Vivamus consectetuer risus in justo. Sed lobortis augue nec nisi. Pellentesque adipiscing sapien vitae dolor. Integer libero massa, aliquam eu, pharetra ac, posuere in, mi. Fusce faucibus. Aliquam erat volutpat. Donec massa. Phasellus condimentum pede a nisl gravida aliquam. Praesent nisl felis, pretium a, egestas et, faucibus nec, arcu. Suspendisse condimentum odio quis nunc. Nullam auctor. Nulla facilisi. Integer orci diam, tristique sed, condimentum ac, fermentum vitae, nunc. Suspendisse dapibus eros. Nam cursus lectus vitae eros.

+

+Nullam auctor arcu sollicitudin ligula. Morbi rhoncus quam sit amet nulla ullamcorper vulputate. Integer vel mauris. Duis iaculis consectetuer massa. Praesent mollis, sapien eu facilisis dapibus, elit mi vestibulum justo, eget rhoncus dolor orci vel augue. Mauris rhoncus. Nulla facilisi. Etiam ullamcorper molestie justo. Aliquam aliquam, diam quis iaculis tincidunt, nulla orci ultrices nisl, ac elementum nisi lorem at magna. Aenean vel lorem. Proin sapien libero, congue ac, placerat vel, luctus id, lectus. Donec eu tortor vitae urna faucibus sodales. Phasellus at nulla. Mauris laoreet rutrum risus. Vestibulum dictum semper justo. Mauris lobortis, pede sed luctus molestie, nibh sem imperdiet mauris, ac tempus lacus lacus dapibus sapien. Vestibulum semper pellentesque sapien. Cras condimentum nibh quis odio. Donec eget mauris. Proin at dolor.

+

+Curabitur sodales commodo justo. Mauris congue. In in velit vitae lorem mollis semper. Curabitur lectus urna, pulvinar ac, rhoncus at, porttitor eget, pede. Praesent consectetuer. Pellentesque ut libero. Quisque laoreet. Nam rutrum. Suspendisse viverra laoreet est. Nam eu nisi nec mauris viverra adipiscing. Sed quis massa tincidunt metus dictum porttitor. Proin id est. Ut hendrerit, ipsum quis molestie viverra, tellus nibh scelerisque orci, eu dictum arcu augue eget neque.

+

+Ut ut erat. Suspendisse dapibus. Aenean pretium, dolor eget ullamcorper faucibus, massa magna mollis nibh, in sagittis turpis neque porttitor neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam leo orci, fringilla nec, aliquam consequat, rutrum eu, pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Fusce sem. Maecenas in leo non mauris tincidunt suscipit. Fusce euismod metus sit amet diam. Donec pulvinar interdum lectus.

+

+Mauris feugiat, ante non tincidunt euismod, purus nisi tincidunt diam, quis rhoncus augue justo id lorem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In mattis, dolor vitae tempor gravida, sem erat sollicitudin arcu, vitae placerat ante quam nec tortor. Donec in nisi. Quisque a nisl. Proin venenatis. Mauris nec erat id odio rutrum bibendum. In feugiat faucibus quam. Donec venenatis, pede quis lobortis tincidunt, sapien turpis eleifend eros, eu tincidunt ligula metus non tellus. Nunc a mauris ut leo vestibulum egestas. Fusce laoreet feugiat est. Curabitur dignissim risus sit amet leo. Nulla sit amet est. Cras ipsum. Aliquam a augue. Morbi a nisl. Sed vel ligula sit amet tortor congue tincidunt. Mauris commodo, dui sit amet pharetra eleifend, odio mi posuere felis, ut lobortis leo felis et metus.

+

+Vestibulum interdum faucibus ante. Morbi posuere iaculis risus. Proin ac ante vel eros mattis pharetra. Nullam nulla enim, imperdiet nec, condimentum nec, consequat in, mi. Quisque imperdiet quam malesuada metus euismod elementum. Aliquam vestibulum massa in arcu. Suspendisse aliquet gravida arcu. Maecenas quam. Integer porta. Proin sed erat. Suspendisse mauris. Pellentesque eleifend mauris ut dui. Donec vitae augue. Cras congue, urna ut blandit laoreet, magna nisl vehicula nunc, non eleifend nisl turpis non sapien. Aenean eget enim. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque et sapien eget elit tincidunt semper. Nam placerat aliquam massa. Donec at nisl eget odio fermentum semper. Fusce ante enim, fringilla eget, bibendum id, posuere et, massa.

+

+Donec in ligula vitae turpis suscipit suscipit. Vestibulum ultrices. Duis nulla orci, aliquam in, pellentesque eget, condimentum in, mauris. Quisque vulputate vulputate tellus. Sed magna. Nulla sit amet massa et pede pretium sollicitudin. Duis sed mauris tincidunt tellus adipiscing scelerisque. Suspendisse bibendum nunc a nibh. Aliquam tincidunt pulvinar purus. Nam eget libero. Proin molestie.

+

+Curabitur semper orci at mi. Vestibulum tincidunt pede vitae nibh. Nunc metus. Ut mattis placerat nibh. Nulla facilisi. Maecenas tempor metus eget augue. Quisque a dolor porttitor erat placerat volutpat. In tellus. Phasellus pretium. Donec viverra, tellus sit amet sollicitudin consectetuer, orci leo consequat ipsum, in blandit augue leo ut ligula. In hac habitasse platea dictumst. Cras nibh ante, suscipit eu, fermentum non, eleifend vitae, purus. Aliquam ac massa eu mi lacinia porta. Suspendisse ultrices scelerisque ante. Praesent eget tortor. Nunc justo. Duis venenatis, justo eget sollicitudin malesuada, pede risus tempus ante, et sollicitudin nisl ligula at quam. In mauris eros, egestas vel, fringilla ut, interdum vitae, orci. Cras vitae tellus eu sem ornare facilisis.

+

+Nulla non nisl eget urna interdum suscipit. Aliquam eget libero. Duis ac metus. Vestibulum iaculis nisi in est. In sem tellus, ultricies in, hendrerit quis, ultrices ut, justo. Aliquam erat volutpat. Sed gravida, turpis vitae consequat viverra, risus ante dignissim pede, vel tristique dolor pede non urna. Duis a elit. Aliquam accumsan condimentum tellus. Quisque dui. Nullam nibh. Cras accumsan dignissim tortor. Morbi ac magna vitae est feugiat congue. Proin in felis.

+

+Nam ut purus. Donec interdum, quam nec blandit volutpat, enim velit vulputate mauris, sit amet tristique lorem erat non orci. Vivamus at enim. Morbi in odio. Aenean quam. Suspendisse commodo erat vitae lectus. Vestibulum rhoncus. Nam ullamcorper auctor metus. Quisque auctor, mauris non tincidunt sollicitudin, libero nisl venenatis libero, a adipiscing ipsum erat nec metus. Sed turpis. Aenean sem quam, tempor at, ultricies in, facilisis et, nisl. Cras laoreet.

+

+Mauris ut pede et velit egestas venenatis. Mauris tincidunt tortor sit amet erat. Phasellus imperdiet consequat lorem. Donec luctus odio ut felis. Curabitur non nunc id pede porta malesuada. Nunc nunc tortor, tempor sit amet, porttitor eu, fermentum ut, urna. Nulla vulputate. Pellentesque congue rhoncus risus. Phasellus semper convallis nisl. Ut accumsan interdum dolor. Nulla metus quam, porta non, fringilla quis, fringilla at, leo. Cras laoreet vestibulum diam. Donec et nisl et nulla ornare ultrices. Nullam fringilla. Vivamus erat. Morbi vehicula suscipit ipsum. Vestibulum sodales lectus quis nunc. Maecenas fringilla consectetuer neque.

+

+Nullam interdum vulputate orci. Etiam fringilla lacus. Suspendisse eu nisl sit amet libero dignissim aliquet. Ut nonummy malesuada lorem. Praesent cursus posuere urna. Nulla pharetra adipiscing nisl. Cras euismod pretium risus. Sed accumsan nisl ut diam. Maecenas et odio vel neque congue dictum. Nam varius pharetra dui. Pellentesque ligula. Curabitur sollicitudin pede at lorem. Quisque massa sapien, accumsan sed, condimentum a, ullamcorper ut, leo. Sed lectus. Nulla sem tortor, ornare sed, ultrices at, euismod non, purus. Maecenas ultricies nibh in mauris pulvinar suscipit. Fusce in eros id nulla hendrerit egestas. Morbi pellentesque. Quisque dolor tortor, faucibus ac, vehicula elementum, commodo dignissim, sem. Vivamus auctor ornare nunc.

+

+In consequat. Integer lectus turpis, ullamcorper et, scelerisque ac, lobortis quis, nisi. Nullam venenatis. Aliquam et leo. Vivamus felis. Pellentesque vestibulum suscipit lacus. Vivamus placerat rhoncus tellus. Integer sodales erat nec lectus. Integer et dolor. In hac habitasse platea dictumst. Suspendisse suscipit rhoncus arcu. Nullam sit amet erat. Nam elementum gravida magna.

+

+In a risus vitae ante rhoncus fermentum. Nulla facilisi. Maecenas suscipit venenatis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam nulla. Etiam lectus nisl, dignissim a, nonummy nec, bibendum vel, erat. Aenean volutpat diam eu sem. Fusce lobortis, velit id lacinia ultricies, velit purus ullamcorper ligula, sit amet imperdiet mi lacus vitae erat. Phasellus ultricies ligula a nulla tincidunt aliquam. In hac habitasse platea dictumst. Cras congue porttitor diam. Mauris vel lacus eu lorem eleifend porta. Duis aliquam libero id tortor.

+

+Vivamus vel nibh eu lectus volutpat congue. Cras volutpat tristique sem. Nullam facilisis adipiscing enim. Quisque quam justo, feugiat ut, mattis vel, aliquam laoreet, dolor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas interdum neque ac sapien. In odio nulla, posuere ut, porta ut, commodo sit amet, mi. Integer nisi. Nunc sagittis interdum tortor. Etiam tristique adipiscing massa. Nullam pede. Quisque nisl. Cras ac tortor. Phasellus pulvinar, massa id vestibulum varius, eros quam ornare urna, sit amet lacinia nisl urna a elit. Donec luctus. In hac habitasse platea dictumst. Aenean eu odio at metus consectetuer adipiscing. Sed laoreet nisl in urna. Donec vel justo sed arcu interdum vestibulum.

+

+Vivamus nec urna a mauris dictum nonummy. Maecenas ultrices cursus urna. Suspendisse potenti. Aliquam erat volutpat. Proin quam. Sed euismod orci auctor lacus. Vivamus ornare tellus et elit. Nunc volutpat sagittis nisi. Suspendisse dui massa, volutpat id, tincidunt eget, ullamcorper id, magna. Sed sapien nisi, tristique ac, tempor non, hendrerit non, libero. Integer justo quam, vestibulum vehicula, aliquet nec, interdum in, elit. Ut ac enim eu ipsum lacinia scelerisque. Donec vitae eros non nisi blandit euismod. Fusce eget orci. Proin vitae dolor ut nulla rutrum viverra.

+

+Aliquam fringilla aliquam sapien. Donec elementum adipiscing mi. Nulla facilisi. Nullam commodo interdum justo. Vestibulum vulputate sem a nulla. Donec leo metus, rhoncus sit amet, scelerisque mattis, placerat et, odio. Donec hendrerit urna sed eros. In condimentum adipiscing mi. Suspendisse eleifend, velit eget vehicula semper, nunc urna adipiscing diam, sed egestas tortor velit eu lectus. Ut sed mi. Morbi est mi, mollis nec, faucibus a, sodales non, eros. Nullam enim nunc, dapibus sed, semper cursus, aliquam vel, lacus. Quisque ultricies magna quis ligula.

+

+Pellentesque non urna. Nam vel ante. Donec nonummy, elit blandit imperdiet vehicula, ligula nisl pharetra erat, nec varius arcu felis at augue. Maecenas laoreet posuere mi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Suspendisse iaculis dignissim ante. Ut et est. Phasellus interdum. Aliquam varius odio eget lorem. Nunc dapibus justo non dolor. Vivamus posuere, ante vitae lacinia condimentum, libero tortor viverra magna, nec placerat ipsum sem condimentum orci. Sed augue ligula, tempus sed, vulputate ac, bibendum a, lacus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed a mauris. Integer ante. Fusce et orci sit amet mi lacinia posuere. Proin non tellus quis mauris facilisis volutpat. Nullam tincidunt. Pellentesque accumsan.

+

+Aliquam erat volutpat. Vestibulum a tortor quis felis sagittis pharetra. Sed aliquam sapien vel metus. Maecenas dapibus, lorem sed vestibulum pharetra, nisi justo faucibus justo, id congue nisi felis at nulla. Maecenas est ante, placerat consequat, ultricies tempor, vulputate quis, ligula. Praesent sollicitudin, nulla ut vulputate tempor, diam nunc mattis nisi, eget rutrum nisi diam sed tellus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Morbi ultrices sapien non metus pretium lacinia. Suspendisse ligula. Suspendisse fermentum dapibus enim. Mauris tincidunt magna eu lorem. Praesent nunc dui, tempor nec, pulvinar pharetra, semper ac, libero. Morbi placerat interdum ante. Proin molestie, lorem ac elementum luctus, ligula enim venenatis risus, eget mattis ante pede vitae pede. In fermentum. Donec lobortis, magna eu rutrum accumsan, augue pede eleifend tortor, in posuere velit magna ut velit. Suspendisse ac metus in nisl commodo interdum. Duis ornare elit in pede.

+

+Duis ut elit ut velit tempus bibendum. Nulla pretium vulputate tortor. Vestibulum interdum. Integer id pede. Vivamus sem augue, elementum vel, commodo a, fringilla elementum, sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur nec enim. Vivamus facilisis, metus eget pharetra tincidunt, augue lacus elementum diam, in placerat tortor tortor ut risus. Aenean elementum eleifend magna. Nullam nibh tortor, elementum vitae, vestibulum quis, mattis nec, augue. Phasellus a diam at orci porta molestie. Quisque quis purus. Fusce sed dui. Donec tempus. Etiam tincidunt, risus non aliquam tincidunt, ligula est bibendum mauris, sed dapibus libero magna vitae massa. In hac habitasse platea dictumst. Cras ultrices risus ac justo. Fusce pellentesque, justo quis suscipit vestibulum, sapien libero viverra risus, ut condimentum eros purus sed lectus. Nullam id pede. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos.

+

+Quisque blandit luctus diam. Sed posuere. Donec mattis. Etiam bibendum rutrum sapien. Aliquam nec leo vitae mi porttitor aliquet. Nulla metus justo, semper vel, vehicula et, placerat eu, mi. Etiam neque ante, gravida eu, posuere eu, posuere sed, dolor. Nunc et nunc. Suspendisse enim eros, interdum nec, porta at, gravida in, velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed quis ligula eget massa gravida dignissim. Suspendisse nonummy.

+

+Proin pellentesque aliquet neque. Sed porta urna ornare ligula. In hac habitasse platea dictumst. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse a nisl. Curabitur in eros sit amet nisi blandit vehicula. Aliquam rutrum pulvinar augue. Vestibulum tellus sem, convallis eu, eleifend vitae, sagittis nec, nisl. Pellentesque leo. Nam pulvinar tristique est. Praesent volutpat iaculis ligula. Suspendisse potenti.

+

+Etiam ut arcu eget libero rutrum mollis. Cras egestas, ipsum at mattis euismod, purus lectus ultrices nulla, et malesuada urna felis eget sem. Aenean id massa vitae elit commodo cursus. Nam odio massa, nonummy ut, pellentesque suscipit, sollicitudin eget, mi. Nam sagittis. Proin iaculis justo sit amet risus. Nunc eu odio. Suspendisse eget nulla. Donec ut lorem vel risus lacinia tristique. Ut egestas leo bibendum dolor. Duis enim mi, lobortis id, varius id, mollis in, eros. Etiam sapien diam, commodo at, porta sit amet, aliquam id, enim. Sed vel orci eget sapien rhoncus gravida. Nunc nibh. Maecenas facilisis. In hac habitasse platea dictumst. Aenean interdum, tellus a placerat pellentesque, arcu magna lacinia massa, id pulvinar turpis turpis non nisi. Pellentesque elementum. Nunc ut nunc.

+

+Maecenas tincidunt sagittis neque. Maecenas ac magna. Donec lobortis, tellus quis nonummy semper, odio massa accumsan ipsum, vel tincidunt nibh magna eu mi. In quis tortor non tellus consequat accumsan. Quisque molestie ligula et tortor. Fusce porttitor sodales odio. Maecenas at justo id lacus mollis semper. Proin tincidunt volutpat felis. Sed nec nibh a nibh convallis molestie. Sed porta magna eget odio. Aliquam ipsum arcu, commodo in, imperdiet ut, ultrices commodo, velit. Etiam tincidunt congue sem. Proin convallis lacus.

+

+Donec urna. Quisque aliquet suscipit arcu. Donec sit amet leo quis elit convallis venenatis. Pellentesque auctor tellus vel tellus. Suspendisse consectetuer, purus ut fringilla placerat, felis metus rutrum justo, non blandit arcu libero at odio. Mauris euismod, enim vitae tempor accumsan, dui lacus placerat dolor, nec rhoncus est augue non tortor. Sed quis urna in dolor dignissim hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus convallis lacus commodo libero. Phasellus ornare erat. Donec quis est eget augue posuere varius. Phasellus auctor. Maecenas vitae lectus. Aliquam pulvinar. Maecenas vitae magna eget mauris nonummy nonummy. Fusce libero nisl, nonummy non, dignissim ac, blandit non, dui.

+

+Pellentesque nec ligula vel lorem vehicula dictum. Cras vitae risus id diam congue congue. Nam dapibus ultrices nisi. In diam. Nullam velit. Maecenas risus. Nullam in sem. Fusce tincidunt ornare felis. In laoreet massa sed urna. Vestibulum lobortis ullamcorper arcu. Sed feugiat varius justo. Fusce scelerisque. Donec sit amet eros. Curabitur ullamcorper diam ac odio. Duis pharetra ultrices urna.

+

+Maecenas mauris. Integer fermentum, pede at laoreet interdum, lectus dolor laoreet erat, in egestas est lacus mollis erat. Duis hendrerit mauris ac nunc. Maecenas condimentum sem a odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ac nisi et leo malesuada auctor. Cras vestibulum. Quisque dui metus, viverra at, sodales vitae, tincidunt quis, massa. Nunc mauris. Suspendisse enim lorem, tincidunt suscipit, pharetra eget, egestas ac, lectus. Maecenas scelerisque. Nulla dapibus, massa sit amet tempor facilisis, quam sem semper quam, vitae euismod turpis enim in diam.

+

+Donec dignissim. Ut feugiat tincidunt orci. Praesent bibendum venenatis elit. Curabitur accumsan. Quisque ultrices magna. Nam in nisl. Aliquam ac ipsum. Aliquam enim orci, iaculis ut, ultrices id, ultrices ut, massa. Phasellus hendrerit mauris. Praesent feugiat, leo quis molestie luctus, erat massa egestas enim, non posuere velit dui eu felis. Praesent varius fringilla risus.

+

+Sed lacus sem, tempus dictum, convallis sit amet, placerat a, velit. Vestibulum sit amet lacus. Curabitur molestie. Suspendisse nec mauris. Praesent in diam vitae quam iaculis condimentum. Nam fringilla. Sed sollicitudin eros a enim. Curabitur dictum nunc sit amet lorem. Mauris odio purus, adipiscing vitae, porta ut, euismod rhoncus, risus. Pellentesque sit amet diam id urna rutrum nonummy. Morbi velit est, aliquet hendrerit, aliquet in, vestibulum quis, orci. Integer sed felis vitae quam venenatis malesuada. Curabitur scelerisque, massa sed eleifend sagittis, enim magna condimentum eros, a lacinia nisi ante ut nibh. Proin suscipit consectetuer nisl. Donec interdum, nisl eget vestibulum ultricies, massa purus elementum mi, in egestas lacus est at risus. Nunc a nibh vehicula lorem vulputate tincidunt. Cras est ligula, ullamcorper a, pulvinar et, ullamcorper eu, libero. Praesent et tortor id augue pretium condimentum. Pellentesque viverra, orci at placerat sodales, dolor risus dictum velit, sit amet ultrices nisl sapien id felis.

+

+Morbi vel turpis. Cras ut enim eget nisi volutpat nonummy. Sed iaculis. Maecenas metus mauris, fermentum eget, nonummy id, vulputate id, purus. Phasellus egestas lacus ac erat. Nullam sed metus. Morbi nunc pede, lobortis ut, pulvinar lacinia, accumsan quis, pede. Donec posuere rutrum mauris. Mauris cursus, nisl a venenatis congue, sapien tellus commodo magna, id fermentum sapien massa quis dui. Proin dignissim dui in odio.

+

+Mauris sit amet augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras eget eros sed augue faucibus malesuada. Pellentesque adipiscing iaculis orci. Integer id augue in neque convallis condimentum. Donec tristique, dolor id facilisis fermentum, tortor est vehicula turpis, et convallis sapien turpis vel est. Cras et lectus. Nam iaculis. Suspendisse eleifend nibh a nulla. Donec sit amet diam. Fusce porttitor lorem in velit. Maecenas egestas ante nec elit. Suspendisse dui nulla, consequat nec, feugiat sit amet, porta sed, urna. Nullam pellentesque purus non elit.

+

+Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris orci massa, imperdiet nec, pulvinar feugiat, varius at, leo. Pellentesque nec velit ac velit consectetuer iaculis. Etiam nonummy. Quisque et ligula. In ac dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus porta sagittis nulla. Suspendisse et risus.

+

+In in mauris nec libero egestas vehicula. Cras tincidunt blandit lorem. Phasellus facilisis urna vitae nisi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus gravida sem nec nisi. Nam magna est, tempor sed, venenatis eget, dictum sit amet, diam. Fusce elementum tincidunt enim. Integer tortor orci, lobortis nec, vehicula vitae, laoreet vitae, augue. Nullam fringilla aliquet ligula. Suspendisse vehicula nisi non dolor. Quisque nonummy urna et velit. Integer egestas commodo libero. Phasellus in sapien ac mi ornare pretium. In quis lorem vel dolor commodo ultricies.

+

+Mauris dolor. Nunc venenatis. Donec ullamcorper sapien ac est. Integer laoreet, magna nec scelerisque egestas, enim velit cursus dolor, nec pulvinar ligula odio non odio. Proin sit amet nisi eu erat rutrum viverra. Nullam tempus quam quis mi. Quisque tincidunt odio nec tortor. Nulla orci. Mauris sapien sapien, malesuada placerat, elementum bibendum, rhoncus eu, risus. Integer lectus. Curabitur velit magna, congue id, imperdiet id, lobortis in, nisl. Integer ultricies est quis sapien. Suspendisse vitae est.

+

+Quisque lacinia sapien ac diam. Morbi ornare ante ac elit. Quisque viverra. Aliquam erat volutpat. Quisque erat turpis, hendrerit vel, aliquam vel, vulputate tincidunt, ligula. Ut molestie molestie nulla. Vestibulum vitae dui. Etiam tellus. Suspendisse ligula. Maecenas cursus ornare tortor. In placerat consectetuer sem. Mauris quis risus et odio nonummy scelerisque. Aliquam venenatis. Etiam tempor. Sed arcu.

+

+Duis justo. Proin porta mattis nunc. Etiam posuere, arcu nec porta imperdiet, magna lorem interdum purus, vitae congue nisi lacus a est. Duis eu leo quis tortor congue lobortis. Vestibulum eu lorem. Integer bibendum. Integer et mi. Fusce venenatis. Aliquam erat volutpat. Nullam mi massa, dictum vel, ultricies ac, tempus non, leo. Aenean vitae ante. Suspendisse velit lacus, volutpat in, lacinia a, malesuada id, sapien. Duis blandit.

+

+In commodo lorem in leo. Curabitur turpis. Fusce nec odio. Nunc ac augue vel eros faucibus consectetuer. Pellentesque porta. Etiam blandit. Aliquam eget dolor. Curabitur ac elit eget arcu luctus pulvinar. Quisque molestie. Donec fermentum. Aenean pharetra eros a eros. Nam sagittis urna ut libero. Aliquam faucibus tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam justo mauris, posuere vel, vestibulum vel, laoreet at, dolor. Maecenas neque tellus, faucibus a, aliquet sed, varius vel, nisi. Sed commodo, purus quis hendrerit pulvinar, risus lectus ultrices pede, in rhoncus neque libero eu purus. Praesent vel risus. Nulla pharetra nibh a urna imperdiet congue. Sed suscipit laoreet magna.

+

+Phasellus pharetra leo. Vivamus sit amet dui sit amet urna convallis sollicitudin. Duis tempor placerat massa. Nulla dapibus. Nullam rutrum nulla non mi. Curabitur at sapien in risus pretium aliquam. Mauris vel erat sed enim porttitor dapibus. Nulla tincidunt. Etiam non nisl. Pellentesque in dolor. Praesent placerat quam et orci. Donec euismod orci ut ipsum. Quisque mollis porta velit. Suspendisse potenti. Duis accumsan lacus at ante. Etiam tortor justo, dictum ac, viverra quis, ultrices in, odio. In sit amet libero.

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/RunJettyUpload.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/RunJettyUpload.java
new file mode 100644
index 0000000..3ce7482
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/RunJettyUpload.java
@@ -0,0 +1,29 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.upload;
+
+import org.apache.tapestry.test.JettyRunner;
+
+import java.io.File;
+
+public class RunJettyUpload
+{
+    public static void main(String[] args) throws InterruptedException
+    {
+        File workingDir = new File(System.getProperty("user.dir"));
+
+        new JettyRunner(workingDir, "/", 8080, "src/test/webapp");
+    }
+}
diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java
new file mode 100755
index 0000000..a1a6006
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/components/UploadTest.java
@@ -0,0 +1,261 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.components;

+

+import org.apache.tapestry.*;

+import org.apache.tapestry.dom.Element;

+import org.apache.tapestry.services.FormSupport;

+import org.apache.tapestry.test.TapestryTestCase;

+import org.apache.tapestry.upload.services.MultipartDecoder;

+import org.apache.tapestry.upload.services.UploadedFile;

+import static org.easymock.EasyMock.expectLastCall;

+import org.testng.annotations.Test;

+

+public class UploadTest extends TapestryTestCase

+{

+

+    @Test

+    public void upload_is_field() throws Exception

+    {

+        assertTrue(Field.class.isAssignableFrom(Upload.class));

+    }

+

+    @Test

+    public void begin_render_writes_input_tag() throws Exception

+    {

+        MarkupWriter writer = createMarkupWriter();

+        writer.element("form");

+        FormSupport formSupport = mockFormSupport();

+        ComponentResources resources = mockComponentResources();

+

+        formSupport.setEncodingType(Upload.MULTIPART_ENCTYPE);

+

+        resources.renderInformalParameters(writer);

+

+        replay();

+

+        Upload component = new Upload(null, null, null, null, resources, null);

+

+        component.injectDecorator(new BaseValidationDecorator());

+        component.injectFormSupport(formSupport);

+

+        component.beginRender(writer);

+

+        Element element = writer.getElement();

+        assertNotNull(element);

+        assertEquals(element.getName(), "input");

+        assertEquals(element.getAttribute("type"), "file");

+        // assertEquals(element.getAttribute("name"),null);

+        // assertEquals(element.getAttribute("id"),null);

+

+        verify();

+

+    }

+

+    @Test

+    public void validation_decorator_invoked_inside_begin_render() throws Exception

+    {

+        getMocksControl().checkOrder(true);

+

+        ComponentResources resources = mockComponentResources();

+        Upload component = new Upload(null, null, null, null, resources, null);

+        MarkupWriter writer = createMarkupWriter();

+        writer.element("form");

+

+        FormSupport formSupport = mockFormSupport();

+        formSupport.setEncodingType(Upload.MULTIPART_ENCTYPE);

+

+        component.injectFormSupport(formSupport);

+

+        ValidationDecorator decorator = mockValidationDecorator();

+

+        component.injectDecorator(decorator);

+

+        resources.renderInformalParameters(writer);

+        decorator.insideField(component);

+

+        replay();

+

+        component.beginRender(writer);

+

+        verify();

+    }

+

+    private ValidationDecorator mockValidationDecorator()

+    {

+        return newMock(ValidationDecorator.class);

+    }

+

+    @SuppressWarnings("unchecked")

+    @Test

+    public void begin_render_invokes_field_validator() throws Exception

+    {

+        getMocksControl().checkOrder(true);

+

+        FieldValidator<Object> validate = mockFieldValidator();

+        ComponentResources resources = mockComponentResources();

+        Upload component = new Upload(null, validate, null, null, resources, null);

+        MarkupWriter writer = createMarkupWriter();

+        writer.element("form");

+

+        FormSupport formSupport = mockFormSupport();

+        formSupport.setEncodingType(Upload.MULTIPART_ENCTYPE);

+        component.injectFormSupport(formSupport);

+

+        ValidationDecorator decorator = mockValidationDecorator();

+

+        component.injectDecorator(decorator);

+

+        validate.render(writer);

+        resources.renderInformalParameters(writer);

+        decorator.insideField(component);

+

+        replay();

+

+        component.beginRender(writer);

+

+        verify();

+    }

+

+    @Test

+    public void after_render_closes_element() throws Exception

+    {

+        Upload component = new Upload();

+        MarkupWriter writer = mockMarkupWriter();

+

+        expect(writer.end()).andReturn(null);

+

+        replay();

+

+        component.afterRender(writer);

+

+        verify();

+

+    }

+

+    @SuppressWarnings({"unchecked"})

+    @Test

+    public void process_submission_extracts_value_from_decoder() throws Exception

+    {

+        MultipartDecoder decoder = mockMultipartDecoder();

+        UploadedFile uploadedFile = mockUploadedFile();

+        ComponentResources resources = mockComponentResources();

+        FieldValidationSupport support = mockFieldValidationSupport();

+        FieldValidator validate = mockFieldValidator();

+

+        Upload component = new Upload(null, validate, decoder, null, resources, support);

+

+        expect(decoder.getFileUpload("test")).andReturn(uploadedFile);

+        expect(uploadedFile.getFileName()).andReturn("foo").anyTimes();

+

+        support.validate(uploadedFile, resources, validate);

+

+        replay();

+

+        component.processSubmission("test");

+

+        verify();

+

+        assertSame(component.getValue(), uploadedFile);

+    }

+

+    @SuppressWarnings({"unchecked"})

+    @Test

+    public void process_submission_ignores_null_value() throws Exception

+    {

+        MultipartDecoder decoder = mockMultipartDecoder();

+        UploadedFile uploadedFile = mockUploadedFile();

+        ComponentResources resources = mockComponentResources();

+        FieldValidationSupport support = mockFieldValidationSupport();

+        FieldValidator validate = mockFieldValidator();

+

+        Upload component = new Upload(null, validate, decoder, null, resources, support);

+

+        expect(decoder.getFileUpload("test")).andReturn(uploadedFile);

+        expect(uploadedFile.getFileName()).andReturn("").atLeastOnce();

+

+        support.validate(null, resources, validate);

+

+

+        replay();

+

+        component.processSubmission("test");

+

+        verify();

+

+        assertNull(component.getValue());

+    }

+

+    @SuppressWarnings("unchecked")

+    @Test

+    public void process_submission_calls_validator() throws Exception

+    {

+        MultipartDecoder decoder = mockMultipartDecoder();

+        UploadedFile uploadedFile = mockUploadedFile();

+        FieldValidator<Object> validate = mockFieldValidator();

+        ComponentResources resources = mockComponentResources();

+        FieldValidationSupport support = mockFieldValidationSupport();

+

+        Upload component = new Upload(null, validate, decoder, null, resources, support);

+

+        expect(decoder.getFileUpload("test")).andReturn(uploadedFile);

+        expect(uploadedFile.getFileName()).andReturn("test").atLeastOnce();

+

+        support.validate(uploadedFile, resources, validate);

+

+        replay();

+

+        component.processSubmission("test");

+

+        verify();

+    }

+

+    @SuppressWarnings({"unchecked", "ThrowableInstanceNeverThrown"})

+    @Test

+    public void process_submission_tracks_validator_errors() throws Exception

+    {

+        MultipartDecoder decoder = mockMultipartDecoder();

+        UploadedFile uploadedFile = mockUploadedFile();

+        FieldValidator<Object> validate = mockFieldValidator();

+        ValidationTracker tracker = mockValidationTracker();

+        ComponentResources resources = mockComponentResources();

+        FieldValidationSupport support = mockFieldValidationSupport();

+

+        Upload component = new Upload(null, validate, decoder, tracker, resources, support);

+

+        expect(decoder.getFileUpload("test")).andReturn(uploadedFile);

+        expect(uploadedFile.getFileName()).andReturn("test").atLeastOnce();

+

+        support.validate(uploadedFile, resources, validate);

+        expectLastCall().andThrow(new ValidationException("an error"));

+

+        tracker.recordError(component, "an error");

+        replay();

+

+        component.processSubmission("test");

+

+        verify();

+    }

+

+    protected final UploadedFile mockUploadedFile()

+    {

+        return newMock(UploadedFile.class);

+    }

+

+    protected final MultipartDecoder mockMultipartDecoder()

+    {

+        return newMock(MultipartDecoder.class);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/integration/UploadIntegrationTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/integration/UploadIntegrationTest.java
new file mode 100755
index 0000000..3f9fa0e
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/integration/UploadIntegrationTest.java
@@ -0,0 +1,60 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.upload.integration;

+

+import org.apache.tapestry.test.AbstractIntegrationTestSuite;

+import org.example.upload.pages.Start;

+import org.testng.annotations.BeforeTest;

+import org.testng.annotations.Test;

+

+import java.io.File;

+import java.io.IOException;

+

+/**

+ * . TODO: These tests wont work because Selenium cannot enter values for input type="file'

+ */

+public class UploadIntegrationTest extends AbstractIntegrationTestSuite

+{

+

+    @BeforeTest

+    public void setupTargetFolder() throws IOException

+    {

+        File target = new File(Start.TARGET_DIR);

+        if (!target.exists())

+        {

+            target.mkdirs();

+        }

+        else

+        {

+            for (File file : target.listFiles())

+            {

+                file.delete();

+            }

+        }

+    }

+

+    @Test(enabled = false)

+    public void integration_test() throws Exception

+    {

+

+        open(BASE_URL);

+

+        File source = new File("test/data/upload.txt");

+

+        type("file", source.getCanonicalPath());

+        clickAndWait("//input[@value='Upload']");

+

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImplTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImplTest.java
new file mode 100755
index 0000000..af4af5d
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartDecoderImplTest.java
@@ -0,0 +1,221 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.FileItem;

+import org.apache.commons.fileupload.servlet.ServletFileUpload;

+import org.apache.tapestry.test.TapestryTestCase;

+import org.testng.annotations.Test;

+

+import javax.servlet.http.HttpServletRequest;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Collections;

+import java.util.List;

+

+public class MultipartDecoderImplTest extends TapestryTestCase

+{

+

+    @Test

+    public void create_file_upload_gets_configuration_from_symbols() throws Exception

+    {

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, 7777, 6666);

+

+        replay();

+

+        ServletFileUpload servletFileUpload = decoder.createFileUpload();

+        assertNotNull(servletFileUpload);

+

+        verify();

+

+        assertEquals(servletFileUpload.getFileSizeMax(), 6666);

+        assertEquals(servletFileUpload.getSizeMax(), 7777);

+    }

+

+    @Test

+    public void process_file_items_does_nothing_when_null_file_items() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+

+        replay();

+

+        HttpServletRequest decodedRequest = decoder.processFileItems(request, null);

+

+        verify();

+

+        assertSame(request, decodedRequest);

+    }

+

+    @Test

+    public void process_file_items_does_nothing_when_empty_file_items() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+        List<FileItem> fileItems = Collections.emptyList();

+

+        replay();

+

+        HttpServletRequest decodedRequest = decoder.processFileItems(request, fileItems);

+

+        verify();

+

+        assertSame(request, decodedRequest);

+    }

+

+    @Test

+    public void process_file_items_creates_wrapped_request_and_sets_non_file_parameters() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+

+        train_getCharacterEncoding(request, "UTF-8");

+

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+        List<FileItem> fileItems = Arrays.asList(createValueItem("one", "first"), createValueItem("two", "second"));

+

+        replay();

+

+        HttpServletRequest decodedRequest = decoder.processFileItems(request, fileItems);

+

+        assertNotSame(decodedRequest, request);

+

+        assertEquals(decodedRequest.getParameter("one"), "first");

+        assertEquals(decodedRequest.getParameter("two"), "second");

+

+        verify();

+    }

+

+    @Test

+    public void non_file_items_with_null_request_encoding() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+

+        train_getCharacterEncoding(request, null);

+

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+

+        List<FileItem> fileItems = Arrays.asList(createValueItem("one", "first"), createValueItem("two", "second"));

+

+        replay();

+

+        HttpServletRequest decodedRequest = decoder.processFileItems(request, fileItems);

+

+        assertNotSame(decodedRequest, request);

+

+        assertEquals(decodedRequest.getParameter("one"), "first");

+        assertEquals(decodedRequest.getParameter("two"), "second");

+

+        verify();

+    }

+

+    @Test

+    public void process_file_items_set_file_parameters_with_file_name() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+        List<FileItem> fileItems = Arrays.asList(createFileItem("one", "first.txt"),

+                                                 createFileItem("two", "second.txt"));

+

+        train_getCharacterEncoding(request, null);

+

+        replay();

+

+        HttpServletRequest decodedRequest = decoder.processFileItems(request, fileItems);

+

+        assertNotSame(decodedRequest, request);

+

+        assertEquals(decodedRequest.getParameter("one"), "first.txt");

+        assertEquals(decodedRequest.getParameter("two"), "second.txt");

+

+        verify();

+    }

+

+    @Test

+    public void uploaded_file_stored() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+        List<FileItem> fileItems = Arrays.asList(createFileItem("one", "first.txt"),

+                                                 createFileItem("two", "second.txt"));

+

+        train_getCharacterEncoding(request, null);

+

+        replay();

+

+        decoder.processFileItems(request, fileItems);

+

+        verify();

+

+        assertNotNull(decoder.getFileUpload("one"));

+        assertEquals(decoder.getFileUpload("one").getFileName(), "first.txt");

+        assertNotNull(decoder.getFileUpload("two"));

+        assertEquals(decoder.getFileUpload("two").getFileName(), "second.txt");

+    }

+

+    @Test

+    public void file_items_cleaned_up() throws Exception

+    {

+        HttpServletRequest request = mockHttpServletRequest();

+        MultipartDecoderImpl decoder = new MultipartDecoderImpl("/tmp", 888, -1, -1);

+        StubFileItem firstItem = new StubFileItem("one");

+        firstItem.setFormField(false);

+        StubFileItem secondItem = new StubFileItem("two");

+        secondItem.setFormField(false);

+

+        train_getCharacterEncoding(request, null);

+

+        List<FileItem> fileItems = new ArrayList<FileItem>();

+        fileItems.add(firstItem);

+        fileItems.add(secondItem);

+

+

+        replay();

+

+        decoder.processFileItems(request, fileItems);

+

+        assertFalse(firstItem.isDeleted());

+        assertFalse(secondItem.isDeleted());

+        decoder.threadDidCleanup();

+        assertTrue(firstItem.isDeleted());

+        assertTrue(secondItem.isDeleted());

+

+        verify();

+    }

+

+    private FileItem createValueItem(String name, String value)

+    {

+        StubFileItem item = new StubFileItem();

+        item.setFieldName(name);

+        item.setValue(value);

+        item.setFormField(true);

+

+        return item;

+    }

+

+    private FileItem createFileItem(String name, String fileName)

+    {

+        StubFileItem item = new StubFileItem();

+        item.setFieldName(name);

+        item.setFileName(fileName);

+        item.setFormField(false);

+

+        return item;

+    }

+

+    protected final void train_getCharacterEncoding(HttpServletRequest request, String encoding)

+    {

+        expect(request.getCharacterEncoding()).andReturn(encoding).atLeastOnce();

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilterTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilterTest.java
new file mode 100755
index 0000000..4a2d532
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/MultipartServletRequestFilterTest.java
@@ -0,0 +1,72 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.tapestry.services.HttpServletRequestHandler;

+import org.apache.tapestry.test.TapestryTestCase;

+import org.apache.tapestry.upload.services.MultipartDecoder;

+import org.testng.annotations.Test;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+public class MultipartServletRequestFilterTest extends TapestryTestCase

+{

+

+    @Test

+    public void normalRequestDoesNothing() throws Exception

+    {

+        MultipartDecoder decoder = newMock(MultipartDecoder.class);

+        HttpServletRequest request = mockHttpServletRequest();

+        HttpServletResponse response = mockHttpServletResponse();

+        HttpServletRequestHandler handler = newMock(HttpServletRequestHandler.class);

+

+        MultipartServletRequestFilter filter = new MultipartServletRequestFilter(decoder);

+

+        expect(request.getMethod()).andReturn("get");

+

+        expect(handler.service(request, response)).andReturn(true);

+

+        replay();

+

+        boolean isHandled = filter.service(request, response, handler);

+        assertTrue(isHandled);

+        verify();

+    }

+

+    @Test

+    public void multipartRequestIsDecoded() throws Exception

+    {

+        MultipartDecoder decoder = newMock(MultipartDecoder.class);

+        HttpServletRequest request = mockHttpServletRequest();

+        HttpServletRequest decodedRequest = mockHttpServletRequest();

+        HttpServletResponse response = mockHttpServletResponse();

+        HttpServletRequestHandler handler = newMock(HttpServletRequestHandler.class);

+

+        MultipartServletRequestFilter filter = new MultipartServletRequestFilter(decoder);

+

+        expect(request.getMethod()).andReturn("post");

+        expect(request.getContentType()).andReturn("multipart/form");

+        expect(decoder.decode(request)).andReturn(decodedRequest);

+

+        expect(handler.service(decodedRequest, response)).andReturn(true);

+

+        replay();

+

+        boolean isHandled = filter.service(request, response, handler);

+        assertTrue(isHandled);

+        verify();

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParameterValueTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParameterValueTest.java
new file mode 100755
index 0000000..914adf9
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParameterValueTest.java
@@ -0,0 +1,76 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import static org.testng.Assert.*;

+import org.testng.annotations.Test;

+

+public class ParameterValueTest

+{

+

+    @Test

+    public void singleGivesConstructedParameterByDefault() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo");

+        assertEquals(value.single(), "foo");

+    }

+

+    @Test

+    public void multiReturnsArrayWithConstructedParameterByDefault() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo");

+        assertEquals(value.multi(), new String[]{"foo"});

+    }

+

+    @Test

+    public void singleGivesFirstValueOfMultiValue() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo", "blah");

+        assertEquals(value.single(), "foo");

+    }

+

+    @Test

+    public void multiGivesAllValuesOfMultiValue() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo");

+        value.add("blah");

+        assertEquals(value.multi(), new String[]{"foo", "blah"});

+    }

+

+    @Test

+    public void isMultiIsFalseForSingleValue() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo");

+        assertFalse(value.isMulti());

+    }

+

+    @Test

+    public void isMultiIsTrueForMultiValue() throws Exception

+    {

+        ParameterValue value = new ParameterValue("foo");

+        value.add("blah");

+        assertTrue(value.isMulti());

+    }

+

+    @Test

+    public void nullObjectGivesNullForSingleAndMulti() throws Exception

+    {

+        ParameterValue value = ParameterValue.NULL;

+        assertNull(value.single());

+        assertNull(value.multi());

+        assertFalse(value.isMulti());

+    }

+

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapperTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapperTest.java
new file mode 100755
index 0000000..7335002
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/ParametersServletRequestWrapperTest.java
@@ -0,0 +1,173 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import static org.easymock.EasyMock.*;

+import static org.testng.Assert.*;

+import org.testng.annotations.Test;

+

+import javax.servlet.http.HttpServletRequest;

+import java.util.Enumeration;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Set;

+

+public class ParametersServletRequestWrapperTest

+{

+    @Test

+    public void getParameterNamesIsNotDelegated() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+

+        replay(request);

+

+        Enumeration names = wrapper.getParameterNames();

+

+        verify(request);

+

+        assertNotNull(names);

+        assertFalse(names.hasMoreElements());

+    }

+

+    @Test

+    public void getParameterMapIsNotDelegated() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+

+        replay(request);

+

+        Map parameters = wrapper.getParameterMap();

+

+        verify(request);

+        assertNotNull(parameters);

+        assertTrue(parameters.isEmpty());

+    }

+

+    @Test

+    public void getParameterIsNotDelegated() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+

+        replay(request);

+

+        String value = wrapper.getParameter("foo");

+

+        verify(request);

+        assertNull(value);

+    }

+

+    @Test

+    public void getParameterValuesIsNotDelegated() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+

+        replay(request);

+

+        String[] values = wrapper.getParameterValues("foo");

+

+        verify(request);

+        assertNull(values);

+    }

+

+    @Test

+    public void getParameterForSingleValue() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+        replay(request);

+

+        wrapper.addParameter("foo", "blah");

+

+        assertEquals(wrapper.getParameter("foo"), "blah");

+        verify(request);

+    }

+

+    @Test

+    public void getParameterForMultiValueGivesFirstValue() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+        replay(request);

+

+        wrapper.addParameter("foo", "blah");

+        wrapper.addParameter("foo", "another");

+

+        assertEquals(wrapper.getParameter("foo"), "blah");

+        verify(request);

+    }

+

+    @Test

+    public void getParameterValuesForMultiValueGivesAll() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+        replay(request);

+

+        wrapper.addParameter("foo", "blah");

+        wrapper.addParameter("foo", "another");

+

+        assertEquals(wrapper.getParameterValues("foo"), new String[]{"blah", "another"});

+        verify(request);

+    }

+

+    @Test

+    public void getParameterNamesHasAllNames() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+        replay(request);

+

+        wrapper.addParameter("one", "blah");

+        wrapper.addParameter("two", "another");

+

+        Enumeration nameEnumerator = wrapper.getParameterNames();

+        Set<String> names = new HashSet<String>();

+        assertTrue(nameEnumerator.hasMoreElements());

+        names.add((String) nameEnumerator.nextElement());

+        assertTrue(nameEnumerator.hasMoreElements());

+        names.add((String) nameEnumerator.nextElement());

+

+        assertTrue(names.contains("one"));

+        assertTrue(names.contains("two"));

+        verify(request);

+    }

+

+    @Test

+    public void getParameterMapHasAllValues() throws Exception

+    {

+        HttpServletRequest request = createMock(HttpServletRequest.class);

+        ParametersServletRequestWrapper wrapper = new ParametersServletRequestWrapper(request);

+        replay(request);

+

+        wrapper.addParameter("single", "blah");

+        wrapper.addParameter("multi", "one");

+        wrapper.addParameter("multi", "two");

+

+        Map parameters = wrapper.getParameterMap();

+        assertEquals(parameters.size(), 2);

+        assertEquals(parameters.get("single"), "blah");

+        assertEquals((String[]) parameters.get("multi"), new String[]{"one", "two"});

+

+        verify(request);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/StubFileItem.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/StubFileItem.java
new file mode 100755
index 0000000..968ff21
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/StubFileItem.java
@@ -0,0 +1,134 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.FileItem;

+

+import java.io.*;

+

+public class StubFileItem implements FileItem

+{

+    private static final long serialVersionUID = -7041417646464173208L;

+

+    private String fileName;

+

+    private String value;

+

+    private String fieldName;

+

+    private boolean formField;

+

+    private boolean isDeleted;

+

+    public StubFileItem()

+    {

+    }

+

+    public StubFileItem(String fieldName)

+    {

+        this.fieldName = fieldName;

+    }

+

+    public InputStream getInputStream() throws IOException

+    {

+        return null;

+    }

+

+    public String getContentType()

+    {

+        return null;

+    }

+

+    public String getName()

+    {

+        return fileName;

+    }

+

+    public boolean isInMemory()

+    {

+        return true;

+    }

+

+    public long getSize()

+    {

+        return 10;

+    }

+

+    public byte[] get()

+    {

+        return new byte[0]; // To change body of implemented methods use File | Settings | File

+        // Templates.

+    }

+

+    public String getString(String string) throws UnsupportedEncodingException

+    {

+        return getString();

+    }

+

+    public String getString()

+    {

+        return value;

+    }

+

+    public void write(File file) throws Exception

+    {

+    }

+

+    public void delete()

+    {

+        isDeleted = true;

+    }

+

+    public String getFieldName()

+    {

+        return fieldName; // To change body of implemented methods use File | Settings | File

+        // Templates.

+    }

+

+    public void setFieldName(String fieldName)

+    {

+        this.fieldName = fieldName;

+    }

+

+    public boolean isFormField()

+    {

+        return formField;

+    }

+

+    public void setFormField(boolean formField)

+    {

+        this.formField = formField;

+    }

+

+    public OutputStream getOutputStream() throws IOException

+    {

+        return null;

+    }

+

+    public void setFileName(String fileName)

+    {

+        this.fileName = fileName;

+    }

+

+    public void setValue(String value)

+    {

+        this.value = value;

+    }

+

+    public boolean isDeleted()

+    {

+        return isDeleted;

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/UploadedFileItemTest.java b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/UploadedFileItemTest.java
new file mode 100755
index 0000000..c9f0ef2
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/apache/tapestry/upload/internal/services/UploadedFileItemTest.java
@@ -0,0 +1,147 @@
+// Copyright 2007, 2008 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.tapestry.upload.internal.services;

+

+import org.apache.commons.fileupload.FileItem;

+import org.apache.commons.io.input.NullInputStream;

+import org.apache.tapestry.test.TapestryTestCase;

+import org.testng.annotations.Test;

+

+import java.io.File;

+import java.io.InputStream;

+

+public class UploadedFileItemTest extends TapestryTestCase

+{

+    @Test

+    public void contentTypeIsFileItemContentType() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.getContentType()).andReturn("foo");

+

+        replay();

+

+        assertEquals(uploadedFile.getContentType(), "foo");

+

+        verify();

+    }

+

+    @Test

+    public void fileNameExtractedFromFileItemName() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.getName()).andReturn("foo/blah.txt");

+

+        replay();

+

+        assertEquals(uploadedFile.getFileName(), "blah.txt");

+

+        verify();

+    }

+

+    @Test

+    public void filePathIsFileItemName() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.getName()).andReturn("foo/blah.txt");

+

+        replay();

+

+        assertEquals(uploadedFile.getFilePath(), "foo/blah.txt");

+

+        verify();

+    }

+

+    @Test

+    public void sizeIsFileItemSize() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.getSize()).andReturn(66l);

+

+        replay();

+

+        assertEquals(uploadedFile.getSize(), 66);

+

+        verify();

+    }

+

+    @Test

+    public void inMemoryIsFileItemInMemory() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.isInMemory()).andReturn(true);

+

+        replay();

+

+        assertTrue(uploadedFile.isInMemory());

+

+        verify();

+    }

+

+    @Test

+    public void streamIsFileItemStream() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        InputStream stream = new NullInputStream(3);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        expect(item.getInputStream()).andReturn(stream);

+

+        replay();

+

+        assertSame(uploadedFile.getStream(), stream);

+

+        verify();

+    }

+

+    @Test

+    public void writeUsesFileItemWrite() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        File out = new File("");

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+

+        item.write(out);

+

+        replay();

+

+        uploadedFile.write(out);

+

+        verify();

+

+    }

+

+    @Test

+    public void cleanupCallsFileItemDelete() throws Exception

+    {

+        FileItem item = newMock(FileItem.class);

+        UploadedFileItem uploadedFile = new UploadedFileItem(item);

+        item.delete();

+

+        replay();

+        uploadedFile.cleanup();

+        verify();

+    }

+

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/pages/Start.java b/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/pages/Start.java
new file mode 100755
index 0000000..6d387e4
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/pages/Start.java
@@ -0,0 +1,45 @@
+// Copyright 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.example.upload.pages;

+

+import org.apache.tapestry.annotation.Persist;

+import org.apache.tapestry.upload.services.UploadedFile;

+

+import java.io.File;

+

+public class Start

+{

+    public static final String TARGET_DIR = "target/tmp/";

+

+    @Persist

+    private UploadedFile file;

+

+    public UploadedFile getFile()

+    {

+        return file;

+    }

+

+    public void setFile(UploadedFile file)

+    {

+        this.file = file;

+    }

+

+    public void onSuccess()

+    {

+        File copied = new File(TARGET_DIR + file.getFileName());

+

+        file.write(copied);

+    }

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/services/AppModule.java b/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/services/AppModule.java
new file mode 100755
index 0000000..b7d9c35
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/java/org/example/upload/services/AppModule.java
@@ -0,0 +1,28 @@
+// Copyright 2007 The Apache Software Foundation

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//     http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

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

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.example.upload.services;

+

+import org.apache.tapestry.ioc.annotation.SubModule;

+import org.apache.tapestry.upload.services.UploadModule;

+

+/**

+ * The SubModule is not normally needed, except that during tests of tapestry-upload, the necessary JAR Manifest does

+ * not yet exist, so we force the tapestry.upload module into the registry explicitly.

+ */

+@SubModule(UploadModule.class)

+public class AppModule

+{

+

+}

diff --git a/hlship-20080520/tapestry-upload/src/test/webapp/Start.tml b/hlship-20080520/tapestry-upload/src/test/webapp/Start.tml
new file mode 100755
index 0000000..9307a74
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/webapp/Start.tml
@@ -0,0 +1,36 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <!--
+       Copyright 2007, 2008 The Apache Software Foundation
+
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+    -->
+    <head>
+        <title>Start Page</title>
+    </head>
+    <body>
+        <p>
+            This test of the upload component
+        </p>
+        <t:form>
+            <t:errors/>
+            <t:label for="file"/>
+            <input t:type="upload" t:id="file" validate="required"/>
+            <br/>
+            <input type="submit" value="Upload"/>
+        </t:form>
+        <t:if test="file">
+            <p>File: ${file.filePath}</p>
+            <p>Size: ${file.size}</p>
+        </t:if>
+    </body>
+</html>
\ No newline at end of file
diff --git a/hlship-20080520/tapestry-upload/src/test/webapp/WEB-INF/web.xml b/hlship-20080520/tapestry-upload/src/test/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..613fdd2
--- /dev/null
+++ b/hlship-20080520/tapestry-upload/src/test/webapp/WEB-INF/web.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright 2006, 2008 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT 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>Tapestry-Upload Integration Test Application</display-name>
+    <context-param>
+        <param-name>tapestry.app-package</param-name>
+        <param-value>org.example.upload</param-value>
+    </context-param>
+    <filter>
+        <filter-name>app</filter-name>
+        <filter-class>org.apache.tapestry.TapestryFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>app</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+</web-app>